mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Add RED.require to allow nodes to access other modules
This commit is contained in:
@@ -62,6 +62,17 @@ function copyObjectProperties(src,dst,copyList,blockList) {
|
||||
}
|
||||
}
|
||||
}
|
||||
function requireModule(name) {
|
||||
var moduleInfo = registry.getModuleInfo(name);
|
||||
if (moduleInfo && moduleInfo.path) {
|
||||
var relPath = path.relative(__dirname, moduleInfo.path);
|
||||
return require(relPath);
|
||||
} else {
|
||||
var err = new Error(`Cannot find module '${name}'`);
|
||||
err.code = "MODULE_NOT_FOUND";
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
function createNodeApi(node) {
|
||||
var red = {
|
||||
@@ -71,6 +82,7 @@ function createNodeApi(node) {
|
||||
events: runtime.events,
|
||||
util: runtime.util,
|
||||
version: runtime.version,
|
||||
require: requireModule
|
||||
}
|
||||
copyObjectProperties(runtime.nodes,red.nodes,["createNode","getNode","eachNode","addCredentials","getCredentials","deleteCredentials" ]);
|
||||
red.nodes.registerType = function(type,constructor,opts) {
|
||||
@@ -112,6 +124,7 @@ function createNodeApi(node) {
|
||||
|
||||
function loadNodeFiles(nodeFiles) {
|
||||
var promises = [];
|
||||
var nodes = [];
|
||||
for (var module in nodeFiles) {
|
||||
/* istanbul ignore else */
|
||||
if (nodeFiles.hasOwnProperty(module)) {
|
||||
@@ -119,6 +132,7 @@ function loadNodeFiles(nodeFiles) {
|
||||
!semver.satisfies(runtime.version().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}));
|
||||
nodeFiles[module].err = "version_mismatch";
|
||||
continue;
|
||||
}
|
||||
if (module == "node-red" || !registry.getModuleInfo(module)) {
|
||||
@@ -148,7 +162,14 @@ function loadNodeFiles(nodeFiles) {
|
||||
}
|
||||
|
||||
try {
|
||||
promises.push(loadNodeConfig(nodeFiles[module].nodes[node]))
|
||||
promises.push(loadNodeConfig(nodeFiles[module].nodes[node]).then((function() {
|
||||
var m = module;
|
||||
var n = node;
|
||||
return function(nodeSet) {
|
||||
nodeFiles[m].nodes[n] = nodeSet;
|
||||
nodes.push(nodeSet);
|
||||
}
|
||||
})()));
|
||||
} catch(err) {
|
||||
//
|
||||
}
|
||||
@@ -158,16 +179,19 @@ function loadNodeFiles(nodeFiles) {
|
||||
}
|
||||
}
|
||||
return when.settle(promises).then(function(results) {
|
||||
var nodes = results.map(function(r) {
|
||||
registry.addNodeSet(r.value.id,r.value,r.value.version);
|
||||
return r.value;
|
||||
});
|
||||
for (var module in nodeFiles) {
|
||||
if (nodeFiles.hasOwnProperty(module)) {
|
||||
if (!nodeFiles[module].err) {
|
||||
registry.addModule(nodeFiles[module]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return loadNodeSetList(nodes);
|
||||
});
|
||||
}
|
||||
|
||||
function loadNodeConfig(fileInfo) {
|
||||
return when.promise(function(resolve) {
|
||||
return new Promise(function(resolve) {
|
||||
var file = fileInfo.file;
|
||||
var module = fileInfo.module;
|
||||
var name = fileInfo.name;
|
||||
@@ -292,7 +316,7 @@ function loadNodeSet(node) {
|
||||
var nodeDir = path.dirname(node.file);
|
||||
var nodeFn = path.basename(node.file);
|
||||
if (!node.enabled) {
|
||||
return when.resolve(node);
|
||||
return Promise.resolve(node);
|
||||
} else {
|
||||
}
|
||||
try {
|
||||
@@ -316,7 +340,7 @@ function loadNodeSet(node) {
|
||||
if (loadPromise == null) {
|
||||
node.enabled = true;
|
||||
node.loaded = true;
|
||||
loadPromise = when.resolve(node);
|
||||
loadPromise = Promise.resolve(node);
|
||||
}
|
||||
return loadPromise;
|
||||
} catch(err) {
|
||||
@@ -333,7 +357,7 @@ function loadNodeSet(node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return when.resolve(node);
|
||||
return Promise.resolve(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,19 +389,19 @@ function addModule(module) {
|
||||
// TODO: nls
|
||||
var e = new Error("module_already_loaded");
|
||||
e.code = "module_already_loaded";
|
||||
return when.reject(e);
|
||||
return Promise.reject(e);
|
||||
}
|
||||
try {
|
||||
var moduleFiles = localfilesystem.getModuleFiles(module);
|
||||
return loadNodeFiles(moduleFiles);
|
||||
} catch(err) {
|
||||
return when.reject(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
function loadNodeHelp(node,lang) {
|
||||
var base = path.basename(node.template);
|
||||
var localePath = undefined;
|
||||
var localePath;
|
||||
if (node.module === 'node-red') {
|
||||
var cat_dir = path.dirname(node.template);
|
||||
var cat = path.basename(cat_dir);
|
||||
|
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
**/
|
||||
|
||||
var when = require("when");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
@@ -85,6 +84,7 @@ function getLocalNodeFiles(dir) {
|
||||
|
||||
var result = [];
|
||||
var files = [];
|
||||
var icons = [];
|
||||
try {
|
||||
files = fs.readdirSync(dir);
|
||||
} catch(err) {
|
||||
@@ -103,14 +103,16 @@ function getLocalNodeFiles(dir) {
|
||||
} else if (stats.isDirectory()) {
|
||||
// Ignore /.dirs/, /lib/ /node_modules/
|
||||
if (!/^(\..*|lib|icons|node_modules|test|locales)$/.test(fn)) {
|
||||
result = result.concat(getLocalNodeFiles(path.join(dir,fn)));
|
||||
var subDirResults = getLocalNodeFiles(path.join(dir,fn));
|
||||
result = result.concat(subDirResults.files);
|
||||
icons = icons.concat(subDirResults.icons);
|
||||
} else if (fn === "icons") {
|
||||
var iconList = scanIconDir(path.join(dir,fn));
|
||||
events.emit("node-icon-dir",{name:'node-red',path:path.join(dir,fn),icons:iconList});
|
||||
icons.push({path:path.join(dir,fn),icons:iconList});
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
return {files: result, icons: icons}
|
||||
}
|
||||
|
||||
function scanDirForNodesModules(dir,moduleName) {
|
||||
@@ -198,7 +200,7 @@ function getModuleNodeFiles(module) {
|
||||
var nodes = pkg['node-red'].nodes||{};
|
||||
var results = [];
|
||||
var iconDirs = [];
|
||||
|
||||
var iconList = [];
|
||||
for (var n in nodes) {
|
||||
/* istanbul ignore else */
|
||||
if (nodes.hasOwnProperty(n)) {
|
||||
@@ -213,47 +215,54 @@ function getModuleNodeFiles(module) {
|
||||
if (iconDirs.indexOf(iconDir) == -1) {
|
||||
try {
|
||||
fs.statSync(iconDir);
|
||||
var iconList = scanIconDir(iconDir);
|
||||
events.emit("node-icon-dir",{name:pkg.name,path:iconDir,icons:iconList});
|
||||
var icons = scanIconDir(iconDir);
|
||||
iconList.push({path:iconDir,icons:icons});
|
||||
iconDirs.push(iconDir);
|
||||
} catch(err) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = {files:results,icons:iconList};
|
||||
|
||||
var examplesDir = path.join(moduleDir,"examples");
|
||||
try {
|
||||
fs.statSync(examplesDir)
|
||||
events.emit("node-examples-dir",{name:pkg.name,path:examplesDir});
|
||||
} catch(err) {
|
||||
}
|
||||
return results;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNodeFiles(disableNodePathScan) {
|
||||
var dir;
|
||||
// Find all of the nodes to load
|
||||
var nodeFiles = [];
|
||||
var results;
|
||||
|
||||
var dir = path.resolve(__dirname + '/../../../../public/icons');
|
||||
var iconList = scanIconDir(dir);
|
||||
events.emit("node-icon-dir",{name:'node-red',path:dir,icons:iconList});
|
||||
var iconList = [{path:dir,icons:scanIconDir(dir)}];
|
||||
|
||||
if (settings.coreNodesDir) {
|
||||
nodeFiles = getLocalNodeFiles(path.resolve(settings.coreNodesDir));
|
||||
results = getLocalNodeFiles(path.resolve(settings.coreNodesDir));
|
||||
nodeFiles = nodeFiles.concat(results.files);
|
||||
iconList = iconList.concat(results.icons);
|
||||
|
||||
var defaultLocalesPath = path.join(settings.coreNodesDir,"core","locales");
|
||||
i18n.registerMessageCatalog("node-red",defaultLocalesPath,"messages.json");
|
||||
}
|
||||
|
||||
if (settings.userDir) {
|
||||
dir = path.join(settings.userDir,"lib","icons");
|
||||
iconList = scanIconDir(dir);
|
||||
if (iconList.length > 0) {
|
||||
events.emit("node-icon-dir",{name:'Library',path:dir,icons:iconList});
|
||||
var icons = scanIconDir(dir);
|
||||
if (icons.length > 0) {
|
||||
iconList.push({path:dir,icons:icons});
|
||||
}
|
||||
|
||||
dir = path.join(settings.userDir,"nodes");
|
||||
nodeFiles = nodeFiles.concat(getLocalNodeFiles(dir));
|
||||
results = getLocalNodeFiles(path.resolve(dir));
|
||||
nodeFiles = nodeFiles.concat(results.files);
|
||||
iconList = iconList.concat(results.icons);
|
||||
}
|
||||
if (settings.nodesDir) {
|
||||
dir = settings.nodesDir;
|
||||
@@ -261,7 +270,9 @@ function getNodeFiles(disableNodePathScan) {
|
||||
dir = [dir];
|
||||
}
|
||||
for (var i=0;i<dir.length;i++) {
|
||||
nodeFiles = nodeFiles.concat(getLocalNodeFiles(dir[i]));
|
||||
results = getLocalNodeFiles(dir[i]);
|
||||
nodeFiles = nodeFiles.concat(results.files);
|
||||
iconList = iconList.concat(results.icons);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +280,8 @@ function getNodeFiles(disableNodePathScan) {
|
||||
"node-red": {
|
||||
name: "node-red",
|
||||
version: settings.version,
|
||||
nodes: {}
|
||||
nodes: {},
|
||||
icons: iconList
|
||||
}
|
||||
}
|
||||
nodeFiles.forEach(function(node) {
|
||||
@@ -283,20 +295,22 @@ function getNodeFiles(disableNodePathScan) {
|
||||
nodeList[moduleFile.package.name] = {
|
||||
name: moduleFile.package.name,
|
||||
version: moduleFile.package.version,
|
||||
path: moduleFile.dir,
|
||||
local: moduleFile.local||false,
|
||||
nodes: {}
|
||||
nodes: {},
|
||||
icons: nodeModuleFiles.icons
|
||||
};
|
||||
if (moduleFile.package['node-red'].version) {
|
||||
nodeList[moduleFile.package.name].redVersion = moduleFile.package['node-red'].version;
|
||||
}
|
||||
nodeModuleFiles.forEach(function(node) {
|
||||
nodeModuleFiles.files.forEach(function(node) {
|
||||
node.local = moduleFile.local||false;
|
||||
nodeList[moduleFile.package.name].nodes[node.name] = node;
|
||||
});
|
||||
nodeFiles = nodeFiles.concat(nodeModuleFiles);
|
||||
nodeFiles = nodeFiles.concat(nodeModuleFiles.files);
|
||||
});
|
||||
} else {
|
||||
console.log("node path scan disabled");
|
||||
// console.log("node path scan disabled");
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
@@ -316,12 +330,13 @@ function getModuleFiles(module) {
|
||||
nodeList[moduleFile.package.name] = {
|
||||
name: moduleFile.package.name,
|
||||
version: moduleFile.package.version,
|
||||
nodes: {}
|
||||
nodes: {},
|
||||
icons: nodeModuleFiles.icons
|
||||
};
|
||||
if (moduleFile.package['node-red'].version) {
|
||||
nodeList[moduleFile.package.name].redVersion = moduleFile.package['node-red'].version;
|
||||
}
|
||||
nodeModuleFiles.forEach(function(node) {
|
||||
nodeModuleFiles.files.forEach(function(node) {
|
||||
nodeList[moduleFile.package.name].nodes[node.name] = node;
|
||||
nodeList[moduleFile.package.name].nodes[node.name].local = moduleFile.local || false;
|
||||
});
|
||||
|
@@ -181,46 +181,43 @@ function loadNodeConfigs() {
|
||||
}
|
||||
}
|
||||
|
||||
function addNodeSet(id,set,version) {
|
||||
if (!set.err) {
|
||||
set.types.forEach(function(t) {
|
||||
if (nodeTypeToId.hasOwnProperty(t)) {
|
||||
set.err = new Error("Type already registered");
|
||||
set.err.code = "type_already_registered";
|
||||
set.err.details = {
|
||||
type: t,
|
||||
moduleA: getNodeInfo(t).module,
|
||||
moduleB: set.module
|
||||
}
|
||||
function addModule(module) {
|
||||
moduleNodes[module.name] = [];
|
||||
moduleConfigs[module.name] = module;
|
||||
for (var setName in module.nodes) {
|
||||
if (module.nodes.hasOwnProperty(setName)) {
|
||||
var set = module.nodes[setName];
|
||||
moduleNodes[module.name].push(set.name);
|
||||
nodeList.push(set.id);
|
||||
if (!set.err) {
|
||||
set.types.forEach(function(t) {
|
||||
if (nodeTypeToId.hasOwnProperty(t)) {
|
||||
set.err = new Error("Type already registered");
|
||||
set.err.code = "type_already_registered";
|
||||
set.err.details = {
|
||||
type: t,
|
||||
moduleA: getNodeInfo(t).module,
|
||||
moduleB: set.module
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
if (!set.err) {
|
||||
set.types.forEach(function(t) {
|
||||
nodeTypeToId[t] = set.id;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!set.err) {
|
||||
set.types.forEach(function(t) {
|
||||
nodeTypeToId[t] = id;
|
||||
});
|
||||
}
|
||||
}
|
||||
moduleNodes[set.module] = moduleNodes[set.module]||[];
|
||||
moduleNodes[set.module].push(set.name);
|
||||
|
||||
if (!moduleConfigs[set.module]) {
|
||||
moduleConfigs[set.module] = {
|
||||
name: set.module,
|
||||
nodes: {}
|
||||
};
|
||||
if (module.icons) {
|
||||
icon_paths[module.name] = [];
|
||||
module.icons.forEach(icon=>icon_paths[module.name].push(path.resolve(icon.path)) )
|
||||
}
|
||||
|
||||
if (version) {
|
||||
moduleConfigs[set.module].version = version;
|
||||
}
|
||||
moduleConfigs[set.module].local = set.local;
|
||||
|
||||
moduleConfigs[set.module].nodes[set.name] = set;
|
||||
nodeList.push(id);
|
||||
nodeConfigCache = null;
|
||||
}
|
||||
|
||||
|
||||
function removeNode(id) {
|
||||
var config = moduleConfigs[getModule(id)].nodes[getNode(id)];
|
||||
if (!config) {
|
||||
@@ -346,6 +343,7 @@ function getModuleInfo(module) {
|
||||
name: module,
|
||||
version: moduleConfigs[module].version,
|
||||
local: moduleConfigs[module].local,
|
||||
path: moduleConfigs[module].path,
|
||||
nodes: []
|
||||
};
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
@@ -592,6 +590,7 @@ var iconCache = {};
|
||||
var defaultIcon = path.resolve(__dirname + '/../../../../public/icons/arrow-in.png');
|
||||
|
||||
function nodeIconDir(dir) {
|
||||
return;
|
||||
icon_paths[dir.name] = icon_paths[dir.name] || [];
|
||||
icon_paths[dir.name].push(path.resolve(dir.path));
|
||||
|
||||
@@ -647,11 +646,11 @@ function getNodeIcons() {
|
||||
for (var module in moduleConfigs) {
|
||||
if (moduleConfigs.hasOwnProperty(module)) {
|
||||
if (moduleConfigs[module].icons) {
|
||||
iconList[module] = moduleConfigs[module].icons;
|
||||
iconList[module] = [];
|
||||
moduleConfigs[module].icons.forEach(icon=>{ iconList[module] = iconList[module].concat(icon.icons) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iconList;
|
||||
}
|
||||
|
||||
@@ -663,7 +662,9 @@ var registry = module.exports = {
|
||||
registerNodeConstructor: registerNodeConstructor,
|
||||
getNodeConstructor: getNodeConstructor,
|
||||
|
||||
addNodeSet: addNodeSet,
|
||||
|
||||
addModule: addModule,
|
||||
|
||||
enableNodeSet: enableNodeSet,
|
||||
disableNodeSet: disableNodeSet,
|
||||
|
||||
|
Reference in New Issue
Block a user