From ad788fbed1cb942ea0d93f586adfefe9e860a543 Mon Sep 17 00:00:00 2001 From: Kristian Heljas Date: Thu, 8 Apr 2021 21:09:44 +0300 Subject: [PATCH 01/77] Function node: describe `node.outputCount` in help text --- .../@node-red/nodes/locales/en-US/function/10-function.html | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html index 891801bf9..02e85922e 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html @@ -56,6 +56,7 @@

Using environment variables

Environment variables can be accessed using env.get("MY_ENV_VAR").

From 6087002562dc4ebdae08fa779808282ba63b1085 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sat, 10 Apr 2021 21:34:26 +0100 Subject: [PATCH 02/77] Fix handling of user-provided keymap Fixes #2926 --- .../node_modules/@node-red/editor-client/src/js/ui/keyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js b/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js index 2c81cfe63..9e976e4fc 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js @@ -119,7 +119,7 @@ RED.keyboard = (function() { } else { mergedKeymap[action] = [{ scope: themeKeymap[action].scope || "*", - key: [themeKeymap[action].key], + key: themeKeymap[action].key, user: false }] if (mergedKeymap[action][0].scope === "workspace") { From 858b3d640adad3390ca49777197b8e3380b1fb8d Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Sat, 10 Apr 2021 22:17:31 +0100 Subject: [PATCH 03/77] fix CSV parsing with other than , separator (and joining as well... and add tests to close #2925 --- .../@node-red/nodes/core/parsers/70-CSV.js | 11 +++--- test/nodes/core/parsers/70-CSV_spec.js | 36 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js index c5be65020..95a4eb2b2 100644 --- a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js +++ b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js @@ -38,10 +38,11 @@ module.exports = function(RED) { if (this.hdrout === true) { this.hdrout = "all"; } var tmpwarn = true; var node = this; - var re = new RegExp(',(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); + var re = new RegExp(node.sep+'(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); - // pass in an array of column names to be trimed, de-quoted and retrimed - var clean = function(col) { + // pass in an array of column names to be trimmed, de-quoted and retrimmed + var clean = function(col,sep) { + if (sep) { re = new RegExp(sep+'(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); } col = col.trim().split(re) || [""]; col = col.map(x => x.replace(/"/g,'').trim()); if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; } @@ -67,7 +68,7 @@ module.exports = function(RED) { if (node.hdrout !== "none" && node.hdrSent === false) { if ((template.length === 1) && (template[0] === '')) { if (msg.hasOwnProperty("columns")) { - template = clean(msg.columns || ""); + template = clean(msg.columns || "",","); } else { template = Object.keys(msg.payload[0]); @@ -93,7 +94,7 @@ module.exports = function(RED) { } else { if ((template.length === 1) && (template[0] === '') && (msg.hasOwnProperty("columns"))) { - template = clean(msg.columns || ""); + template = clean(msg.columns || "",","); } if ((template.length === 1) && (template[0] === '')) { /* istanbul ignore else */ diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js index fa73380ae..cccf7bf1c 100644 --- a/test/nodes/core/parsers/70-CSV_spec.js +++ b/test/nodes/core/parsers/70-CSV_spec.js @@ -170,6 +170,24 @@ describe('CSV node', function() { n1.emit("input", {payload:testString}); }); }); + + it('should allow passing in a template as first line of CSV (not comma)', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:";", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, "b b":2, "c;c":3, "d, d": 4 }); + msg.should.have.property('columns', 'a,b b,c;c,"d, d"'); + check_parts(msg, 0, 1); + done(); + }); + var testString = 'a;b b;"c;c";" d, d "'+"\n"+"1;2;3;4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + it('should leave numbers starting with 0, e and + as strings (except 0.)', function(done) { var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, {id:"n2", type:"helper"} ]; @@ -609,6 +627,24 @@ describe('CSV node', function() { }); }); + it('should convert a simple object back to a tsv using a tab as a separator', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", sep:"\t", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + try { + msg.should.have.property('payload', '1\tfoo\t"ba""r"\tdi,ng\n'); + done(); + } + catch(e) { done(e); } + }); + var testJson = { d:1, b:"foo", c:"ba\"r", a:"di,ng" }; + n1.emit("input", {payload:testJson}); + }); + }); + it('should handle a template with spaces in the property names', function(done) { var flow = [ { id:"n1", type:"csv", temp:"a,b o,c p,,e", wires:[["n2"]] }, {id:"n2", type:"helper"} ]; From 4672d98e8a13d8ff2f695c8cc76ec2092fff4a9a Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Mon, 12 Apr 2021 09:47:18 +0100 Subject: [PATCH 04/77] split node - add comment to info re $N being number of messages arriving --- .../@node-red/nodes/locales/en-US/sequence/17-split.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html b/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html index b0059992f..3334ec126 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/sequence/17-split.html @@ -91,7 +91,7 @@
complete
-
If set, the node will append the payload, and then send the output message in its current state. +
If set, the node will append the payload, and then send the output message in its current state. If you don't wish to append the payload, delete it from the msg.

Details

@@ -150,6 +150,7 @@

By default, the reduce expression is applied in order, from the first to the last message of the sequence. It can optionally be applied in reverse order.

+

$N is the number of messages that arrive - even if they are identical.

Example: the following settings, given a sequence of numeric values, calculates the average value: From 13406e76de045117afad9beae1d203b953b44f3d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 12 Apr 2021 10:05:44 +0100 Subject: [PATCH 05/77] Ensure theme login image is passed through to api response Fixes #2929 --- .../node_modules/@node-red/editor-api/lib/auth/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/auth/index.js b/packages/node_modules/@node-red/editor-api/lib/auth/index.js index d4ec10f08..fb95ede7b 100644 --- a/packages/node_modules/@node-red/editor-api/lib/auth/index.js +++ b/packages/node_modules/@node-red/editor-api/lib/auth/index.js @@ -90,7 +90,7 @@ function getToken(req,res,next) { return server.token()(req,res,next); } -function login(req,res) { +async function login(req,res) { var response = {}; if (settings.adminAuth) { var mergedAdminAuth = Object.assign({}, settings.adminAuth, settings.adminAuth.module); @@ -116,8 +116,9 @@ function login(req,res) { response.prompts[0].image = theme.serveFile('/login/',mergedAdminAuth.strategy.image); } } - if (theme.context().login && theme.context().login.image) { - response.image = theme.context().login.image; + let themeContext = await theme.context(); + if (themeContext.login && themeContext.login.image) { + response.image = themeContext.login.image; } } res.json(response); From 51aaf1b1503c50d111bc8d3080a888c834ce49f2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 12 Apr 2021 10:34:43 +0100 Subject: [PATCH 06/77] Handle package.json without dependencies section --- packages/node_modules/@node-red/registry/lib/localfilesystem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/registry/lib/localfilesystem.js b/packages/node_modules/@node-red/registry/lib/localfilesystem.js index 9e08c4c53..62080b4a8 100644 --- a/packages/node_modules/@node-red/registry/lib/localfilesystem.js +++ b/packages/node_modules/@node-red/registry/lib/localfilesystem.js @@ -472,7 +472,7 @@ function getPackageList() { try { var userPackage = path.join(settings.userDir,"package.json"); var pkg = JSON.parse(fs.readFileSync(userPackage,"utf-8")); - return pkg.dependencies; + return pkg.dependencies || {}; } catch(err) { log.error(err); } From 5028377d45a7cb6f7e3998782eef905e499eefcf Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 12 Apr 2021 11:48:10 +0100 Subject: [PATCH 07/77] Fix MQTT Broker TLS config row layout Fixes #2927 --- .../node_modules/@node-red/nodes/core/network/10-mqtt.html | 4 ++-- .../node_modules/@node-red/nodes/locales/de/messages.json | 2 +- .../node_modules/@node-red/nodes/locales/ko/messages.json | 2 +- .../node_modules/@node-red/nodes/locales/ru/messages.json | 2 +- .../node_modules/@node-red/nodes/locales/zh-CN/messages.json | 2 +- .../node_modules/@node-red/nodes/locales/zh-TW/messages.json | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html index ee5e973b0..7b96aaf2f 100644 --- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html +++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.html @@ -186,8 +186,8 @@

