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 1.0.0-beta.2 to 1.0.0-beta.3

22

lib/api/context.js

@@ -70,3 +70,3 @@ /**

* @param {String} opts.key - the context key
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - the node information

@@ -85,3 +85,3 @@ * @memberof @node-red/runtime_context

if (store && availableStores.stores.indexOf(store) === -1) {
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"}, opts.req);
var err = new Error();

@@ -111,3 +111,3 @@ err.code = "not_found";

}
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key}, opts.req);
resolve(encoded);

@@ -133,3 +133,3 @@ });

errorReported = true;
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"unexpected_error"});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"unexpected_error"}, opts.req);
var err = new Error();

@@ -146,3 +146,3 @@ err.code = "unexpected_error";

if (!errorReported) {
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req);
resolve(result);

@@ -155,3 +155,3 @@ }

} else {
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key},opts.req);
resolve({});

@@ -170,3 +170,3 @@ }

* @param {String} opts.key - the context key
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - the node information

@@ -185,3 +185,3 @@ * @memberof @node-red/runtime_context

if (store && availableStores.stores.indexOf(store) === -1) {
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req);
var err = new Error();

@@ -207,3 +207,3 @@ err.code = "not_found";

ctx.set(key,undefined,store,function(err) {
runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key});
runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req);
resolve();

@@ -214,3 +214,3 @@ });

// TODO: support deleting whole context
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"});
runtime.log.audit({event: "context.get",scope:scope,id:id,store:store,key:key,error:"not_found"},opts.req);
var err = new Error();

@@ -256,3 +256,3 @@ err.code = "not_found";

} else {
runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key});
runtime.log.audit({event: "context.delete",scope:scope,id:id,store:store,key:key},opts.req);
resolve();

@@ -259,0 +259,0 @@ }

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

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Flows>} - the active flow configuration

@@ -52,3 +53,3 @@ * @memberof @node-red/runtime_flows

return new Promise(function(resolve,reject) {
runtime.log.audit({event: "flows.get"}/*,req*/);
runtime.log.audit({event: "flows.get"}, opts.req);
return resolve(runtime.nodes.getFlows());

@@ -61,2 +62,3 @@ });

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Flows>} - the active flow configuration

@@ -70,3 +72,3 @@ * @memberof @node-red/runtime_flows

var deploymentType = opts.deploymentType||"full";
runtime.log.audit({event: "flows.set",type:deploymentType}/*,req*/);
runtime.log.audit({event: "flows.set",type:deploymentType}, opts.req);

@@ -105,2 +107,3 @@ var apiPromise;

* @param {Object} opts.flow - the flow to add
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the id of the added flow

@@ -113,6 +116,6 @@ * @memberof @node-red/runtime_flows

runtime.nodes.addFlow(flow).then(function(id) {
runtime.log.audit({event: "flow.add",id:id});
runtime.log.audit({event: "flow.add",id:id}, opts.req);
return resolve(id);
}).catch(function(err) {
runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "flow.add",error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -131,2 +134,3 @@ return reject(err);

* @param {Object} opts.id - the id of the flow to retrieve
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Flow>} - the active flow configuration

@@ -139,6 +143,6 @@ * @memberof @node-red/runtime_flows

if (flow) {
runtime.log.audit({event: "flow.get",id:opts.id});
runtime.log.audit({event: "flow.get",id:opts.id}, opts.req);
return resolve(flow);
} else {
runtime.log.audit({event: "flow.get",id:opts.id,error:"not_found"});
runtime.log.audit({event: "flow.get",id:opts.id,error:"not_found"}, opts.req);
var err = new Error();

@@ -158,2 +162,3 @@ err.code = "not_found";

* @param {Object} opts.flow - the flow configuration
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the id of the updated flow

@@ -168,6 +173,6 @@ * @memberof @node-red/runtime_flows

runtime.nodes.updateFlow(id,flow).then(function() {
runtime.log.audit({event: "flow.update",id:id});
runtime.log.audit({event: "flow.update",id:id}, opts.req);
return resolve(id);
}).catch(function(err) {
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -178,3 +183,3 @@ return reject(err);

if (err.code === 404) {
runtime.log.audit({event: "flow.update",id:id,error:"not_found"});
runtime.log.audit({event: "flow.update",id:id,error:"not_found"}, opts.req);
// TODO: this swap around of .code and .status isn't ideal

@@ -185,3 +190,3 @@ err.status = 404;

} else {
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "flow.update",error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -199,2 +204,3 @@ return reject(err);

* @param {Object} opts.id - the id of the flow to delete
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - resolves if successful

@@ -208,6 +214,6 @@ * @memberof @node-red/runtime_flows

runtime.nodes.removeFlow(id).then(function() {
runtime.log.audit({event: "flow.remove",id:id});
runtime.log.audit({event: "flow.remove",id:id}, opts.req);
return resolve();
}).catch(function(err) {
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -218,3 +224,3 @@ return reject(err);

if (err.code === 404) {
runtime.log.audit({event: "flow.remove",id:id,error:"not_found"});
runtime.log.audit({event: "flow.remove",id:id,error:"not_found"}, opts.req);
// TODO: this swap around of .code and .status isn't ideal

@@ -225,3 +231,3 @@ err.status = 404;

} else {
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "flow.remove",id:id,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -240,2 +246,3 @@ return reject(err);

* @param {String} opts.id - the node id
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the safe credentials

@@ -246,3 +253,3 @@ * @memberof @node-red/runtime_flows

return new Promise(function(resolve,reject) {
runtime.log.audit({event: "credentials.get",type:opts.type,id:opts.id});
runtime.log.audit({event: "credentials.get",type:opts.type,id:opts.id}, opts.req);
var credentials = runtime.nodes.getCredentials(opts.id);

@@ -249,0 +256,0 @@ if (!credentials) {

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

* @param {String} opts.path - the path of the entry
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String|Object>} - resolves when complete

@@ -42,3 +43,3 @@ * @memberof @node-red/runtime_library

runtime.library.getEntry(opts.library,opts.type,opts.path).then(function(result) {
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path});
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path}, opts.req);
return resolve(result);

@@ -56,6 +57,6 @@ }).catch(function(err) {

}
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path,error:err.code});
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,path:opts.path,error:err.code}, opts.req);
return reject(err);
}
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,error:"not_found"});
runtime.log.audit({event: "library.get",library:opts.library,type:opts.type,error:"not_found"}, opts.req);
var error = new Error();

