Compare commits

..

43 Commits

Author SHA1 Message Date
dependabot[bot]
158243b69c Bump peter-evans/create-pull-request in the github-actions group
Bumps the github-actions group with 1 update: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `peter-evans/create-pull-request` from 6 to 7
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-01 07:14:17 +00:00
Nick O'Leary
84a2fbed2e Merge pull request #4811 from GogoVega/handle-bad-subflow
Handle the import of an incomplete Subflow
2024-11-25 16:49:32 +00:00
Nick O'Leary
5ce3cdb845 Merge branch 'master' into handle-bad-subflow 2024-11-25 16:27:41 +00:00
Nick O'Leary
3e0b5f2fe8 Merge pull request #4809 from GogoVega/fix-subflow-name
Fix updating the Subflow name during a copy
2024-11-25 16:22:31 +00:00
Nick O'Leary
69b413040f Merge pull request #4963 from node-red/rename-var
Rename variable to avoid confusion in view.js
2024-11-18 16:39:52 +00:00
Nick O'Leary
ffecf86281 Merge pull request #4960 from GogoVega/fix-4942
Get the env config node from the parent subflow
2024-11-18 16:39:37 +00:00
Nick O'Leary
4cb3ccc984 Rename variable to avoid confusion in view.js 2024-11-18 16:20:58 +00:00
Nick O'Leary
47e1389548 Merge pull request #4959 from hungtcs/master
Change groups.length to groups.size
2024-11-18 16:18:27 +00:00
GogoVega
6d6e6fa416 Get the env config node from the parent subflow 2024-11-15 14:30:47 +01:00
鸿则
ad615a76c8 Change groups.length to groups.size
Fix wrong length attribute of Set
2024-11-14 16:31:36 +08:00
Nick O'Leary
e48607c743 Merge pull request #4940 from node-red/Delay-node-not-send-on-reset-if-queue-empty
Make delay node rate limit reset consistent - not send on reset.
2024-11-11 13:49:41 +00:00
Nick O'Leary
604c70ec04 Merge pull request #4946 from GogoVega/fix-quickAddDialog
Remove disabled node types from QuickAddDialog list
2024-11-08 13:46:19 +00:00
Gauthier Dandele
59a133cc13 Need to guard against subflows that doesn't have a set property
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2024-11-08 12:28:40 +01:00
Nick O'Leary
0590d81e80 Merge pull request #4939 from GogoVega/fix-4831
Fix `setModulePendingUpdated` with plugins
2024-11-08 11:26:52 +00:00
GogoVega
abe0b60bf7 Remove disabled node types from QuickAddDialog list 2024-11-06 17:28:51 +01:00
Nick O'Leary
54bf3f4402 Merge pull request #4934 from ersinpw/patch-1
Missing getSubscriptions in the docs while its implemented
2024-11-01 09:06:36 +00:00
Dave Conway-Jones
d3219f0600 do add to queue in case it needs to also be flushed 2024-10-31 17:21:53 +00:00
Nick O'Leary
348ec34446 Merge pull request #4925 from GogoVega/fix-4923
Apply `envVarExcludes` setting to `util.getSetting` into the function node
2024-10-31 17:18:32 +00:00
Dave Conway-Jones
33a5b2527c Make delay node rate limit reset consistent - not send on reset.
to fix #4830
2024-10-31 17:06:13 +00:00
GogoVega
443492d6eb Fix setModulePendingUpdated with plugins 2024-10-31 17:12:13 +01:00
Ersin
a7ee31307e missing getSubscriptions in the docs while its implemented
See:
https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/nodes/core/network/10-mqtt.js#L1288
2024-10-29 13:38:32 +01:00
Gauthier Dandele
f67268b89a Revert and force getSetting to use the local node
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2024-10-28 18:01:42 +01:00
Nick O'Leary
42382e1a03 Merge pull request #4932 from GogoVega/fix-envVarList-sortable
Fix `envVar` editable list should be sortable
2024-10-28 16:35:56 +00:00
Nick O'Leary
419dfbf08b Merge pull request #4915 from node-red/Fix-for-trigger-node-date-handling
Fix trigger node date handling for latest time type input
2024-10-28 16:17:38 +00:00
GogoVega
70aed23ef0 Fix envVarList sortable value 2024-10-28 16:31:36 +01:00
GogoVega
2fd7aee4da Move envVarExcludes to the top scope 2024-10-24 13:44:40 +02:00
GogoVega
7555e0644f Apply envVarExcludes setting to RED.util.getSetting into the function node 2024-10-23 12:15:24 +02:00
Nick O'Leary
c363f375b6 Merge pull request #4912 from GogoVega/improve-node-name
Improve the node name auto-generated with the first available number
2024-10-21 16:42:04 +01:00
Nick O'Leary
2220956007 Ensure trigger second output is revaluated for date types 2024-10-21 16:35:11 +01:00
Nick O'Leary
b3aff3a3e6 Ensure trigger node properties work with evaluateNodeProperty 2024-10-21 16:26:03 +01:00
Nick O'Leary
d0ad62a82b Revert trigger node fix 2024-10-21 16:24:21 +01:00
Dave Conway-Jones
892933ff75 Update 89-trigger_spec.js 2024-10-12 17:22:24 +01:00
Dave Conway-Jones
61fd01b871 And add some tests 2024-10-12 17:09:18 +01:00
Dave Conway-Jones
2eba754801 Fix trigger node date handling for latest time type input
to fix #4914
2024-10-12 16:49:09 +01:00
GogoVega
a7b1ce0cf8 Improve the node name auto-generated with the first available nb 2024-10-10 15:47:42 +02:00
Nick O'Leary
2854351909 Merge pull request #4910 from node-red/rel405
Bump for 4.0.5
2024-10-10 11:11:54 +01:00
Nick O'Leary
fe9354d10b Bump for 4.0.5 2024-10-10 11:05:08 +01:00
Nick O'Leary
71cfa87303 Merge pull request #4908 from GogoVega/refix-4891
Refix link call node can call out of a subflow
2024-10-10 10:57:51 +01:00
GogoVega
802b116b01 Refix link call node can call out of a subflow 2024-10-10 08:53:33 +02:00
GogoVega
8aec038c24 Remove duplicate type definition 2024-07-01 17:59:28 +02:00
Gauthier Dandele
bda9f249bc Update packages/node_modules/@node-red/editor-client/src/js/nodes.js
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2024-07-01 17:43:39 +02:00
GogoVega
bea08706cc Handle the import of an incomplete Subflow 2024-06-26 22:51:08 +02:00
GogoVega
7950ee1241 Fix updating the subflow name during a copy 2024-06-26 21:16:59 +02:00
23 changed files with 196 additions and 80 deletions