- - + +
diff --git a/packages/node_modules/@node-red/nodes/locales/de/messages.json b/packages/node_modules/@node-red/nodes/locales/de/messages.json index aabab9f79..38fe83ce6 100755 --- a/packages/node_modules/@node-red/nodes/locales/de/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/de/messages.json @@ -363,7 +363,7 @@ "keepalive": "Keep-Alive", "cleansession": "Bereinigte Sitzung (clean session) verwenden", "cleanstart": "Verwende bereinigten Start", - "use-tls": "Sichere Verbindung (SSL/TLS) verwenden", + "use-tls": "TLS", "tls-config": "TLS-Konfiguration", "verify-server-cert": "Server-Zertifikat überprüfen", "compatmode": "MQTT 3.1 unterstützen", diff --git a/packages/node_modules/@node-red/nodes/locales/ko/messages.json b/packages/node_modules/@node-red/nodes/locales/ko/messages.json index 8e3a4f325..74a7885d2 100755 --- a/packages/node_modules/@node-red/nodes/locales/ko/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ko/messages.json @@ -333,7 +333,7 @@ "port": "포트", "keepalive": "킵 얼라이브 시간", "cleansession": "세션 초기화", - "use-tls": "SSL/TLS접속을 사용", + "use-tls": "사용TLS", "tls-config": "TLS설정", "verify-server-cert": "서버인증서를 확인", "compatmode": "구 MQTT 3.1서포트" diff --git a/packages/node_modules/@node-red/nodes/locales/ru/messages.json b/packages/node_modules/@node-red/nodes/locales/ru/messages.json index 08e2b6b73..f32160bf1 100755 --- a/packages/node_modules/@node-red/nodes/locales/ru/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ru/messages.json @@ -352,7 +352,7 @@ "port": "Порт", "keepalive": "Keep-alive время (сек)", "cleansession": "Использовать чистую сессию", - "use-tls": "Включить безопасное (SSL/TLS) соединение", + "use-tls": "TLS", "tls-config":"Конфигурация TLS", "verify-server-cert":"Проверить сертификат сервера", "compatmode": "Использовать устаревшую поддержку MQTT 3.1" diff --git a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json index ee074c0fe..e2afa0fc1 100644 --- a/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/zh-CN/messages.json @@ -353,7 +353,7 @@ "port": "端口", "keepalive": "Keepalive计时(秒)", "cleansession": "使用新的会话", - "use-tls": "使用安全连接 (SSL/TLS)", + "use-tls": "使用 TLS", "tls-config": "TLS 设置", "verify-server-cert": "验证服务器证书", "compatmode": "使用旧式MQTT 3.1支持" diff --git a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json index de48fe9f9..1335e9ff2 100644 --- a/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/zh-TW/messages.json @@ -353,7 +353,7 @@ "port": "埠", "keepalive": "Keepalive計時(秒)", "cleansession": "使用新的會話", - "use-tls": "使用安全連接 (SSL/TLS)", + "use-tls": "使用 TLS", "tls-config": "TLS 設置", "verify-server-cert": "驗證伺服器憑證", "compatmode": "使用舊式MQTT 3.1支援" From e44131f97a828943aa0da670924ba8bdac10a1ba Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 12 Apr 2021 12:08:07 +0100 Subject: [PATCH 08/77] Update function node help reference to node properties --- .../@node-red/nodes/locales/en-US/function/10-function.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html index 02e85922e..dd13b6732 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html @@ -52,7 +52,7 @@ pass msg as a second argument to node.error:

node.error("Error",msg);

Accessing Node Information

-

In the function block, id and name of the node can be referenced using the following properties:

+

