mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add async to all paths that JSONata env var calls
This commit is contained in:
		| @@ -416,23 +416,50 @@ class Flow { | ||||
|         return this.activeNodes; | ||||
|     } | ||||
|  | ||||
|     /*! | ||||
|      * Get value of environment variable defined in group node. | ||||
|      * @param {String} group - group node | ||||
|      * @param {String} name - name of variable | ||||
|      * @return {Object} object containing the value in val property or null if not defined | ||||
|  | ||||
|     /** | ||||
|      * Group callback signature | ||||
|      * | ||||
|      * @callback GroupEnvCallback | ||||
|      * @param {Error} err The error object (or null) | ||||
|      * @param {[result: {val:Any}, name: String]} result The result of the callback | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     getGroupEnvSetting(node, group, name) { | ||||
|  | ||||
|     /** | ||||
|     * @function getGroupEnvSetting | ||||
|     * Get a group setting value synchronously. | ||||
|     * This currently automatically defers to the parent | ||||
|     * @overload | ||||
|      * @param {Object} node | ||||
|      * @param {Object} group | ||||
|      * @param {String} name | ||||
|      * @returns {Any} | ||||
|      * | ||||
|      * Get a group setting value asynchronously. | ||||
|      * @overload | ||||
|      * @param {Object} node | ||||
|      * @param {Object} group | ||||
|      * @param {String} name | ||||
|      * @param {GroupEnvCallback} callback | ||||
|      * @returns {void} | ||||
|     */ | ||||
|  | ||||
|     getGroupEnvSetting(node, group, name, callback) { | ||||
|         /** @type {GroupEnvCallback} */ | ||||
|         const returnOrCallback = (err, [result, newName]) => { | ||||
|             if (callback) { | ||||
|                 callback(err, [result, newName]); | ||||
|                 return | ||||
|             } | ||||
|             return [result, newName]; | ||||
|         } | ||||
|         if (group) { | ||||
|             if (name === "NR_GROUP_NAME") { | ||||
|                 return [{ | ||||
|                     val: group.name | ||||
|                 }, null]; | ||||
|                 return returnOrCallback(null, [{ val: group.name }, null]); | ||||
|             } | ||||
|             if (name === "NR_GROUP_ID") { | ||||
|                 return [{ | ||||
|                     val: group.id | ||||
|                 }, null]; | ||||
|                 return returnOrCallback(null, [{ val: group.id }, null]); | ||||
|             } | ||||
|  | ||||
|             if (group.credentials === undefined) { | ||||
| @@ -457,33 +484,32 @@ class Flow { | ||||
|                     if (env) { | ||||
|                         let value = env.value; | ||||
|                         const type = env.type; | ||||
|                         if ((type !== "env") || | ||||
|                             (value !== name)) { | ||||
|                         if ((type !== "env") || (value !== name)) { | ||||
|                             if (type === "env") { | ||||
|                                 value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}"); | ||||
|                             } | ||||
|                             if (type === "bool") { | ||||
|                                 const val | ||||
|                                       = ((value === "true") || | ||||
|                                          (value === true)); | ||||
|                                 return [{ | ||||
|                                     val: val | ||||
|                                 }, null]; | ||||
|                             } else if (type === "bool") { | ||||
|                                 const val = ((value === "true") || (value === true)); | ||||
|                                 return returnOrCallback(null, [{ val: val }, null]) | ||||
|                             } | ||||
|                             if (type === "cred") { | ||||
|                                 return [{ | ||||
|                                     val: value | ||||
|                                 }, null]; | ||||
|                                 return returnOrCallback(null, [{ val: value }, null]) | ||||
|                             } | ||||
|                             try { | ||||
|                                 var val = redUtil.evaluateNodeProperty(value, type, node, null, null); | ||||
|                                 return [{ | ||||
|                                     val: val | ||||
|                                 }, null]; | ||||
|                                 if (!callback) { | ||||
|                                     var val = redUtil.evaluateNodeProperty(value, type, node, null, null); | ||||
|                                     return [{ val: val }, null]; | ||||
|                                 } else { | ||||
|                                     redUtil.evaluateNodeProperty(value, type, node, null, (err, value) => { | ||||
|                                         return returnOrCallback(err, [{ val: value }, null]) | ||||
|                                     }); | ||||
|                                     return | ||||
|                                 } | ||||
|                             } | ||||
|                             catch (e) { | ||||
|                                 this.error(e); | ||||
|                                 return [null, null]; | ||||
|                                 if (!callback) { | ||||
|                                     this.error(e); | ||||
|                                 } | ||||
|                                 return returnOrCallback(e, null); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| @@ -494,27 +520,47 @@ class Flow { | ||||
|             } | ||||
|             if (group.g) { | ||||
|                 const parent = this.getGroupNode(group.g); | ||||
|                 return this.getGroupEnvSetting(node, parent, name); | ||||
|                 const gVal = this.getGroupEnvSetting(node, parent, name, callback); | ||||
|                 if (callback) { | ||||
|                     return; | ||||
|                 } | ||||
|                 return gVal; | ||||
|             } | ||||
|         } | ||||
|         return [null, name]; | ||||
|         return returnOrCallback(null, [null, name]); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Settings callback signature | ||||
|      * | ||||
|      * @callback SettingsCallback | ||||
|      * @param {Error} err The error object (or null) | ||||
|      * @param {Any} result The result of the callback | ||||
|      * @returns {void} | ||||
|      */ | ||||
|     /** | ||||
|      * Get a flow setting value. This currently automatically defers to the parent | ||||
|      * flow which, as defined in ./index.js returns `process.env[key]`. | ||||
|      * This lays the groundwork for Subflow to have instance-specific settings | ||||
|      * @param  {[type]} key [description] | ||||
|      * @return {[type]}     [description] | ||||
|      * @param  {String} key The settings key | ||||
|      * @param  {SettingsCallback} callback Optional callback function | ||||
|      * @return {Any} | ||||
|      */ | ||||
|     getSetting(key) { | ||||
|     getSetting(key, callback) { | ||||
|         /** @type {SettingsCallback} */ | ||||
|         const returnOrCallback = (err, result) => { | ||||
|             if (callback) { | ||||
|                 callback(err, result); | ||||
|                 return | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
|         const flow = this.flow; | ||||
|         if (key === "NR_FLOW_NAME") { | ||||
|             return flow.label; | ||||
|             return returnOrCallback(null, flow.label); | ||||
|         } | ||||
|         if (key === "NR_FLOW_ID") { | ||||
|             return flow.id; | ||||
|             return returnOrCallback(null, flow.id); | ||||
|         } | ||||
|         if (flow.credentials === undefined) { | ||||
|             flow.credentials = credentials.get(flow.id) || {}; | ||||
| @@ -544,15 +590,14 @@ class Flow { | ||||
|                         } | ||||
|                         try { | ||||
|                             if (type === "bool") { | ||||
|                                 const val = ((value === "true") || | ||||
|                                              (value === true)); | ||||
|                                 return val; | ||||
|                                 const val = ((value === "true") || (value === true)); | ||||
|                                 return returnOrCallback(null, val); | ||||
|                             } | ||||
|                             if (type === "cred") { | ||||
|                                 return value; | ||||
|                                 return returnOrCallback(null, value); | ||||
|                             } | ||||
|                             var val = redUtil.evaluateNodeProperty(value, type, null, null, null); | ||||
|                             return val; | ||||
|                             return returnOrCallback(null, val); | ||||
|                         } | ||||
|                         catch (e) { | ||||
|                             this.error(e); | ||||
| @@ -564,7 +609,11 @@ class Flow { | ||||
|                 key = key.substring(8); | ||||
|             } | ||||
|         } | ||||
|         return this.parent.getSetting(key); | ||||
|         const pVal = this.parent.getSetting(key, callback); | ||||
|         if (callback) { | ||||
|             return; | ||||
|         } | ||||
|         return pVal; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -780,7 +780,7 @@ const flowAPI = { | ||||
|     getNode: getNode, | ||||
|     handleError: () => false, | ||||
|     handleStatus: () => false, | ||||
|     getSetting: k => flowUtil.getEnvVar(k), | ||||
|     getSetting: (k, callback) => flowUtil.getEnvVar(k, callback), | ||||
|     log: m => log.log(m) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -308,16 +308,34 @@ module.exports = { | ||||
|             runtime.settings.envVarExcludes.forEach(v => envVarExcludes[v] = true); | ||||
|         } | ||||
|     }, | ||||
|     getEnvVar: function(k) { | ||||
|         if (!envVarExcludes[k]) { | ||||
|             const item = getGlobalEnv(k); | ||||
|     /** | ||||
|      * Get the value of an environment variable | ||||
|      * Call with a callback to get the value asynchronously | ||||
|      * or without to get the value synchronously | ||||
|      * @param {String} key The name of the environment variable | ||||
|      * @param {(err: Error, val: Any)} [callback] Optional callback for asynchronous call | ||||
|      * @returns {Any | void} The value of the environment variable or undefined if not found | ||||
|      */ | ||||
|     getEnvVar: function(key, callback) { | ||||
|         const returnOrCallback = function(err, val) { | ||||
|             if (callback) { | ||||
|                 callback(err, val); | ||||
|                 return; | ||||
|             } | ||||
|             return val; | ||||
|         } | ||||
|         if (!envVarExcludes[key]) { | ||||
|             const item = getGlobalEnv(key); | ||||
|             if (item) { | ||||
|                 const val = redUtil.evaluateNodeProperty(item.value, item.type, null, null, null); | ||||
|                 const val = redUtil.evaluateNodeProperty(item.value, item.type, null, null, callback); | ||||
|                 if (callback) { | ||||
|                     return; | ||||
|                 } | ||||
|                 return val; | ||||
|             } | ||||
|             return process.env[k]; | ||||
|             return returnOrCallback(null, process.env[key]); | ||||
|         } | ||||
|         return undefined; | ||||
|         return returnOrCallback(undefined); | ||||
|     }, | ||||
|     diffNodes: diffNodes, | ||||
|     mapEnvVarProperties: mapEnvVarProperties, | ||||
|   | ||||
							
								
								
									
										82
									
								
								packages/node_modules/@node-red/util/lib/util.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								packages/node_modules/@node-red/util/lib/util.js
									
									
									
									
										vendored
									
									
								
							| @@ -18,6 +18,7 @@ | ||||
| /** | ||||
|  * @mixin @node-red/util_util | ||||
|  */ | ||||
| /** @typedef {import('../../runtime/lib/flows/Flow.js').Flow} RuntimeLibFlowsFlow */ | ||||
|  | ||||
| const clonedeep = require("lodash.clonedeep"); | ||||
| const jsonata = require("jsonata"); | ||||
| @@ -526,37 +527,67 @@ function setObjectProperty(msg,prop,value,createMissing) { | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| /*! | ||||
| /** | ||||
|  * Get value of environment variable. | ||||
|  * @param {Node} node - accessing node | ||||
|  * @param {String} name - name of variable | ||||
|  * @param {RuntimeLibFlowsFlow} flow_ - (optional) flow to check for setting | ||||
|  * @param  {(err: Error, result: Any) => void} callback - (optional) called when the property is evaluated | ||||
|  * @return {String} value of env var | ||||
|  */ | ||||
| function getSetting(node, name, flow_) { | ||||
| function getSetting(node, name, flow_, callback) { | ||||
|     const returnOrCallback = (err, result) => { | ||||
|         if (callback) { | ||||
|             callback(err, result); | ||||
|             return | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     if (node) { | ||||
|         if (name === "NR_NODE_NAME") { | ||||
|             return node.name; | ||||
|             return returnOrCallback(null, node.name); | ||||
|         } | ||||
|         if (name === "NR_NODE_ID") { | ||||
|             return node.id; | ||||
|             return returnOrCallback(null, node.id); | ||||
|         } | ||||
|         if (name === "NR_NODE_PATH") { | ||||
|             return node._path; | ||||
|             return returnOrCallback(null, node._path); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @type {RuntimeLibFlowsFlow} */ | ||||
|     var flow = (flow_ ? flow_ : (node ? node._flow : null)); | ||||
|     if (flow) { | ||||
|         if (node && node.g) { | ||||
|             const group = flow.getGroupNode(node.g); | ||||
|             const [result, newName] = flow.getGroupEnvSetting(node, group, name); | ||||
|             if (result) { | ||||
|                 return result.val; | ||||
|             if (callback) { | ||||
|                 flow.getGroupEnvSetting(node, group, name, (e, [result, newName]) => { | ||||
|                     if (e) { | ||||
|                         callback(e); | ||||
|                         return | ||||
|                     } | ||||
|                     if (result) { | ||||
|                         callback(null, result.val); | ||||
|                     } | ||||
|                     name = newName; | ||||
|                     flow.getSetting(name, callback); | ||||
|                 }); | ||||
|                 return | ||||
|             } else { | ||||
|                 const [result, newName] = flow.getGroupEnvSetting(node, group, name); | ||||
|                 if (result) { | ||||
|                     return result.val; | ||||
|                 } | ||||
|                 name = newName; | ||||
|             } | ||||
|             name = newName; | ||||
|         } | ||||
|         return flow.getSetting(name); | ||||
|         const fVal = flow.getSetting(name, callback) | ||||
|         if (callback) { | ||||
|             return | ||||
|         } | ||||
|         return fVal; | ||||
|     } | ||||
|     return process.env[name]; | ||||
|     return returnOrCallback(null, process.env[name]); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -568,19 +599,34 @@ function getSetting(node, name, flow_) { | ||||
|  * will return `Hello Joe!`. | ||||
|  * @param  {String} value - the string to parse | ||||
|  * @param  {Node} node - the node evaluating the property | ||||
|  * @param  {(err: Error, result: Any) => void} callback - (optional) called when the property is evaluated | ||||
|  * @return {String} The parsed string | ||||
|  * @memberof @node-red/util_util | ||||
|  */ | ||||
| function evaluateEnvProperty(value, node) { | ||||
| function evaluateEnvProperty(value, node, callback) { | ||||
|     const returnOrCallback = (err, result) => { | ||||
|         if (callback) { | ||||
|             callback(err, result); | ||||
|             return | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     /** @type {RuntimeLibFlowsFlow}  */ | ||||
|     var flow = (node && hasOwnProperty.call(node, "_flow")) ? node._flow : null; | ||||
|     var result; | ||||
|     if (/^\${[^}]+}$/.test(value)) { | ||||
|         // ${ENV_VAR} | ||||
|         var name = value.substring(2,value.length-1); | ||||
|         result = getSetting(node, name, flow); | ||||
|         result = getSetting(node, name, flow, callback); | ||||
|         if (callback) { | ||||
|             return | ||||
|         } | ||||
|     } else if (!/\${\S+}/.test(value)) { | ||||
|         // ENV_VAR | ||||
|         result = getSetting(node, value, flow); | ||||
|         result = getSetting(node, value, flow, callback); | ||||
|         if (callback) { | ||||
|             return | ||||
|         } | ||||
|     } else { | ||||
|         // FOO${ENV_VAR}BAR | ||||
|         return value.replace(/\${([^}]+)}/g, function(match, name) { | ||||
| @@ -588,8 +634,7 @@ function evaluateEnvProperty(value, node) { | ||||
|             return (val === undefined)?"":val; | ||||
|         }); | ||||
|     } | ||||
|     return (result === undefined)?"":result; | ||||
|  | ||||
|     return returnOrCallback(null, (result === undefined)?"":result); | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -677,7 +722,10 @@ function evaluateNodeProperty(value, type, node, msg, callback) { | ||||
|             return | ||||
|         } | ||||
|     } else if (type === 'env') { | ||||
|         result = evaluateEnvProperty(value, node); | ||||
|         result = evaluateEnvProperty(value, node, callback); | ||||
|         if (callback) { | ||||
|             return | ||||
|         } | ||||
|     } | ||||
|     if (callback) { | ||||
|         callback(null,result); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user