View File

@@ -32,7 +32,7 @@ jobs:
node-version: '16'
- run: node ./node-red/.github/scripts/update-node-red-docker.js
- name: Create Docker Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.NR_REPO_TOKEN }}
committer: GitHub <noreply@github.com>
@@ -48,7 +48,7 @@ jobs:
This PR was auto-generated by a GitHub Action. Any questions, speak to @knolleary
- run: node ./node-red/.github/scripts/update-node-red-website.js
- name: Create Website Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.NR_REPO_TOKEN }}
committer: GitHub <noreply@github.com>

View File

@@ -1,3 +1,9 @@
#### 4.0.5: Maintenance Release
Editor
- Refix link call node can call out of a subflow (#4908) @GogoVega
#### 4.0.4: Maintenance Release
Editor

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "4.0.4",
"version": "4.0.5",
"description": "Low-code programming for event-driven applications",
"homepage": "https://nodered.org",
"license": "Apache-2.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-api",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
"@node-red/util": "4.0.4",
"@node-red/editor-client": "4.0.4",
"@node-red/util": "4.0.5",
"@node-red/editor-client": "4.0.5",
"bcryptjs": "2.4.3",
"body-parser": "1.20.3",
"clone": "2.1.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -73,7 +73,13 @@ RED.nodes = (function() {
var exports = {
setModulePendingUpdated: function(module,version) {
moduleList[module].pending_version = version;
if (!!RED.plugins.getModule(module)) {
// The module updated is a plugin
RED.plugins.getModule(module).pending_version = version;
} else {
moduleList[module].pending_version = version;
}
RED.events.emit("registry:module-updated",{module:module,version:version});
},
getModule: function(module) {
@@ -1032,23 +1038,34 @@ RED.nodes = (function() {
return {nodes:removedNodes,links:removedLinks, groups: removedGroups, junctions: removedJunctions};
}
/**
* Add a Subflow to the Workspace
*
* @param {object} sf The Subflow to add.
* @param {boolean|undefined} createNewIds Whether to update the name.
*/
function addSubflow(sf, createNewIds) {
if (createNewIds) {
var subflowNames = Object.keys(subflows).map(function(sfid) {
return subflows[sfid].name;
});
// Update the Subflow name to highlight that this is a copy
const subflowNames = Object.keys(subflows).map(function (sfid) {
return subflows[sfid].name || "";
})
subflowNames.sort()
subflowNames.sort();
var copyNumber = 1;
var subflowName = sf.name;
let copyNumber = 1;
let subflowName = sf.name;
subflowNames.forEach(function(name) {
if (subflowName == name) {
subflowName = sf.name + " (" + copyNumber + ")";
copyNumber++;
subflowName = sf.name+" ("+copyNumber+")";
}
});
sf.name = subflowName;
}
sf.instances = [];
subflows[sf.id] = sf;
allNodes.addTab(sf.id);
linkTabMap[sf.id] = [];
@@ -1101,7 +1118,7 @@ RED.nodes = (function() {
module: "node-red"
}
});
sf.instances = [];
sf._def = RED.nodes.getType("subflow:"+sf.id);
RED.events.emit("subflows:add",sf);
}
@@ -1743,7 +1760,8 @@ RED.nodes = (function() {
// Remove the old subflow definition - but leave the instances in place
var removalResult = RED.subflow.removeSubflow(n.id, true);
// Create the list of nodes for the new subflow def
var subflowNodes = [n].concat(zMap[n.id]);
// Need to sort the list in order to remove missing nodes
var subflowNodes = [n].concat(zMap[n.id]).filter((s) => !!s);
// Import the new subflow - no clashes should occur as we've removed
// the old version
var result = importNodes(subflowNodes);
@@ -2023,6 +2041,8 @@ RED.nodes = (function() {
if (matchingSubflow) {
subflow_denylist[n.id] = matchingSubflow;
} else {
const oldId = n.id;
subflow_map[n.id] = n;
if (createNewIds || options.importMap[n.id] === "copy") {
nid = getID();
@@ -2050,7 +2070,7 @@ RED.nodes = (function() {
n.status.id = getID();
}
new_subflows.push(n);
addSubflow(n,createNewIds || options.importMap[n.id] === "copy");
addSubflow(n,createNewIds || options.importMap[oldId] === "copy");
}
}
}
@@ -2170,7 +2190,7 @@ RED.nodes = (function() {
x:parseFloat(n.x || 0),
y:parseFloat(n.y || 0),
z:n.z,
type:0,
type: n.type,
info: n.info,
changed:false,
_config:{}
@@ -2231,7 +2251,6 @@ RED.nodes = (function() {
}
}
}
node.type = n.type;
node._def = def;
if (node.type === "group") {
node._def = RED.group.def;
@@ -2261,6 +2280,15 @@ RED.nodes = (function() {
outputs: n.outputs|| (n.wires && n.wires.length) || 0,
set: registry.getNodeSet("node-red/unknown")
}
var orig = {};
for (var p in n) {
if (n.hasOwnProperty(p) && p!="x" && p!="y" && p!="z" && p!="id" && p!="wires") {
orig[p] = n[p];
}
}
node._orig = orig;
node.name = n.type;
node.type = "unknown";
} else {
if (subflow_denylist[parentId] || createNewIds || options.importMap[n.id] === "copy") {
parentId = subflow.id;
@@ -2419,10 +2447,10 @@ RED.nodes = (function() {
if (otherNode.z === n.z) {
// Both ends in the same flow/subflow
return true
} else if (n.type === "link call" && !!getSubflow(otherNode.z)) {
} else if (n.type === "link call" && !getSubflow(otherNode.z)) {
// Link call node can call out of a subflow as long as otherNode is
// not in a subflow
return false
return true
} else if (!!getSubflow(n.z) || !!getSubflow(otherNode.z)) {
// One end is in a subflow - remove the link
return false
@@ -2458,9 +2486,11 @@ RED.nodes = (function() {
n = new_subflows[i];
n.in.forEach(function(input) {
input.wires.forEach(function(wire) {
var link = {source:input, sourcePort:0, target:node_map[wire.id]};
addLink(link);
new_links.push(link);
if (node_map.hasOwnProperty(wire.id)) {
var link = {source:input, sourcePort:0, target:node_map[wire.id]};
addLink(link);
new_links.push(link);
}
});
delete input.wires;
});
@@ -2469,11 +2499,13 @@ RED.nodes = (function() {
var link;
if (subflow_map[wire.id] && subflow_map[wire.id].id == n.id) {
link = {source:n.in[wire.port], sourcePort:wire.port,target:output};
} else {
} else if (node_map.hasOwnProperty(wire.id) || subflow_map.hasOwnProperty(wire.id)) {
link = {source:node_map[wire.id]||subflow_map[wire.id], sourcePort:wire.port,target:output};
}
addLink(link);
new_links.push(link);
if (link) {
addLink(link);
new_links.push(link);
}
});
delete output.wires;
});
@@ -2482,11 +2514,13 @@ RED.nodes = (function() {
var link;
if (subflow_map[wire.id] && subflow_map[wire.id].id == n.id) {
link = {source:n.in[wire.port], sourcePort:wire.port,target:n.status};
} else {
} else if (node_map.hasOwnProperty(wire.id) || subflow_map.hasOwnProperty(wire.id)) {
link = {source:node_map[wire.id]||subflow_map[wire.id], sourcePort:wire.port,target:n.status};
}
addLink(link);
new_links.push(link);
if (link) {
addLink(link);
new_links.push(link);
}
});
delete n.status.wires;
}

View File

@@ -131,7 +131,7 @@ RED.editor.envVarList = (function() {
nameField.trigger('change');
}
},
sortable: ".red-ui-editableList-item-handle",
sortable: true,
removable: false
});
var parentEnv = {};

View File

@@ -382,7 +382,7 @@ RED.typeSearch = (function() {
var items = [];
RED.nodes.registry.getNodeTypes().forEach(function(t) {
var def = RED.nodes.getType(t);
if (def.category !== 'config' && t !== 'unknown' && t !== 'tab') {
if (def.set?.enabled !== false && def.category !== 'config' && t !== 'unknown' && t !== 'tab') {
items.push({type:t,def: def, label:getTypeLabel(t,def)});
}
});

View File

@@ -1102,18 +1102,27 @@ RED.view.tools = (function() {
const paletteLabel = RED.utils.getPaletteLabel(n.type, nodeDef)
const defaultNodeNameRE = new RegExp('^'+paletteLabel.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')+' (\\d+)$')
if (!typeIndex.hasOwnProperty(n.type)) {
const existingNodes = RED.nodes.filterNodes({type: n.type})
let maxNameNumber = 0;
existingNodes.forEach(n => {
let match = defaultNodeNameRE.exec(n.name)
const existingNodes = RED.nodes.filterNodes({ type: n.type });
const existingIds = existingNodes.reduce((ids, node) => {
let match = defaultNodeNameRE.exec(node.name);
if (match) {
let nodeNumber = parseInt(match[1])
if (nodeNumber > maxNameNumber) {
maxNameNumber = nodeNumber
const nodeNumber = parseInt(match[1], 10);
if (!ids.includes(nodeNumber)) {
ids.push(nodeNumber);
}
}
})
typeIndex[n.type] = maxNameNumber + 1
return ids;
}, []).sort((a, b) => a - b);
let availableNameNumber = 1;
for (let i = 0; i < existingIds.length; i++) {
if (existingIds[i] !== availableNameNumber) {
break;
}
availableNameNumber++;
}
typeIndex[n.type] = availableNameNumber;
}
if ((options.renameBlank && n.name === '') || (options.renameClash && defaultNodeNameRE.test(n.name))) {
if (generateHistory) {

View File

@@ -288,7 +288,7 @@ RED.view = (function() {
}
selectedLinks.clearUnselected()
},
length: () => groups.length,
length: () => groups.size,
forEach: (func) => { groups.forEach(func) },
toArray: () => [...groups],
clear: function () {
@@ -2689,22 +2689,21 @@ RED.view = (function() {
addToRemovedLinks(reconnectResult.removedLinks)
}
var startDirty = RED.nodes.dirty();
var startChanged = false;
var selectedGroups = [];
const startDirty = RED.nodes.dirty();
let movingSelectedGroups = [];
if (movingSet.length() > 0) {
for (var i=0;i<movingSet.length();i++) {
node = movingSet.get(i).n;
if (node.type === "group") {
selectedGroups.push(node);
movingSelectedGroups.push(node);
}
}
// Make sure we have identified all groups about to be deleted
for (i=0;i<selectedGroups.length;i++) {
selectedGroups[i].nodes.forEach(function(n) {
if (n.type === "group" && selectedGroups.indexOf(n) === -1) {
selectedGroups.push(n);
for (i=0;i<movingSelectedGroups.length;i++) {
movingSelectedGroups[i].nodes.forEach(function(n) {
if (n.type === "group" && movingSelectedGroups.indexOf(n) === -1) {
movingSelectedGroups.push(n);
}
})
}
@@ -2721,7 +2720,7 @@ RED.view = (function() {
addToRemovedLinks(removedEntities.links);
if (node.g) {
var group = RED.nodes.group(node.g);
if (selectedGroups.indexOf(group) === -1) {
if (movingSelectedGroups.indexOf(group) === -1) {
// Don't use RED.group.removeFromGroup as that emits
// a change event on the node - but we're deleting it
var index = group.nodes.indexOf(node);
@@ -2735,7 +2734,7 @@ RED.view = (function() {
removedLinks = removedLinks.concat(result.links);
if (node.g) {
var group = RED.nodes.group(node.g);
if (selectedGroups.indexOf(group) === -1) {
if (movingSelectedGroups.indexOf(group) === -1) {
// Don't use RED.group.removeFromGroup as that emits
// a change event on the node - but we're deleting it
var index = group.nodes.indexOf(node);
@@ -2757,8 +2756,8 @@ RED.view = (function() {
// Groups must be removed in the right order - from inner-most
// to outermost.
for (i = selectedGroups.length-1; i>=0; i--) {
var g = selectedGroups[i];
for (i = movingSelectedGroups.length-1; i>=0; i--) {
var g = movingSelectedGroups[i];
removedGroups.push(g);
RED.nodes.removeGroup(g);
}

View File

@@ -111,8 +111,6 @@ module.exports = function(RED) {
throw new Error(RED._("function.error.externalModuleNotAllowed"));
}
var functionText = "var results = null;"+
"results = (async function(msg,__send__,__done__){ "+
"var __msgid__ = msg._msgid;"+
@@ -166,7 +164,13 @@ module.exports = function(RED) {
Buffer:Buffer,
Date: Date,
RED: {
util: RED.util
util: {
...RED.util,
getSetting: function (_node, name, _flow) {
// Ensure `node` argument is the Function node and do not allow flow to be overridden.
return RED.util.getSetting(node, name);
}
}
},
__node__: {
id: node.id,

View File

@@ -253,7 +253,13 @@ module.exports = function(RED) {
if (node.allowrate && m.hasOwnProperty("rate") && !isNaN(parseFloat(m.rate))) {
node.rate = m.rate;
}
send(m);
if (msg.hasOwnProperty("reset")) {
if (msg.hasOwnProperty("flush")) {
node.buffer.push({msg: m, send: send, done: done});
}
}
else { send(m); }
node.reportDepth();
node.intervalID = setInterval(sendMsgFromBuffer, node.rate);
done();
@@ -303,7 +309,8 @@ module.exports = function(RED) {
node.droppedMsgs++;
}
}
} else {
}
else {
if (node.allowrate && msg.hasOwnProperty("rate") && !isNaN(parseFloat(msg.rate))) {
node.rate = msg.rate;
}

View File

@@ -24,6 +24,14 @@ module.exports = function(RED) {
this.op2 = n.op2 || "0";
this.op1type = n.op1type || "str";
this.op2type = n.op2type || "str";
// If the op1/2type is 'date', then we need to leave op1/2 alone so that
// evaluateNodeProperty works as expected.
if (this.op1type === 'date' && this.op1 === '1') {
this.op1 = ''
}
if (this.op2type === 'date' && this.op2 === '0') {
this.op2 = ''
}
this.second = (n.outputs == 2) ? true : false;
this.topic = n.topic || "topic";
@@ -193,7 +201,7 @@ module.exports = function(RED) {
if (node.op2type !== "nul") {
var promise = Promise.resolve();
msg2 = RED.util.cloneMessage(msg);
if (node.op2type === "flow" || node.op2type === "global") {
if (node.op2type === "flow" || node.op2type === "global" || node.op2type === "date") {
promise = new Promise((resolve,reject) => {
RED.util.evaluateNodeProperty(node.op2,node.op2type,node,msg,(err,value) => {
if (err) {
@@ -213,7 +221,6 @@ module.exports = function(RED) {
}
else {
msg2.payload = node.topics[topic].m2;
if (node.op2type === "date") { msg2.payload = Date.now(); }
if (node.second === true) { msgInfo.send([null,msg2]); }
else { msgInfo.send(msg2); }
}

View File

@@ -48,7 +48,8 @@
<dl class="message-properties">
<dt>action <span class="property-type">string</span></dt>
<dd>the name of the action the node should perform. Available actions are: <code>"connect"</code>,
<code>"disconnect"</code>, <code>"subscribe"</code> and <code>"unsubscribe"</code>.</dd>
<code>"disconnect"</code>, <code>"getSubscriptions"</code>, <code>"subscribe"</code> and
<code>"unsubscribe"</code>.</dd>
<dt class="optional">topic <span class="property-type">string|object|array</span></dt>
<dd>For the <code>"subscribe"</code> and <code>"unsubscribe"</code> actions, this property
provides the topic. It can be set as either:<ul>

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/nodes",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/registry",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,7 +16,7 @@
}
],
"dependencies": {
"@node-red/util": "4.0.4",
"@node-red/util": "4.0.5",
"clone": "2.1.2",
"fs-extra": "11.2.0",
"semver": "7.6.3",

View File

@@ -113,6 +113,10 @@ async function evaluateEnvProperties(flow, env, credentials) {
resolve()
});
}))
} else if (type === "conf-type" && /^\${[^}]+}$/.test(value)) {
// Get the config node from the parent subflow
const name = value.substring(2, value.length - 1);
value = flow.getSetting(name);
} else {
try {
value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/runtime",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"main": "./lib/index.js",
"repository": {
@@ -16,8 +16,8 @@
}
],
"dependencies": {
"@node-red/registry": "4.0.4",
"@node-red/util": "4.0.4",
"@node-red/registry": "4.0.5",
"@node-red/util": "4.0.5",
"async-mutex": "0.5.0",
"clone": "2.1.2",
"express": "4.21.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/util",
"version": "4.0.4",
"version": "4.0.5",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -1,6 +1,6 @@
{
"name": "node-red",
"version": "4.0.4",
"version": "4.0.5",
"description": "Low-code programming for event-driven applications",
"homepage": "https://nodered.org",
"license": "Apache-2.0",
@@ -31,10 +31,10 @@
"flow"
],
"dependencies": {
"@node-red/editor-api": "4.0.4",
"@node-red/runtime": "4.0.4",
"@node-red/util": "4.0.4",
"@node-red/nodes": "4.0.4",
"@node-red/editor-api": "4.0.5",
"@node-red/runtime": "4.0.5",
"@node-red/util": "4.0.5",
"@node-red/nodes": "4.0.5",
"basic-auth": "2.0.1",
"bcryptjs": "2.4.3",
"cors": "2.8.5",

View File

@@ -36,10 +36,12 @@ function generateScript() {
packages.forEach(name => {
const tarName = name.replace(/@/,"").replace(/\//,"-")
lines.push(`npm publish ${tarName}-${version}.tgz ${tagArg}\n`);
if (updateNextToLatest) {
lines.push(`npm dist-tag add ${name}@${version} next\n`);
}
})
if (updateNextToLatest) {
packages.forEach(name => {
lines.push(`npm dist-tag add ${name}@${version} next\n`);
})
}
resolve(lines.join(""))
});
}

View File

@@ -1009,6 +1009,29 @@ describe('delay Node', function() {
});
});
it('sending a msg with reset to empty queue doesnt send anything', function(done) {
this.timeout(2000);
var flow = [{"id":"delayNode1","type":"delay","name":"delayNode","pauseType":"rate","timeout":1,"timeoutUnits":"seconds","rate":2,"rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"wires":[["helperNode1"]]},
{id:"helperNode1", type:"helper", wires:[]}];
helper.load(delayNode, flow, function() {
var delayNode1 = helper.getNode("delayNode1");
var helperNode1 = helper.getNode("helperNode1");
var t = Date.now();
var c = 0;
helperNode1.on("input", function(msg) {
console.log("Shold not get here")
done(e);
});
setTimeout( function() {
if (c === 0) { done(); }
}, 250);
// send test messages
delayNode1.receive({payload:1,topic:"foo",reset:true}); // send something with blank topic
});
});
/* Messaging API support */
function mapiDoneTestHelper(done, pauseType, drop, msgAndTimings) {
const completeNode = require("nr-test-utils").require("@node-red/nodes/core/common/24-complete.js");

View File

@@ -111,7 +111,15 @@ describe('trigger node', function() {
try {
if (rval) {
msg.should.have.property("payload");
should.deepEqual(msg.payload, rval);
if (type == "date" && val == "1") {
should.deepEqual(Math.round(msg.payload/1000000), Math.round(Date.now()/1000000));
}
else if (type == "date" && val == "iso") {
should.deepEqual(msg.payload.substr(0,11), rval.substr(0,11));
}
else {
should.deepEqual(msg.payload, rval);
}
}
else {
msg.should.have.property("payload", val);
@@ -126,6 +134,7 @@ describe('trigger node', function() {
});
it('should output 2st value when triggered ('+type+')', function(done) {
if (type == "date" && val == "1") { val = "0"; }
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1:"foo", op1type:"str", op2:val, op2type:type, duration:"20", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
process.env[val] = rval;
@@ -142,7 +151,15 @@ describe('trigger node', function() {
else {
if (rval) {
msg.should.have.property("payload");
should.deepEqual(msg.payload, rval);
if (type == "date" && val == "0") {
;(Math.round(msg.payload/1000000)).should.be.approximately(parseInt(Date.now()/1000000), 1);
}
else if (type == "date" && val == "iso") {
should.deepEqual(msg.payload.substr(0,11), rval.substr(0,11));
}
else {
should.deepEqual(msg.payload, rval);
}
}
else {
msg.should.have.property("payload", val);
@@ -166,6 +183,9 @@ describe('trigger node', function() {
var val_buf = "[1,2,3,4,5]";
basicTest("bin", val_buf, Buffer.from(JSON.parse(val_buf)));
basicTest("env", "NR-TEST", "env-val");
basicTest("date", "1", Date.now());
basicTest("date", "iso", (new Date()).toISOString());
// basicTest("date", "object", Date.now());
it('should output 1 then 0 when triggered (default)', function(done) {
var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", duration:"20", wires:[["n2"]] },