From 6e35a9f682a9547cfcc4439ba9fa5742c47190dd Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Thu, 14 Apr 2022 23:55:57 +0100 Subject: [PATCH 1/8] use typedInput for filename on file nodes --- .../@node-red/nodes/core/storage/10-file.html | 36 +++++++++++++++-- .../@node-red/nodes/core/storage/10-file.js | 39 +++++++++++++++++-- 2 files changed, 69 insertions(+), 6 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 b76a01615..fa3fdccc9 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 @@ -3,6 +3,7 @@
+
@@ -38,6 +39,7 @@
+
@@ -197,6 +199,7 @@ defaults: { name: {value:""}, filename: {value:""}, + filenameType: {value:""}, appendNewline: {value:true}, createDir: {value:false}, overwriteFile: {value:"false"}, @@ -207,10 +210,12 @@ outputs:1, icon: "file-out.svg", label: function() { + var fn = this.filename; + if(this.filenameType != "str") { fn = ""; } if (this.overwriteFile === "delete") { - return this.name||this._("file.label.deletelabel",{file:this.filename}); + return this.name||this._("file.label.deletelabel",{file:fn}); } else { - return this.name||this.filename||this._("file.label.write"); + return this.name||fn||this._("file.label.write"); } }, paletteLabel: RED._("node-red:file.label.write"), @@ -229,6 +234,17 @@ value: "setbymsg", label: node._("file.encoding.setbymsg") }).text(label).appendTo(encSel); + $("#node-input-filename").typedInput({ + default: "str", + types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], + typeField: $("#node-input-filenameType") + }); + if(!node.filename && !node.filenameType) { + node.filename = "filename" + node.filenameType = "msg" + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } encodings.forEach(function(item) { if(Array.isArray(item)) { var group = $("", { @@ -267,6 +283,7 @@ defaults: { name: {value:""}, filename: {value:""}, + filenameType: {value:""}, format: {value:"utf8"}, chunk: {value:false}, sendError: {value: false}, @@ -291,7 +308,9 @@ }, icon: "file-in.svg", label: function() { - return this.name||this.filename||this._("file.label.read"); + var fn = this.filename; + if(this.filenameType != "str") { fn = ""; } + return this.name||fn||this._("file.label.read"); }, paletteLabel: RED._("node-red:file.label.read"), labelStyle: function() { @@ -305,6 +324,17 @@ value: "none", label: label }).text(label).appendTo(encSel); + $("#node-input-filename").typedInput({ + default: "str", + types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], + typeField: $("#node-input-filenameType") + }); + if(!node.filename && !node.filenameType) { + node.filename = "filename" + node.filenameType = "msg" + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } encodings.forEach(function(item) { if(Array.isArray(item)) { var group = $("", { 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 ba81125fe..309de1abf 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 @@ -39,6 +39,7 @@ module.exports = function(RED) { // Write/delete a file RED.nodes.createNode(this,n); this.filename = n.filename; + this.filenameType = n.filenameTpye; this.appendNewline = n.appendNewline; this.overwriteFile = n.overwriteFile.toString(); this.createDir = n.createDir || false; @@ -50,7 +51,22 @@ module.exports = function(RED) { node.closeCallback = null; function processMsg(msg,nodeSend, done) { - var filename = node.filename || msg.filename || ""; + var filename = node.filename || ""; + //Pre V3 compatibility - if filename and filenameType are empty, check msg.filename + if(!node.filenameType && !node.filename) { + msg.filename = "filename"; + node.filenameType = "msg"; + } + + RED.util.evaluateNodeProperty(node.filename,node.filenameType,node,msg,(err,value) => { + if (err) { + node.error(err,msg); + return done(); + } else { + filename = value; + } + }); + var fullFilename = filename; if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) { fullFilename = path.resolve(path.join(RED.settings.fileWorkingDirectory,filename)); @@ -158,7 +174,7 @@ module.exports = function(RED) { done(); }); } - if (node.filename) { + if (node.filenameType === "str") { // Static filename - write and reuse the stream next time node.wstream.write(buf, function() { nodeSend(msg); @@ -256,6 +272,7 @@ module.exports = function(RED) { // Read a file RED.nodes.createNode(this,n); this.filename = n.filename; + this.filenameType = n.filenameType; this.format = n.format; this.chunk = false; this.encoding = n.encoding || "none"; @@ -270,8 +287,24 @@ module.exports = function(RED) { var node = this; this.on("input",function(msg, nodeSend, nodeDone) { - var filename = (node.filename || msg.filename || "").replace(/\t|\r|\n/g,''); + var filename = node.filename || ""; + //Pre V3 compatibility - if filename and filenameType are empty, check msg.filename + if(!node.filenameType && !node.filename) { + msg.filename = "filename"; + node.filenameType = "msg"; + } + + RED.util.evaluateNodeProperty(node.filename,node.filenameType,node,msg,(err,value) => { + if (err) { + node.error(err,msg); + return done(); + } else { + filename = (value || "").replace(/\t|\r|\n/g,''); + } + }); + var fullFilename = filename; + var filePath = ""; if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) { fullFilename = path.resolve(path.join(RED.settings.fileWorkingDirectory,filename)); } From 99b049fe2db5755d05372be27f961a8eacd89c2c Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Sat, 16 Apr 2022 14:25:37 +0100 Subject: [PATCH 2/8] final updates to file node filename typedInput - ensure node settings are auto updated to correct typedInput type/value - improve label - ensure str and env are considered "static" (keep stream open) --- .../@node-red/nodes/core/storage/10-file.html | 54 ++++++++++++++----- .../@node-red/nodes/core/storage/10-file.js | 39 ++++++++++---- .../nodes/locales/en-US/storage/10-file.html | 7 --- 3 files changed, 71 insertions(+), 29 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 fa3fdccc9..ec694471d 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 @@ -211,7 +211,8 @@ icon: "file-out.svg", label: function() { var fn = this.filename; - if(this.filenameType != "str") { fn = ""; } + if(this.filenameType != "str" && this.filenameType != "env" ) { fn = ""; } + if(this.filenameType === "env") { fn = "env."+fn; } if (this.overwriteFile === "delete") { return this.name||this._("file.label.deletelabel",{file:fn}); } else { @@ -239,11 +240,25 @@ types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], typeField: $("#node-input-filenameType") }); - if(!node.filename && !node.filenameType) { - node.filename = "filename" - node.filenameType = "msg" - $("#node-input-filename").typedInput("type", node.filenameType); - $("#node-input-filename").typedInput("value", node.filename); + if(typeof node.filenameType == 'undefined') { + //existing node AND filenameType is not set - inplace (compatible) upgrade to new typedInput + if(node.filename == "") { //was using empty value to denote msg.filename - set typedInput to match + node.filename = "filename"; + node.filenameType = "msg"; + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } else if(/^\${[^}]+}$/.test(node.filename)) { //was using an ${ENV_VAR} + node.filenameType = "env"; + node.filename = node.filename.replace(/\${([^}]+)}/g, function(match, name) { + return (name === undefined)?"":name; + }); + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } else { //was using a static filename - set typedInput type to str + node.filenameType = "str"; + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } } encodings.forEach(function(item) { if(Array.isArray(item)) { @@ -309,7 +324,8 @@ icon: "file-in.svg", label: function() { var fn = this.filename; - if(this.filenameType != "str") { fn = ""; } + if(this.filenameType != "str" && this.filenameType != "env" ) { fn = ""; } + if(this.filenameType === "env") { fn = "env."+fn; } return this.name||fn||this._("file.label.read"); }, paletteLabel: RED._("node-red:file.label.read"), @@ -329,11 +345,25 @@ types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], typeField: $("#node-input-filenameType") }); - if(!node.filename && !node.filenameType) { - node.filename = "filename" - node.filenameType = "msg" - $("#node-input-filename").typedInput("type", node.filenameType); - $("#node-input-filename").typedInput("value", node.filename); + if(typeof node.filenameType == 'undefined') { + //existing node AND filenameType is not set - inplace (compatible) upgrade to new typedInput + if(node.filename == "") { //was using empty value to denote msg.filename - set typedInput to match + node.filename = "filename"; + node.filenameType = "msg"; + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } else if(/^\${[^}]+}$/.test(node.filename)) { //was using an ${ENV_VAR} + node.filenameType = "env"; + node.filename = node.filename.replace(/\${([^}]+)}/g, function(match, name) { + return (name === undefined)?"":name; + }); + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } else { //was using a static filename - set typedInput type to str + node.filenameType = "str"; + $("#node-input-filename").typedInput("type", node.filenameType); + $("#node-input-filename").typedInput("value", node.filename); + } } encodings.forEach(function(item) { if(Array.isArray(item)) { 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 309de1abf..b6531a3a6 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 @@ -52,10 +52,20 @@ module.exports = function(RED) { function processMsg(msg,nodeSend, done) { var filename = node.filename || ""; - //Pre V3 compatibility - if filename and filenameType are empty, check msg.filename - if(!node.filenameType && !node.filename) { - msg.filename = "filename"; - node.filenameType = "msg"; + //Pre V3 compatibility - if filenameType is empty, do in place upgrade + if(typeof node.filenameType == 'undefined' || node.filenameType == "") { + //existing node AND filenameType is not set - inplace (compatible) upgrade + if(filename == "") { //was using empty value to denote msg.filename + node.filename = "filename"; + node.filenameType = "msg"; + } else if(/^\${[^}]+}$/.test(filename)) { //was using an ${ENV_VAR} + node.filenameType = "env"; + node.filename = filename.replace(/\${([^}]+)}/g, function(match, name) { + return (name === undefined)?"":name; + }); + } else { //was using a static filename - set typedInput type to str + node.filenameType = "str"; + } } RED.util.evaluateNodeProperty(node.filename,node.filenameType,node,msg,(err,value) => { @@ -174,7 +184,7 @@ module.exports = function(RED) { done(); }); } - if (node.filenameType === "str") { + if (node.filenameType === "str" || node.filenameType === "env") { // Static filename - write and reuse the stream next time node.wstream.write(buf, function() { nodeSend(msg); @@ -288,12 +298,21 @@ module.exports = function(RED) { this.on("input",function(msg, nodeSend, nodeDone) { var filename = node.filename || ""; - //Pre V3 compatibility - if filename and filenameType are empty, check msg.filename - if(!node.filenameType && !node.filename) { - msg.filename = "filename"; - node.filenameType = "msg"; + //Pre V3 compatibility - if filenameType is empty, do in place upgrade + if(typeof node.filenameType == 'undefined' || node.filenameType == "") { + //existing node AND filenameType is not set - inplace (compatible) upgrade + if(filename == "") { //was using empty value to denote msg.filename + node.filename = "filename"; + node.filenameType = "msg"; + } else if(/^\${[^}]+}$/.test(filename)) { //was using an ${ENV_VAR} + node.filenameType = "env"; + node.filename = filename.replace(/\${([^}]+)}/g, function(match, name) { + return (name === undefined)?"":name; + }); + } else { //was using a static filename - set typedInput type to str + node.filenameType = "str"; + } } - RED.util.evaluateNodeProperty(node.filename,node.filenameType,node,msg,(err,value) => { if (err) { node.error(err,msg); 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 70400f676..1e8e7e3c2 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 @@ -19,8 +19,6 @@ Alternatively, it can delete the file.

Inputs

-
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.
@@ -40,11 +38,6 @@ @@ -38,7 +38,7 @@ From f63da0c58b7f7f9d2ecb04893a3defcc2d905030 Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Wed, 27 Apr 2022 20:44:41 +0100 Subject: [PATCH 8/8] Default to msg.filename as per v2 condition --- .../@node-red/nodes/core/storage/10-file.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 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 45a825b50..ddddcb687 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 @@ -198,8 +198,8 @@ category: 'storage', defaults: { name: {value:""}, - filename: {value:""}, - filenameType: {value:""}, + filename: {value:"filename"}, + filenameType: {value:"msg"}, appendNewline: {value:true}, createDir: {value:false}, overwriteFile: {value:"false"}, @@ -236,7 +236,7 @@ label: node._("file.encoding.setbymsg") }).text(label).appendTo(encSel); $("#node-input-filename").typedInput({ - default: "str", + default: "msg", types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], typeField: $("#node-input-filenameType") }); @@ -297,8 +297,8 @@ category: 'storage', defaults: { name: {value:""}, - filename: {value:""}, - filenameType: {value:""}, + filename: {value:"filename"}, + filenameType: {value:"msg"}, format: {value:"utf8"}, chunk: {value:false}, sendError: {value: false}, @@ -341,7 +341,7 @@ label: label }).text(label).appendTo(encSel); $("#node-input-filename").typedInput({ - default: "str", + default: "msg", types:[{ value: "str", label:"", icon:"red/images/typedInput/az.svg"}, "msg", "jsonata", "env"], typeField: $("#node-input-filenameType") });