Socket
Socket
Sign inDemoInstall

@node-red/runtime

Package Overview
Dependencies
7
Maintainers
2
Versions
107
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.20.0-beta.4 to 0.20.0-beta.5

89

lib/nodes/context/index.js

@@ -21,2 +21,3 @@ /**

var memory = require("./memory");
var flows;

@@ -51,2 +52,3 @@ var settings;

function init(_settings) {
flows = require("../flows");
settings = _settings;

@@ -203,4 +205,20 @@ contexts = {};

function followParentContext(parent, key) {
if (key === "$parent") {
return [parent, undefined];
}
else if (key.startsWith("$parent.")) {
var len = "$parent.".length;
var new_key = key.substring(len);
var ctx = parent;
while (ctx && new_key.startsWith("$parent.")) {
ctx = ctx.$parent;
new_key = new_key.substring(len);
}
return [ctx, new_key];
}
return null;
}
function createContext(id,seed) {
function createContext(id,seed,parent) {
// Seed is only set for global context - sourced from functionGlobalContext

@@ -260,2 +278,17 @@ var scope = id;

}
var result = followParentContext(parent, key);
if (result) {
var [ctx, new_key] = result;
if (ctx && new_key) {
return ctx.get(new_key, storage, callback);
}
else {
if (callback) {
return callback(undefined);
}
else {
return undefined;
}
}
}
} else {

@@ -328,2 +361,15 @@ if (!storage) {

}
var result = followParentContext(parent, key);
if (result) {
var [ctx, new_key] = result;
if (ctx && new_key) {
return ctx.set(new_key, value, storage, callback);
}
else {
if (callback) {
return callback();
}
return undefined;
}
}
} else {

@@ -369,6 +415,32 @@ if (!storage) {

});
if (parent) {
Object.defineProperty(obj, "$parent", {
value: parent
});
}
return obj;
}
function getContext(localId,flowId) {
function createRootContext() {
var obj = {};
Object.defineProperties(obj, {
get: {
value: function(key, storage, callback) {
return undefined;
}
},
set: {
value: function(key, value, storage, callback) {
}
},
keys: {
value: function(storage, callback) {
return undefined;
}
}
});
return obj;
}
function getContext(localId,flowId,parent) {
var contextId = localId;

@@ -381,6 +453,15 @@ if (flowId) {

}
var newContext = createContext(contextId);
var newContext = createContext(contextId,undefined,parent);
if (flowId) {
var node = flows.get(flowId);
var parent = undefined;
if (node && node.type.startsWith("subflow:")) {
parent = node.context().flow;
}
else {
parent = createRootContext();
}
var flowContext = getContext(flowId,undefined,parent);
Object.defineProperty(newContext, 'flow', {
value: getContext(flowId)
value: flowContext
});

@@ -387,0 +468,0 @@ }

@@ -215,2 +215,17 @@ /**

}
this.catchNodes.sort(function(A,B) {
if (A.scope && !B.scope) {
return -1;
} else if (!A.scope && B.scope) {
return 1;
} else if (A.scope && B.scope) {
return 0;
} else if (A.uncaught && !B.uncaught) {
return 1;
} else if (!A.uncaught && B.uncaught) {
return -1;
}
return 0;
});
if (activeCount > 0) {

@@ -269,3 +284,2 @@ this.trace("------------------|--------------|-----------------");

/**

@@ -286,7 +300,9 @@ * Update the flow definition. This doesn't change anything that is running.

* flow, pass the request up to the parent.
* @param {[type]} id [description]
* @param {String} id [description]
* @param {Boolean} cancelBubble if true, prevents the flow from passing the request to the parent
* This stops infinite loops when the parent asked this Flow for the
* node to begin with.
* @return {[type]} [description]
*/
getNode(id) {
// console.log('getNode',id,!!this.activeNodes[id])
getNode(id, cancelBubble) {
if (!id) {

@@ -304,3 +320,6 @@ return undefined;

}
return this.parent.getNode(id);
if (!cancelBubble) {
return this.parent.getNode(id);
}
return undefined;
}

@@ -422,2 +441,4 @@

} else {
var handledByUncaught = false;
this.catchNodes.forEach(function(targetCatchNode) {

@@ -427,2 +448,10 @@ if (targetCatchNode.scope && targetCatchNode.scope.indexOf(reportingNode.id) === -1) {

}
if (!targetCatchNode.scope && targetCatchNode.uncaught && !handledByUncaught) {
if (handled) {
// This has been handled by a !uncaught catch node
return;
}
// This is an uncaught error
handledByUncaught = true;
}
var errorMessage;

@@ -470,2 +499,3 @@ if (msg) {

}
}

@@ -472,0 +502,0 @@

4

lib/nodes/flows/index.js

@@ -210,7 +210,7 @@ /**

if (activeNodesToFlow[id] && activeFlows[activeNodesToFlow[id]]) {
return activeFlows[activeNodesToFlow[id]].getNode(id);
return activeFlows[activeNodesToFlow[id]].getNode(id,true);
}
for (var flowId in activeFlows) {
if (activeFlows.hasOwnProperty(flowId)) {
node = activeFlows[flowId].getNode(id);
node = activeFlows[flowId].getNode(id,true);
if (node) {

@@ -217,0 +217,0 @@ return node;

@@ -20,2 +20,4 @@ /**

const util = require("util");
const redUtil = require("@node-red/util").util;

@@ -26,2 +28,3 @@ const flowUtil = require("./util");

/**

@@ -42,3 +45,2 @@ * This class represents a subflow - which is handled as a special type of Flow

constructor(parent,globalFlow,subflowDef,subflowInstance) {
// console.log(subflowDef);
// console.log("CREATE SUBFLOW",subflowDef.id,subflowInstance.id);

@@ -96,2 +98,11 @@ // console.log("SubflowInstance\n"+JSON.stringify(subflowInstance," ",2));

this.node_map = node_map;
var env = [];
if (this.subflowDef.env) {
this.subflowDef.env.forEach(e => { env[e.name] = e; });
}
if (this.subflowInstance.env) {
this.subflowInstance.env.forEach(e => { env[e.name] = e; });
}
this.env = env;
}

@@ -111,2 +122,36 @@

var Node = require("../Node");
if (this.subflowDef.status) {
var subflowStatusConfig = {
id: this.subflowInstance.id+":status",
type: "subflow-status",
z: this.subflowInstance.id,
_flow: this.parent
}
this.statusNode = new Node(subflowStatusConfig);
this.statusNode.on("input", function(msg) {
if (msg.payload !== undefined) {
if (typeof msg.payload === "string") {
// if msg.payload is a String, use it as status text
self.node.status({text:msg.payload})
return;
} else if (Object.prototype.toString.call(msg.payload) === "[object Object]") {
if (msg.payload.hasOwnProperty('text') || msg.payload.hasOwnProperty('fill') || msg.payload.hasOwnProperty('shape') || Object.keys(msg.payload).length === 0) {
// msg.payload is an object that looks like a status object
self.node.status(msg.payload);
return;
}
}
// Anything else - inspect it and use as status text
var text = util.inspect(msg.payload);
if (text.length > 32) { text = text.substr(0,32) + "..."; }
self.node.status({text:text});
} else if (msg.status !== undefined) {
// if msg.status exists
self.node.status(msg.status)
}
})
}
var subflowInstanceConfig = {

@@ -172,11 +217,10 @@ id: this.subflowInstance.id,

}
}
};
// Wire the subflow outputs
if (this.subflowDef.out) {
var modifiedNodes = {};
for (var i=0;i<this.subflowDef.out.length;i++) {
// i: the output index
// This is what this Output is wired to
wires = this.subflowDef.out[i].wires;
var wires = this.subflowDef.out[i].wires;
for (var j=0;j<wires.length;j++) {

@@ -189,3 +233,2 @@ if (wires[j].id === this.subflowDef.id) {

var node = self.node_map[wires[j].id];
modifiedNodes[node.id] = node;
if (!node._originalWires) {

@@ -199,2 +242,22 @@ node._originalWires = clone(node.wires);

}
if (this.subflowDef.status) {
var subflowStatusId = this.statusNode.id;
wires = this.subflowDef.status.wires;
for (var j=0;j<wires.length;j++) {
if (wires[j].id === this.subflowDef.id) {
// A subflow input wired straight to a subflow output
subflowInstanceConfig.wires[wires[j].port].push(subflowStatusId);
this.node._updateWires(subflowInstanceConfig.wires);
} else {
var node = self.node_map[wires[j].id];
if (!node._originalWires) {
node._originalWires = clone(node.wires);
}
node.wires[wires[j].port] = (node.wires[wires[j].port]||[]);
node.wires[wires[j].port].push(subflowStatusId);
}
}
}
super.start(diff);

@@ -204,2 +267,45 @@ }

/**
* Get environment variable of subflow
* @param {String} name name of env var
* @return {Object} val value of env var
*/
getSetting(name) {
var env = this.env;
if (env && env.hasOwnProperty(name)) {
var val = env[name];
try {
var ret = redUtil.evaluateNodeProperty(val.value, val.type, this.node, null, null);
return ret;
}
catch (e) {
this.error(e);
return undefined;
}
}
var parent = this.parent;
if (parent) {
var val = parent.getSetting(name);
return val;
}
return undefined;
}
/**
* Get a node instance from this subflow.
* If the subflow has a status node, check for that, otherwise use
* the super-class function
* @param {String} id [description]
* @param {Boolean} cancelBubble if true, prevents the flow from passing the request to the parent
* This stops infinite loops when the parent asked this Flow for the
* node to begin with.
* @return {[type]} [description]
*/
getNode(id, cancelBubble) {
if (this.statusNode && this.statusNode.id === id) {
return this.statusNode;
}
return super.getNode(id,cancelBubble);
}
/**
* Handle a status event from a node within this flow.

@@ -217,6 +323,10 @@ * @param {Node} node The original node that triggered the event

if (!handled) {
// No status node on this subflow caught the status message.
// Pass up to the parent with this subflow's instance as the
// reporting node
handled = this.parent.handleStatus(node,statusMessage,this.node,true);
if (!this.statusNode || node === this.node) {
// No status node on this subflow caught the status message.
// AND there is no Subflow Status node - so the user isn't
// wanting to manage status messages themselves
// Pass up to the parent with this subflow's instance as the
// reporting node
handled = this.parent.handleStatus(node,statusMessage,this.node,true);
}
}

@@ -247,3 +357,2 @@ return handled;

}

@@ -250,0 +359,0 @@

@@ -41,3 +41,7 @@ /**

// the object (such as dashboard) will not like circular refs
Object.defineProperty(this,'_flow', {value: n._flow, })
// The value must still be writable in the case that a node does:
// Object.assign(this,config)
// as part of its constructure - config._flow will overwrite this._flow
// which we can tolerate as they are the same object.
Object.defineProperty(this,'_flow', {value: n._flow, enumerable: false, writable: true })
}

@@ -44,0 +48,0 @@ this.updateWires(n.wires);

{
"name": "@node-red/runtime",
"version": "0.20.0-beta.4",
"version": "0.20.0-beta.5",
"license": "Apache-2.0",

@@ -19,4 +19,4 @@ "main": "./lib/index.js",

"dependencies": {
"@node-red/registry": "0.20.0-beta.4",
"@node-red/util": "0.20.0-beta.4",
"@node-red/registry": "0.20.0-beta.5",
"@node-red/util": "0.20.0-beta.5",
"clone": "2.1.2",

@@ -23,0 +23,0 @@ "express": "4.16.4",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc