From bd58431603fb4169c1696f6b97a618b1acae5091 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Thu, 11 Apr 2024 14:40:29 +0100 Subject: [PATCH 1/9] Fix use of spawn on windows with cmd files --- .../@node-red/nodes/core/function/90-exec.js | 6 +++++- .../@node-red/registry/lib/externalModules.js | 2 +- .../@node-red/registry/lib/installer.js | 19 +++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/function/90-exec.js b/packages/node_modules/@node-red/nodes/core/function/90-exec.js index 2ae9947dd..70aec8d2b 100644 --- a/packages/node_modules/@node-red/nodes/core/function/90-exec.js +++ b/packages/node_modules/@node-red/nodes/core/function/90-exec.js @@ -20,6 +20,7 @@ module.exports = function(RED) { var exec = require('child_process').exec; var fs = require('fs'); var isUtf8 = require('is-utf8'); + const isWindows = process.platform === 'win32' function ExecNode(n) { RED.nodes.createNode(this,n); @@ -85,9 +86,12 @@ module.exports = function(RED) { } }); 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 */ 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}); var unknownCommand = (child.pid === undefined); if (node.timer !== 0) { diff --git a/packages/node_modules/@node-red/registry/lib/externalModules.js b/packages/node_modules/@node-red/registry/lib/externalModules.js index a8a2c634c..78765f80e 100644 --- a/packages/node_modules/@node-red/registry/lib/externalModules.js +++ b/packages/node_modules/@node-red/registry/lib/externalModules.js @@ -273,7 +273,7 @@ async function installModule(moduleDetails) { let extraArgs = triggerPayload.args || []; let args = ['install', ...extraArgs, installSpec] 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 { log.trace("skipping npm install"); } diff --git a/packages/node_modules/@node-red/registry/lib/installer.js b/packages/node_modules/@node-red/registry/lib/installer.js index 95022fbb1..d5949a546 100644 --- a/packages/node_modules/@node-red/registry/lib/installer.js +++ b/packages/node_modules/@node-red/registry/lib/installer.js @@ -25,12 +25,15 @@ const registryUtil = require("./util"); const library = require("./library"); const {exec,log,events,hooks} = require("@node-red/util"); 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; + const moduleRe = /^(@[^/@]+?[/])?[^/@]+?$/; -const slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/; +const slashRe = isWindows ? /\\|[/]/ : /[/]/; const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//; const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/; @@ -225,7 +228,7 @@ async function installModule(module,version,url) { let extraArgs = triggerPayload.args || []; let args = ['install', ...extraArgs, installName] 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 { log.trace("skipping npm install"); } @@ -260,7 +263,7 @@ async function installModule(module,version,url) { log.warn("------------------------------------------"); e = new Error(log._("server.install.install-failed")+": "+err.toString()); 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; }) } @@ -356,7 +359,7 @@ async function getModuleVersionFromNPM(module, version) { } 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 { if (!stdout) { log.warn(log._("server.install.install-failed-not-found",{name:module})); @@ -511,7 +514,7 @@ function uninstallModule(module) { let extraArgs = triggerPayload.args || []; let args = ['remove', ...extraArgs, module] 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 { log.trace("skipping npm uninstall"); } @@ -578,7 +581,7 @@ async function checkPrereq() { installerEnabled = false; } else { return new Promise(resolve => { - child_process.execFile(npmCommand,['-v'],function(err,stdout) { + child_process.execFile(npmCommand,['-v'],{ shell: true },function(err,stdout) { if (err) { log.info(log._("server.palette-editor.npm-not-found")); installerEnabled = false; From c13b8266ddbbc0d5a077a34dae0caec2e84bb964 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Thu, 11 Apr 2024 17:05:10 +0100 Subject: [PATCH 2/9] Prevent subflow being added to itself --- .../@node-red/editor-client/src/js/ui/view.js | 225 +++++++++--------- 1 file changed, 119 insertions(+), 106 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index a71daaea1..a2571dc28 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -646,120 +646,128 @@ RED.view = (function() { } d3.event = event; 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 { - var isLink = (nn.type === "link in" || nn.type === "link out") - var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink; - - 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); + var result = createNode(selected_tool); + if (!result) { + return; } - } catch(err) { - } + var historyEvent = result.historyEvent; + var nn = RED.nodes.add(result.node); - mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]); - mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]); - mousePos[1] /= scaleFactor; - mousePos[0] /= scaleFactor; + 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; + } - nn.x = mousePos[0]; - nn.y = mousePos[1]; + 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); - 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; - } + try { + var isLink = (nn.type === "link in" || nn.type === "link out") + var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink; - if (snapGrid) { - var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn); - nn.x -= gridOffset.x; - nn.y -= gridOffset.y; - } + 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 linkToSplice = $(ui.helper).data("splice"); - if (linkToSplice) { - spliceLink(linkToSplice, nn, historyEvent) - } + mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]); + mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]); + 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], - }; - if (moveEvent) { - historyEvent.events.push(moveEvent) + 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); + } + } 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); } } }); @@ -6063,14 +6071,19 @@ RED.view = (function() { function createNode(type, x, y, z) { const wasDirty = RED.nodes.dirty() 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) { var subflowId = m[1]; + let err 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)) { - throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddCircularReference") })) + if (err) { + err.code = 'NODE_RED' + throw err } } From e39216e65a32f7186d4f65ba4d2c2b9b097fde0d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Thu, 11 Apr 2024 19:15:46 +0100 Subject: [PATCH 3/9] Bump for 3.1.9 release --- CHANGELOG.md | 7 +++++++ package.json | 4 ++-- .../node_modules/@node-red/editor-api/package.json | 6 +++--- .../node_modules/@node-red/editor-client/package.json | 2 +- packages/node_modules/@node-red/nodes/package.json | 2 +- packages/node_modules/@node-red/registry/package.json | 6 +++--- packages/node_modules/@node-red/runtime/package.json | 6 +++--- packages/node_modules/@node-red/util/package.json | 2 +- packages/node_modules/node-red/package.json | 10 +++++----- 9 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc45650d2..59e951261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +#### 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 diff --git a/package.json b/package.json index 80478388e..26482b620 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "3.1.8", + "version": "3.1.9", "description": "Low-code programming for event-driven applications", "homepage": "https://nodered.org", "license": "Apache-2.0", @@ -74,7 +74,7 @@ "passport-oauth2-client-password": "0.1.2", "raw-body": "2.5.2", "semver": "7.5.4", - "tar": "6.1.13", + "tar": "6.2.1", "tough-cookie": "4.1.3", "uglify-js": "3.17.4", "uuid": "9.0.0", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index 5c9b70f2b..61c36c924 100644 --- a/packages/node_modules/@node-red/editor-api/package.json +++ b/packages/node_modules/@node-red/editor-api/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-api", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "3.1.8", - "@node-red/editor-client": "3.1.8", + "@node-red/util": "3.1.9", + "@node-red/editor-client": "3.1.9", "bcryptjs": "2.4.3", "body-parser": "1.20.2", "clone": "2.1.2", diff --git a/packages/node_modules/@node-red/editor-client/package.json b/packages/node_modules/@node-red/editor-client/package.json index da7d416f1..dbdb68e0d 100644 --- a/packages/node_modules/@node-red/editor-client/package.json +++ b/packages/node_modules/@node-red/editor-client/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-client", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json index 3f6031f71..190f5cb73 100644 --- a/packages/node_modules/@node-red/nodes/package.json +++ b/packages/node_modules/@node-red/nodes/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/nodes", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json index 0e25aa515..a85bc5d1a 100644 --- a/packages/node_modules/@node-red/registry/package.json +++ b/packages/node_modules/@node-red/registry/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/registry", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,11 +16,11 @@ } ], "dependencies": { - "@node-red/util": "3.1.8", + "@node-red/util": "3.1.9", "clone": "2.1.2", "fs-extra": "11.1.1", "semver": "7.5.4", - "tar": "6.1.13", + "tar": "6.2.1", "uglify-js": "3.17.4" } } diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json index 2b650f5d3..ca38553dd 100644 --- a/packages/node_modules/@node-red/runtime/package.json +++ b/packages/node_modules/@node-red/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/runtime", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/registry": "3.1.8", - "@node-red/util": "3.1.8", + "@node-red/registry": "3.1.9", + "@node-red/util": "3.1.9", "async-mutex": "0.4.0", "clone": "2.1.2", "express": "4.19.2", diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json index 828564bea..04316d5cc 100644 --- a/packages/node_modules/@node-red/util/package.json +++ b/packages/node_modules/@node-red/util/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/util", - "version": "3.1.8", + "version": "3.1.9", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/node-red/package.json b/packages/node_modules/node-red/package.json index b4ad0ff83..1d722b32a 100644 --- a/packages/node_modules/node-red/package.json +++ b/packages/node_modules/node-red/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "3.1.8", + "version": "3.1.9", "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": "3.1.8", - "@node-red/runtime": "3.1.8", - "@node-red/util": "3.1.8", - "@node-red/nodes": "3.1.8", + "@node-red/editor-api": "3.1.9", + "@node-red/runtime": "3.1.9", + "@node-red/util": "3.1.9", + "@node-red/nodes": "3.1.9", "basic-auth": "2.0.1", "bcryptjs": "2.4.3", "express": "4.19.2", From e354d2ce2994846f30fafb3579aa144d3b843ec2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 12 Apr 2024 14:08:07 +0100 Subject: [PATCH 4/9] Fix saving of conf-type properties in module packaged subflows --- .../node_modules/@node-red/editor-client/src/js/ui/subflow.js | 2 +- packages/node_modules/@node-red/registry/lib/subflow.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js index 60ae87aee..68e949f68 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js @@ -1363,7 +1363,7 @@ RED.subflow = (function() { break; case "conf-types": item.value = input.val() - item.type = data.parent.value; + item.type = "conf-type" } if (ui.type === "cred" || item.type !== data.parent.type || item.value !== data.parent.value) { env.push(item); diff --git a/packages/node_modules/@node-red/registry/lib/subflow.js b/packages/node_modules/@node-red/registry/lib/subflow.js index 97516691e..39fe083ab 100644 --- a/packages/node_modules/@node-red/registry/lib/subflow.js +++ b/packages/node_modules/@node-red/registry/lib/subflow.js @@ -88,7 +88,7 @@ function generateSubflowConfig(subflow) { this.credentials['has_' + prop.name] = (this.credentials[prop.name] !== ""); } else { switch(prop.type) { - case "str": this[prop.name] = prop.value||""; break; + case "str": case "conf-type": this[prop.name] = prop.value||""; break; case "bool": this[prop.name] = (typeof prop.value === 'boolean')?prop.value:prop.value === "true" ; break; case "num": this[prop.name] = (typeof prop.value === 'number')?prop.value:Number(prop.value); break; default: From 1fdc600ecd0c06e8c2f205e3b9bd2b963f887c15 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Thu, 18 Apr 2024 11:27:32 +0100 Subject: [PATCH 5/9] Add npm install timeout notification part of https://github.com/node-red/node-red/issues/4622 --- .../editor-client/locales/en-US/editor.json | 3 ++- .../editor-client/src/js/ui/palette-editor.js | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index 34ed30cef..05bb7fc66 100644 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -668,7 +668,8 @@ "remove": "Remove", "update": "Update" } - } + }, + "timeout": "

Install continuing the background, Nodes will appear in palette when complete.

Or you can monitor the install logs

" } }, "sidebar": { diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js index 8d3815749..a1df37185 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js @@ -133,7 +133,7 @@ RED.palette.editor = (function() { }).done(function(data,textStatus,xhr) { callback(); }).fail(function(xhr,textStatus,err) { - callback(xhr); + callback(xhr,textStatus,err); }); } function removeNodeModule(id,callback) { @@ -143,7 +143,7 @@ RED.palette.editor = (function() { }).done(function(data,textStatus,xhr) { callback(); }).fail(function(xhr,textStatus,err) { - callback(xhr); + callback(xhr, textStatus, err); }) } @@ -1270,9 +1270,28 @@ RED.palette.editor = (function() { RED.actions.invoke("core:show-event-log"); }); RED.eventLog.startEvent(RED._("palette.editor.confirm.button.install")+" : "+entry.id+" "+entry.version); - installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr) { + installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr, textStatus,err) { spinner.remove(); - if (xhr) { + if (err && xhr.status === 504) { + var notification = RED.notify(RED._("palette.editor.timeout"), { + modal: true, + fixed: true, + buttons: [ + { + text: RED._("common.label.close"), + click: function() { + notification.close(); + } + },{ + text: RED._("eventLog.view"), + click: function() { + notification.close(); + RED.actions.invoke("core:show-event-log"); + } + } + ] + }) + } else if (xhr) { if (xhr.responseJSON) { var notification = RED.notify(RED._('palette.editor.errors.installFailed',{module: entry.id,message:xhr.responseJSON.message}),{ type: 'error', From c990ec39d603059b0249d24a17b9e4c48fd6ea92 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Thu, 18 Apr 2024 11:35:51 +0100 Subject: [PATCH 6/9] revert DELETE change --- .../@node-red/editor-client/src/js/ui/palette-editor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js index a1df37185..05e6522b0 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js @@ -143,7 +143,7 @@ RED.palette.editor = (function() { }).done(function(data,textStatus,xhr) { callback(); }).fail(function(xhr,textStatus,err) { - callback(xhr, textStatus, err); + callback(xhr); }) } From 5f4ece68130c41a455a9af2144b6c06e081b30d2 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Thu, 18 Apr 2024 11:47:49 +0100 Subject: [PATCH 7/9] Move translation --- .../@node-red/editor-client/locales/en-US/editor.json | 4 ++-- .../@node-red/editor-client/src/js/ui/palette-editor.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index 05bb7fc66..1578fb923 100644 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -641,6 +641,7 @@ "errors": { "catalogLoadFailed": "

Failed to load node catalogue.

Check the browser console for more information

", "installFailed": "

Failed to install: __module__

__message__

Check the log for more information

", + "installTimeout": "

Install continuing the background, Nodes will appear in palette when complete.

Or you can monitor the install logs

", "removeFailed": "

Failed to remove: __module__

__message__

Check the log for more information

", "updateFailed": "

Failed to update: __module__

__message__

Check the log for more information

", "enableFailed": "

Failed to enable: __module__

__message__

Check the log for more information

", @@ -668,8 +669,7 @@ "remove": "Remove", "update": "Update" } - }, - "timeout": "

Install continuing the background, Nodes will appear in palette when complete.

Or you can monitor the install logs

" + } } }, "sidebar": { diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js index 05e6522b0..e2830b755 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js @@ -1273,7 +1273,7 @@ RED.palette.editor = (function() { installNodeModule(entry.id,entry.version,entry.pkg_url,function(xhr, textStatus,err) { spinner.remove(); if (err && xhr.status === 504) { - var notification = RED.notify(RED._("palette.editor.timeout"), { + var notification = RED.notify(RED._("palette.editor.errors.installTimeout"), { modal: true, fixed: true, buttons: [ From 148e64c3daa39f064d83e74a0a212101c0350e6f Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Thu, 18 Apr 2024 14:22:50 +0100 Subject: [PATCH 8/9] Update packages/node_modules/@node-red/editor-client/locales/en-US/editor.json Co-authored-by: Nick O'Leary --- .../@node-red/editor-client/locales/en-US/editor.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index faf8b2f72..94abf9b0a 100644 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -643,7 +643,7 @@ "errors": { "catalogLoadFailed": "

Failed to load node catalogue.

Check the browser console for more information

", "installFailed": "

Failed to install: __module__

__message__

Check the log for more information

", - "installTimeout": "

Install continuing the background, Nodes will appear in palette when complete.

Or you can monitor the install logs

", + "installTimeout": "

Install continuing the background.

Nodes will appear in palette when complete. Check the log for more information.

", "removeFailed": "

Failed to remove: __module__

__message__

Check the log for more information

", "updateFailed": "

Failed to update: __module__

__message__

Check the log for more information

", "enableFailed": "

Failed to enable: __module__

__message__

Check the log for more information

", From 236e6682014c60201261c976dc0c6628d93414a5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 24 Apr 2024 22:58:11 +0200 Subject: [PATCH 9/9] Allow blank strings to be used for env var property substitutions Fixes #4663 --- packages/node_modules/@node-red/runtime/lib/flows/util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/flows/util.js b/packages/node_modules/@node-red/runtime/lib/flows/util.js index e753075b5..6ec1ef982 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/util.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/util.js @@ -68,7 +68,7 @@ function mapEnvVarProperties(obj,prop,flow,config) { if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) { const envVar = v.substring(2,v.length-1); const r = redUtil.getSetting(config, envVar, flow); - if (r !== undefined && r !== '') { + if (r !== undefined) { obj[prop] = r } }