@@ -78,2 +79,3 @@ error.code = "not_found";

* @param {String} opts.body - the body of the entry
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - resolves when complete

@@ -85,3 +87,3 @@ * @memberof @node-red/runtime_library

runtime.library.saveEntry(opts.library,opts.type,opts.path,opts.meta,opts.body).then(function() {
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path});
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path}, opts.req);
return resolve();

@@ -91,7 +93,7 @@ }).catch(function(err) {

if (err.code === 'forbidden') {
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"forbidden"});
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"forbidden"}, opts.req);
err.status = 403;
return reject(err);
}
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"unexpected_error",message:err.toString()});
runtime.log.audit({event: "library.set",type:opts.type,path:opts.path,error:"unexpected_error",message:err.toString()}, opts.req);
var error = new Error();

@@ -98,0 +100,0 @@ error.status = 400;

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

* @param {String} opts.id - the id of the node set to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<NodeInfo>} - the node information

@@ -60,7 +61,7 @@ * @memberof @node-red/runtime_nodes

if (result) {
runtime.log.audit({event: "nodes.info.get",id:id});
runtime.log.audit({event: "nodes.info.get",id:id}, opts.req);
delete result.loaded;
return resolve(result);
} else {
runtime.log.audit({event: "nodes.info.get",id:id,error:"not_found"});
runtime.log.audit({event: "nodes.info.get",id:id,error:"not_found"}, opts.req);
var err = new Error();

@@ -78,2 +79,3 @@ err.code = "not_found";

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<NodeList>} - the list of node modules

@@ -84,3 +86,3 @@ * @memberof @node-red/runtime_nodes

return new Promise(function(resolve,reject) {
runtime.log.audit({event: "nodes.list.get"});
runtime.log.audit({event: "nodes.list.get"}, opts.req);
return resolve(runtime.nodes.getNodeList());

@@ -96,2 +98,3 @@ })

* @param {String} opts.lang - the locale language to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the node html content

@@ -106,6 +109,6 @@ * @memberof @node-red/runtime_nodes

if (result) {
runtime.log.audit({event: "nodes.config.get",id:id});
runtime.log.audit({event: "nodes.config.get",id:id}, opts.req);
return resolve(result);
} else {
runtime.log.audit({event: "nodes.config.get",id:id,error:"not_found"});
runtime.log.audit({event: "nodes.config.get",id:id,error:"not_found"}, opts.req);
var err = new Error();

@@ -123,2 +126,3 @@ err.code = "not_found";

* @param {String} opts.lang - the locale language to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the node html content

@@ -129,3 +133,3 @@ * @memberof @node-red/runtime_nodes

return new Promise(function(resolve,reject) {
runtime.log.audit({event: "nodes.configs.get"});
runtime.log.audit({event: "nodes.configs.get"}, opts.req);
return resolve(runtime.nodes.getNodeConfigs(opts.lang));

@@ -140,2 +144,3 @@ });

* @param {String} opts.module - the id of the module to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<ModuleInfo>} - the node module info

@@ -148,6 +153,6 @@ * @memberof @node-red/runtime_nodes

if (result) {
runtime.log.audit({event: "nodes.module.get",id:opts.module});
runtime.log.audit({event: "nodes.module.get",id:opts.module}, opts.req);
return resolve(result);
} else {
runtime.log.audit({event: "nodes.module.get",id:opts.module,error:"not_found"});
runtime.log.audit({event: "nodes.module.get",id:opts.module,error:"not_found"}, opts.req);
var err = new Error();

@@ -167,2 +172,3 @@ err.code = "not_found";

* @param {String} opts.version - (optional) the version of the module to install
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<ModuleInfo>} - the node module info

@@ -174,3 +180,3 @@ * @memberof @node-red/runtime_nodes

if (!runtime.settings.available()) {
runtime.log.audit({event: "nodes.install",error:"settings_unavailable"});
runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req);
var err = new Error("Settings unavailable");

@@ -185,3 +191,3 @@ err.code = "settings_unavailable";

if (!opts.version || existingModule.version === opts.version) {
runtime.log.audit({event: "nodes.install",module:opts.module, version:opts.version, error:"module_already_loaded"});
runtime.log.audit({event: "nodes.install",module:opts.module, version:opts.version, error:"module_already_loaded"}, opts.req);
var err = new Error("Module already loaded");

@@ -194,7 +200,7 @@ err.code = "module_already_loaded";

runtime.nodes.installModule(opts.module,opts.version).then(function(info) {
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version});
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version}, opts.req);
return resolve(info);
}).catch(function(err) {
if (err.code === 404) {
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"});
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:"not_found"}, opts.req);
// TODO: code/status

@@ -204,6 +210,6 @@ err.status = 404;

err.status = 400;
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code});
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code}, opts.req);
} else {
err.status = 400;
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "nodes.install",module:opts.module,version:opts.version,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
}

