mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
33 Commits
3.1.7
...
undo-histo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c294532152 | ||
|
|
960af87fb0 | ||
|
|
de7339ae97 | ||
|
|
0995af62b6 | ||
|
|
c2e03a40b4 | ||
|
|
29ed5b2792 | ||
|
|
e39216e65a | ||
|
|
7ac7f9b4c8 | ||
|
|
4709eb9d49 | ||
|
|
c13b8266dd | ||
|
|
bd58431603 | ||
|
|
9a3cb0b2b5 | ||
|
|
6beae5a806 | ||
|
|
a0636632a1 | ||
|
|
5dfa47ab6c | ||
|
|
ade4679e8c | ||
|
|
410b938442 | ||
|
|
19dcc3a683 | ||
|
|
20d067c1ea | ||
|
|
9526566799 | ||
|
|
0b9dd82c91 | ||
|
|
19213434f9 | ||
|
|
014691346a | ||
|
|
6738b95c29 | ||
|
|
6a8230ec1e | ||
|
|
5679d264b6 | ||
|
|
37265cf4ef | ||
|
|
8a63275989 | ||
|
|
7fc64a84e8 | ||
|
|
02f7cdd5aa | ||
|
|
d7dcceef60 | ||
|
|
ae5e1570ae | ||
|
|
3ca045394a |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,19 @@
|
|||||||
|
#### 3.1.9: Maintenance Release
|
||||||
|
|
||||||
|
- Prevent subflow being added to itself (#4654) @knolleary
|
||||||
|
- Fix use of spawn on windows with cmd files (#4652) @knolleary
|
||||||
|
- Guard refresh of unknown subflow (#4640) @knolleary
|
||||||
|
- Fix subflow module sending messages to debug sidebar (#4642) @knolleary
|
||||||
|
|
||||||
|
#### 3.1.8: Maintenance Release
|
||||||
|
|
||||||
|
- Add validation and error handling on subflow instance properties (#4632) @knolleary
|
||||||
|
- Hide import/export context menu if disabled in theme (#4633) @knolleary
|
||||||
|
- Show change indicator on subflow tabs (#4631) @knolleary
|
||||||
|
- Bump dependencies (#4630) @knolleary
|
||||||
|
- Reset workspace index when clearing nodes (#4619) @knolleary
|
||||||
|
- Remove typo in global config (#4613) @kazuhitoyokoi
|
||||||
|
|
||||||
#### 3.1.7: Maintenance Release
|
#### 3.1.7: Maintenance Release
|
||||||
|
|
||||||
- Add Japanese translation for v3.1.6 (#4603) @kazuhitoyokoi
|
- Add Japanese translation for v3.1.6 (#4603) @kazuhitoyokoi
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "https://nodered.org",
|
"homepage": "https://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"cronosjs": "1.7.1",
|
"cronosjs": "1.7.1",
|
||||||
"denque": "2.1.0",
|
"denque": "2.1.0",
|
||||||
"express": "4.18.2",
|
"express": "4.19.2",
|
||||||
"express-session": "1.17.3",
|
"express-session": "1.17.3",
|
||||||
"form-data": "4.0.0",
|
"form-data": "4.0.0",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
"mqtt": "4.3.7",
|
"mqtt": "4.3.7",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
"mustache": "4.2.0",
|
"mustache": "4.2.0",
|
||||||
"node-red-admin": "^3.1.2",
|
"node-red-admin": "^3.1.3",
|
||||||
"node-watch": "0.7.4",
|
"node-watch": "0.7.4",
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"oauth2orize": "1.11.1",
|
"oauth2orize": "1.11.1",
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
"passport-oauth2-client-password": "0.1.2",
|
"passport-oauth2-client-password": "0.1.2",
|
||||||
"raw-body": "2.5.2",
|
"raw-body": "2.5.2",
|
||||||
"semver": "7.5.4",
|
"semver": "7.5.4",
|
||||||
"tar": "6.1.13",
|
"tar": "6.2.1",
|
||||||
"tough-cookie": "4.1.3",
|
"tough-cookie": "4.1.3",
|
||||||
"uglify-js": "3.17.4",
|
"uglify-js": "3.17.4",
|
||||||
"uuid": "9.0.0",
|
"uuid": "9.0.0",
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
"mermaid": "^10.4.0",
|
"mermaid": "^10.4.0",
|
||||||
"minami": "1.2.3",
|
"minami": "1.2.3",
|
||||||
"mocha": "9.2.2",
|
"mocha": "9.2.2",
|
||||||
"node-red-node-test-helper": "^0.3.2",
|
"node-red-node-test-helper": "^0.3.3",
|
||||||
"nodemon": "2.0.20",
|
"nodemon": "2.0.20",
|
||||||
"proxy": "^1.0.2",
|
"proxy": "^1.0.2",
|
||||||
"sass": "1.62.1",
|
"sass": "1.62.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-api",
|
"name": "@node-red/editor-api",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,14 +16,14 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "3.1.7",
|
"@node-red/util": "3.1.9",
|
||||||
"@node-red/editor-client": "3.1.7",
|
"@node-red/editor-client": "3.1.9",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.2",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"express-session": "1.17.3",
|
"express-session": "1.17.3",
|
||||||
"express": "4.18.2",
|
"express": "4.19.2",
|
||||||
"memorystore": "1.6.7",
|
"memorystore": "1.6.7",
|
||||||
"mime": "3.0.0",
|
"mime": "3.0.0",
|
||||||
"multer": "1.4.5-lts.1",
|
"multer": "1.4.5-lts.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/editor-client",
|
"name": "@node-red/editor-client",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -706,11 +706,36 @@ RED.history = (function() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function markEventDirty (evt) {
|
||||||
|
// This isn't 100% thorough - just covers the main move/edit/delete cases
|
||||||
|
evt.dirty = true
|
||||||
|
if (evt.multi) {
|
||||||
|
for (let i = 0; i < evt.events.length-1; i++) {
|
||||||
|
markEventDirty(evt.events[i])
|
||||||
|
}
|
||||||
|
} else if (evt.t === 'move') {
|
||||||
|
for (let i=0;i<evt.nodes.length;i++) {
|
||||||
|
evt.nodes[i].moved = true
|
||||||
|
}
|
||||||
|
} else if (evt.t === 'edit') {
|
||||||
|
evt.changed = true
|
||||||
|
} else if (evt.t === 'delete') {
|
||||||
|
if (evt.nodes) {
|
||||||
|
for (let i=0;i<evt.nodes.length;i++) {
|
||||||
|
evt.nodes[i].changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
|
||||||
markAllDirty: function() {
|
markAllDirty: function() {
|
||||||
for (var i=0;i<undoHistory.length;i++) {
|
// A deploy has happened meaning any undo into the history will represent
|
||||||
|
// an undeployed change - regardless of what it was when the event was recorded.
|
||||||
|
// This goes back through the history any marks them all as being dirty events
|
||||||
|
// and also ensures individual node states are marked dirty
|
||||||
|
for (let i=0;i<undoHistory.length;i++) {
|
||||||
undoHistory[i].dirty = true;
|
undoHistory[i].dirty = true;
|
||||||
|
markEventDirty(undoHistory[i])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
list: function() {
|
list: function() {
|
||||||
|
|||||||
@@ -547,12 +547,16 @@ RED.nodes = (function() {
|
|||||||
* @param {String} z tab id
|
* @param {String} z tab id
|
||||||
*/
|
*/
|
||||||
checkTabState: function (z) {
|
checkTabState: function (z) {
|
||||||
const ws = workspaces[z]
|
const ws = workspaces[z] || subflows[z]
|
||||||
if (ws) {
|
if (ws) {
|
||||||
const contentsChanged = tabDirtyMap[z].size > 0 || tabDeletedNodesMap[z].size > 0
|
const contentsChanged = tabDirtyMap[z].size > 0 || tabDeletedNodesMap[z].size > 0
|
||||||
if (Boolean(ws.contentsChanged) !== contentsChanged) {
|
if (Boolean(ws.contentsChanged) !== contentsChanged) {
|
||||||
ws.contentsChanged = contentsChanged
|
ws.contentsChanged = contentsChanged
|
||||||
RED.events.emit("flows:change", ws);
|
if (ws.type === 'tab') {
|
||||||
|
RED.events.emit("flows:change", ws);
|
||||||
|
} else {
|
||||||
|
RED.events.emit("subflows:change", ws);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1025,7 +1029,22 @@ RED.nodes = (function() {
|
|||||||
RED.nodes.registerType("subflow:"+sf.id, {
|
RED.nodes.registerType("subflow:"+sf.id, {
|
||||||
defaults:{
|
defaults:{
|
||||||
name:{value:""},
|
name:{value:""},
|
||||||
env:{value:[]}
|
env:{value:[], validate: function(value) {
|
||||||
|
const errors = []
|
||||||
|
if (value) {
|
||||||
|
value.forEach(env => {
|
||||||
|
const r = RED.utils.validateTypedProperty(env.value, env.type)
|
||||||
|
if (r !== true) {
|
||||||
|
errors.push(env.name+': '+r)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (errors.length === 0) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
}}
|
||||||
},
|
},
|
||||||
icon: function() { return sf.icon||"subflow.svg" },
|
icon: function() { return sf.icon||"subflow.svg" },
|
||||||
category: sf.category || "subflows",
|
category: sf.category || "subflows",
|
||||||
|
|||||||
@@ -118,10 +118,16 @@ RED.contextMenu = (function () {
|
|||||||
onselect: 'core:split-wire-with-link-nodes',
|
onselect: 'core:split-wire-with-link-nodes',
|
||||||
disabled: !canEdit || !hasLinks
|
disabled: !canEdit || !hasLinks
|
||||||
},
|
},
|
||||||
null,
|
null
|
||||||
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
|
|
||||||
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
|
|
||||||
)
|
)
|
||||||
|
if (RED.settings.theme("menu.menu-item-import-library", true)) {
|
||||||
|
insertOptions.push(
|
||||||
|
{ onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
|
||||||
|
{ onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (hasSelection && canEdit) {
|
if (hasSelection && canEdit) {
|
||||||
const nodeOptions = []
|
const nodeOptions = []
|
||||||
if (!hasMultipleSelection && !isGroup) {
|
if (!hasMultipleSelection && !isGroup) {
|
||||||
@@ -194,8 +200,14 @@ RED.contextMenu = (function () {
|
|||||||
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
|
{ onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
|
||||||
{ onselect: 'core:delete-selection', label: RED._('keyboard.deleteSelected'), disabled: !canEdit || !canDelete },
|
{ onselect: 'core:delete-selection', label: RED._('keyboard.deleteSelected'), disabled: !canEdit || !canDelete },
|
||||||
{ onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
|
{ onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
|
||||||
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
|
)
|
||||||
{ onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") },
|
if (RED.settings.theme("menu.menu-item-export-library", true)) {
|
||||||
|
menuItems.push(
|
||||||
|
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
menuItems.push(
|
||||||
|
{ onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -612,7 +612,10 @@ RED.deploy = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
RED.nodes.eachSubflow(function (subflow) {
|
RED.nodes.eachSubflow(function (subflow) {
|
||||||
subflow.changed = false;
|
if (subflow.changed) {
|
||||||
|
subflow.changed = false;
|
||||||
|
RED.events.emit("subflows:change", subflow);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
RED.nodes.eachWorkspace(function (ws) {
|
RED.nodes.eachWorkspace(function (ws) {
|
||||||
if (ws.changed || ws.added) {
|
if (ws.changed || ws.added) {
|
||||||
|
|||||||
@@ -1623,8 +1623,8 @@ RED.editor = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isSameObj(old_env, new_env)) {
|
if (!isSameObj(old_env, new_env)) {
|
||||||
editing_node.env = new_env;
|
|
||||||
editState.changes.env = editing_node.env;
|
editState.changes.env = editing_node.env;
|
||||||
|
editing_node.env = new_env;
|
||||||
editState.changed = true;
|
editState.changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,8 +158,10 @@ RED.sidebar.help = (function() {
|
|||||||
|
|
||||||
function refreshSubflow(sf) {
|
function refreshSubflow(sf) {
|
||||||
var item = treeList.treeList('get',"node-type:subflow:"+sf.id);
|
var item = treeList.treeList('get',"node-type:subflow:"+sf.id);
|
||||||
item.subflowLabel = sf._def.label().toLowerCase();
|
if (item) {
|
||||||
item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
|
item.subflowLabel = sf._def.label().toLowerCase();
|
||||||
|
item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideTOC() {
|
function hideTOC() {
|
||||||
|
|||||||
@@ -646,120 +646,128 @@ RED.view = (function() {
|
|||||||
}
|
}
|
||||||
d3.event = event;
|
d3.event = event;
|
||||||
var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
|
var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
|
||||||
var result = createNode(selected_tool);
|
|
||||||
if (!result) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var historyEvent = result.historyEvent;
|
|
||||||
var nn = RED.nodes.add(result.node);
|
|
||||||
|
|
||||||
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
|
||||||
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
|
||||||
nn.l = showLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0));
|
|
||||||
var helperWidth = ui.helper.width();
|
|
||||||
var helperHeight = ui.helper.height();
|
|
||||||
var mousePos = d3.touches(this)[0]||d3.mouse(this);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var isLink = (nn.type === "link in" || nn.type === "link out")
|
var result = createNode(selected_tool);
|
||||||
var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink;
|
if (!result) {
|
||||||
|
return;
|
||||||
var label = RED.utils.getNodeLabel(nn, nn.type);
|
|
||||||
var labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
|
||||||
if (hideLabel) {
|
|
||||||
nn.w = node_height;
|
|
||||||
nn.h = Math.max(node_height,(nn.outputs || 0) * 15);
|
|
||||||
} else {
|
|
||||||
nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) );
|
|
||||||
nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30);
|
|
||||||
}
|
}
|
||||||
} catch(err) {
|
var historyEvent = result.historyEvent;
|
||||||
}
|
var nn = RED.nodes.add(result.node);
|
||||||
|
|
||||||
mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]);
|
var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
|
||||||
mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]);
|
if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
|
||||||
mousePos[1] /= scaleFactor;
|
nn.l = showLabel;
|
||||||
mousePos[0] /= scaleFactor;
|
}
|
||||||
|
|
||||||
nn.x = mousePos[0];
|
var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0));
|
||||||
nn.y = mousePos[1];
|
var helperWidth = ui.helper.width();
|
||||||
|
var helperHeight = ui.helper.height();
|
||||||
|
var mousePos = d3.touches(this)[0]||d3.mouse(this);
|
||||||
|
|
||||||
var minX = nn.w/2 -5;
|
try {
|
||||||
if (nn.x < minX) {
|
var isLink = (nn.type === "link in" || nn.type === "link out")
|
||||||
nn.x = minX;
|
var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink;
|
||||||
}
|
|
||||||
var minY = nn.h/2 -5;
|
|
||||||
if (nn.y < minY) {
|
|
||||||
nn.y = minY;
|
|
||||||
}
|
|
||||||
var maxX = space_width -nn.w/2 +5;
|
|
||||||
if (nn.x > maxX) {
|
|
||||||
nn.x = maxX;
|
|
||||||
}
|
|
||||||
var maxY = space_height -nn.h +5;
|
|
||||||
if (nn.y > maxY) {
|
|
||||||
nn.y = maxY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snapGrid) {
|
var label = RED.utils.getNodeLabel(nn, nn.type);
|
||||||
var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
|
var labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
||||||
nn.x -= gridOffset.x;
|
if (hideLabel) {
|
||||||
nn.y -= gridOffset.y;
|
nn.w = node_height;
|
||||||
}
|
nn.h = Math.max(node_height,(nn.outputs || 0) * 15);
|
||||||
|
} else {
|
||||||
|
nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) );
|
||||||
|
nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30);
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
|
}
|
||||||
|
|
||||||
var linkToSplice = $(ui.helper).data("splice");
|
mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]);
|
||||||
if (linkToSplice) {
|
mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]);
|
||||||
spliceLink(linkToSplice, nn, historyEvent)
|
mousePos[1] /= scaleFactor;
|
||||||
}
|
mousePos[0] /= scaleFactor;
|
||||||
|
|
||||||
|
nn.x = mousePos[0];
|
||||||
|
nn.y = mousePos[1];
|
||||||
|
|
||||||
|
var minX = nn.w/2 -5;
|
||||||
|
if (nn.x < minX) {
|
||||||
|
nn.x = minX;
|
||||||
|
}
|
||||||
|
var minY = nn.h/2 -5;
|
||||||
|
if (nn.y < minY) {
|
||||||
|
nn.y = minY;
|
||||||
|
}
|
||||||
|
var maxX = space_width -nn.w/2 +5;
|
||||||
|
if (nn.x > maxX) {
|
||||||
|
nn.x = maxX;
|
||||||
|
}
|
||||||
|
var maxY = space_height -nn.h +5;
|
||||||
|
if (nn.y > maxY) {
|
||||||
|
nn.y = maxY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapGrid) {
|
||||||
|
var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
|
||||||
|
nn.x -= gridOffset.x;
|
||||||
|
nn.y -= gridOffset.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
var linkToSplice = $(ui.helper).data("splice");
|
||||||
|
if (linkToSplice) {
|
||||||
|
spliceLink(linkToSplice, nn, historyEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
var group = $(ui.helper).data("group");
|
||||||
|
if (group) {
|
||||||
|
var oldX = group.x;
|
||||||
|
var oldY = group.y;
|
||||||
|
RED.group.addToGroup(group, nn);
|
||||||
|
var moveEvent = null;
|
||||||
|
if ((group.x !== oldX) ||
|
||||||
|
(group.y !== oldY)) {
|
||||||
|
moveEvent = {
|
||||||
|
t: "move",
|
||||||
|
nodes: [{n: group,
|
||||||
|
ox: oldX, oy: oldY,
|
||||||
|
dx: group.x -oldX,
|
||||||
|
dy: group.y -oldY}],
|
||||||
|
dirty: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
historyEvent = {
|
||||||
|
t: 'multi',
|
||||||
|
events: [historyEvent],
|
||||||
|
|
||||||
var group = $(ui.helper).data("group");
|
|
||||||
if (group) {
|
|
||||||
var oldX = group.x;
|
|
||||||
var oldY = group.y;
|
|
||||||
RED.group.addToGroup(group, nn);
|
|
||||||
var moveEvent = null;
|
|
||||||
if ((group.x !== oldX) ||
|
|
||||||
(group.y !== oldY)) {
|
|
||||||
moveEvent = {
|
|
||||||
t: "move",
|
|
||||||
nodes: [{n: group,
|
|
||||||
ox: oldX, oy: oldY,
|
|
||||||
dx: group.x -oldX,
|
|
||||||
dy: group.y -oldY}],
|
|
||||||
dirty: true
|
|
||||||
};
|
};
|
||||||
|
if (moveEvent) {
|
||||||
|
historyEvent.events.push(moveEvent)
|
||||||
|
}
|
||||||
|
historyEvent.events.push({
|
||||||
|
t: "addToGroup",
|
||||||
|
group: group,
|
||||||
|
nodes: nn
|
||||||
|
})
|
||||||
}
|
}
|
||||||
historyEvent = {
|
|
||||||
t: 'multi',
|
|
||||||
events: [historyEvent],
|
|
||||||
|
|
||||||
};
|
RED.history.push(historyEvent);
|
||||||
if (moveEvent) {
|
RED.editor.validateNode(nn);
|
||||||
historyEvent.events.push(moveEvent)
|
RED.nodes.dirty(true);
|
||||||
|
// auto select dropped node - so info shows (if visible)
|
||||||
|
clearSelection();
|
||||||
|
nn.selected = true;
|
||||||
|
movingSet.add(nn);
|
||||||
|
updateActiveNodes();
|
||||||
|
updateSelection();
|
||||||
|
redraw();
|
||||||
|
|
||||||
|
if (nn._def.autoedit) {
|
||||||
|
RED.editor.edit(nn);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code != "NODE_RED") {
|
||||||
|
RED.notify(RED._("notification.error",{message:error.toString()}),"error");
|
||||||
|
} else {
|
||||||
|
RED.notify(RED._("notification.error",{message:error.message}),"error");
|
||||||
}
|
}
|
||||||
historyEvent.events.push({
|
|
||||||
t: "addToGroup",
|
|
||||||
group: group,
|
|
||||||
nodes: nn
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
RED.history.push(historyEvent);
|
|
||||||
RED.editor.validateNode(nn);
|
|
||||||
RED.nodes.dirty(true);
|
|
||||||
// auto select dropped node - so info shows (if visible)
|
|
||||||
clearSelection();
|
|
||||||
nn.selected = true;
|
|
||||||
movingSet.add(nn);
|
|
||||||
updateActiveNodes();
|
|
||||||
updateSelection();
|
|
||||||
redraw();
|
|
||||||
|
|
||||||
if (nn._def.autoedit) {
|
|
||||||
RED.editor.edit(nn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -2159,9 +2167,9 @@ RED.view = (function() {
|
|||||||
if (n.ox !== n.n.x || n.oy !== n.n.y || addedToGroup) {
|
if (n.ox !== n.n.x || n.oy !== n.n.y || addedToGroup) {
|
||||||
// This node has moved or added to a group
|
// This node has moved or added to a group
|
||||||
if (rehomedNodes.has(n)) {
|
if (rehomedNodes.has(n)) {
|
||||||
moveAndChangedGroupEvent.nodes.push({...n})
|
moveAndChangedGroupEvent.nodes.push({...n, moved: n.n.moved})
|
||||||
} else {
|
} else {
|
||||||
moveEvent.nodes.push({...n})
|
moveEvent.nodes.push({...n, moved: n.n.moved})
|
||||||
}
|
}
|
||||||
n.n.dirty = true;
|
n.n.dirty = true;
|
||||||
n.n.moved = true;
|
n.n.moved = true;
|
||||||
@@ -6063,14 +6071,19 @@ RED.view = (function() {
|
|||||||
function createNode(type, x, y, z) {
|
function createNode(type, x, y, z) {
|
||||||
const wasDirty = RED.nodes.dirty()
|
const wasDirty = RED.nodes.dirty()
|
||||||
var m = /^subflow:(.+)$/.exec(type);
|
var m = /^subflow:(.+)$/.exec(type);
|
||||||
var activeSubflow = z ? RED.nodes.subflow(z) : null;
|
var activeSubflow = (z || RED.workspaces.active()) ? RED.nodes.subflow(z || RED.workspaces.active()) : null;
|
||||||
|
|
||||||
if (activeSubflow && m) {
|
if (activeSubflow && m) {
|
||||||
var subflowId = m[1];
|
var subflowId = m[1];
|
||||||
|
let err
|
||||||
if (subflowId === activeSubflow.id) {
|
if (subflowId === activeSubflow.id) {
|
||||||
throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddSubflowToItself") }))
|
err = new Error(RED._("notification.errors.cannotAddSubflowToItself"))
|
||||||
|
} else if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
|
||||||
|
err = new Error(RED._("notification.errors.cannotAddCircularReference"))
|
||||||
}
|
}
|
||||||
if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
|
if (err) {
|
||||||
throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddCircularReference") }))
|
err.code = 'NODE_RED'
|
||||||
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -491,6 +491,11 @@ RED.workspaces = (function() {
|
|||||||
createWorkspaceTabs();
|
createWorkspaceTabs();
|
||||||
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
RED.events.on("sidebar:resize",workspace_tabs.resize);
|
||||||
|
|
||||||
|
RED.events.on("workspace:clear", () => {
|
||||||
|
// Reset the index used to generate new flow names
|
||||||
|
workspaceIndex = 0
|
||||||
|
})
|
||||||
|
|
||||||
RED.actions.add("core:show-next-tab",function() {
|
RED.actions.add("core:show-next-tab",function() {
|
||||||
var oldActive = activeWorkspace;
|
var oldActive = activeWorkspace;
|
||||||
workspace_tabs.nextTab();
|
workspace_tabs.nextTab();
|
||||||
@@ -657,6 +662,9 @@ RED.workspaces = (function() {
|
|||||||
RED.events.on("flows:change", (ws) => {
|
RED.events.on("flows:change", (ws) => {
|
||||||
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
|
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
|
||||||
})
|
})
|
||||||
|
RED.events.on("subflows:change", (ws) => {
|
||||||
|
$("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
|
||||||
|
})
|
||||||
|
|
||||||
hideWorkspace();
|
hideWorkspace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,7 +378,7 @@
|
|||||||
return { id: id, label: RED.nodes.workspace(id).label } //flow id + name
|
return { id: id, label: RED.nodes.workspace(id).label } //flow id + name
|
||||||
} else {
|
} else {
|
||||||
const instanceNode = RED.nodes.node(id)
|
const instanceNode = RED.nodes.node(id)
|
||||||
const pathLabel = (instanceNode.name || RED.nodes.subflow(instanceNode.type.substring(8)).name)
|
const pathLabel = (instanceNode.name || RED.nodes.subflow(instanceNode.type.substring(8))?.name || instanceNode.type)
|
||||||
return { id: id, label: pathLabel }
|
return { id: id, label: pathLabel }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ module.exports = function(RED) {
|
|||||||
var exec = require('child_process').exec;
|
var exec = require('child_process').exec;
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var isUtf8 = require('is-utf8');
|
var isUtf8 = require('is-utf8');
|
||||||
|
const isWindows = process.platform === 'win32'
|
||||||
|
|
||||||
function ExecNode(n) {
|
function ExecNode(n) {
|
||||||
RED.nodes.createNode(this,n);
|
RED.nodes.createNode(this,n);
|
||||||
@@ -85,9 +86,12 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
var cmd = arg.shift();
|
var cmd = arg.shift();
|
||||||
|
// Since 18.20.2/20.12.2, it is invalid to call spawn on Windows with a .bat/.cmd file
|
||||||
|
// without using shell: true.
|
||||||
|
const opts = isWindows ? { ...node.spawnOpt, shell: true } : node.spawnOpt
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
node.debug(cmd+" ["+arg+"]");
|
node.debug(cmd+" ["+arg+"]");
|
||||||
child = spawn(cmd,arg,node.spawnOpt);
|
child = spawn(cmd,arg,opts);
|
||||||
node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid});
|
node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid});
|
||||||
var unknownCommand = (child.pid === undefined);
|
var unknownCommand = (child.pid === undefined);
|
||||||
if (node.timer !== 0) {
|
if (node.timer !== 0) {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
<h4>Automatic mode</h4>
|
<h4>Automatic mode</h4>
|
||||||
<p>Automatic mode uses the <code>parts</code> property of incoming messages to
|
<p>Automatic mode uses the <code>parts</code> property of incoming messages to
|
||||||
determine how the sequence should be joined. This allows it to automatically
|
determine how the sequence should be joined. This allows it to automatically
|
||||||
reverse the action of a <b>split</b> node.
|
reverse the action of a <b>split</b> node.</p>
|
||||||
|
|
||||||
<h4>Manual mode</h4>
|
<h4>Manual mode</h4>
|
||||||
<p>When configured to join in manual mode, the node is able to join sequences
|
<p>When configured to join in manual mode, the node is able to join sequences
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<script type="text/html" data-help-name="global-config">
|
<script type="text/html" data-help-name="global-config">
|
||||||
<p>大域的なフローの設定を保持するノード。大域的な環境変数の定義を含みます。</p>
|
<p>大域的なフローの設定を保持するノード。大域的な環境変数の定義を含みます。</p>
|
||||||
</script>p
|
</script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/nodes",
|
"name": "@node-red/nodes",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ async function installModule(moduleDetails) {
|
|||||||
let extraArgs = triggerPayload.args || [];
|
let extraArgs = triggerPayload.args || [];
|
||||||
let args = ['install', ...extraArgs, installSpec]
|
let args = ['install', ...extraArgs, installSpec]
|
||||||
log.trace(NPM_COMMAND + JSON.stringify(args));
|
log.trace(NPM_COMMAND + JSON.stringify(args));
|
||||||
return exec.run(NPM_COMMAND, args, { cwd: installDir },true)
|
return exec.run(NPM_COMMAND, args, { cwd: installDir, shell: true },true)
|
||||||
} else {
|
} else {
|
||||||
log.trace("skipping npm install");
|
log.trace("skipping npm install");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,15 @@ const registryUtil = require("./util");
|
|||||||
const library = require("./library");
|
const library = require("./library");
|
||||||
const {exec,log,events,hooks} = require("@node-red/util");
|
const {exec,log,events,hooks} = require("@node-red/util");
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
||||||
let installerEnabled = false;
|
|
||||||
|
|
||||||
|
const isWindows = process.platform === 'win32'
|
||||||
|
const npmCommand = isWindows ? 'npm.cmd' : 'npm';
|
||||||
|
|
||||||
|
let installerEnabled = false;
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
const moduleRe = /^(@[^/@]+?[/])?[^/@]+?$/;
|
const moduleRe = /^(@[^/@]+?[/])?[^/@]+?$/;
|
||||||
const slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
|
const slashRe = isWindows ? /\\|[/]/ : /[/]/;
|
||||||
const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
|
const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
|
||||||
const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/;
|
const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/;
|
||||||
|
|
||||||
@@ -225,7 +228,7 @@ async function installModule(module,version,url) {
|
|||||||
let extraArgs = triggerPayload.args || [];
|
let extraArgs = triggerPayload.args || [];
|
||||||
let args = ['install', ...extraArgs, installName]
|
let args = ['install', ...extraArgs, installName]
|
||||||
log.trace(npmCommand + JSON.stringify(args));
|
log.trace(npmCommand + JSON.stringify(args));
|
||||||
return exec.run(npmCommand,args,{ cwd: installDir}, true)
|
return exec.run(npmCommand,args,{ cwd: installDir, shell: true }, true)
|
||||||
} else {
|
} else {
|
||||||
log.trace("skipping npm install");
|
log.trace("skipping npm install");
|
||||||
}
|
}
|
||||||
@@ -260,7 +263,7 @@ async function installModule(module,version,url) {
|
|||||||
log.warn("------------------------------------------");
|
log.warn("------------------------------------------");
|
||||||
e = new Error(log._("server.install.install-failed")+": "+err.toString());
|
e = new Error(log._("server.install.install-failed")+": "+err.toString());
|
||||||
if (err.hook === "postInstall") {
|
if (err.hook === "postInstall") {
|
||||||
return exec.run(npmCommand,["remove",module],{ cwd: installDir}, false).finally(() => {
|
return exec.run(npmCommand,["remove",module],{ cwd: installDir, shell: true }, false).finally(() => {
|
||||||
throw e;
|
throw e;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -356,7 +359,7 @@ async function getModuleVersionFromNPM(module, version) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
child_process.execFile(npmCommand,['info','--json',installName],function(err,stdout,stderr) {
|
child_process.execFile(npmCommand,['info','--json',installName],{ shell: true },function(err,stdout,stderr) {
|
||||||
try {
|
try {
|
||||||
if (!stdout) {
|
if (!stdout) {
|
||||||
log.warn(log._("server.install.install-failed-not-found",{name:module}));
|
log.warn(log._("server.install.install-failed-not-found",{name:module}));
|
||||||
@@ -511,7 +514,7 @@ function uninstallModule(module) {
|
|||||||
let extraArgs = triggerPayload.args || [];
|
let extraArgs = triggerPayload.args || [];
|
||||||
let args = ['remove', ...extraArgs, module]
|
let args = ['remove', ...extraArgs, module]
|
||||||
log.trace(npmCommand + JSON.stringify(args));
|
log.trace(npmCommand + JSON.stringify(args));
|
||||||
return exec.run(npmCommand,args,{ cwd: installDir}, true)
|
return exec.run(npmCommand,args,{ cwd: installDir, shell: true }, true)
|
||||||
} else {
|
} else {
|
||||||
log.trace("skipping npm uninstall");
|
log.trace("skipping npm uninstall");
|
||||||
}
|
}
|
||||||
@@ -578,7 +581,7 @@ async function checkPrereq() {
|
|||||||
installerEnabled = false;
|
installerEnabled = false;
|
||||||
} else {
|
} else {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
child_process.execFile(npmCommand,['-v'],function(err,stdout) {
|
child_process.execFile(npmCommand,['-v'],{ shell: true },function(err,stdout) {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.info(log._("server.palette-editor.npm-not-found"));
|
log.info(log._("server.palette-editor.npm-not-found"));
|
||||||
installerEnabled = false;
|
installerEnabled = false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/registry",
|
"name": "@node-red/registry",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/util": "3.1.7",
|
"@node-red/util": "3.1.9",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
"semver": "7.5.4",
|
"semver": "7.5.4",
|
||||||
"tar": "6.1.13",
|
"tar": "6.2.1",
|
||||||
"uglify-js": "3.17.4"
|
"uglify-js": "3.17.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,14 +106,22 @@ async function evaluateEnvProperties(flow, env, credentials) {
|
|||||||
result = { value: result, __clone__: true}
|
result = { value: result, __clone__: true}
|
||||||
}
|
}
|
||||||
evaluatedEnv[name] = result
|
evaluatedEnv[name] = result
|
||||||
|
} else {
|
||||||
|
evaluatedEnv[name] = undefined
|
||||||
|
flow.error(`Error evaluating env property '${name}': ${err.toString()}`)
|
||||||
}
|
}
|
||||||
resolve()
|
resolve()
|
||||||
});
|
});
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);
|
try {
|
||||||
if (typeof value === 'object') {
|
value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);
|
||||||
value = { value: value, __clone__: true}
|
if (typeof value === 'object') {
|
||||||
|
value = { value: value, __clone__: true}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
value = undefined
|
||||||
|
flow.error(`Error evaluating env property '${name}': ${err.toString()}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
evaluatedEnv[name] = value
|
evaluatedEnv[name] = value
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/runtime",
|
"name": "@node-red/runtime",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/registry": "3.1.7",
|
"@node-red/registry": "3.1.9",
|
||||||
"@node-red/util": "3.1.7",
|
"@node-red/util": "3.1.9",
|
||||||
"async-mutex": "0.4.0",
|
"async-mutex": "0.4.0",
|
||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"express": "4.18.2",
|
"express": "4.19.2",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
"json-stringify-safe": "5.0.1"
|
"json-stringify-safe": "5.0.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@node-red/util",
|
"name": "@node-red/util",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
14
packages/node_modules/node-red/package.json
vendored
14
packages/node_modules/node-red/package.json
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "node-red",
|
"name": "node-red",
|
||||||
"version": "3.1.7",
|
"version": "3.1.9",
|
||||||
"description": "Low-code programming for event-driven applications",
|
"description": "Low-code programming for event-driven applications",
|
||||||
"homepage": "https://nodered.org",
|
"homepage": "https://nodered.org",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -31,15 +31,15 @@
|
|||||||
"flow"
|
"flow"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@node-red/editor-api": "3.1.7",
|
"@node-red/editor-api": "3.1.9",
|
||||||
"@node-red/runtime": "3.1.7",
|
"@node-red/runtime": "3.1.9",
|
||||||
"@node-red/util": "3.1.7",
|
"@node-red/util": "3.1.9",
|
||||||
"@node-red/nodes": "3.1.7",
|
"@node-red/nodes": "3.1.9",
|
||||||
"basic-auth": "2.0.1",
|
"basic-auth": "2.0.1",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"express": "4.18.2",
|
"express": "4.19.2",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
"node-red-admin": "^3.1.2",
|
"node-red-admin": "^3.1.3",
|
||||||
"nopt": "5.0.0",
|
"nopt": "5.0.0",
|
||||||
"semver": "7.5.4"
|
"semver": "7.5.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ describe('HTTP Request Node', function() {
|
|||||||
function startServer(done) {
|
function startServer(done) {
|
||||||
testPort += 1;
|
testPort += 1;
|
||||||
testServer = stoppable(http.createServer(testApp));
|
testServer = stoppable(http.createServer(testApp));
|
||||||
|
const promises = []
|
||||||
testServer.listen(testPort,function(err) {
|
testServer.listen(testPort,function(err) {
|
||||||
testSslPort += 1;
|
testSslPort += 1;
|
||||||
console.log("ssl port", testSslPort);
|
console.log("ssl port", testSslPort);
|
||||||
@@ -81,13 +82,17 @@ describe('HTTP Request Node', function() {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
testSslServer = stoppable(https.createServer(sslOptions,testApp));
|
testSslServer = stoppable(https.createServer(sslOptions,testApp));
|
||||||
testSslServer.listen(testSslPort, function(err){
|
console.log('> start testSslServer')
|
||||||
if (err) {
|
promises.push(new Promise((resolve, reject) => {
|
||||||
console.log(err);
|
testSslServer.listen(testSslPort, function(err){
|
||||||
} else {
|
console.log(' done testSslServer')
|
||||||
console.log("started testSslServer");
|
if (err) {
|
||||||
}
|
reject(err)
|
||||||
});
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
|
||||||
testSslClientPort += 1;
|
testSslClientPort += 1;
|
||||||
var sslClientOptions = {
|
var sslClientOptions = {
|
||||||
@@ -97,10 +102,17 @@ describe('HTTP Request Node', function() {
|
|||||||
requestCert: true
|
requestCert: true
|
||||||
};
|
};
|
||||||
testSslClientServer = stoppable(https.createServer(sslClientOptions, testApp));
|
testSslClientServer = stoppable(https.createServer(sslClientOptions, testApp));
|
||||||
testSslClientServer.listen(testSslClientPort, function(err){
|
console.log('> start testSslClientServer')
|
||||||
console.log("ssl-client", err)
|
promises.push(new Promise((resolve, reject) => {
|
||||||
});
|
testSslClientServer.listen(testSslClientPort, function(err){
|
||||||
|
console.log(' done testSslClientServer')
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}))
|
||||||
testProxyPort += 1;
|
testProxyPort += 1;
|
||||||
testProxyServer = stoppable(httpProxy(http.createServer()))
|
testProxyServer = stoppable(httpProxy(http.createServer()))
|
||||||
|
|
||||||
@@ -109,7 +121,17 @@ describe('HTTP Request Node', function() {
|
|||||||
res.setHeader("x-testproxy-header", "foobar")
|
res.setHeader("x-testproxy-header", "foobar")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
testProxyServer.listen(testProxyPort)
|
console.log('> testProxyServer')
|
||||||
|
promises.push(new Promise((resolve, reject) => {
|
||||||
|
testProxyServer.listen(testProxyPort, function(err) {
|
||||||
|
console.log(' done testProxyServer')
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
testProxyAuthPort += 1
|
testProxyAuthPort += 1
|
||||||
testProxyServerAuth = stoppable(httpProxy(http.createServer()))
|
testProxyServerAuth = stoppable(httpProxy(http.createServer()))
|
||||||
@@ -131,9 +153,19 @@ describe('HTTP Request Node', function() {
|
|||||||
res.setHeader("x-testproxy-header", "foobar")
|
res.setHeader("x-testproxy-header", "foobar")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
testProxyServerAuth.listen(testProxyAuthPort)
|
console.log('> testProxyServerAuth')
|
||||||
|
promises.push(new Promise((resolve, reject) => {
|
||||||
|
testProxyServerAuth.listen(testProxyAuthPort, function(err) {
|
||||||
|
console.log(' done testProxyServerAuth')
|
||||||
|
if (err) {
|
||||||
|
reject(err)
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
|
||||||
done(err);
|
Promise.all(promises).then(() => { done() }).catch(done)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,7 +461,11 @@ describe('HTTP Request Node', function() {
|
|||||||
if (err) {
|
if (err) {
|
||||||
done(err);
|
done(err);
|
||||||
}
|
}
|
||||||
helper.startServer(done);
|
console.log('> helper.startServer')
|
||||||
|
helper.startServer(function(err) {
|
||||||
|
console.log('> helper started')
|
||||||
|
done(err)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user