Massimo преди 5 години
родител
ревизия
c64a935a82
променени са 15 файла, в които са добавени 420 реда и са изтрити 277 реда
  1. +5
    -0
      CHANGELOG.md
  2. +39
    -32
      README.md
  3. +2
    -7
      boolean-logic-ultimate/BDebug.html
  4. +0
    -2
      boolean-logic-ultimate/BDebug.js
  5. +123
    -0
      boolean-logic-ultimate/BooleanLogicUltimate.html
  6. +139
    -0
      boolean-logic-ultimate/BooleanLogicUltimate.js
  7. +2
    -7
      boolean-logic-ultimate/Invert.html
  8. +0
    -2
      boolean-logic-ultimate/Invert.js
  9. +24
    -11
      boolean-logic-ultimate/NodeHelper.js
  10. +0
    -106
      boolean-logic/BooleanLogic.html
  11. +0
    -96
      boolean-logic/BooleanLogic.js
  12. +9
    -0
      node_modules/fs/README.md
  13. +45
    -0
      node_modules/fs/package.json
  14. +13
    -0
      package-lock.json
  15. +19
    -14
      package.json

+ 5
- 0
CHANGELOG.md Целия файл

@@ -0,0 +1,5 @@
# node-red-contrib-boolean-logic-ultimate
<p>
<b>Version 0.0.1</b><br/>
- Initial release<br/>
</p>

+ 39
- 32
README.md Целия файл