@@ -213,3 +219,3 @@ return reject(err);

} else {
runtime.log.audit({event: "nodes.install",module:opts.module,error:"invalid_request"});
runtime.log.audit({event: "nodes.install",module:opts.module,error:"invalid_request"}, opts.req);
var err = new Error("Invalid request");

@@ -228,2 +234,3 @@ err.code = "invalid_request";

* @param {String} opts.module - the id of the module to remove
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - resolves when complete

@@ -235,3 +242,3 @@ * @memberof @node-red/runtime_nodes

if (!runtime.settings.available()) {
runtime.log.audit({event: "nodes.install",error:"settings_unavailable"});
runtime.log.audit({event: "nodes.install",error:"settings_unavailable"}, opts.req);
var err = new Error("Settings unavailable");

@@ -244,3 +251,3 @@ err.code = "settings_unavailable";

if (!module) {
runtime.log.audit({event: "nodes.remove",module:opts.module,error:"not_found"});
runtime.log.audit({event: "nodes.remove",module:opts.module,error:"not_found"}, opts.req);
var err = new Error();

@@ -253,11 +260,11 @@ err.code = "not_found";

runtime.nodes.uninstallModule(opts.module).then(function() {
runtime.log.audit({event: "nodes.remove",module:opts.module});
runtime.log.audit({event: "nodes.remove",module:opts.module}, opts.req);
resolve();
}).catch(function(err) {
err.status = 400;
runtime.log.audit({event: "nodes.remove",module:opts.module,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "nodes.remove",module:opts.module,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
return reject(err);
})
} catch(error) {
runtime.log.audit({event: "nodes.remove",module:opts.module,error:error.code||"unexpected_error",message:error.toString()});
runtime.log.audit({event: "nodes.remove",module:opts.module,error:error.code||"unexpected_error",message:error.toString()}, opts.req);
error.status = 400;

@@ -275,2 +282,3 @@ return reject(error);

* @param {String} opts.enabled - whether the module should be enabled or disabled
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<ModuleInfo>} - the module info object

@@ -283,3 +291,3 @@ * @memberof @node-red/runtime_nodes

if (!runtime.settings.available()) {
runtime.log.audit({event: "nodes.module.set",error:"settings_unavailable"});
runtime.log.audit({event: "nodes.module.set",error:"settings_unavailable"}, opts.req);
var err = new Error("Settings unavailable");

@@ -293,3 +301,3 @@ err.code = "settings_unavailable";

if (!module) {
runtime.log.audit({event: "nodes.module.set",module:mod,error:"not_found"});
runtime.log.audit({event: "nodes.module.set",module:mod,error:"not_found"}, opts.req);
var err = new Error();

@@ -313,3 +321,3 @@ err.code = "not_found";

} catch(error) {
runtime.log.audit({event: "nodes.module.set",module:mod,enabled:opts.enabled,error:error.code||"unexpected_error",message:error.toString()});
runtime.log.audit({event: "nodes.module.set",module:mod,enabled:opts.enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req);
error.status = 400;

@@ -327,2 +335,3 @@ return reject(error);

* @param {String} opts.enabled - whether the module should be enabled or disabled
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<ModuleInfo>} - the module info object

@@ -334,3 +343,3 @@ * @memberof @node-red/runtime_nodes

if (!runtime.settings.available()) {
runtime.log.audit({event: "nodes.info.set",error:"settings_unavailable"});
runtime.log.audit({event: "nodes.info.set",error:"settings_unavailable"}, opts.req);
var err = new Error("Settings unavailable");

@@ -347,3 +356,3 @@ err.code = "settings_unavailable";

if (!node) {
runtime.log.audit({event: "nodes.info.set",id:id,error:"not_found"});
runtime.log.audit({event: "nodes.info.set",id:id,error:"not_found"}, opts.req);
var err = new Error();

@@ -356,6 +365,6 @@ err.code = "not_found";

putNode(node,enabled).then(function(result) {
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled});
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled}, opts.req);
return resolve(result);
}).catch(function(err) {
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -366,3 +375,3 @@ return reject(err);

} catch(error) {
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:error.code||"unexpected_error",message:error.toString()});
runtime.log.audit({event: "nodes.info.set",id:id,enabled:enabled,error:error.code||"unexpected_error",message:error.toString()}, opts.req);
error.status = 400;

@@ -379,2 +388,3 @@ return reject(error);

* @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US)
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the message catalogs

@@ -409,2 +419,3 @@ * @memberof @node-red/runtime_nodes

* @param {User} opts.lang - the i18n language to return. If not set, uses runtime default (en-US)
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the message catalog

@@ -431,2 +442,3 @@ * @memberof @node-red/runtime_nodes

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<IconList>} - the list of all icons

@@ -437,3 +449,3 @@ * @memberof @node-red/runtime_nodes

return new Promise(function(resolve,reject) {
runtime.log.audit({event: "nodes.icons.get"});
runtime.log.audit({event: "nodes.icons.get"}, opts.req);
return resolve(runtime.nodes.getNodeIcons());

@@ -449,2 +461,3 @@ });

* @param {String} opts.icon - the name of the icon
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Buffer>} - the icon file as a Buffer or null if no icon available

@@ -451,0 +464,0 @@ * @memberof @node-red/runtime_nodes

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

},
/**

@@ -36,2 +35,4 @@ * List projects known to the runtime

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -61,2 +62,3 @@ * @memberof @node-red/runtime_projects

* @param {Object} opts.project - the project information
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -66,2 +68,3 @@ * @memberof @node-red/runtime_projects

createProject: function(opts) {
runtime.log.audit({event: "projects.create",name:opts.project?opts.project.name:"missing-name"}, opts.req);
return runtime.storage.projects.createProject(opts.user, opts.project)

@@ -76,2 +79,3 @@ },

* @param {Object} opts.project - the project information
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -82,2 +86,3 @@ * @memberof @node-red/runtime_projects

// Initialised set when creating default files for an empty repo
runtime.log.audit({event: "projects.initialise",id:opts.id}, opts.req);
return runtime.storage.projects.initialiseProject(opts.user, opts.id, opts.project)

@@ -90,2 +95,3 @@ },

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the active project

@@ -103,2 +109,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.id - the id of the project to activate
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -109,2 +116,3 @@ * @memberof @node-red/runtime_projects

var currentProject = runtime.storage.projects.getActiveProject(opts.user);
runtime.log.audit({event: "projects.set",id:opts.id}, opts.req);
if (!currentProject || opts.id !== currentProject.name) {

@@ -122,2 +130,3 @@ return runtime.storage.projects.setActiveProject(opts.user, opts.id);

* @param {String} opts.id - the id of the project to get
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the project metadata

@@ -136,2 +145,3 @@ * @memberof @node-red/runtime_projects

* @param {Object} opts.project - the project information
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -141,2 +151,3 @@ * @memberof @node-red/runtime_projects

updateProject: function(opts) {
runtime.log.audit({event: "projects.update",id:opts.id}, opts.req);
return runtime.storage.projects.updateProject(opts.user, opts.id, opts.project);

@@ -150,2 +161,3 @@ },

* @param {String} opts.id - the id of the project to update
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -155,2 +167,3 @@ * @memberof @node-red/runtime_projects

deleteProject: function(opts) {
runtime.log.audit({event: "projects.delete",id:opts.id}, opts.req);
return runtime.storage.projects.deleteProject(opts.user, opts.id);

@@ -165,2 +178,3 @@ },

* @param {Boolean} opts.remote - whether to include status of remote repos
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the project status

@@ -179,2 +193,3 @@ * @memberof @node-red/runtime_projects

* @param {Boolean} opts.remote - whether to return remote branches (true) or local (false)
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - a list of the local branches

@@ -193,2 +208,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.branch - the name of the branch
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the status of the branch

@@ -208,2 +224,3 @@ * @memberof @node-red/runtime_projects

* @param {Boolean} opts.create - whether to create the branch if it doesn't exist
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -213,2 +230,3 @@ * @memberof @node-red/runtime_projects

setBranch: function(opts) {
runtime.log.audit({event: "projects.branch.set",id:opts.id, branch: opts.branch, create:opts.create}, opts.req);
return runtime.storage.projects.setBranch(opts.user, opts.id, opts.branch, opts.create)

@@ -224,2 +242,3 @@ },

* @param {Boolean} opts.force - whether to force delete
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -229,2 +248,3 @@ * @memberof @node-red/runtime_projects

deleteBranch: function(opts) {
runtime.log.audit({event: "projects.branch.delete",id:opts.id, branch: opts.branch, force:opts.force}, opts.req);
return runtime.storage.projects.deleteBranch(opts.user, opts.id, opts.branch, false, opts.force);

@@ -239,2 +259,3 @@ },

* @param {String} opts.message - the message to associate with the commit
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -244,2 +265,3 @@ * @memberof @node-red/runtime_projects

commit: function(opts) {
runtime.log.audit({event: "projects.commit",id:opts.id}, opts.req);
return runtime.storage.projects.commit(opts.user, opts.id,{message: opts.message});

@@ -254,2 +276,3 @@ },

* @param {String} opts.sha - the sha of the commit to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the commit details

@@ -269,2 +292,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.before - id of the commit to work back from
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Array>} - an array of commits

@@ -285,2 +309,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.id - the id of the project
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -290,2 +315,3 @@ * @memberof @node-red/runtime_projects

abortMerge: function(opts) {
runtime.log.audit({event: "projects.merge.abort",id:opts.id}, opts.req);
return runtime.storage.projects.abortMerge(opts.user, opts.id);

@@ -301,2 +327,3 @@ },

* @param {String} opts.resolutions - how to resolve the merge conflict
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -306,2 +333,3 @@ * @memberof @node-red/runtime_projects

resolveMerge: function(opts) {
runtime.log.audit({event: "projects.merge.resolve",id:opts.id, file:opts.path}, opts.req);
return runtime.storage.projects.resolveMerge(opts.user, opts.id, opts.path, opts.resolution);

@@ -315,2 +343,3 @@ },

* @param {String} opts.id - the id of the project
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the file listing

@@ -330,2 +359,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.tree - the version control tree to use
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the content of the file

@@ -344,2 +374,3 @@ * @memberof @node-red/runtime_projects

* @param {String|Array} opts.path - the path of the file, or an array of paths
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -349,2 +380,3 @@ * @memberof @node-red/runtime_projects

stageFile: function(opts) {
runtime.log.audit({event: "projects.file.stage",id:opts.id, file:opts.path}, opts.req);
return runtime.storage.projects.stageFile(opts.user, opts.id, opts.path);

@@ -359,2 +391,3 @@ },

* @param {String} opts.path - the path of the file. If not set, all staged files are unstaged
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -364,2 +397,3 @@ * @memberof @node-red/runtime_projects

unstageFile: function(opts) {
runtime.log.audit({event: "projects.file.unstage",id:opts.id, file:opts.path}, opts.req);
return runtime.storage.projects.unstageFile(opts.user, opts.id, opts.path);

@@ -374,2 +408,3 @@ },

* @param {String} opts.path - the path of the file
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -379,2 +414,3 @@ * @memberof @node-red/runtime_projects

revertFile: function(opts) {
runtime.log.audit({event: "projects.file.revert",id:opts.id, file:opts.path}, opts.req);
return runtime.storage.projects.revertFile(opts.user, opts.id,opts.path)

@@ -390,2 +426,3 @@ },

* @param {String} opts.type - the type of diff
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the requested diff

@@ -403,2 +440,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.id - the id of the project
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - a list of project remotes

@@ -420,2 +458,3 @@ * @memberof @node-red/runtime_projects

* @param {String} opts.remote.url - the url of the remote
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -425,2 +464,3 @@ * @memberof @node-red/runtime_projects

addRemote: function(opts) {
runtime.log.audit({event: "projects.remote.add",id:opts.id, remote:opts.remote.name}, opts.req);
return runtime.storage.projects.addRemote(opts.user, opts.id, opts.remote)

@@ -435,2 +475,3 @@ },

* @param {String} opts.remote - the name of the remote
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -440,2 +481,3 @@ * @memberof @node-red/runtime_projects

removeRemote: function(opts) {
runtime.log.audit({event: "projects.remote.delete",id:opts.id, remote:opts.remote}, opts.req);
return runtime.storage.projects.removeRemote(opts.user, opts.id, opts.remote);

@@ -451,2 +493,3 @@ },

* @param {String} opts.remote.name - the name of the remote
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -456,2 +499,3 @@ * @memberof @node-red/runtime_projects

updateRemote: function(opts) {
runtime.log.audit({event: "projects.remote.update",id:opts.id, remote:opts.remote.name}, opts.req);
return runtime.storage.projects.updateRemote(opts.user, opts.id, opts.remote.name, opts.remote)

@@ -464,2 +508,6 @@ },

* @param {User} opts.user - the user calling the api
* @param {String} opts.remote - the remote to pull
* @param {Boolean} opts.track - whether to track this remote
* @param {Boolean} opts.allowUnrelatedHistories -
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -469,2 +517,3 @@ * @memberof @node-red/runtime_projects

pull: function(opts) {
runtime.log.audit({event: "projects.pull",id:opts.id, remote: opts.remote, track:opts.track}, opts.req);
return runtime.storage.projects.pull(opts.user, opts.id, opts.remote, opts.track, opts.allowUnrelatedHistories);

@@ -480,2 +529,3 @@ },

* @param {String} opts.track - whether to set the remote as the upstream
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - resolves when complete

@@ -485,2 +535,3 @@ * @memberof @node-red/runtime_projects

push: function(opts) {
runtime.log.audit({event: "projects.push",id:opts.id, remote: opts.remote, track:opts.track}, opts.req);
return runtime.storage.projects.push(opts.user, opts.id, opts.remote, opts.track);

@@ -487,0 +538,0 @@ }

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

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the runtime settings

@@ -129,2 +130,3 @@ * @memberof @node-red/runtime_settings

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the user settings

@@ -148,2 +150,3 @@ * @memberof @node-red/runtime_settings

* @param {Object} opts.settings - the updates to the user settings
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the user settings

@@ -164,6 +167,6 @@ * @memberof @node-red/runtime_settings

runtime.settings.setUserSettings(username, currentSettings).then(function() {
runtime.log.audit({event: "settings.update",username:username});
runtime.log.audit({event: "settings.update",username:username}, opts.req);
return resolve();
}).catch(function(err) {
runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -174,3 +177,3 @@ return reject(err);

runtime.log.warn(runtime.log._("settings.user-not-available",{message:runtime.log._("settings.not-available")}));
runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()});
runtime.log.audit({event: "settings.update",username:username,error:err.code||"unexpected_error",message:err.toString()}, opts.req);
err.status = 400;

@@ -186,2 +189,3 @@ return reject(err);

* @param {User} opts.user - the user calling the api
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<Object>} - the user's ssh keys

@@ -207,2 +211,3 @@ * @memberof @node-red/runtime_settings

* @param {User} opts.id - the id of the key to return
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the user's ssh public key

@@ -239,2 +244,3 @@ * @memberof @node-red/runtime_settings

* @param {User} opts.size - (optional) the size of the key. Default: 2048
* @param {Object} opts.req - the request to log (optional)
* @return {Promise<String>} - the id of the generated key

@@ -260,2 +266,3 @@ * @memberof @node-red/runtime_settings

* @param {User} opts.id - the id of the key to delete
* @param {Object} opts.req - the request to log (optional)
* @return {Promise} - resolves when deleted

@@ -262,0 +269,0 @@ * @memberof @node-red/runtime_settings

@@ -132,3 +132,3 @@ /*!

log.error("*****************************************************************");
log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=4"})+" *");
log.error("* "+log._("runtime.unsupported_version",{component:"Node.js",version:process.version,requires: ">=8.9.0"})+" *");
log.error("*****************************************************************");

@@ -135,0 +135,0 @@ events.emit("runtime-event",{id:"runtime-unsupported-version",payload:{type:"error",text:"notification.errors.unsupportedVersion"},retain:true});

@@ -26,3 +26,3 @@ /**

function getEntry(type,path) {
var examples = runtime.nodes.getNodeExampleFlows();
var examples = runtime.nodes.getNodeExampleFlows()||{};
var result = [];

@@ -29,0 +29,0 @@ if (path === "") {

@@ -237,3 +237,3 @@ /**

}
value[0] = undefined;
values[0] = undefined;
}

@@ -250,3 +250,3 @@ }

}
value[i] = undefined;
values[i] = undefined;
}

@@ -253,0 +253,0 @@ }

@@ -140,2 +140,12 @@ /**

function writeFileAtomic(storagePath, content) {
// To protect against file corruption, write to a tmp file first and then
// rename to the destination file
let finalFile = storagePath + ".json";
let tmpFile = finalFile + "."+Date.now()+".tmp";
return fs.outputFile(tmpFile, content, "utf8").then(function() {
return fs.rename(tmpFile,finalFile);
})
}
function LocalFileSystem(config){

@@ -206,3 +216,3 @@ this.config = config;

log.debug("Flushing localfilesystem context scope "+scope);
promises.push(fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8"));
promises.push(writeFileAtomic(storagePath, stringifiedContext.json))
});

@@ -324,3 +334,3 @@ delete self._pendingWriteTimeout;

}
return fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8");
return writeFileAtomic(storagePath, stringifiedContext.json);
}).then(function(){

@@ -327,0 +337,0 @@ if(typeof callback === "function"){

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

var nodeCloseTimeout = 15000;
var asyncMessageDelivery = true;

@@ -129,2 +130,3 @@ /**

this.statusNodes = [];
this.completeNodeMap = {};

@@ -137,25 +139,35 @@ var configNodes = Object.keys(this.flow.configs);

if (!this.activeNodes[id]) {
var readyToCreate = true;
// This node doesn't exist.
// Check it doesn't reference another non-existent config node
for (var prop in node) {
if (node.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== '_users' && this.flow.configs[node[prop]]) {
if (!this.activeNodes[node[prop]]) {
// References a non-existent config node
// Add it to the back of the list to try again later
configNodes.push(id);
configNodeAttempts[id] = (configNodeAttempts[id]||0)+1;
if (configNodeAttempts[id] === 100) {
throw new Error("Circular config node dependency detected: "+id);
if (node.d !== true) {
var readyToCreate = true;
// This node doesn't exist.
// Check it doesn't reference another non-existent config node
for (var prop in node) {
if (node.hasOwnProperty(prop) &&
prop !== 'id' &&
prop !== 'wires' &&
prop !== '_users' &&
this.flow.configs[node[prop]] &&
this.flow.configs[node[prop]].d !== true
) {
if (!this.activeNodes[node[prop]]) {
// References a non-existent config node
// Add it to the back of the list to try again later
configNodes.push(id);
configNodeAttempts[id] = (configNodeAttempts[id]||0)+1;
if (configNodeAttempts[id] === 100) {
throw new Error("Circular config node dependency detected: "+id);
}
readyToCreate = false;
break;
}
readyToCreate = false;
break;
}
}
}
if (readyToCreate) {
newNode = flowUtil.createNode(this,node);
if (newNode) {
this.activeNodes[id] = newNode;
if (readyToCreate) {
newNode = flowUtil.createNode(this,node);
if (newNode) {
this.activeNodes[id] = newNode;
}
}
} else {
this.debug("not starting disabled config node : "+id);
}

@@ -177,35 +189,39 @@ }

node = this.flow.nodes[id];
if (!node.subflow) {
if (!this.activeNodes[id]) {
newNode = flowUtil.createNode(this,node);
if (newNode) {
this.activeNodes[id] = newNode;
if (node.d !== true) {
if (!node.subflow) {
if (!this.activeNodes[id]) {
newNode = flowUtil.createNode(this,node);
if (newNode) {
this.activeNodes[id] = newNode;
}
}
}
} else {
if (!this.subflowInstanceNodes[id]) {
try {
var subflowDefinition = this.flow.subflows[node.subflow]||this.global.subflows[node.subflow]
// console.log("NEED TO CREATE A SUBFLOW",id,node.subflow);
this.subflowInstanceNodes[id] = true;
var subflow = Subflow.create(
this,
this.global,
subflowDefinition,
node
);
this.subflowInstanceNodes[id] = subflow;
subflow.start();
this.activeNodes[id] = subflow.node;
} else {
if (!this.subflowInstanceNodes[id]) {
try {
var subflowDefinition = this.flow.subflows[node.subflow]||this.global.subflows[node.subflow]
// console.log("NEED TO CREATE A SUBFLOW",id,node.subflow);
this.subflowInstanceNodes[id] = true;
var subflow = Subflow.create(
this,
this.global,
subflowDefinition,
node
);
this.subflowInstanceNodes[id] = subflow;
subflow.start();
this.activeNodes[id] = subflow.node;
// this.subflowInstanceNodes[id] = nodes.map(function(n) { return n.id});
// for (var i=0;i<nodes.length;i++) {
// if (nodes[i]) {
// this.activeNodes[nodes[i].id] = nodes[i];
// }
// }
} catch(err) {
console.log(err.stack)
// this.subflowInstanceNodes[id] = nodes.map(function(n) { return n.id});
// for (var i=0;i<nodes.length;i++) {
// if (nodes[i]) {
// this.activeNodes[nodes[i].id] = nodes[i];
// }
// }
} catch(err) {
console.log(err.stack)
}
}
}
} else {
this.debug("not starting disabled node : "+id);
}

@@ -221,3 +237,3 @@ }

}
// Build the map of catch/status nodes.
// Build the map of catch/status/complete nodes.
for (id in this.activeNodes) {

@@ -231,2 +247,9 @@ if (this.activeNodes.hasOwnProperty(id)) {

this.statusNodes.push(node);
} else if (node.type === "complete") {
if (node.scope) {
node.scope.forEach(id => {
this.completeNodeMap[id] = this.completeNodeMap[id] || [];
this.completeNodeMap[id].push(node);
})
}
}

@@ -286,3 +309,3 @@ }

(function(subflow) {
promises.push(stopNode(node,false).then(() => { subflow.stop() }));
promises.push(stopNode(node,false).then(() => subflow.stop()));
})(this.subflowInstanceNodes[stopList[i]]);

@@ -512,2 +535,16 @@ } catch(err) {

handleComplete(node,msg) {
if (this.completeNodeMap[node.id]) {
let toSend = msg;
this.completeNodeMap[node.id].forEach((completeNode,index) => {
toSend = redUtil.cloneMessage(msg);
completeNode.receive(toSend);
})
}
}
get asyncMessageDelivery() {
return asyncMessageDelivery
}
dump() {

@@ -559,2 +596,3 @@ console.log("==================")

nodeCloseTimeout = runtime.settings.nodeCloseTimeout || 15000;
asyncMessageDelivery = !runtime.settings.runtimeSyncDelivery
Log = runtime.log;

@@ -561,0 +599,0 @@ Subflow = require("./Subflow");

@@ -732,4 +732,8 @@ /**

disableFlow:null,
enableFlow:null
enableFlow:null,
isDeliveryModeAsync: function() {
// If settings is null, this is likely being run by unit tests
return !settings || !settings.runtimeSyncDelivery
}
};

@@ -27,4 +27,52 @@ /**

/**
* Create deep copy of object
*/
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
/**
* Evaluate Input Value
*/
function evaluateInputValue(value, type, node) {
if (type === "bool") {
return (value === "true") || (value === true);
}
return redUtil.evaluateNodeProperty(value, type, node, null, null);
}
/**
* Compose information object for env var
*/
function composeInfo(info, val) {
var result = {
name: info.name,
type: info.type,
value: val,
};
if (info.ui) {
var ui = info.ui;
result.ui = {
hasUI: ui.hasUI,
icon: ui.icon,
labels: ui.labels,
type: ui.type
};
var retUI = result.ui;
if (ui.type === "input") {
retUI.inputTypes = ui.inputTypes;
}
if (ui.type === "select") {
retUI.menu = ui.menu;
}
if (ui.type === "spinner") {
retUI.spinner = ui.spinner;
}
}
return result;
}
/**
* This class represents a subflow - which is handled as a special type of Flow

@@ -99,6 +147,15 @@ */

