Move exec and events components to util module

The exec and events components are common components that
are used by both runtime and registry. It makes sense to
move them into the util package.

This also adds some docs to the registry module
This commit is contained in:
Nick O'Leary
2020-12-02 09:25:10 +00:00
parent a1f565f756
commit 6fb96fa3c1
33 changed files with 491 additions and 319 deletions

View File

@@ -1,4 +1,4 @@
/**
/*!
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,16 +29,27 @@ var loader = require("./loader");
var installer = require("./installer");
var library = require("./library");
var settings;
/**
* Initialise the registry with a reference to a runtime object
* @param {Object} runtime - a runtime object
* @memberof @node-red/registry
*/
function init(runtime) {
settings = runtime.settings;
installer.init(runtime);
installer.init(runtime.settings);
// Loader requires the full runtime object because it initialises
// the util module it. The Util module is responsible for constructing the
// RED object passed to node modules when they are loaded.
loader.init(runtime);
registry.init(settings,loader,runtime.events);
registry.init(runtime.settings,loader);
library.init();
}
/**
* Triggers the intial discovery and loading of all Node-RED node modules.
* found on the node path.
* @return {Promise} - resolves when the registry has finised discovering node modules.
* @memberof @node-red/registry
*/
function load() {
registry.load();
return installer.checkPrereq().then(loader.load);
@@ -66,34 +77,221 @@ module.exports = {
init:init,
load:load,
clear: registry.clear,
/**
* Register a node constructor function.
*
* @param {Object} nodeSet - the Node Set object the constructor is for
* @param {String} type - the node type
* @param {Function} constructor - the node constructor function
* @function
* @memberof @node-red/registry
*/
registerType: registry.registerNodeConstructor,
/**
* Get a node constructor function.
*
* @param {String} type - the node type
* @return {Function} the node constructor function
* @function
* @memberof @node-red/registry
*/
get: registry.getNodeConstructor,
/**
* Get a node's set information.
*
* @param {String} type - the node type or set identifier
* @return {Object} the node set information
* @function
* @memberof @node-red/registry
*/
getNodeInfo: registry.getNodeInfo,
/**
* Get a list of all nodes in the registry.
*
* @return {Object} the node list
* @function
* @memberof @node-red/registry
*/
getNodeList: registry.getNodeList,
/**
* Get a modules's information.
*
* @param {String} type - the module identifier
* @return {Object} the module information
* @function
* @memberof @node-red/registry
*/
getModuleInfo: registry.getModuleInfo,
/**
* Get a list of all moduless in the registry.
*
* @return {Object} the module list
* @function
* @memberof @node-red/registry
*/
getModuleList: registry.getModuleList,
/**
* Get the HTML configs for all nodes in the registry.
*
* @param {String} lang - the language to return, default `en-US`
* @return {String} the node configs
* @function
* @memberof @node-red/registry
*/
getNodeConfigs: registry.getAllNodeConfigs,
/**
* Get the HTML config for a single node set.
*
* @param {String} id - the node identifier
* @param {String} lang - the language to return, default `en-US`
* @return {String} the node config
* @function
* @memberof @node-red/registry
*/
getNodeConfig: registry.getNodeConfig,
/**
* Get the local path to a node's icon file.
*
* @param {String} module - the module that provides the icon
* @param {String} icon - the name of the icon
* @return {String} the local path to the icon
* @function
* @memberof @node-red/registry
*/
getNodeIconPath: registry.getNodeIconPath,
/**
* Get the full list of all icons available.
*
* @return {String} the icon list
* @function
* @memberof @node-red/registry
*/
getNodeIcons: registry.getNodeIcons,
/**
* Enables a node set, making it available for use.
*
* @param {String} type - the node type or set identifier
* @return {Promise} A promise that resolves when the node set has been enabled
* @throws if the identifier is not recognised or runtime settings are unavailable
* @function
* @memberof @node-red/registry
*/
enableNode: enableNodeSet,
/**
* Disables a node set, making it unavailable for use.
*
* @param {String} type - the node type or set identifier
* @return {Promise} A promise that resolves when the node set has been disabled
* @throws if the identifier is not recognised or runtime settings are unavailable
* @function
* @memberof @node-red/registry
*/
disableNode: registry.disableNodeSet,
/**
* Loads a new module into the registry.
*
* This will rescan the node module paths looking for this module.
*
* @param {String} module - the name of the module to add
* @return {Promise<Object>} A promise that resolves with the module information once it has been added
* @throws if the module has already been added or the runtime settings are unavailable
* @function
* @memberof @node-red/registry
*/
addModule: addModule,
/**
* Removes a module from the registry.
*
* @param {String} module - the name of the module to remove
* @return {Promise<Array>} A promise that resolves with the list of removed node sets
* @throws if the module is not found or the runtime settings are unavailable
* @function
* @memberof @node-red/registry
*/
removeModule: registry.removeModule,
/**
* Installs a new node module using npm and then add to the registry
*
* @param {String|Buffer} module - the name of the module to install, or a Buffer containing a module tar file
* @param {String} version - the version of the module to install, default: `latest`
* @param {String} url - (optional) a url to install the module from
* @return {Promise<Array>} A promise that resolves with the module information once it has been installed
* @function
* @memberof @node-red/registry
*/
installModule: installer.installModule,
/**
* Uninstalls a module using npm
*
* @param {String} module - the name of the module to uninstall
* @return {Promise<Array>} A promise that resolves when the module has been removed
* @function
* @memberof @node-red/registry
*/
uninstallModule: installer.uninstallModule,
/**
* Update to internal list of available modules based on what has been actually
* loaded.
*
* The `autoInstallModules` runtime option means the runtime may try to install
* missing modules after the initial load is complete. If that flag is not set
* this function is used to remove the modules from the registry's saved list.
* @function
* @memberof @node-red/registry
*/
cleanModuleList: registry.cleanModuleList,
/**
* Check if the regisrty is able to install/remove modules.
*
* This is based on whether it has found `npm` on the command-line.
* @return {Boolean} whether the installer is enabled
*
* @function
* @memberof @node-red/registry
*/
paletteEditorEnabled: installer.paletteEditorEnabled,
/**
* Get a list of all example flows provided by nodes in the registry.
* @return {Object} an object, indexed by module, listing all example flows
*
* @function
* @memberof @node-red/registry
*/
getNodeExampleFlows: library.getExampleFlows,
/**
* Gets the full path to a node example
* @param {String} module - the name of the module providing the example
* @param {String} path - the relative path of the example
* @return {String} the full path to the example
*
* @function
* @memberof @node-red/registry
*/
getNodeExampleFlowPath: library.getExampleFlowPath,
deprecated: require("./deprecated")

View File

@@ -22,11 +22,7 @@ var tar = require("tar");
var registry = require("./registry");
var library = require("./library");
var log;
var exec;
var events;
const {exec,log,events} = require("@node-red/util");
var child_process = require('child_process');
var npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
var paletteEditorEnabled = false;
@@ -37,11 +33,8 @@ const slashRe = process.platform === "win32" ? /\\|[/]/ : /[/]/;
const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/;
function init(runtime) {
events = runtime.events;
settings = runtime.settings;
log = runtime.log;
exec = runtime.exec;
function init(_settings) {
settings = _settings;
}
var activePromise = Promise.resolve();

View File

@@ -14,7 +14,7 @@
* limitations under the License.
**/
var fs = require('fs');
var fs = require('fs-extra');
var fspath = require('path');
var runtime;
@@ -22,38 +22,34 @@ var runtime;
var exampleRoots = {};
var exampleFlows = null;
function getFlowsFromPath(path) {
return new Promise(function(resolve,reject) {
var result = {};
fs.readdir(path,function(err,files) {
var promises = [];
var validFiles = [];
files.forEach(function(file) {
var fullPath = fspath.join(path,file);
var stats = fs.lstatSync(fullPath);
if (stats.isDirectory()) {
validFiles.push(file);
promises.push(getFlowsFromPath(fullPath));
} else if (/\.json$/.test(file)){
validFiles.push(file);
promises.push(Promise.resolve(file.split(".")[0]))
}
})
var i=0;
Promise.all(promises).then(function(results) {
results.forEach(function(r) {
if (typeof r === 'string') {
result.f = result.f||[];
result.f.push(r);
} else {
result.d = result.d||{};
result.d[validFiles[i]] = r;
}
i++;
})
resolve(result);
})
});
async function getFlowsFromPath(path) {
var result = {};
var validFiles = [];
return fs.readdir(path).then(files => {
var promises = [];
files.forEach(function(file) {
var fullPath = fspath.join(path,file);
var stats = fs.lstatSync(fullPath);
if (stats.isDirectory()) {
validFiles.push(file);
promises.push(getFlowsFromPath(fullPath));
} else if (/\.json$/.test(file)){
validFiles.push(file);
promises.push(Promise.resolve(file.split(".")[0]))
}
})
return Promise.all(promises)
}).then(results => {
results.forEach(function(r,i) {
if (typeof r === 'string') {
result.f = result.f||[];
result.f.push(r);
} else {
result.d = result.d||{};
result.d[validFiles[i]] = r;
}
})
return result;
})
}

View File

@@ -22,15 +22,14 @@ var localfilesystem = require("./localfilesystem");
var registry = require("./registry");
var registryUtil = require("./util")
var i18n = require("@node-red/util").i18n;
var log = require("@node-red/util").log;
var settings;
var runtime;
function init(_runtime) {
runtime = _runtime;
settings = runtime.settings;
localfilesystem.init(runtime);
registryUtil.init(runtime);
settings = _runtime.settings;
localfilesystem.init(settings);
registryUtil.init(_runtime);
}
function load(disableNodePathScan) {
@@ -38,7 +37,7 @@ function load(disableNodePathScan) {
// We should expose that as an option at some point, although the
// performance gains are minimal.
//return loadNodeFiles(registry.getModuleList());
runtime.log.info(runtime.log._("server.loading"));
log.info(log._("server.loading"));
var nodeFiles = localfilesystem.getNodeFiles(disableNodePathScan);
return loadNodeFiles(nodeFiles);
@@ -51,9 +50,9 @@ function loadNodeFiles(nodeFiles) {
/* istanbul ignore else */
if (nodeFiles.hasOwnProperty(module)) {
if (nodeFiles[module].redVersion &&
!semver.satisfies(runtime.version().replace(/(\-[1-9A-Za-z-][0-9A-Za-z-\.]*)?(\+[0-9A-Za-z-\.]+)?$/,""), nodeFiles[module].redVersion)) {
!semver.satisfies((settings.version||"0.0.0").replace(/(\-[1-9A-Za-z-][0-9A-Za-z-\.]*)?(\+[0-9A-Za-z-\.]+)?$/,""), nodeFiles[module].redVersion)) {
//TODO: log it
runtime.log.warn("["+module+"] "+runtime.log._("server.node-version-mismatch",{version:nodeFiles[module].redVersion}));
log.warn("["+module+"] "+log._("server.node-version-mismatch",{version:nodeFiles[module].redVersion}));
nodeFiles[module].err = "version_mismatch";
continue;
}

View File

@@ -16,9 +16,6 @@
var fs = require("fs");
var path = require("path");
var log;
var log = require("@node-red/util").log;
var i18n = require("@node-red/util").i18n;
@@ -26,8 +23,8 @@ var settings;
var disableNodePathScan = false;
var iconFileExtensions = [".png", ".gif", ".svg"];
function init(runtime) {
settings = runtime.settings;
function init(_settings) {
settings = _settings;
}
function isIncluded(name) {

View File

@@ -19,8 +19,7 @@ var path = require("path");
var fs = require("fs");
var library = require("./library");
var events;
const {events} = require("@node-red/util")
var settings;
var loader;
@@ -31,10 +30,9 @@ var nodeConstructors = {};
var nodeTypeToId = {};
var moduleNodes = {};
function init(_settings,_loader, _events) {
function init(_settings,_loader) {
settings = _settings;
loader = _loader;
events = _events;
moduleNodes = {};
nodeTypeToId = {};
nodeConstructors = {};

View File

@@ -14,9 +14,8 @@
* limitations under the License.
**/
var path = require("path");
var i18n = require("@node-red/util").i18n;
var registry;
const path = require("path");
const {events,i18n,log} = require("@node-red/util");
var runtime;
function copyObjectProperties(src,dst,copyList,blockList) {
@@ -40,7 +39,7 @@ function copyObjectProperties(src,dst,copyList,blockList) {
}
}
function requireModule(name) {
var moduleInfo = registry.getModuleInfo(name);
var moduleInfo = require("./index").getModuleInfo(name);
if (moduleInfo && moduleInfo.path) {
var relPath = path.relative(__dirname, moduleInfo.path);
return require(relPath);
@@ -56,14 +55,14 @@ function createNodeApi(node) {
nodes: {},
log: {},
settings: {},
events: runtime.events,
events: events,
hooks: runtime.hooks,
util: runtime.util,
version: runtime.version,
require: requireModule,
comms: {
publish: function(topic,data,retain) {
runtime.events.emit("comms",{
events.emit("comms",{
topic: topic,
data: data,
retain: retain
@@ -83,7 +82,7 @@ function createNodeApi(node) {
red.nodes.registerType = function(type,constructor,opts) {
runtime.nodes.registerType(node.id,type,constructor,opts);
}
copyObjectProperties(runtime.log,red.log,null,["init"]);
copyObjectProperties(log,red.log,null,["init"]);
copyObjectProperties(runtime.settings,red.settings,null,["init","load","reset"]);
if (runtime.adminApi) {
red.auth = runtime.adminApi.auth;
@@ -108,7 +107,6 @@ function createNodeApi(node) {
module.exports = {
init: function(_runtime) {
runtime = _runtime;
registry = require("@node-red/registry/lib");
},
createNodeApi: createNodeApi
}