mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Added support for codefile
This commit is contained in:
		| @@ -6,10 +6,13 @@ To make a change to the node-red runtime being used by K4 avalanche: | |||||||
| 3. PR into this branch | 3. PR into this branch | ||||||
| 4. Merge on approval | 4. Merge on approval | ||||||
| 5. Manually bump the package version | 5. Manually bump the package version | ||||||
| 6. Run `npm run build` | 6. Run `npm run build` - note you need to run node 10 to do this, you also need to have xcode installed | ||||||
| 7. Manually publish to NPM with `npm publish` - Request creds from ops for this | 7. Manually publish to NPM with `npm publish` - Request creds from ops for this | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Dev Work | ||||||
|  | When doing dev work dont try to link into k4/k5 it just causes issue, instead just go into the node-modules of k4/k5 and make your changes in there | ||||||
|  |  | ||||||
| # CHANGE-LOG | # CHANGE-LOG | ||||||
|  |  | ||||||
| ## 0.18.7-patch-11 | ## 0.18.7-patch-11 | ||||||
|   | |||||||
| @@ -14,7 +14,8 @@ | |||||||
|  * limitations under the License. |  * limitations under the License. | ||||||
|  **/ |  **/ | ||||||
|  |  | ||||||
| const PayloadValidator = require('../../PayloadValidator') | const clone = require("clone"); | ||||||
|  | const PayloadValidator = require("../../PayloadValidator"); | ||||||
|  |  | ||||||
| module.exports = function (RED) { | module.exports = function (RED) { | ||||||
|   "use strict"; |   "use strict"; | ||||||
| @@ -36,15 +37,25 @@ module.exports = function(RED) { | |||||||
|         for (var n = 0; n < msgs[m].length; n++) { |         for (var n = 0; n < msgs[m].length; n++) { | ||||||
|           var msg = msgs[m][n]; |           var msg = msgs[m][n]; | ||||||
|           if (msg !== null && msg !== undefined) { |           if (msg !== null && msg !== undefined) { | ||||||
|                         if (typeof msg === 'object' && !Buffer.isBuffer(msg) && !util.isArray(msg)) { |             if ( | ||||||
|  |               typeof msg === "object" && | ||||||
|  |               !Buffer.isBuffer(msg) && | ||||||
|  |               !util.isArray(msg) | ||||||
|  |             ) { | ||||||
|               msg._msgid = _msgid; |               msg._msgid = _msgid; | ||||||
|               msgCount++; |               msgCount++; | ||||||
|             } else { |             } else { | ||||||
|               var type = typeof msg; |               var type = typeof msg; | ||||||
|                             if (type === 'object') { |               if (type === "object") { | ||||||
|                                 type = Buffer.isBuffer(msg)?'Buffer':(util.isArray(msg)?'Array':'Date'); |                 type = Buffer.isBuffer(msg) | ||||||
|  |                   ? "Buffer" | ||||||
|  |                   : util.isArray(msg) | ||||||
|  |                   ? "Array" | ||||||
|  |                   : "Date"; | ||||||
|               } |               } | ||||||
|                             node.error(RED._("function.error.non-message-returned",{ type: type })) |               node.error( | ||||||
|  |                 RED._("function.error.non-message-returned", { type: type }) | ||||||
|  |               ); | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @@ -60,7 +71,8 @@ module.exports = function(RED) { | |||||||
|     var node = this; |     var node = this; | ||||||
|     this.name = n.name; |     this.name = n.name; | ||||||
|     this.func = n.func; |     this.func = n.func; | ||||||
|         var functionText = "var results = null;"+ |     var functionText = | ||||||
|  |       "var results = null;" + | ||||||
|       "results = (function(msg){ " + |       "results = (function(msg){ " + | ||||||
|       "var __msgid__ = msg._msgid;" + |       "var __msgid__ = msg._msgid;" + | ||||||
|       "var node = {" + |       "var node = {" + | ||||||
| @@ -73,7 +85,8 @@ module.exports = function(RED) { | |||||||
|       "status:__node__.status," + |       "status:__node__.status," + | ||||||
|       "send:function(msgs){ __node__.send(__msgid__,msgs);}" + |       "send:function(msgs){ __node__.send(__msgid__,msgs);}" + | ||||||
|       "};\n" + |       "};\n" + | ||||||
|                               this.func+"\n"+ |       this.func + | ||||||
|  |       "\n" + | ||||||
|       "})(msg);"; |       "})(msg);"; | ||||||
|     this.topic = n.topic; |     this.topic = n.topic; | ||||||
|     this.outstandingTimers = []; |     this.outstandingTimers = []; | ||||||
| @@ -84,7 +97,7 @@ module.exports = function(RED) { | |||||||
|       //Buffer:Buffer, |       //Buffer:Buffer, | ||||||
|       //Date: Date, |       //Date: Date, | ||||||
|       RED: { |       RED: { | ||||||
|                 util: RED.util |         util: RED.util, | ||||||
|       }, |       }, | ||||||
|       __node__: { |       __node__: { | ||||||
|         log: function () { |         log: function () { | ||||||
| @@ -113,7 +126,7 @@ module.exports = function(RED) { | |||||||
|         }, |         }, | ||||||
|         status: function () { |         status: function () { | ||||||
|           node.status.apply(node, arguments); |           node.status.apply(node, arguments); | ||||||
|                 } |         }, | ||||||
|       }, |       }, | ||||||
|       context: { |       context: { | ||||||
|         set: function () { |         set: function () { | ||||||
| @@ -130,7 +143,7 @@ module.exports = function(RED) { | |||||||
|         }, |         }, | ||||||
|         get flow() { |         get flow() { | ||||||
|           return node.context().flow; |           return node.context().flow; | ||||||
|                 } |         }, | ||||||
|       }, |       }, | ||||||
|       flow: { |       flow: { | ||||||
|         set: function () { |         set: function () { | ||||||
| @@ -141,7 +154,7 @@ module.exports = function(RED) { | |||||||
|         }, |         }, | ||||||
|         keys: function () { |         keys: function () { | ||||||
|           return node.context().flow.keys.apply(node, arguments); |           return node.context().flow.keys.apply(node, arguments); | ||||||
|                 } |         }, | ||||||
|       }, |       }, | ||||||
|       // global: { |       // global: { | ||||||
|       //     set: function() { |       //     set: function() { | ||||||
| @@ -196,37 +209,116 @@ module.exports = function(RED) { | |||||||
|         if (index > -1) { |         if (index > -1) { | ||||||
|           node.outstandingIntervals.splice(index, 1); |           node.outstandingIntervals.splice(index, 1); | ||||||
|         } |         } | ||||||
|             } |       }, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|         if (util.hasOwnProperty('promisify')) { |     if (util.hasOwnProperty("promisify")) { | ||||||
|       sandbox.setTimeout[util.promisify.custom] = function (after, value) { |       sandbox.setTimeout[util.promisify.custom] = function (after, value) { | ||||||
|         return new Promise(function (resolve, reject) { |         return new Promise(function (resolve, reject) { | ||||||
|                     sandbox.setTimeout(function(){ resolve(value) }, after); |           sandbox.setTimeout(function () { | ||||||
|  |             resolve(value); | ||||||
|  |           }, after); | ||||||
|         }); |         }); | ||||||
|             } |       }; | ||||||
|     } |     } | ||||||
|     try { |     try { | ||||||
|             this.on("input", function(msg) { |       this.on("input", async function (msg) { | ||||||
|         try { |         try { | ||||||
|                     const payloadValidator = new PayloadValidator(msg, this.id) |           const originalMessage = clone(msg); | ||||||
|  |           const payloadValidator = new PayloadValidator(msg, this.id); | ||||||
|           var start = process.hrtime(); |           var start = process.hrtime(); | ||||||
|           sandbox.msg = msg; |           sandbox.msg = msg; | ||||||
|           const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 }); |           const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 }); | ||||||
|  |           const beforeVm2 = process.hrtime(); | ||||||
|           const result = vm2Instance.run(functionText); |           const result = vm2Instance.run(functionText); | ||||||
|                     payloadValidator.verify(result) |           const afterVm2 = process.hrtime(beforeVm2); | ||||||
|  |           payloadValidator.verify(result); | ||||||
|           sendResults(this, msg._msgid, result); |           sendResults(this, msg._msgid, result); | ||||||
|  |           const logger = clone(msg.logger); | ||||||
|  |           let lambdaRequestId; | ||||||
|  |           let { | ||||||
|  |             payload: { | ||||||
|  |               system: { organization }, | ||||||
|  |             }, | ||||||
|  |             event: { | ||||||
|  |               workers: [{ id: workerId }], | ||||||
|  |             }, | ||||||
|  |           } = originalMessage; | ||||||
|  |  | ||||||
|  |           const { | ||||||
|  |             settings: { | ||||||
|  |               api: { codefile = false } | ||||||
|  |             }, | ||||||
|  |           } = RED; | ||||||
|  |  | ||||||
|  |           if (codefile) { | ||||||
|  |             try { | ||||||
|  |               const messageToSend = clone(msg); | ||||||
|  |               delete messageToSend.logger; | ||||||
|  |  | ||||||
|  |               const beforeCodefile = process.hrtime(); | ||||||
|  |               const { | ||||||
|  |                 result: { | ||||||
|  |                   Result: { msg: responseMessage }, | ||||||
|  |                 }, | ||||||
|  |               } = await codefile.run({ srcCode: this.func, context: { msg } }); | ||||||
|  |               const afterCodefile = process.hrtime(beforeCodefile); | ||||||
|  |  | ||||||
|  |               responseMessage.logger = logger; | ||||||
|  |               payloadValidator.verify(responseMessage); | ||||||
|  |               // to make function node return result from code file uncomment this line, and comment out the sendResults above | ||||||
|  |               // sendResults(this,msg._msgid, responseMessage); | ||||||
|  |  | ||||||
|  |               workerId = workerId.split(":::")[0]; | ||||||
|  |               const nodeId = this.id.split(`${organization}-${workerId}-`)[1]; | ||||||
|  |               lambdaRequestId = responseMessage.lambdaRequestId; | ||||||
|  |               const metrics = { | ||||||
|  |                 lambdaRequestId: requestId, | ||||||
|  |                 organization, | ||||||
|  |                 workerId: workerId, | ||||||
|  |                 nodeId: nodeId, | ||||||
|  |                 rawCode: this.func, | ||||||
|  |                 vm2Runtime: `${ | ||||||
|  |                   Math.floor((afterVm2[0] * 1e9 + afterVm2[1]) / 10000) / 100 | ||||||
|  |                 }ms`, | ||||||
|  |                 codefileRuntime: `${ | ||||||
|  |                   Math.floor( | ||||||
|  |                     (afterCodefile[0] * 1e9 + afterCodefile[1]) / 10000 | ||||||
|  |                   ) / 100 | ||||||
|  |                 }ms`, | ||||||
|  |               }; | ||||||
|  |               logger.info(JSON.stringify(metrics, null, 2)); | ||||||
|  |             } catch (e) { | ||||||
|  |               logger.error({ | ||||||
|  |                 message: "Error running codefile", | ||||||
|  |                 error: e, | ||||||
|  |                 lambdaRequestId, | ||||||
|  |                 organization, | ||||||
|  |                 workerId: workerId, | ||||||
|  |                 nodeId: nodeId, | ||||||
|  |                 rawCode: this.func, | ||||||
|  |               }); | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           // sendResults(this,msg._msgid, responseMessage); | ||||||
|           var duration = process.hrtime(start); |           var duration = process.hrtime(start); | ||||||
|                     var converted = Math.floor((duration[0] * 1e9 + duration[1])/10000)/100; |           var converted = | ||||||
|  |             Math.floor((duration[0] * 1e9 + duration[1]) / 10000) / 100; | ||||||
|           this.metric("duration", msg, converted); |           this.metric("duration", msg, converted); | ||||||
|           if (process.env.NODE_RED_FUNCTION_TIME) { |           if (process.env.NODE_RED_FUNCTION_TIME) { | ||||||
|             this.status({ fill: "yellow", shape: "dot", text: "" + converted }); |             this.status({ fill: "yellow", shape: "dot", text: "" + converted }); | ||||||
|           } |           } | ||||||
|         } catch (err) { |         } catch (err) { | ||||||
|           //remove unwanted part |           //remove unwanted part | ||||||
|                     var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/); |           var index = err.stack.search( | ||||||
|                     err.stack = err.stack.slice(0, index).split('\n').slice(0,-1).join('\n'); |             /\n\s*at ContextifyScript.Script.runInContext/ | ||||||
|  |           ); | ||||||
|  |           err.stack = err.stack | ||||||
|  |             .slice(0, index) | ||||||
|  |             .split("\n") | ||||||
|  |             .slice(0, -1) | ||||||
|  |             .join("\n"); | ||||||
|           var stack = err.stack.split(/\r?\n/); |           var stack = err.stack.split(/\r?\n/); | ||||||
|  |  | ||||||
|           //store the error in msg to be used in flows |           //store the error in msg to be used in flows | ||||||
| @@ -236,7 +328,10 @@ module.exports = function(RED) { | |||||||
|           var errorMessage; |           var errorMessage; | ||||||
|           var stack = err.stack.split(/\r?\n/); |           var stack = err.stack.split(/\r?\n/); | ||||||
|           if (stack.length > 0) { |           if (stack.length > 0) { | ||||||
|                         while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) { |             while ( | ||||||
|  |               line < stack.length && | ||||||
|  |               stack[line].indexOf("ReferenceError") !== 0 | ||||||
|  |             ) { | ||||||
|               line++; |               line++; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -265,13 +360,13 @@ module.exports = function(RED) { | |||||||
|       }); |       }); | ||||||
|       this.on("close", function () { |       this.on("close", function () { | ||||||
|         while (node.outstandingTimers.length > 0) { |         while (node.outstandingTimers.length > 0) { | ||||||
|                     clearTimeout(node.outstandingTimers.pop()) |           clearTimeout(node.outstandingTimers.pop()); | ||||||
|         } |         } | ||||||
|         while (node.outstandingIntervals.length > 0) { |         while (node.outstandingIntervals.length > 0) { | ||||||
|                     clearInterval(node.outstandingIntervals.pop()) |           clearInterval(node.outstandingIntervals.pop()); | ||||||
|         } |         } | ||||||
|         this.status({}); |         this.status({}); | ||||||
|             }) |       }); | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|       // eg SyntaxError - which v8 doesn't include line number information |       // eg SyntaxError - which v8 doesn't include line number information | ||||||
|       // so we can't do better than this |       // so we can't do better than this | ||||||
| @@ -280,4 +375,4 @@ module.exports = function(RED) { | |||||||
|   } |   } | ||||||
|   RED.nodes.registerType("function", FunctionNode); |   RED.nodes.registerType("function", FunctionNode); | ||||||
|   RED.library.register("functions"); |   RED.library.register("functions"); | ||||||
| } | }; | ||||||
|   | |||||||
							
								
								
									
										1885
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1885
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -97,7 +97,7 @@ | |||||||
|     "grunt-jsonlint": "~1.1.0", |     "grunt-jsonlint": "~1.1.0", | ||||||
|     "grunt-mocha-istanbul": "5.0.2", |     "grunt-mocha-istanbul": "5.0.2", | ||||||
|     "grunt-nodemon": "~0.4.2", |     "grunt-nodemon": "~0.4.2", | ||||||
|     "grunt-sass": "~2.0.0", |     "grunt-sass": "^2.0.0", | ||||||
|     "grunt-simple-mocha": "~0.4.1", |     "grunt-simple-mocha": "~0.4.1", | ||||||
|     "grunt-webdriver": "^2.0.3", |     "grunt-webdriver": "^2.0.3", | ||||||
|     "http-proxy": "^1.16.2", |     "http-proxy": "^1.16.2", | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user