if (this.subflowDef.env) {
this.subflowDef.env.forEach(e => { env[e.name] = e; });
this.subflowDef.env.forEach(e => {
env[e.name] = e;
});
}
if (this.subflowInstance.env) {
this.subflowInstance.env.forEach(e => { env[e.name] = e; });
this.subflowInstance.env.forEach(e => {
var old = env[e.name];
var ui = old ? old.ui : null;
env[e.name] = e;
if (ui) {
env[e.name].ui = ui;
}
});
}

@@ -262,2 +319,3 @@ this.env = env;

/**

@@ -272,4 +330,12 @@ * Get environment variable of subflow

var env = this.env;
if (env && env.hasOwnProperty(name)) {
var val = env[name];
var is_info = name.endsWith("_info");
var is_type = name.endsWith("_type");
var ename = (is_info || is_type) ? name.substring(0, name.length -5) : name; // 5 = length of "_info"/"_type"
if (env && env.hasOwnProperty(ename)) {
var val = env[ename];
if (is_type) {
return val ? val.type : undefined;
}
// If this is an env type property we need to be careful not

@@ -283,7 +349,11 @@ // to get into lookup loops.

let value = val.value;
if (val.type === 'env') {
var type = val.type;
if (type === 'env') {
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
}
try {
var ret = redUtil.evaluateNodeProperty(value, val.type, this.node, null, null);
var ret = evaluateInputValue(value, type, this.node);
if (is_info) {
return composeInfo(val, ret);
}
return ret;

@@ -417,3 +487,7 @@ }

for (k=0;k<wires.length;k++) {
outputs[j][k] = nodeMap[outputs[j][k]].id
if (nodeMap[outputs[j][k]]) {
outputs[j][k] = nodeMap[outputs[j][k]].id
} else {
outputs[j][k] = null;
}
}

@@ -430,3 +504,2 @@ }

if (nodeMap[node[prop]]) {
//console.log("Mapped",node.type,node.id,prop,nodeMap[node[prop]].id);
node[prop] = nodeMap[node[prop]].id;

@@ -433,0 +506,0 @@ }

@@ -21,6 +21,16 @@ /**

var redUtil = require("@node-red/util").util;
var Log = require("@node-red/util").log; // TODO: separate module
var Log = require("@node-red/util").log;
var context = require("./context");
var flows = require("./flows");
const NOOP_SEND = function() {}
/**
* The Node object is the heart of a Node-RED flow. It is the object that all
* nodes extend.
*
* The Node object itself inherits from EventEmitter, although it provides
* custom implementations of some of the EE functions in order to handle
* `input` and `close` events properly.
*/
function Node(n) {

@@ -31,2 +41,4 @@ this.id = n.id;

this._closeCallbacks = [];
this._inputCallback = null;
this._inputCallbacks = null;

@@ -48,3 +60,7 @@ if (n.name) {

Object.defineProperty(this,'_flow', {value: n._flow, enumerable: false, writable: true })
this._asyncDelivery = n._flow.asyncMessageDelivery;
}
if (this._asyncDelivery === undefined) {
this._asyncDelivery = true;
}
this.updateWires(n.wires);

@@ -55,2 +71,17 @@ }