The following properties are available to access information about the node:

  • node.id - id of the node
  • node.name - name of the node
  • From 023486e175f76aa5996c04c0fcb9d25a63f23f8f Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Mon, 12 Apr 2021 12:16:23 +0100 Subject: [PATCH 09/77] File out node - fix timing of msg.send to be after close., and... allow msg.encoding to set encoding if desired. To close #2921 --- .../@node-red/nodes/core/storage/10-file.html | 4 ++ .../@node-red/nodes/core/storage/10-file.js | 52 ++++++++++++------- .../nodes/locales/en-US/messages.json | 1 + .../nodes/locales/en-US/storage/10-file.html | 2 + 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/storage/10-file.html b/packages/node_modules/@node-red/nodes/core/storage/10-file.html index 5487920b8..a7349715f 100755 --- a/packages/node_modules/@node-red/nodes/core/storage/10-file.html +++ b/packages/node_modules/@node-red/nodes/core/storage/10-file.html @@ -219,6 +219,10 @@ value: "none", label: label }).text(label).appendTo(encSel); + $("", { diff --git a/packages/node_modules/@node-red/nodes/core/storage/10-file.js b/packages/node_modules/@node-red/nodes/core/storage/10-file.js index 54ce55764..f2065c87a 100644 --- a/packages/node_modules/@node-red/nodes/core/storage/10-file.js +++ b/packages/node_modules/@node-red/nodes/core/storage/10-file.js @@ -61,11 +61,13 @@ module.exports = function(RED) { if (filename === "") { node.warn(RED._("file.errors.nofilename")); done(); - } else if (node.overwriteFile === "delete") { + } + else if (node.overwriteFile === "delete") { fs.unlink(filename, function (err) { if (err) { node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg); - } else { + } + else { if (RED.settings.verbose) { node.log(RED._("file.status.deletedfile",{file:filename})); } @@ -73,12 +75,14 @@ module.exports = function(RED) { } done(); }); - } else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) { + } + else if (msg.hasOwnProperty("payload") && (typeof msg.payload !== "undefined")) { var dir = path.dirname(filename); if (node.createDir) { try { fs.ensureDirSync(dir); - } catch(err) { + } + catch(err) { node.error(RED._("file.errors.createfail",{error:err.toString()}),msg); done(); return; @@ -92,7 +96,11 @@ module.exports = function(RED) { if (typeof data === "boolean") { data = data.toString(); } if (typeof data === "number") { data = data.toString(); } if ((node.appendNewline) && (!Buffer.isBuffer(data))) { data += os.EOL; } - var buf = encode(data, node.encoding); + var buf; + if (node.encoding === "setbymsg") { + buf = encode(data, msg.encoding || "none"); + } + else { buf = encode(data, node.encoding); } if (node.overwriteFile === "true") { var wstream = fs.createWriteStream(filename, { encoding:'binary', flags:'w', autoClose:true }); node.wstream = wstream; @@ -101,10 +109,11 @@ module.exports = function(RED) { done(); }); wstream.on("open", function() { - wstream.end(buf, function() { + wstream.once("close", function() { nodeSend(msg); done(); }); + wstream.end(buf); }) return; } @@ -126,7 +135,8 @@ module.exports = function(RED) { delete node.wstream; delete node.wstreamIno; } - } catch(err) { + } + catch(err) { // File does not exist recreateStream = true; node.wstream.end(); @@ -154,14 +164,16 @@ module.exports = function(RED) { nodeSend(msg); done(); }); - } else { + } + else { // Dynamic filename - write and close the stream - node.wstream.end(buf, function() { + node.wstream.once("close", function() { nodeSend(msg); delete node.wstream; delete node.wstreamIno; done(); }); + node.wstream.end(buf); } } } @@ -276,7 +288,6 @@ module.exports = function(RED) { ch = "\n"; type = "string"; } - var hwm; var getout = false; var rs = fs.createReadStream(filename) @@ -340,16 +351,17 @@ module.exports = function(RED) { nodeSend(msg); } else if (node.format === "lines") { - var m = { payload: spare, - topic:msg.topic, - parts: { - index: count, - count: count+1, - ch: ch, - type: type, - id: msg._msgid - } - }; + var m = { + payload: spare, + topic:msg.topic, + parts: { + index: count, + count: count+1, + ch: ch, + type: type, + id: msg._msgid + } + }; nodeSend(m); } else if (getout) { // last chunk same size as high water mark - have to send empty extra packet. diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index 17b230c69..5ca06426c 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -877,6 +877,7 @@ }, "encoding": { "none": "default", + "setbymsg": "set by msg.encoding", "native": "Native", "unicode": "Unicode", "japanese": "Japanese", diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html index fe2bbc324..70400f676 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/storage/10-file.html @@ -21,6 +21,8 @@
    filename string
    If not configured in the node, this optional property sets the name of the file to be updated.
    +
    encoding string
    +
    If encoding is configured to be set by msg, then this optional property can set the encoding.

    Output

    On completion of write, input message is sent to output port.

    From 39274b0c5dbd88650618639a3c03390bc7a4e31b Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Mon, 12 Apr 2021 22:15:07 +0900 Subject: [PATCH 10/77] Add Japanese translations for Node-RED v1.3.1 (#2930) --- .../@node-red/editor-client/locales/ja/editor.json | 4 ++-- .../node_modules/@node-red/nodes/core/function/10-function.js | 2 +- .../node_modules/@node-red/nodes/locales/en-US/messages.json | 1 + .../@node-red/nodes/locales/ja/function/10-function.html | 3 ++- .../node_modules/@node-red/nodes/locales/ja/messages.json | 2 ++ .../@node-red/nodes/locales/ja/storage/10-file.html | 2 ++ 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json index 6a7edb202..3870c9336 100644 --- a/packages/node_modules/@node-red/editor-client/locales/ja/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/ja/editor.json @@ -524,8 +524,8 @@ "title": "パレットの管理", "palette": "パレット", "times": { - "seconds": "秒前", - "minutes": "分前", + "seconds": "数秒前", + "minutes": "数分前", "minutesV": "__count__ 分前", "hoursV": "__count__ 時間前", "hoursV_plural": "__count__ 時間前", diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.js b/packages/node_modules/@node-red/nodes/core/function/10-function.js index 0e8b7f5ef..17e6e569a 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.js +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.js @@ -302,7 +302,7 @@ module.exports = function(RED) { } }); if (moduleErrors) { - throw new Error("Function node failed to load external modules"); + throw new Error(RED._("function.error.externalModuleLoadError")); } } diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json index 5ca06426c..f4766c634 100755 --- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json @@ -227,6 +227,7 @@ "error": { "externalModuleNotAllowed": "Function node not allowed to load external modules", "moduleNotAllowed": "Module __module__ not allowed", + "externalModuleLoadError": "Function node failed to load external modules", "moduleLoadError": "Failed to load module __module__: __error__", "moduleNameError": "Invalid module variable name: __name__", "moduleNameReserved": "Reserved variable name: __name__", diff --git a/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html index de6f44e3d..1ee1aa2b0 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/ja/function/10-function.html @@ -44,10 +44,11 @@

    catchノードを用いてエラー処理が可能です。catchノードで処理させるためには、msgnode.errorの第二引数として渡します:

    node.error("エラー",msg);

    ノード情報の参照

    -

    コード中ではノードのIDおよび名前を以下のプロパティで参照できます:

    +

    ノードに関する情報を参照するための以下のプロパティを利用できます:

    • node.id - ノードのID
    • node.name - ノードの名称
    • +
    • node.outputCount - ノードの出力数

    環境変数の利用

    環境変数はenv.get("MY_ENV_VAR")により参照できます。

    diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json index f8412efff..bab9fd724 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json +++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json @@ -227,6 +227,7 @@ "error": { "externalModuleNotAllowed": "Functionノードは、外部モジュールを読み込みできません", "moduleNotAllowed": "モジュール __module__ は利用できません", + "externalModuleLoadError": "Functionノードは、外部モジュールの読み込みに失敗しました", "moduleLoadError": "モジュール __module__ の読み込みに失敗しました: __error__", "moduleNameError": "モジュール変数名が不正です: __name__", "moduleNameReserved": "予約された変数名です: __name__", @@ -875,6 +876,7 @@ }, "encoding": { "none": "デフォルト", + "setbymsg": "msg.encodingで設定", "native": "ネイティブ", "unicode": "UNICODE", "japanese": "日本", diff --git a/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html b/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html index 21d4af9be..3e67368d3 100644 --- a/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html +++ b/packages/node_modules/@node-red/nodes/locales/ja/storage/10-file.html @@ -20,6 +20,8 @@
    filename 文字列
    対象ファイル名をノードに設定していない場合、このプロパティでファイルを指定できます
    +
    encoding 文字列
    +
    エンコーディングをmsgで設定する構成にした際は、この任意のプロパティでエンコーディングを設定できます。

    出力

    書き込みの完了時、入力メッセージを出力端子に送出します。

    From 6a8cf1b7686ca7fd62aa00e05eba089225359d31 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 13 Apr 2021 13:24:54 +0100 Subject: [PATCH 11/77] Fix variable reference error in editableList Fixes #2933 --- .../editor-client/src/js/ui/common/editableList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js index 7f823289e..00666e5b4 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js @@ -71,7 +71,7 @@ var buttons = this.options.buttons || []; if (this.options.addButton !== false) { - var addLabel, addTittle; + var addLabel, addTitle; if (typeof this.options.addButton === 'string') { addLabel = this.options.addButton } else { @@ -102,7 +102,7 @@ button.click(evt); } }); - + if (button.title) { element.attr("title", button.title); } @@ -113,7 +113,7 @@ element.append($("").text(" " + button.label)); } }); - + if (this.element.css("position") === "absolute") { ["top","left","bottom","right"].forEach(function(s) { var v = that.element.css(s); From a4a624d53776a9032d367d377b85ab4626b507e5 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 13 Apr 2021 13:33:41 +0100 Subject: [PATCH 12/77] Update changelog --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cb1464cc..40724e589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +### 1.3.2: Maintenance Release + + +Runtime + - Handle package.json without dependencies section + +Editor + + - Fix variable reference error in editableList Fixes #2933 + - Fix handling of user-provided keymap Fixes #2926 + - Ensure theme login image is passed through to api response Fixes #2929 + - Add Japanese translations for Node-RED v1.3.1 (#2930) @kazuhitoyokoi + +Nodes + + - CSV: Fix CSV parsing with other than , separator + - File out: Fix timing of msg.send to be after close + - Function: describe `node.outputCount` in help text + - MQTT: Fix MQTT Broker TLS config row layout Fixes #2927 + - Split: add comment to info re $N being number of messages arriving ### 1.3.1: Maintenance Release From b0955705be599ff091d6fe0bae841985d10c04ac Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 13 Apr 2021 13:34:16 +0100 Subject: [PATCH 13/77] Update to 1.3.2 --- package.json | 2 +- .../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 | 4 ++-- 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 +++++----- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 1c5861755..c836a35d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "1.3.1", + "version": "1.3.2", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index 34fb833d4..c1c0bf905 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": "1.3.1", + "version": "1.3.2", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "1.3.1", - "@node-red/editor-client": "1.3.1", + "@node-red/util": "1.3.2", + "@node-red/editor-client": "1.3.2", "bcryptjs": "2.4.3", "body-parser": "1.19.0", "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 9da45ea59..ff0722c0e 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": "1.3.1", + "version": "1.3.2", "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 84465ba5e..77143545d 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": "1.3.1", + "version": "1.3.2", "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 513385e7a..ac1c66709 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": "1.3.1", + "version": "1.3.2", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,7 +16,7 @@ } ], "dependencies": { - "@node-red/util": "1.3.1", + "@node-red/util": "1.3.2", "semver": "6.3.0", "tar": "6.1.0", "uglify-js": "3.13.3" diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json index a9e7bc0ac..0f434840e 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": "1.3.1", + "version": "1.3.2", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/registry": "1.3.1", - "@node-red/util": "1.3.1", + "@node-red/registry": "1.3.2", + "@node-red/util": "1.3.2", "async-mutex": "0.3.1", "clone": "2.1.2", "express": "4.17.1", diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json index 1c04d1e4e..6bee2d78c 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": "1.3.1", + "version": "1.3.2", "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 fd9462798..2df31c0c6 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": "1.3.1", + "version": "1.3.2", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -31,10 +31,10 @@ "flow" ], "dependencies": { - "@node-red/editor-api": "1.3.1", - "@node-red/runtime": "1.3.1", - "@node-red/util": "1.3.1", - "@node-red/nodes": "1.3.1", + "@node-red/editor-api": "1.3.2", + "@node-red/runtime": "1.3.2", + "@node-red/util": "1.3.2", + "@node-red/nodes": "1.3.2", "basic-auth": "2.0.1", "bcryptjs": "2.4.3", "express": "4.17.1", From b5fda5642f037f3402bcc4f7ed8e54b5eb377523 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 14 Apr 2021 18:06:59 +0100 Subject: [PATCH 14/77] Fix package semver comparison to allow >1 version increment --- .../@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 2fe3d448e..e57a19349 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 @@ -331,7 +331,7 @@ RED.palette.editor = (function() { nodeEntry.versionSpan.html(moduleInfo.version+' '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow) nodeEntry.updateButton.text(RED._('palette.editor.updated')).addClass('disabled').css('display', 'inline-block'); } else if (loadedIndex.hasOwnProperty(module)) { - if (semVerCompare(loadedIndex[module].version,moduleInfo.version) === 1) { + if (semVerCompare(loadedIndex[module].version,moduleInfo.version) > 0) { nodeEntry.updateButton.show(); nodeEntry.updateButton.text(RED._('palette.editor.update',{version:loadedIndex[module].version})); } else { From 04a3c4bb222f1708877ddd98379be801bfc6fc72 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 14 Apr 2021 22:28:25 +0100 Subject: [PATCH 15/77] Ensure mqtt-close message is published when closing mqtt nodes The change in 1.3 where we ensure config nodes are closed last broke this behaviour. Previously, the config node would get closed triggering the close message. With the new 1.3 behaviour, the flow nodes are stopped and as soon as the last flow node deregisters itself, the broker node would disconnect without sending the close message. The fix is to send the close message as part of the deregister flow as that will handle all cases properly --- .../@node-red/nodes/core/network/10-mqtt.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js index db4d300fe..fe4ce1b3b 100644 --- a/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js +++ b/packages/node_modules/@node-red/nodes/core/network/10-mqtt.js @@ -400,7 +400,15 @@ module.exports = function(RED) { } if (Object.keys(node.users).length === 0) { if (node.client && node.client.connected) { - return node.client.end(done); + // Send close message + if (node.closeMessage) { + node.publish(node.closeMessage,function(err) { + node.client.end(done); + }); + } else { + node.client.end(done); + } + return; } else { node.client.end(); return done(); @@ -639,10 +647,6 @@ module.exports = function(RED) { this.on('close', function(done) { this.closing = true; if (this.connected) { - // Send close message - if (node.closeMessage) { - node.publish(node.closeMessage); - } this.client.once('close', function() { done(); }); @@ -873,4 +877,4 @@ module.exports = function(RED) { } } RED.nodes.registerType("mqtt out",MQTTOutNode); -}; \ No newline at end of file +}; From 0167c25e088a5f8b0c0a1aa61a3861d446531468 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Fri, 16 Apr 2021 11:56:23 +0100 Subject: [PATCH 16/77] Export package version in Grunt file so docs template can access --- Gruntfile.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 23481f793..f19432a18 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -40,8 +40,11 @@ module.exports = function(grunt) { if (nonHeadless) { process.env.NODE_RED_NON_HEADLESS = true; } + let packageFile = grunt.file.readJSON('package.json') + process.env.NODE_RED_PACKAGE_VERSION = packageFile.version; + grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), + pkg: packageFile, paths: { dist: ".dist" }, @@ -467,7 +470,8 @@ module.exports = function(grunt) { ], options: { destination: 'docs', - configure: './jsdoc.json' + configure: './jsdoc.json', + fred: "hi there" } }, _editor: { From 235690064fe25bba1f5442b59c3cfc3993cb6dc3 Mon Sep 17 00:00:00 2001 From: Ben Hardill Date: Fri, 16 Apr 2021 13:26:11 +0100 Subject: [PATCH 17/77] Fix for #2935 --- .../node_modules/@node-red/nodes/core/network/21-httpin.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httpin.js b/packages/node_modules/@node-red/nodes/core/network/21-httpin.js index 26234b737..b458a459c 100644 --- a/packages/node_modules/@node-red/nodes/core/network/21-httpin.js +++ b/packages/node_modules/@node-red/nodes/core/network/21-httpin.js @@ -46,7 +46,9 @@ module.exports = function(RED) { isText = true; } else if (parsedType.type !== "application") { isText = false; - } else if ((parsedType.subtype !== "octet-stream") && (parsedType.subtype !== "cbor")) { + } else if ((parsedType.subtype !== "octet-stream") + && (parsedType.subtype !== "cbor") + && (parsedType.subtype !== "x-protobuf")) { checkUTF = true; } else { // application/octet-stream or application/cbor From 0253dc9623fc18a8c6855ce7ac1fb1d31c79da19 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Mon, 19 Apr 2021 10:03:11 +0100 Subject: [PATCH 18/77] ensure CSV node can send false as string --- packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js index 95a4eb2b2..894968935 100644 --- a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js +++ b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js @@ -81,7 +81,7 @@ module.exports = function(RED) { if ((Array.isArray(msg.payload[s])) || (typeof msg.payload[s] !== "object")) { if (typeof msg.payload[s] !== "object") { msg.payload = [ msg.payload ]; } for (var t = 0; t < msg.payload[s].length; t++) { - if (!msg.payload[s][t] && (msg.payload[s][t] !== 0)) { msg.payload[s][t] = ""; } + if (msg.payload[s][t] === undefined) { msg.payload[s][t] = ""; } if (msg.payload[s][t].toString().indexOf(node.quo) !== -1) { // add double quotes if any quotes msg.payload[s][t] = msg.payload[s][t].toString().replace(/"/g, '""'); msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo; From 4a4e7fc7cb685dd1e013572267b91f9ea6ce7c2e Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 19 Apr 2021 10:39:58 +0100 Subject: [PATCH 19/77] Make typedInput.disable more consistent in behaviour Fixes #2942 --- .../editor-client/src/js/ui/common/typedInput.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 1b5af5f13..b5d82b830 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -1004,16 +1004,17 @@ this.uiSelect.hide(); }, disable: function(val) { - if(val === true) { + if(val === undefined || !!val === true) { this.uiSelect.attr("disabled", "disabled"); - } else if (val === false) { - this.uiSelect.attr("disabled", null); //remove attr } else { - this.uiSelect.attr("disabled", val); //user value + this.uiSelect.attr("disabled", null); //remove attr } }, + enable: function() { + this.uiSelect.attr("disabled", null); //remove attr + }, disabled: function() { - return this.uiSelect.attr("disabled"); + return this.uiSelect.attr("disabled") === "disabled"; } }); })(jQuery); From 3f43dc1855007aa2708d4ef413b7dfac526dec48 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 19 Apr 2021 10:43:01 +0100 Subject: [PATCH 20/77] Fix jshint error --- .../@node-red/editor-client/src/js/ui/common/typedInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index b5d82b830..7cbad2f05 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -1004,7 +1004,7 @@ this.uiSelect.hide(); }, disable: function(val) { - if(val === undefined || !!val === true) { + if(val === undefined || !!val ) { this.uiSelect.attr("disabled", "disabled"); } else { this.uiSelect.attr("disabled", null); //remove attr From ff00afb5d7ed1356d0752f75a33d6adfb392ca8c Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 19 Apr 2021 11:32:26 +0100 Subject: [PATCH 21/77] Fix project credential secret reset handling Part of #2868 --- .../editor-client/src/js/ui/projects/projectSettings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js index c39ac97be..336893a59 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js @@ -928,11 +928,11 @@ RED.projects.settings = (function() { saveDisabled = isFlowInvalid || credFileLabelText.text()===""; - if (credentialSecretExistingInput.is(":visible")) { + if (credentialSecretExistingRow.is(":visible")) { credentialSecretExistingInput.toggleClass("input-error", credentialSecretExistingInput.val() === ""); saveDisabled = saveDisabled || credentialSecretExistingInput.val() === ""; } - if (credentialSecretNewInput.is(":visible")) { + if (credentialSecretNewRow.is(":visible")) { credentialSecretNewInput.toggleClass("input-error", credentialSecretNewInput.val() === ""); saveDisabled = saveDisabled || credentialSecretNewInput.val() === ""; } @@ -1130,7 +1130,7 @@ RED.projects.settings = (function() { } if (credentialSecretResetButton.hasClass('selected') || credentialSecretEditButton.hasClass('selected')) { payload.credentialSecret = credentialSecretNewInput.val(); - if (credentialSecretExistingInput.is(":visible")) { + if (credentialSecretExistingRow.is(":visible")) { payload.currentCredentialSecret = credentialSecretExistingInput.val(); } } From 233a74c1460ef63b19a79df818ba4490c0719c6d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 19 Apr 2021 15:27:47 +0100 Subject: [PATCH 22/77] Remove TypedInput from tab focus when only one type available --- .../@node-red/editor-client/src/js/ui/common/typedInput.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 7cbad2f05..5da62c74a 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -669,6 +669,11 @@ that.typeMap[result.value] = result; return result; }); + if (this.typeList.length < 2) { + this.selectTrigger.attr("tabindex", -1) + } else { + this.selectTrigger.attr("tabindex", 0) + } this.selectTrigger.toggleClass("disabled", this.typeList.length === 1); this.selectTrigger.find(".fa-caret-down").toggle(this.typeList.length > 1) if (this.menu) { From 9eb668ab30c9f99db8c40727e8fdcaeb5c941739 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 19 Apr 2021 15:28:17 +0100 Subject: [PATCH 23/77] Prevent TypedInput label overflowing element Also adds title attribute to the button for the label so it gets a tooltip --- .../@node-red/editor-client/src/js/ui/common/typedInput.js | 5 +++++ .../editor-client/src/sass/ui/common/typedInput.scss | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 5da62c74a..764c6185c 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -773,6 +773,11 @@ if (opt.hasValue === false || (opt.showLabel !== false && !opt.icon)) { this.selectLabel.text(opt.label); } + if (opt.label) { + this.selectTrigger.attr("title",opt.label); + } else { + this.selectTrigger.attr("title",""); + } if (opt.hasValue === false) { this.selectTrigger.addClass("red-ui-typedInput-full-width"); } else { diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss index 14cb3f70e..2b12fffea 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss @@ -24,7 +24,7 @@ margin: 0; vertical-align: middle; box-sizing: border-box; - overflow:visible; + overflow: hidden; position: relative; &[disabled] { input, button { @@ -33,7 +33,7 @@ cursor: not-allowed; } } - + .red-ui-typedInput-input-wrap { flex-grow: 1; } From 0e06da6c63326b92cacc5926e054a94b3d3ef31e Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 20 Apr 2021 11:06:23 +0100 Subject: [PATCH 24/77] Update for 1.3.3 --- CHANGELOG.md | 22 ++++++++++++++++++- package.json | 2 +- .../@node-red/editor-api/package.json | 6 ++--- .../@node-red/editor-client/package.json | 2 +- .../node_modules/@node-red/nodes/package.json | 2 +- .../@node-red/registry/package.json | 4 ++-- .../@node-red/runtime/package.json | 6 ++--- .../node_modules/@node-red/util/package.json | 2 +- packages/node_modules/node-red/package.json | 10 ++++----- 9 files changed, 38 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40724e589..744ff06e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ -### 1.3.2: Maintenance Release +### 1.3.3: Maintenance Release +Editor + + - Fix package semver comparison to allow >1 version increment + - Prevent TypedInput label overflowing element Fixes #2941 + - Remove TypedInput from tab focus when only one type available + - Make typedInput.disable more consistent in behaviour Fixes #2942 + - Fix project credential secret reset handling Part of #2868 + +Runtime + + - Export package version in Grunt file so docs template can access + +Nodes + + - CSV: ensure CSV node can send false as string + - HTTPIn: handle application/x-protobuf as Buffer type (#2935 #2938) @hardillb + - MQTT: Ensure mqtt-close message is published when closing mqtt nodes + + +### 1.3.2: Maintenance Release Runtime - Handle package.json without dependencies section diff --git a/package.json b/package.json index c836a35d5..9c336d690 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "1.3.2", + "version": "1.3.3", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index c1c0bf905..25b217c58 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": "1.3.2", + "version": "1.3.3", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "1.3.2", - "@node-red/editor-client": "1.3.2", + "@node-red/util": "1.3.3", + "@node-red/editor-client": "1.3.3", "bcryptjs": "2.4.3", "body-parser": "1.19.0", "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 ff0722c0e..785f2ad2c 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": "1.3.2", + "version": "1.3.3", "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 77143545d..524f0d2e8 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": "1.3.2", + "version": "1.3.3", "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 ac1c66709..b0f943ab6 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": "1.3.2", + "version": "1.3.3", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,7 +16,7 @@ } ], "dependencies": { - "@node-red/util": "1.3.2", + "@node-red/util": "1.3.3", "semver": "6.3.0", "tar": "6.1.0", "uglify-js": "3.13.3" diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json index 0f434840e..5d7e44b2e 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": "1.3.2", + "version": "1.3.3", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/registry": "1.3.2", - "@node-red/util": "1.3.2", + "@node-red/registry": "1.3.3", + "@node-red/util": "1.3.3", "async-mutex": "0.3.1", "clone": "2.1.2", "express": "4.17.1", diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json index 6bee2d78c..64603d084 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": "1.3.2", + "version": "1.3.3", "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 2df31c0c6..c42a97fe6 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": "1.3.2", + "version": "1.3.3", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -31,10 +31,10 @@ "flow" ], "dependencies": { - "@node-red/editor-api": "1.3.2", - "@node-red/runtime": "1.3.2", - "@node-red/util": "1.3.2", - "@node-red/nodes": "1.3.2", + "@node-red/editor-api": "1.3.3", + "@node-red/runtime": "1.3.3", + "@node-red/util": "1.3.3", + "@node-red/nodes": "1.3.3", "basic-auth": "2.0.1", "bcryptjs": "2.4.3", "express": "4.17.1", From f8d5fef3c40cb3315f766fb8c78fb5a7ab38441e Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 20 Apr 2021 23:25:56 +0100 Subject: [PATCH 25/77] Ensure typedInput without value has focus class removed Closes #2945 --- .../@node-red/editor-client/src/js/ui/common/typedInput.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 764c6185c..63455fe17 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -389,6 +389,11 @@ evt.stopPropagation(); }).on('focus', function() { that.uiSelect.addClass('red-ui-typedInput-focus'); + }).on('blur', function() { + var opt = that.typeMap[that.propertyType]; + if (opt.hasValue === false) { + that.uiSelect.removeClass('red-ui-typedInput-focus'); + } }) // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline' From 23a5cb1917fa6f7fd80e8cae8d04c753c76eecbb Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 20 Apr 2021 23:39:21 +0100 Subject: [PATCH 26/77] Ensure typedInput option is selected in dropdown menu Part of #2945 --- .../@node-red/editor-client/src/js/ui/common/typedInput.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 63455fe17..2dbd6d71a 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -443,7 +443,11 @@ }); this._showMenu(this.optionMenu,this.optionSelectTrigger); - var selectedOption = this.optionMenu.find("[value='"+this.optionValue+"']"); + var targetValue = this.optionValue; + if (this.optionValue === null || this.optionValue === undefined) { + targetValue = this.value(); + } + var selectedOption = this.optionMenu.find("[value='"+targetValue+"']"); if (selectedOption.length === 0) { selectedOption = this.optionMenu.children(":first"); } From 372122037fa0ff514d05152c27d60d96110223f5 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Wed, 21 Apr 2021 13:14:46 +0900 Subject: [PATCH 27/77] Fix margin between nodes on palette --- .../node_modules/@node-red/editor-client/src/sass/palette.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/palette.scss b/packages/node_modules/@node-red/editor-client/src/sass/palette.scss index 385ad761f..2855ee494 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/palette.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/palette.scss @@ -134,7 +134,7 @@ &:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child { margin-top: 15px; } - &:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):first-child { + &:not(.red-ui-palette-node-config):not(.red-ui-palette-node-small):last-child { margin-bottom: 15px; } } From 4cebbf8d22617e17d3cbf55391c221041db3c85b Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 23 Apr 2021 10:47:23 +0100 Subject: [PATCH 28/77] Fix CSV handling of special chars as separators (ie escape regex special chars) and add tests to close #2950 --- .../@node-red/nodes/core/parsers/70-CSV.js | 8 ++--- test/nodes/core/parsers/70-CSV_spec.js | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js index 894968935..8ab296159 100644 --- a/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js +++ b/packages/node_modules/@node-red/nodes/core/parsers/70-CSV.js @@ -38,18 +38,18 @@ module.exports = function(RED) { if (this.hdrout === true) { this.hdrout = "all"; } var tmpwarn = true; var node = this; - var re = new RegExp(node.sep+'(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); + var re = new RegExp(node.sep.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g,'\\$&') + '(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); // pass in an array of column names to be trimmed, de-quoted and retrimmed var clean = function(col,sep) { - if (sep) { re = new RegExp(sep+'(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); } + if (sep) { re = new RegExp(sep.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g,'\\$&') +'(?=(?:(?:[^"]*"){2})*[^"]*$)','g'); } col = col.trim().split(re) || [""]; col = col.map(x => x.replace(/"/g,'').trim()); if ((col.length === 1) && (col[0] === "")) { node.goodtmpl = false; } else { node.goodtmpl = true; } return col; } - var template = clean(node.template); + var template = clean(node.template,','); var notemplate = template.length === 1 && template[0] === ''; node.hdrSent = false; @@ -185,7 +185,7 @@ module.exports = function(RED) { if ((node.hdrin === true) && first) { // if the template is in the first line if ((line[i] === "\n")||(line[i] === "\r")||(line.length - i === 1)) { // look for first line break if (line.length - i === 1) { tmp += line[i]; } - template = clean(tmp); + template = clean(tmp,node.sep); first = false; } else { tmp += line[i]; } diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js index cccf7bf1c..b2004eb75 100644 --- a/test/nodes/core/parsers/70-CSV_spec.js +++ b/test/nodes/core/parsers/70-CSV_spec.js @@ -87,6 +87,40 @@ describe('CSV node', function() { }); }); + it('should convert a simple string to a javascript object with | separator (no template)', function(done) { + var flow = [ { id:"n1", type:"csv", sep:"|", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { col1: 1, col2: 2, col3: 3, col4: 4 }); + msg.should.have.property('columns', "col1,col2,col3,col4"); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1|2|3|4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should convert a simple string to a javascript object with tab separator (with template)', function(done) { + var flow = [ { id:"n1", type:"csv", sep:"\t", temp:"A,B,,D", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { A: 1, B: 2, D: 4 }); + msg.should.have.property('columns', "A,B,D"); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1\t2\t3\t4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + it('should remove quotes and whitespace from template', function(done) { var flow = [ { id:"n1", type:"csv", temp:'"a", "b" , " c "," d " ', wires:[["n2"]] }, {id:"n2", type:"helper"} ]; From 9f1deb0c36b07d871a4e474783c85a8959dcc100 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 23 Apr 2021 11:19:23 +0100 Subject: [PATCH 29/77] CSV Add couple more special character tests just to make sure --- test/nodes/core/parsers/70-CSV_spec.js | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js index b2004eb75..8cecbb7fb 100644 --- a/test/nodes/core/parsers/70-CSV_spec.js +++ b/test/nodes/core/parsers/70-CSV_spec.js @@ -222,6 +222,40 @@ describe('CSV node', function() { }); }); + it('should allow passing in a template as first line of CSV (special char /)', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:"/", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, "b b":2, "c/c":3, "d, d": 4 }); + msg.should.have.property('columns', 'a,b b,c/c,"d, d"'); + check_parts(msg, 0, 1); + done(); + }); + var testString = 'a/b b/"c/c"/" d, d "'+"\n"+"1/2/3/4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + + it('should allow passing in a template as first line of CSV (special char \\)', function(done) { + var flow = [ { id:"n1", type:"csv", temp:"", hdrin:true, sep:"\\", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { a: 1, "b b":2, "c\\c":3, "d, d": 4 }); + msg.should.have.property('columns', 'a,b b,c\\c,"d, d"'); + check_parts(msg, 0, 1); + done(); + }); + var testString = 'a\\b b\\"c\\c"\\" d, d "'+"\n"+"1\\2\\3\\4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + it('should leave numbers starting with 0, e and + as strings (except 0.)', function(done) { var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] }, {id:"n2", type:"helper"} ]; From f8abf9fce16981df75243b722ede62031fde0d6b Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Sun, 25 Apr 2021 08:53:18 +0100 Subject: [PATCH 30/77] add another test to csv --- test/nodes/core/parsers/70-CSV_spec.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js index 8cecbb7fb..f8e99ac31 100644 --- a/test/nodes/core/parsers/70-CSV_spec.js +++ b/test/nodes/core/parsers/70-CSV_spec.js @@ -121,6 +121,23 @@ describe('CSV node', function() { }); }); + it('should convert a simple string to a javascript object with space separator (with spaced template)', function(done) { + var flow = [ { id:"n1", type:"csv", sep:" ", temp:"A, B, , D", wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(csvNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', { A: 1, B: 2, D: 4 }); + msg.should.have.property('columns', "A,B,D"); + check_parts(msg, 0, 1); + done(); + }); + var testString = "1 2 3 4"+String.fromCharCode(10); + n1.emit("input", {payload:testString}); + }); + }); + it('should remove quotes and whitespace from template', function(done) { var flow = [ { id:"n1", type:"csv", temp:'"a", "b" , " c "," d " ', wires:[["n2"]] }, {id:"n2", type:"helper"} ]; From a480919ec3ff361c6aef97cce24fbed88213cabc Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Mon, 26 Apr 2021 09:05:53 +0900 Subject: [PATCH 31/77] fix error on auto commit for no flow change --- .../lib/storage/localfilesystem/projects/index.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js index 0533fe5e6..1565decdd 100644 --- a/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js +++ b/packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js @@ -608,8 +608,15 @@ async function saveFlows(flows, user) { var workflowMode = (gitSettings.workflow||{}).mode || settings.editorTheme.projects.workflow.mode; if (workflowMode === 'auto') { return activeProject.stageFile([flowsFullPath, credentialsFile]).then(() => { - return activeProject.commit(user,{message:"Update flow files"}) - }) + return activeProject.status(user, false).then((result) => { + const items = Object.values(result.files || {}); + // check if saved flow make modification to repository + if (items.findIndex((item) => (item.status === "M ")) < 0) { + return Promise.resolve(); + } + return activeProject.commit(user,{message:"Update flow files"}) + }); + }); } } }); From 1d12017f116aebe020443e39566cd0645f2c2434 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Apr 2021 10:13:57 +0100 Subject: [PATCH 32/77] Sort context stores in TypedInput and ensure default first Fixes #2954 --- .../editor-client/src/js/ui/common/typedInput.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js index 2dbd6d71a..0401be1b9 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js @@ -15,7 +15,7 @@ **/ (function($) { var contextParse = function(v,defaultStore) { - var parts = RED.utils.parseContextKey(v, defaultStore); + var parts = RED.utils.parseContextKey(v, defaultStore&&defaultStore.value); return { option: parts.store, value: parts.key @@ -279,6 +279,14 @@ var contextStores = RED.settings.context.stores; var contextOptions = contextStores.map(function(store) { return {value:store,label: store, icon:''} + }).sort(function(A,B) { + if (A.value === RED.settings.context.default) { + return -1; + } else if (B.value === RED.settings.context.default) { + return 1; + } else { + return A.value.localeCompare(B.value); + } }) if (contextOptions.length < 2) { allOptions.flow.options = []; From bbac49ff3819d9b0b6afce7825bd8e74e31860dc Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Apr 2021 10:18:25 +0100 Subject: [PATCH 33/77] Ensure function expand button is above vertical scrollbar Fixes #2955 --- .../@node-red/nodes/core/function/10-function.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.html b/packages/node_modules/@node-red/nodes/core/function/10-function.html index a57655cf8..20e51da6c 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.html @@ -74,21 +74,21 @@ From 4cb8e99430bcb6667e6e42dd9b22ea24f1bad313 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Apr 2021 11:45:28 +0100 Subject: [PATCH 34/77] Timeout http upgrade requests that are not otherwise handled Fixes #2956 --- .../@node-red/runtime/lib/index.js | 21 +++++++++++++++++++ packages/node_modules/node-red/settings.js | 6 ++++++ 2 files changed, 27 insertions(+) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 30481740f..c09d202f9 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -64,6 +64,27 @@ var server; */ function init(userSettings,httpServer,_adminApi) { server = httpServer; + + if (server && server.on) { + // Add a listener to the upgrade event so that we can properly timeout connection + // attempts that do not get handled by any nodes in the user's flow. + // See #2956 + server.on('upgrade',(request, socket, head) => { + // Add a no-op handler to the error event in case nothing upgrades this socket + // before the remote end closes it. This ensures we don't get as uncaughtException + socket.on("error", err => {}) + setTimeout(function() { + // If this request has been handled elsewhere, the upgrade will have + // been completed and bytes written back to the client. + // If nothing has been written on the socket, nothing has handled the + // upgrade, so we can consider this an unhandled upgrade. + if (socket.bytesWritten === 0) { + socket.destroy(); + } + },userSettings.inboundWebSocketTimeout || 5000) + }); + } + userSettings.version = getVersion(); settings.init(userSettings); diff --git a/packages/node_modules/node-red/settings.js b/packages/node_modules/node-red/settings.js index 331654ed8..a39731f37 100644 --- a/packages/node_modules/node-red/settings.js +++ b/packages/node_modules/node-red/settings.js @@ -46,6 +46,12 @@ module.exports = { // defaults to 10Mb //execMaxBufferSize: 10000000, + // Timeout in milliseconds for inbound WebSocket connections that do not + // match any configured node. + // defaults to 5000 + //inboundWebSocketTimeout: 5000 + + // The maximum length, in characters, of any message sent to the debug sidebar tab debugMaxLength: 1000, From 8e7efd98b2c8ac2b387808dbf2f0c8ddd03b4858 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 26 Apr 2021 16:48:21 +0100 Subject: [PATCH 35/77] Don't let 'escape' whilst moving nodes interrupt things Fixes #2960 --- .../node_modules/@node-red/editor-client/src/js/ui/view.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 e19387a1e..bffc6fd85 100755 --- 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 @@ -1751,7 +1751,6 @@ RED.view = (function() { } } if (mouse_mode == RED.state.IMPORT_DRAGGING) { - RED.keyboard.remove("escape"); updateActiveNodes(); RED.nodes.dirty(true); } @@ -1786,6 +1785,9 @@ RED.view = (function() { } function selectNone() { + if (mouse_mode === RED.state.MOVING || mouse_mode === RED.state.MOVING_ACTIVE) { + return; + } if (mouse_mode === RED.state.IMPORT_DRAGGING) { clearSelection(); RED.history.pop(); From 70433f3d0597212e61d69982bb4833723f329af0 Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Wed, 28 Apr 2021 21:40:17 +0900 Subject: [PATCH 36/77] fix grunt fail on exec node test --- test/nodes/core/function/90-exec_spec.js | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/test/nodes/core/function/90-exec_spec.js b/test/nodes/core/function/90-exec_spec.js index e89465c3e..73d8674dd 100644 --- a/test/nodes/core/function/90-exec_spec.js +++ b/test/nodes/core/function/90-exec_spec.js @@ -541,13 +541,17 @@ describe('exec node', function() { var n2 = helper.getNode("n2"); var n3 = helper.getNode("n3"); var n4 = helper.getNode("n4"); + var payload = ""; n2.on("input", function(msg) { //console.log(msg); try { msg.should.have.property("payload"); msg.payload.should.be.a.String(); - msg.payload.should.equal(expected); - done(); + payload += msg.payload; + if (payload.endsWith("\n")) { + payload.should.equal(expected); + done(); + } } catch(err) { done(err); } }); @@ -567,6 +571,7 @@ describe('exec node', function() { {id:"n2", type:"helper"},{id:"n3", type:"helper"},{id:"n4", type:"helper"}]; expected = "12345 deg C\n"; } + var payload = ""; helper.load(execNode, flow, function() { var n1 = helper.getNode("n1"); @@ -578,8 +583,11 @@ describe('exec node', function() { try { msg.should.have.property("payload"); msg.payload.should.be.a.String(); - msg.payload.should.equal(expected); - done(); + payload += msg.payload; + if (payload.endsWith("\n")) { + payload.should.equal(expected); + done(); + } } catch(err) { done(err); } }); @@ -661,8 +669,16 @@ describe('exec node', function() { }; n2.on("input", function(msg) { - messages[0] = msg; - completeTest(); + var payload = msg.payload; + if (messages[0]) { + messages[0].payload += payload; + } + else { + messages[0] = msg; + } + if (payload.endsWith("\n")) { + completeTest(); + } }); n4.on("input", function(msg) { messages[1] = msg; @@ -869,8 +885,16 @@ describe('exec node', function() { }; n2.on("input", function(msg) { - messages[0] = msg; - completeTest(); + var payload = msg.payload; + if (messages[0]) { + messages[0].payload += payload; + } + else { + messages[0] = msg; + } + if (payload.endsWith("\n")) { + completeTest(); + } }); n4.on("input", function(msg) { messages[1] = msg; From d47a8aa562de5369462fcc2730e6f106fa74761d Mon Sep 17 00:00:00 2001 From: GitHub Date: Wed, 28 Apr 2021 17:25:26 +0200 Subject: [PATCH 37/77] Fix remove item when depth=0 and wrong gutter calc --- .../src/js/ui/common/treeList.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js index a6db02ffb..5c9bdb5fe 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js @@ -312,7 +312,7 @@ } if (child.depth !== parent.depth+1) { child.depth = parent.depth+1; - var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20)); + var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20)); child.treeList.labelPadding.width(labelPaddingWidth+'px'); if (child.element) { $(child.element).css({ @@ -348,6 +348,16 @@ that._selected.delete(item); delete item.treeList; delete that._items[item.id]; + if(item.depth === 0) { + for(var key in that._items) { + var child = that._items[key]; + if(child.parent && child.parent.id === item.id) { + delete that._items[key].treeList; + delete that._items[key]; + } + } + that._data = that._data.filter(data => data.id !== item.id) + } } item.treeList.insertChildAt = function(newItem,position,select) { newItem.parent = item; @@ -480,7 +490,10 @@ if (item.treeList.container) { $(item.element).remove(); $(element).appendTo(item.treeList.label); - var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(item.depth*20); + // using the JQuery Object, the gutter width will + // be wrong when the element is reattached the second time + var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (item.depth * 20); + $(element).css({ width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)" }) @@ -516,7 +529,7 @@ }).appendTo(label) } - var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20); + var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20) item.treeList.labelPadding = $('').css({ display: "inline-block", width: labelPaddingWidth+'px' From 91f5542a57e04d6f6d417cd36e088f37cc6c1ce7 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 28 Apr 2021 20:54:31 +0100 Subject: [PATCH 38/77] Fix importing node to currently flow rather than match its old z value If you import a node whose z value is a known existing tab, it is getting imported to that tab, rather than the expected behaviour of being imported to the current tab. This commit fixes that by checked if the node is being imported to a tab that was included in the import, rather than pre-existing. --- .../node_modules/@node-red/editor-client/src/js/nodes.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js index 174892d43..9b580f9a0 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js +++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -1424,6 +1424,8 @@ RED.nodes = (function() { nid = getID(); workspace_map[n.id] = nid; n.id = nid; + } else { + workspace_map[n.id] = n.id; } addWorkspace(n); RED.workspaces.add(n); @@ -1523,7 +1525,7 @@ RED.nodes = (function() { } } } else { - if (n.z && !workspaces[n.z] && !subflow_map[n.z]) { + if (n.z && !workspace_map[n.z] && !subflow_map[n.z]) { n.z = activeWorkspace; } } @@ -1621,7 +1623,7 @@ RED.nodes = (function() { node.id = getID(); } else { node.id = n.id; - if (node.z == null || (!workspaces[node.z] && !subflow_map[node.z])) { + if (node.z == null || (!workspace_map[node.z] && !subflow_map[node.z])) { if (createMissingWorkspace) { if (missingWorkspace === null) { missingWorkspace = RED.workspaces.add(null,true); From 7df1a03b4b348fdbbba2336d7cfadda2a2485f76 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 28 Apr 2021 21:49:32 +0100 Subject: [PATCH 39/77] Handle subflow modules that contain subflows --- .../@node-red/runtime/lib/flows/util.js | 5 +- .../runtime/lib/nodes/credentials.js | 6 +- .../runtime/lib/nodes/credentials_spec.js | 87 +++++++++---------- 3 files changed, 51 insertions(+), 47 deletions(-) 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 edb348ac4..79c70fb02 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/util.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/util.js @@ -95,6 +95,9 @@ function createNode(flow,config) { } else if (nodeTypeConstructor) { // console.log(nodeTypeConstructor) var subflowConfig = parseConfig([nodeTypeConstructor.subflow].concat(nodeTypeConstructor.subflow.flow)); + var subflowInstanceConfig = subflowConfig.subflows[nodeTypeConstructor.subflow.id]; + delete subflowConfig.subflows[nodeTypeConstructor.subflow.id]; + subflowInstanceConfig.subflows = subflowConfig.subflows; var instanceConfig = clone(config); instanceConfig.env = clone(nodeTypeConstructor.subflow.env); @@ -124,7 +127,7 @@ function createNode(flow,config) { nodeTypeConstructor.type, flow, flow.global, - subflowConfig.subflows[nodeTypeConstructor.subflow.id], + subflowInstanceConfig, instanceConfig ); subflow.start(); diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js b/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js index 86ea1d3a1..30b2ccdb0 100644 --- a/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js +++ b/packages/node_modules/@node-red/runtime/lib/nodes/credentials.js @@ -343,7 +343,11 @@ var api = module.exports = { if (newCreds) { delete node.credentials; var savedCredentials = credentialCache[nodeID] || {}; - if (/^subflow(:|$)/.test(nodeType)) { + // Need to check the type of constructor for this node. + // - Function : regular node + // - !Function: subflow module + + if (/^subflow(:|$)/.test(nodeType) || typeof runtime.nodes.getType(nodeType) !== 'function') { for (cred in newCreds) { if (newCreds.hasOwnProperty(cred)) { if (newCreds[cred] === "__PWRD__") { diff --git a/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js b/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js index 5e4bc8094..6db0b867b 100644 --- a/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js +++ b/test/unit/@node-red/runtime/lib/nodes/credentials_spec.js @@ -36,102 +36,96 @@ describe('red/runtime/nodes/credentials', function() { index.clearRegistry(); }); - it('loads provided credentials',function(done) { + it('loads provided credentials',function() { credentials.init({ log: log, settings: encryptionDisabledSettings }); - credentials.load({"a":{"b":1,"c":2}}).then(function() { - + return credentials.load({"a":{"b":1,"c":2}}).then(function() { credentials.get("a").should.have.property('b',1); credentials.get("a").should.have.property('c',2); - - done(); }); }); - it('adds a new credential',function(done) { + it('adds a new credential',function() { credentials.init({ log: log, settings: encryptionDisabledSettings }); - credentials.load({"a":{"b":1,"c":2}}).then(function() { + return credentials.load({"a":{"b":1,"c":2}}).then(function() { credentials.dirty().should.be.false(); should.not.exist(credentials.get("b")); - credentials.add("b",{"foo":"bar"}).then(function() { + return credentials.add("b",{"foo":"bar"}).then(function() { credentials.get("b").should.have.property("foo","bar"); credentials.dirty().should.be.true(); - done(); }); }); }); - it('deletes an existing credential',function(done) { + it('deletes an existing credential',function() { credentials.init({ log: log, settings: encryptionDisabledSettings }); - credentials.load({"a":{"b":1,"c":2}}).then(function() { + return credentials.load({"a":{"b":1,"c":2}}).then(function() { credentials.dirty().should.be.false(); credentials.delete("a"); should.not.exist(credentials.get("a")); credentials.dirty().should.be.true(); - done(); }); }); - it('exports the credentials, clearing dirty flag', function(done) { + it('exports the credentials, clearing dirty flag', function() { credentials.init({ log: log, settings: encryptionDisabledSettings }); var creds = {"a":{"b":1,"c":2}}; - credentials.load(creds).then(function() { - credentials.add("b",{"foo":"bar"}).then(function() { - credentials.dirty().should.be.true(); - credentials.export().then(function(exported) { - exported.should.eql(creds); - credentials.dirty().should.be.false(); - done(); - }) - }); + return credentials.load(creds).then(function() { + return credentials.add("b",{"foo":"bar"}) + }).then(function() { + credentials.dirty().should.be.true(); + return credentials.export().then(function(exported) { + exported.should.eql(creds); + credentials.dirty().should.be.false(); + }) }); }) describe("#clean",function() { - it("removes credentials of unknown nodes",function(done) { + it("removes credentials of unknown nodes",function() { credentials.init({ log: log, - settings: encryptionDisabledSettings + settings: encryptionDisabledSettings, + nodes: { getType: () => function(){} } }); var creds = {"a":{"b":1,"c":2},"b":{"d":3}}; - credentials.load(creds).then(function() { + return credentials.load(creds).then(function() { credentials.dirty().should.be.false(); should.exist(credentials.get("a")); should.exist(credentials.get("b")); - credentials.clean([{id:"b"}]).then(function() { + return credentials.clean([{id:"b"}]).then(function() { credentials.dirty().should.be.true(); should.not.exist(credentials.get("a")); should.exist(credentials.get("b")); - done(); }); }); }); - it("extracts credentials of known nodes",function(done) { + it("extracts credentials of known nodes",function() { credentials.init({ log: log, - settings: encryptionDisabledSettings + settings: encryptionDisabledSettings, + nodes: { getType: () => function(){} } }); credentials.register("testNode",{"b":"text","c":"password"}) var creds = {"a":{"b":1,"c":2}}; var newConfig = [{id:"a",type:"testNode",credentials:{"b":"newBValue","c":"newCValue"}}]; - credentials.load(creds).then(function() { + return credentials.load(creds).then(function() { credentials.dirty().should.be.false(); - credentials.clean(newConfig).then(function() { + return credentials.clean(newConfig).then(function() { credentials.dirty().should.be.true(); credentials.get("a").should.have.property('b',"newBValue"); credentials.get("a").should.have.property('c',"newCValue"); should.not.exist(newConfig[0].credentials); - done(); }); }); }); @@ -139,12 +133,13 @@ describe('red/runtime/nodes/credentials', function() { }); - it('warns if a node has no credential definition', function(done) { + it('warns if a node has no credential definition', function() { credentials.init({ log: log, - settings: encryptionDisabledSettings + settings: encryptionDisabledSettings, + nodes: { getType: () => function(){} } }); - credentials.load({}).then(function() { + return credentials.load({}).then(function() { var node = {id:"node",type:"test",credentials:{ user1:"newUser", password1:"newPassword" @@ -154,14 +149,14 @@ describe('red/runtime/nodes/credentials', function() { log.warn.called.should.be.true(); should.not.exist(node.credentials); log.warn.restore(); - done(); }); }) it('extract credential updates in the provided node', function(done) { credentials.init({ log: log, - settings: encryptionDisabledSettings + settings: encryptionDisabledSettings, + nodes: { getType: () => function(){} } }); var defintion = { user1:{type:"text"}, @@ -205,7 +200,8 @@ describe('red/runtime/nodes/credentials', function() { it('extract ignores node without credentials', function(done) { credentials.init({ log: log, - settings: encryptionDisabledSettings + settings: encryptionDisabledSettings, + nodes: { getType: () => function(){} } }); credentials.load({"node":{user1:"abc",password1:"123"}}).then(function() { var node = {id:"node",type:"test"}; @@ -233,7 +229,8 @@ describe('red/runtime/nodes/credentials', function() { delete settings[key]; return Promise.resolve(); } - } + }, + nodes: { getType: () => function(){} } } it('migrates to encrypted and generates default key', function(done) { settings = {}; @@ -341,7 +338,7 @@ describe('red/runtime/nodes/credentials', function() { }); }); }); - it('migrates from default key to user key', function(done) { + it('migrates from default key to user key', function() { settings = { _credentialSecret: "e3a36f47f005bf2aaa51ce3fc6fcaafd79da8d03f2b1a9281f8fb0a285e6255a", credentialSecret: "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbcccccccccccccddddddddddddeeeee" @@ -349,21 +346,20 @@ describe('red/runtime/nodes/credentials', function() { // {"node":{user1:"abc",password1:"123"}} var cryptedFlows = {"$":"5b89d8209b5158a3c313675561b1a5b5phN1gDBe81Zv98KqS/hVDmc9EKvaKqRIvcyXYvBlFNzzzJtvN7qfw06i"}; credentials.init(runtime); - credentials.load(cryptedFlows).then(function() { + return credentials.load(cryptedFlows).then(function() { credentials.dirty().should.be.true(); should.exist(credentials.get("node")); - credentials.export().then(function(result) { + return credentials.export().then(function(result) { result.should.have.a.property("$"); settings.should.not.have.a.property("_credentialSecret"); // reset everything - but with _credentialSecret still set credentials.init(runtime); // load the freshly encrypted version - credentials.load(result).then(function() { + return credentials.load(result).then(function() { should.exist(credentials.get("node")); credentials.get("node").should.have.a.property("user1","abc"); credentials.get("node").should.have.a.property("password1","123"); - done(); }) }); }); @@ -459,7 +455,8 @@ describe('red/runtime/nodes/credentials', function() { set: function(key,value) { throw new Error(); } - } + }, + nodes: { getType: () => function(){} } } // {"node":{user1:"abc",password1:"123"}} credentials.init(runtime); From 6da8e92f20cd429bb284c56385894c4a222dc39c Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 28 Apr 2021 22:01:39 +0100 Subject: [PATCH 40/77] Fix inject node output tooltip extra property count --- .../node_modules/@node-red/nodes/core/common/20-inject.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html index 22b98cc9c..717752377 100644 --- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html +++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html @@ -214,7 +214,7 @@ for (var i=0,l=props.length; i 0) lab += "\n"; if (i === 5) { - lab += " + "+(props.length-4); + lab += "... +"+(props.length-5); break; } lab += props[i].p+": "; From a150d8e2899f494781730123b369feedbaa3e762 Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 28 Apr 2021 23:37:26 +0200 Subject: [PATCH 41/77] Update packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js Thanks for the tip, I'll remember next time. Co-authored-by: Nick O'Leary --- .../@node-red/editor-client/src/js/ui/common/treeList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js index 5c9bdb5fe..df9592508 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js @@ -356,7 +356,7 @@ delete that._items[key]; } } - that._data = that._data.filter(data => data.id !== item.id) + that._data = that._data.filter(function(data) { return data.id !== item.id}) } } item.treeList.insertChildAt = function(newItem,position,select) { From cd3aba2b89e0d570c99210820e703aab2a360a32 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Thu, 29 Apr 2021 10:17:07 +0100 Subject: [PATCH 42/77] Allow nodes to access resolved theme files Fixes #2968 --- .../@node-red/editor-api/lib/editor/theme.js | 10 +++++++ .../@node-red/nodes/core/common/21-debug.js | 28 +++++++++++++++++-- .../nodes/core/common/lib/debug/view.html | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/editor/theme.js b/packages/node_modules/@node-red/editor-api/lib/editor/theme.js index 3ea4ede73..fc65753bf 100644 --- a/packages/node_modules/@node-red/editor-api/lib/editor/theme.js +++ b/packages/node_modules/@node-red/editor-api/lib/editor/theme.js @@ -129,6 +129,14 @@ module.exports = { } themeContext.page.title = theme.page.title || themeContext.page.title; + + // Store the resolved urls to these resources so nodes (such as Debug) + // can access them + theme.page._ = { + css: themeContext.page.css, + scripts: themeContext.page.scripts, + favicon: themeContext.page.favicon + } } if (theme.header) { @@ -223,6 +231,7 @@ module.exports = { themePlugin.path ); themeContext.page.css = cssFiles.concat(themeContext.page.css || []) + theme.page._.css = cssFiles.concat(theme.page._.css || []) } if (themePlugin.scripts) { const scriptFiles = serveFilesFromTheme( @@ -232,6 +241,7 @@ module.exports = { themePlugin.path ) themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || []) + theme.page._.scripts = cssFiles.concat(theme.page._.scripts || []) } } activeThemeInitialised = true; diff --git a/packages/node_modules/@node-red/nodes/core/common/21-debug.js b/packages/node_modules/@node-red/nodes/core/common/21-debug.js index 0e00a8fff..8d2121580 100644 --- a/packages/node_modules/@node-red/nodes/core/common/21-debug.js +++ b/packages/node_modules/@node-red/nodes/core/common/21-debug.js @@ -2,7 +2,8 @@ module.exports = function(RED) { "use strict"; var util = require("util"); var events = require("events"); - //var path = require("path"); + const fs = require("fs-extra"); + const path = require("path"); var debuglength = RED.settings.debugMaxLength || 1000; var useColors = RED.settings.debugUseColors || false; util.inspect.styles.boolean = "red"; @@ -249,11 +250,34 @@ module.exports = function(RED) { } }); + let cachedDebugView; + RED.httpAdmin.get("/debug/view/view.html", function(req,res) { + if (!cachedDebugView) { + fs.readFile(path.join(__dirname,"lib","debug","view.html")).then(data => { + let customStyles = ""; + try { + let customStyleList = RED.settings.editorTheme.page._.css || []; + customStyleList.forEach(style => { + customStyles += `\n` + }) + } catch(err) {} + cachedDebugView = data.toString().replace("",customStyles) + res.set('Content-Type', 'text/html'); + res.send(cachedDebugView).end(); + }).catch(err => { + res.sendStatus(404); + }) + } else { + res.send(cachedDebugView).end(); + } + + }); + // As debug/view/debug-utils.js is loaded via