@@ -1,32 +1,39 @@
# node-red-contrib-boolean-logic
[Node-RED](http://nodered.org/) nodes to easily perform boolean logic.

## The problem
[Node-RED](http://nodered.org/) does not support multiple inputs on nodes, and it has been discussed at length in [this thread](https://groups.google.com/forum/#!searchin/node-red/multiple$20inputs%7Csort:relevance/node-red/Q0YLQYCUJ_E/JVNjznmx2e8J). The TL;DR - as I understand it - is that the developers of NR argue that multiple inputs makes it too complex for users without a background in electrical engineering and that it is [preferred](https://groups.google.com/d/msg/node-red/Q0YLQYCUJ_E/DTxHFcVfAwAJ) users of NR instead use other means to create the desired logic (i.e. write Javascript in function-nodes).

## A solution
I really needed a simple and reusable way to perform boolean logic on multiple topics without the need to write the same code over and over.

Could this be solved using a subflow? No, function-node within a subflow cannot be configured on an instance basis which is required as the logic must know how many inputs it is expecting when performing operations such as ```A || B``` or ```A && (B || C)```. Yes, that could be hard coded, but then it would not be reusable. Also, a subflow cannot use the status indicator which is a great help to the user.

What I came up with are the following nodes.
* BooleanLogic: Can perform AND, OR and XOR operations on ```msg.payload``` on any number of topics.
* Invert: Inverts the ```msg.payload```, e.g. true -> false.
* Debug: A debug node that displays the status direcly in the editor, making it easier to see the boolean value at a specific point.

All nodes attempts to convert the incoming ```msg.payload``` to a boolean value according to these rules:
* Boolean values are taken as-is.
* For numbers, 0 evaluates to false, all other numbers evaluates to true.
* Strings are converted to numbers if they match the format of a decimal value, then the same rule as for numbers are applied. If it does not match, it evaluates to false. Also, the string "true" evaluates to true.

### BooleanLogic
This node must be configured with the expected number of topics. It will not output a value until it has received the configured number of topics. Also, if it receives more than the configured number of topics it will reset (but not output a value) and wait until it once again sees the configured number of topics.

## Example
![Example](http://i.imgur.com/m2s6JRl.png)

## Version history
* 0.0.1 First release
* 0.0.2
* Changed status indicators from dot to rings for false-values.
* Reworked the conversion of input values to be consistent between numbers and strings with numeric meaning.
# node-red-contrib-boolean-logic-ultimate

## DESCRIPTION
The node performs Boolean logic on the incoming payloads.<br/>
The node performs 3 checks (<b>AND,OR,XOR</b>) on the incoming boolean payloads and outputs the result at the same time, as follow:<br/>
- Output "AND": true or false<br/>
- Output "OR": true or false<br/>
- Output "XOR": true or false<br/>

The node can have a persistent input: the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.

## CHANGELOG
* See <a href="https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate/blob/master/CHANGELOG.md">here the changelog</a>

## CONFIGURATION
<p>
The node expects a fixed number of topics (configured in the settings) on which it will operate. It will only output a value
when it has seen the expected number of topics. If it ever sees more than the configured number of topics it will log a message then reset its state and start over.<br/>
Changing the topic is usually only needed when chaining multiple boolean nodes after each other becuse the topics will then all be the same when delivered to the nodes further down the chain.<br/>
<br/>
<b>Filter output result</b><br />
<ol>
<li>Output both 'true' and 'false' results: Standard behaviour, the node will output <b>true</b> and <b>false</b> whenever it receives an input and calculate the boolean logics as output.</li>
<li>Output only 'true' results: whenever the node receives an input, it outputs a payload <b>true</b> only if the result of the logic is true. <b>False</b> results are filtered out.</li>
</ol>
<br/>
<b>Remember latest input values after reboot</b><br />
If checked, the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.<br/>
Every time you modify the node's config, <b>the retained values are cleared</b>.<br/>
<br/>
All incoming msg.payloads are converted into a boolean value according to the following rules (this applies to all boolean logic nodes):
<ol>
<li>Boolean values are taken as-is.</li>
<li>For numbers, 0 evaluates to false, all other numbers evaluates to true.</li>
<li>Strings are converted to numbers if they match the format of a decimal value, then the same rule as for numbers are applied. If it does not match, it evaluates to false. Also, the string "true" evaluates to true.</li>
</ol>
<br>
The XOR operation operates in a one, and only one mode, i.e. (A ^ B) ^ C ... ^ n
</p>

boolean-logic/BDebug.html → boolean-logic-ultimate/BDebug.html Целия файл

@@ -1,12 +1,7 @@
<!--
Licensed under the MIT license, see LICENSE file.
Author: Per Malmberg (https://github.com/PerMalmberg)
-->

<script type="text/javascript">
RED.nodes.registerType('BDebug',{
category: 'boolean logic',
color: '#C0DEED',
category: 'boolean logic ultimate',
color: '#ff8080',
defaults: {
name: {
value: "Debug"

boolean-logic/BDebug.js → boolean-logic-ultimate/BDebug.js Целия файл

@@ -1,5 +1,3 @@
// Licensed under the MIT license, see LICENSE file.
// Author: Per Malmberg (https://github.com/PerMalmberg)
module.exports = function(RED) {
function BDebug(config) {
RED.nodes.createNode(this,config);

+ 123
- 0
boolean-logic-ultimate/BooleanLogicUltimate.html Целия файл

@@ -0,0 +1,123 @@
<script type="text/javascript">
RED.nodes.registerType('BooleanLogicUltimate',{
category: 'boolean logic ultimate',
color: '#ff8080',
defaults: {
name: {
value: ""
},
filtertrue: {value:"both"},
persist: {value:true},
inputCount: {
value: 2,
required: true,
validate:
function(v) {
return !isNaN( parseInt( v ) ) && parseInt( v ) >= 2;
}
},
topic: {
value: "result",
required: true,
validate:
function(v) {
return v !== undefined && v.length > 0;
}
}
},
inputs:1,
outputs:3,
outputLabels: function(i) {
var ret="";
switch (i) {
case 0:
return "AND";
break;
case 1:
return "OR";
break;
case 2
:
return "XOR";
break;
default:
break;
}
},
icon: "serial.png",
label:
function() {
var label = "Logic" + " [" + this.inputCount + "]";
if( this.name !== undefined && this.name.length > 0 ) {
label = label + " (" + this.name + ")";
}
return label;
},
paletteLabel: function() {
return "Boolean Logic Ultimate";
},
oneditsave: function () {
}
});
</script>

<script type="text/x-red" data-template-name="BooleanLogicUltimate">
<div class="form-row">
<label for="node-input-filtertrue"><i class="icon-tag"></i> Filter output result</label>
<select type="text" id="node-input-filtertrue" placeholder="Filter">
<option value="both">Output both 'true' and 'false' results</option>
<option value="onlytrue">Output only 'true' results</option>
</select>
</div>
<div class="form-row">
<input type="checkbox" id="node-input-persist" style="display:inline-block; width:auto; vertical-align:top;">
<label style="width:auto" for="node-input-persist"> Remember latest input values after reboot</label>
<div id="helpallga"><i> If checked, the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.</div>
</div>
<div class="form-row">
<label for="node-input-inputCount"><i class="icon-tag"></i> Number of topics</label>
<input type="text" id="node-input-inputCount" placeholder="Number of topics to consider">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="icon-tag"></i> Topic</label>
<input type="text" id="node-input-topic" placeholder="Topic">
</div>
</script>

<script type="text/x-red" data-help-name="BooleanLogicUltimate">
<p>The node performs Boolean logic on the incoming payloads.<br/>
The node performs 3 checks (<b>AND,OR,XOR</b>) on the incoming boolean payloads and outputs the result at the same time, as follow:<br/>
- Output "AND": true or false<br/>
- Output "OR": true or false<br/>
- Output "XOR": true or false<br/>
<br/>
Changing the topic is usually only needed when chaining multiple boolean nodes after each other becuse the topics will then all be the same when delivered to the nodes further down the chain.<br/>
<br/>
The node expects a fixed number of topics (configured in the settings) on which it will operate. It will only output a value
when it has seen the expected number of topics. If it ever sees more than the configured number of topics it will log a message then reset its state and start over.<br/>
<br/><br/>
<b>Filter output result</b><br />
<ol>
<li>Output both 'true' and 'false' results: Standard behaviour, the node will output <b>true</b> and <b>false</b> whenever it receives an input and calculate the boolean logics as output.</li>
<li>Output only 'true' results: whenever the node receives an input, it outputs a payload <b>true</b> only if the result of the logic is true. <b>False</b> results are filtered out.</li>
</ol>
<br/><br/>
<b>Remember latest input values after reboot</b><br />
If checked, the input values are retained after a node-red reboot. That means, that if you reboot your node-red, you don't need to wait all inputs to arrive and initialize the node, before the node can output a payload.<br/>
Every time you modify the node's config, <b>the retained values are cleared</b>.<br/>
<br/>
All incoming msg.payloads are converted into a boolean value according to the following rules (this applies to all boolean logic nodes):
<ol>
<li>Boolean values are taken as-is.</li>
<li>For numbers, 0 evaluates to false, all other numbers evaluates to true.</li>
<li>Strings are converted to numbers if they match the format of a decimal value, then the same rule as for numbers are applied. If it does not match, it evaluates to false. Also, the string "true" evaluates to true.</li>
</ol>
<br>
The XOR operation operates in a one, and only one mode, i.e. (A ^ B) ^ C ... ^ n
</p>
</script>

+ 139
- 0
boolean-logic-ultimate/BooleanLogicUltimate.js Целия файл

@@ -0,0 +1,139 @@
module.exports = function(RED) {
function BooleanLogicUltimate(config) {
RED.nodes.createNode(this,config);
this.config = config;
this.state = {};
var node = this;
var NodeHelper = require('./NodeHelper.js');
var fs = require('fs');
var h = new NodeHelper(node);
// Delete persistent states on change/deploy
DeletePersistFile();

// Populate the state array with the persisten file
if (this.config.persist == true) {
try {
var contents = fs.readFileSync(node.id.toString()).toString();
if (typeof contents !== 'undefined') {
node.state = JSON.parse(contents);
node.status({fill: "blue",shape: "ring",text: "Loaded persistent states (" + Object.keys(this.state).length + " total)."});
}
} catch (error) {
node.status({fill: "grey",shape: "ring",text: "No persistent states"});
}
} else {
node.status({fill: "yellow",shape: "dot",text: "Waiting for input states"});
}

this.on('input', function (msg) {
var topic = msg.topic;
var payload = msg.payload;
if (topic !== undefined && payload !== undefined) {
var value = h.ToBoolean( payload );
var state = node.state;
state[topic] = value;

// Sabe the state array to a perisistent file
if (this.config.persist == true) {
fs.writeFileSync(this.id.toString(),JSON.stringify(state));
}
// Do we have as many inputs as we expect?
var keyCount = Object.keys(state).length;

if( keyCount == node.config.inputCount ) {
var resAND = CalculateResult("AND");
var resOR = CalculateResult("OR");
var resXOR = CalculateResult("XOR");

if (this.config.filtertrue == "onlytrue") {
if (!resAND) { resAND = null };
if (!resOR) { resOR = null };
if (!resXOR) { resXOR = null };
}
h.SetResult(resAND,resOR,resXOR, node.config.topic);
}
else if(keyCount > node.config.inputCount ) {
node.warn(
(node.config.name !== undefined && node.config.name.length > 0
? node.config.name : "BooleanLogicUltimate")
+ " [Logic]: More than the specified "
+ node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received.");
node.state = {};
h.DisplayUnkownStatus();
}
}
});
function DeletePersistFile (){
// Detele the persist file
try {
fs.unlinkSync(node.id.toString());
node.status({fill: "red",shape: "ring",text: "Persistent states deleted."});
} catch (error) {
node.status({fill: "red",shape: "ring",text: "Error deleting persistent file: " + error.toString()});
}
}

function CalculateResult(_operation) {
var res;
if( _operation == "XOR") {
res = PerformXOR();
}
else {
// We need a starting value to perform AND and OR operations.
var keys = Object.keys(node.state);
res = node.state[keys[0]];
for( var i = 1; i < keys.length; ++i ) {
var key = keys[i];
res = PerformSimpleOperation( _operation, res, node.state[key] );
}
}
return res;
}
function PerformXOR()
{
// XOR = exclusively one input is true. As such, we just count the number of true values and compare to 1.
var trueCount = 0;
for( var key in node.state ) {
if( node.state[key] ) {
trueCount++;
}
}
return trueCount == 1;
}
function PerformSimpleOperation( operation, val1, val2 ) {
var res;
if( operation === "AND" ) {
res = val1 && val2;
}
else if( operation === "OR" ) {
res = val1 || val2;
}
else {
node.error( "Unknown operation: " + operation );
}
return res;
}
}
RED.nodes.registerType("BooleanLogicUltimate",BooleanLogicUltimate);
}

boolean-logic/Invert.html → boolean-logic-ultimate/Invert.html Целия файл

@@ -1,12 +1,7 @@
<!--
Licensed under the MIT license, see LICENSE file.
Author: Per Malmberg (https://github.com/PerMalmberg)
-->

<script type="text/javascript">
RED.nodes.registerType('Invert',{
category: 'boolean logic',
color: '#C0DEED',
category: 'boolean logic ultimate',
color: '#ff8080',
defaults: {
name: {
value: "Invert"

boolean-logic/Invert.js → boolean-logic-ultimate/Invert.js Целия файл

@@ -1,5 +1,3 @@
// Licensed under the MIT license, see LICENSE file.
// Author: Per Malmberg (https://github.com/PerMalmberg)
module.exports = function(RED) {
function Invert(config) {
RED.nodes.createNode(this,config);

boolean-logic/NodeHelper.js → boolean-logic-ultimate/NodeHelper.js Целия файл

@@ -1,6 +1,3 @@
// Licensed under the MIT license, see LICENSE file.
// Author: Per Malmberg (https://github.com/PerMalmberg)

var NodeHelper = function( node ) {
var myNode = node;
var self = this;
@@ -46,15 +43,31 @@ var NodeHelper = function( node ) {
});
};
this.SetResult = function( value, optionalTopic ) {
self.DisplayStatus( value );
this.SetResult = function( _valueAND, _valueOR, _valueXOR, optionalTopic ) {
self.DisplayStatus( "AND:" + _valueAND + " OR:" +_valueOR + " XOR:" +_valueXOR);
var msg = {
topic: optionalTopic === undefined ? "result" : optionalTopic,
payload: value
};

myNode.send(msg);
if (_valueAND!=null){
var msgAND = {
topic: optionalTopic === undefined ? "result" : optionalTopic,
operation:"AND",
payload: _valueAND
};
}
if (_valueOR!=null){
var msgOR = {
topic: optionalTopic === undefined ? "result" : optionalTopic,
operation:"OR",
payload: _valueOR
};
}
if (_valueXOR!=null){
var msgXOR = {
topic: optionalTopic === undefined ? "result" : optionalTopic,
operation:"XOR",
payload: _valueXOR
};
}
myNode.send([msgAND,msgOR,msgXOR]);
};
};
module.exports = NodeHelper;

+ 0
- 106
boolean-logic/BooleanLogic.html Целия файл

@@ -1,106 +0,0 @@
<!--
Licensed under the MIT license, see LICENSE file.
Author: Per Malmberg (https://github.com/PerMalmberg)
-->

<script type="text/javascript">
RED.nodes.registerType('BooleanLogic',{
category: 'boolean logic',
color: '#C0DEED',
defaults: {
name: {
value: ""
},
operation: {
value: "AND",
required: true,
validate:
function(v) {
return v !== undefined && v.length > 0;
}
},
inputCount: {
value: 2,
required: true,
validate:
function(v) {
return !isNaN( parseInt( v ) ) && parseInt( v ) >= 2;
}
},
topic: {
value: "result",
required: true,
validate:
function(v) {
return v !== undefined && v.length > 0;
}
}
},
inputs:1,
outputs:1,
icon: "serial.png",
label:
function() {
var label = this.operation + " [" + this.inputCount + "]";
if( this.name !== undefined && this.name.length > 0 ) {
label = label + " (" + this.name + ")";
}
return label;
},
paletteLabel: function() {
return "Boolean logic";
}
});
</script>

<script type="text/x-red" data-template-name="BooleanLogic">
<div class="form-row">
<label for="node-input-operation"><i class="icon-tag"></i> Operation</label>
<select type="text" id="node-input-operation" placeholder="Operation">
<option value="AND">And</option>
<option value="OR">Or</option>
<option value="XOR">Exclusive Or</option>
</select>
</div>
<div class="form-row">
<label for="node-input-inputCount"><i class="icon-tag"></i> Number of topics</label>
<input type="text" id="node-input-inputCount" placeholder="Number of topics to consider">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="icon-tag"></i> Topic</label>
<input type="text" id="node-input-topic" placeholder="Topic">
</div>
</script>

<script type="text/x-red" data-help-name="BooleanLogic">
<p>A node that performs Boolean logic on the incoming payloads.<br/>
Select the operation in the settings.<br/>
Changing the topic is usually only needed when chaining multiple boolean nodes after each other becuse the topics will then all be the same when delivered to the nodes further down the chain.<br/>
<br/>
The node expects a fixed number of topics (configured in the settings) on which it will operate. It will only output a value
when it has seen the expected number of topics. If it ever sees more than the configured number of topics it will log a message then reset its state and start over.<br/>
<br/>
Example:<br/>
The node has been configured for two topics, with the operation OR.
<br/>
<ol>
<li>Topic 'A' with value false arrives - only one topic seen so no output.</li>
<li>Topic 'B' with value true arrives - two topics seen so the node evaluates the received topics and outputs true.</li>
<li>Topic 'C' arrives. This is the third topic which is one more than the configured number so the node resets and will not output another value until
two new topics have been received. Note that when resetting it does not output any value.</li>
</ol>
<br/>
All incoming msg.payloads are converted into a boolean value according to the following rules (this applies to all boolean logic nodes):
<ol>
<li>Boolean values are taken as-is.</li>
<li>For numbers, 0 evaluates to false, all other numbers evaluates to true.</li>
<li>Strings are converted to numbers if they match the format of a decimal value, then the same rule as for numbers are applied. If it does not match, it evaluates to false. Also, the string "true" evaluates to true.</li>
</ol>
<br>
The XOR operation operates in a one, and only one mode, i.e. (A ^ B) ^ C ... ^ n
</p>
</script>

+ 0
- 96
boolean-logic/BooleanLogic.js Целия файл

@@ -1,96 +0,0 @@
// Licensed under the MIT license, see LICENSE file.
// Author: Per Malmberg (https://github.com/PerMalmberg)
module.exports = function(RED) {
function BooleanLogic(config) {
RED.nodes.createNode(this,config);
this.config = config;
this.state = {};
var node = this;
var NodeHelper = require('./NodeHelper.js');
var h = new NodeHelper( node );
this.on('input', function(msg) {
var topic = msg.topic;
var payload = msg.payload;
if( topic !== undefined && payload !== undefined ) {
var value = h.ToBoolean( payload );
var state = node.state;
state[topic] = value;
// Do we have as many inputs as we expect?
var keyCount = Object.keys(state).length;

if( keyCount == node.config.inputCount ) {
var res = CalculateResult();
h.SetResult( res, node.config.topic );
}
else if(keyCount > node.config.inputCount ) {
node.warn(
(node.config.name !== undefined && node.config.name.length > 0
? node.config.name : "BooleanLogic")
+ " [" + node.config.operation + "]: More than the specified "
+ node.config.inputCount + " topics received, resetting. Will not output new value until " + node.config.inputCount + " new topics have been received.");
node.state = {};
h.DisplayUnkownStatus();
}
}
});
function CalculateResult() {
var res;
if( node.config.operation == "XOR") {
res = PerformXOR();
}
else {
// We need a starting value to perform AND and OR operations.
var keys = Object.keys(node.state);
res = node.state[keys[0]];
for( var i = 1; i < keys.length; ++i ) {
var key = keys[i];
res = PerformSimpleOperation( node.config.operation, res, node.state[key] );
}
}
return res;
}
function PerformXOR()
{
// XOR = exclusively one input is true. As such, we just count the number of true values and compare to 1.
var trueCount = 0;
for( var key in node.state ) {
if( node.state[key] ) {
trueCount++;
}
}
return trueCount == 1;
}
function PerformSimpleOperation( operation, val1, val2 ) {
var res;
if( operation === "AND" ) {
res = val1 && val2;
}
else if( operation === "OR" ) {
res = val1 || val2;
}
else {
node.error( "Unknown operation: " + operation );
}
return res;
}
h.DisplayUnkownStatus();
}
RED.nodes.registerType("BooleanLogic",BooleanLogic);
}

+ 9
- 0
node_modules/fs/README.md Целия файл

@@ -0,0 +1,9 @@
# Security holding package

This package name is not currently in use, but was formerly occupied
by another package. To avoid malicious use, npm is hanging on to the
package name, but loosely, and we'll probably give it to you if you
want it.

You may adopt this package by contacting support@npmjs.com and
requesting the name.

+ 45
- 0
node_modules/fs/package.json Целия файл

@@ -0,0 +1,45 @@
{
"_from": "fs@0.0.1-security",
"_id": "fs@0.0.1-security",
"_inBundle": false,
"_integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=",
"_location": "/fs",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "fs@0.0.1-security",
"name": "fs",
"escapedName": "fs",
"rawSpec": "0.0.1-security",
"saveSpec": null,
"fetchSpec": "0.0.1-security"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"_shasum": "8a7bd37186b6dddf3813f23858b57ecaaf5e41d4",
"_spec": "fs@0.0.1-security",
"_where": "/Users/massimosaccani/Documents/GitHub/node-red-contrib-boolean-logic-ultimate",
"author": "",
"bugs": {
"url": "https://github.com/npm/security-holder/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "This package name is not currently in use, but was formerly occupied by another package. To avoid malicious use, npm is hanging on to the package name, but loosely, and we'll probably give it to you if you want it.",
"homepage": "https://github.com/npm/security-holder#readme",
"keywords": [],
"license": "ISC",
"main": "index.js",
"name": "fs",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/security-holder.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "0.0.1-security"
}

+ 13
- 0
package-lock.json Целия файл

@@ -0,0 +1,13 @@
{
"name": "node-red-contrib-boolean-logic-ultimate",
"version": "0.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"fs": {
"version": "0.0.1-security",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
}
}
}

+ 19
- 14
package.json Целия файл

@@ -1,21 +1,26 @@
{
"name": "node-red-contrib-boolean-logic",
"version": "0.0.3",
"description": "A set of Node-RED nodes for boolean logic",
"author": "Per Malmberg (https://github.com/PerMalmberg)",
"name": "node-red-contrib-boolean-logic-ultimate",
"version": "0.0.1",
"description": "A set of Node-RED enhanced boolean logic, with persisten values after reboot and more",
"author": "Supergiovane (https://github.com/Supergiovane)",
"dependencies": {
"fs": "0.0.1-security"
},
"keywords": [
"node-red",
"boolean",
"logic"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Supergiovane/node-red-contrib-boolean-logic-ultimate"
},
"keywords": [ "node-red", "boolean", "logic" ],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/PerMalmberg/node-red-contrib-boolean-logic"
},
"node-red": {
"nodes": {
"BooleanLogic": "boolean-logic/BooleanLogic.js",
"Invert": "boolean-logic/Invert.js",
"BDebug": "boolean-logic/BDebug.js"
"BooleanLogicUltimate": "boolean-logic-ultimate/BooleanLogicUltimate.js",
"Invert": "boolean-logic-ultimate/Invert.js",
"BDebug": "boolean-logic-ultimate/BDebug.js"
}
}
}
}

Loading…
Отказ
Запис