/**
* Update the wiring configuration for this node.
*
* We try to optimise the message handling path. To do this there are three
* cases to consider:
* 1. this node is wired to nothing. In this case we replace node.send with a
* NO-OP function.
* 2. this node is wired to one other node. In this case we set `this._wire`
* as a reference to the node it is wired to. This means we avoid unnecessary
* iterations over what would otherwise be a 1-element array.
* 3. this node is wired to multiple things. The normal node.send processing of
* this.wires applies.
*
* @param {array} wires the new wiring configuration
*/
Node.prototype.updateWires = function(wires) {

@@ -68,3 +99,3 @@ //console.log("UPDATE",this.id);

// With nothing wired to the node, no-op send
this.send = function(msg) {}
this.send = NOOP_SEND
} else {

@@ -80,2 +111,9 @@ this.send = Node.prototype.send;

}
/**
* Get the context object for this node.
*
* As most nodes do not use context, this is a lazy function that will only
* create a context instance for the node if it is needed.
* @return {object} the context object
*/
Node.prototype.context = function() {

@@ -88,4 +126,28 @@ if (!this._context) {

/**
* Handle the complete event for a message
*
* @param {object} msg The message that has completed
* @param {error} error (optional) an error hit whilst handling the message
*/
Node.prototype._complete = function(msg,error) {
if (error) {
// For now, delegate this to this.error
// But at some point, the timeout handling will need to know about
// this as well.
this.error(error,msg);
} else {
this._flow.handleComplete(this,msg);
}
}
/**
* An internal reference to the original EventEmitter.on() function
*/
Node.prototype._on = Node.prototype.on;
/**
* Register a callback function for a named event.
* 'close' and 'input' events are handled locally, other events defer to EventEmitter.on()
*/
Node.prototype.on = function(event, callback) {

@@ -95,2 +157,11 @@ var node = this;

this._closeCallbacks.push(callback);
} else if (event === "input") {
if (this._inputCallback) {
this._inputCallbacks = [this._inputCallback, callback];
this._inputCallback = null;
} else if (this._inputCallbacks) {
this._inputCallbacks.push(callback);
} else {
this._inputCallback = callback;
}
} else {

@@ -101,2 +172,131 @@ this._on(event, callback);

/**
* An internal reference to the original EventEmitter.emit() function
*/
Node.prototype._emit = Node.prototype.emit;
/**
* Emit an event to all registered listeners.
*/
Node.prototype.emit = function(event,arg) {
var node = this;
if (event === "input") {
// When Pluggable Message Routing arrives, this will be called from
// that and will already be sync/async depending on the router.
if (this._asyncDelivery) {
setImmediate(function() {
node._emitInput(arg);
});
} else {
this._emitInput(arg);
}
} else {
this._emit(event,arg);
}
}
/**
* Handle the 'input' event.
*
* This will call all registered handlers for the 'input' event.
*/
Node.prototype._emitInput = function(arg) {
var node = this;
if (node._inputCallback) {
// Just one callback registered.
try {
node._inputCallback(
arg,
function() { node.send.apply(node,arguments) },
function(err) { node._complete(arg,err); }
);
} catch(err) {
node.error(err,arg);
}
} else if (node._inputCallbacks) {
// Multiple callbacks registered. Call each one, tracking eventual completion
var c = node._inputCallbacks.length;
for (var i=0;i<c;i++) {
var cb = node._inputCallbacks[i];
if (cb.length === 2) {
c++;
}
try {
node._inputCallbacks[i](
arg,
function() { node.send.apply(node,arguments) },
function(err) {
c--;
if (c === 0) {
node._complete(arg,err);
}
}
);
} catch(err) {
node.error(err,msg);
}
}
}
}
/**
* An internal reference to the original EventEmitter.removeListener() function
*/
Node.prototype._removeListener = Node.prototype.removeListener;
/**
* Remove a listener for an event
*/
Node.prototype.removeListener = function(name, listener) {
var index;
if (name === "input") {
if (this._inputCallback && this._inputCallback === listener) {
// Removing the only callback
this._inputCallback = null;
} else if (this._inputCallbacks) {
// Removing one of many callbacks
index = this._inputCallbacks.indexOf(listener);
if (index > -1) {
this._inputCallbacks.splice(index,1);
}
// Check if we can optimise back to a single callback
if (this._inputCallbacks.length === 1) {
this._inputCallback = this._inputCallbacks[0];
this._inputCallbacks = null;
}
}
} else if (name === "close") {
index = this._closeCallbacks.indexOf(listener);
if (index > -1) {
this._closeCallbacks.splice(index,1);
}
} else {
this._removeListener(name, listener);
}
}
/**
* An internal reference to the original EventEmitter.removeAllListeners() function
*/
Node.prototype._removeAllListeners = Node.prototype.removeAllListeners;
/**
* Remove all listeners for an event
*/
Node.prototype.removeAllListeners = function(name) {
if (name === "input") {
this._inputCallback = null;
this._inputCallbacks = null;
} else if (name === "close") {
this._closeCallbacks = [];
} else {
this._removeAllListeners(name);
}
}
/**
* Called when the node is being stopped
* @param {boolean} removed Whether the node has been removed, or just being stopped
* @return {Promise} resolves when the node has closed
*/
Node.prototype.close = function(removed) {

@@ -106,5 +306,7 @@ //console.log(this.type,this.id,removed);

var node = this;
// Call all registered close callbacks.
for (var i=0;i<this._closeCallbacks.length;i++) {
var callback = this._closeCallbacks[i];
if (callback.length > 0) {
// The callback takes a 'done' callback and (maybe) the removed flag
promises.push(

@@ -115,2 +317,3 @@ new Promise((resolve) => {

if (callback.length === 2) {
// The listener expects the removed flag
args.push(!!removed);

@@ -130,2 +333,3 @@ }

} else {
// No done callback so handle synchronously
try {

@@ -153,2 +357,8 @@ callback.call(node);

/**
* Send a message to the nodes wired.
*
*
* @param {object} msg A message or array of messages to send
*/
Node.prototype.send = function(msg) {

@@ -241,2 +451,8 @@ var msgSent = false;

/**
* Receive a message.
*
* This will emit the `input` event with the provided message.
* As of 1.0, this will return *before* any 'input' callback handler is invoked.
*/
Node.prototype.receive = function(msg) {

@@ -250,7 +466,3 @@ if (!msg) {

this.metric("receive",msg);
try {
this.emit("input", msg);
} catch(err) {
this.error(err,msg);
}
this.emit("input",msg);
};

@@ -276,3 +488,5 @@

}
/**
* Log an INFO level message
*/
Node.prototype.log = function(msg) {

@@ -282,2 +496,5 @@ log_helper(this, Log.INFO, msg);

/**
* Log a WARN level message
*/
Node.prototype.warn = function(msg) {

@@ -287,2 +504,5 @@ log_helper(this, Log.WARN, msg);

/**
* Log an ERROR level message
*/
Node.prototype.error = function(logMessage,msg) {

@@ -293,3 +513,3 @@ if (typeof logMessage != 'boolean') {

var handled = false;
if (msg) {
if (msg && typeof msg === 'object') {
handled = this._flow.handleError(this,logMessage,msg);

@@ -302,2 +522,5 @@ }

/**
* Log an DEBUG level message
*/
Node.prototype.debug = function(msg) {

@@ -307,2 +530,5 @@ log_helper(this, Log.DEBUG, msg);

/**
* Log an TRACE level message
*/
Node.prototype.trace = function(msg) {

@@ -313,2 +539,3 @@ log_helper(this, Log.TRACE, msg);

/**
* Log a metric event.
* If called with no args, returns whether metric collection is enabled

@@ -330,2 +557,4 @@ */

/**
* Set the node's status object
*
* status: { fill:"red|green", shape:"dot|ring", text:"blah" }

@@ -332,0 +561,0 @@ * or

@@ -54,2 +54,8 @@ /**

});
child.on('error', function(err) {
if (/ENOENT/.test(err.toString())) {
err.code = "command_not_found";
}
reject(err);
});
});

@@ -56,0 +62,0 @@ }

{
"name": "@node-red/runtime",
"version": "1.0.0-beta.2",
"version": "1.0.0-beta.3",
"license": "Apache-2.0",

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

"dependencies": {
"@node-red/registry": "1.0.0-beta.2",
"@node-red/util": "1.0.0-beta.2",
"@node-red/registry": "1.0.0-beta.3",
"@node-red/util": "1.0.0-beta.3",
"clone": "2.1.2",
"express": "4.17.0",
"fs-extra": "8.0.1",
"express": "4.17.1",
"fs-extra": "8.1.0",
"json-stringify-safe": "5.0.1",

@@ -26,0 +26,0 @@ "when": "3.7.8"

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