From d673846e3defc23c996aef1060e0f3835fb5fec1 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 17 Nov 2015 21:12:43 +0000 Subject: [PATCH] WIP: runtime api for node modules --- red/red.js | 8 ++-- red/runtime/index.js | 2 +- red/runtime/nodes/index.js | 10 ++--- red/runtime/nodes/registry/index.js | 10 ++--- red/runtime/nodes/registry/loader.js | 40 +++++++------------ red/runtime/nodes/registry/localfilesystem.js | 11 +++-- test/red/runtime/nodes/credentials_spec.js | 2 +- test/red/runtime/nodes/index_spec.js | 19 +++++---- .../red/runtime/nodes/registry/loader_spec.js | 26 ++++++------ .../nodes/registry/localfilesystem_spec.js | 21 ++++++---- 10 files changed, 74 insertions(+), 75 deletions(-) diff --git a/red/red.js b/red/red.js index 52328ff19b..8e978d5a30 100644 --- a/red/red.js +++ b/red/red.js @@ -38,7 +38,7 @@ function checkBuild() { } } -var RED = { +module.exports = { init: function(httpServer,userSettings) { server = httpServer; @@ -79,12 +79,12 @@ var RED = { }) }, nodes: runtime.api, - events: runtime.events, log: runtime.log, - comms: api.comms, settings:runtime.settings, util: runtime.util, version: runtime.version, + + comms: api.comms, library: api.library, auth: api.auth, @@ -93,5 +93,3 @@ var RED = { get httpNode() { return nodeApp }, get server() { return server } }; - -module.exports = RED; diff --git a/red/runtime/index.js b/red/runtime/index.js index 94153ba239..c277117a27 100644 --- a/red/runtime/index.js +++ b/red/runtime/index.js @@ -66,7 +66,7 @@ function start() { } log.info(log._("runtime.version",{component:"Node.js ",version:process.version})); log.info(log._("server.loading")); - redNodes.init(settings,storage); + redNodes.init(runtime); return redNodes.load().then(function() { var i; diff --git a/red/runtime/nodes/index.js b/red/runtime/nodes/index.js index 1f30500b84..371e4cead2 100644 --- a/red/runtime/nodes/index.js +++ b/red/runtime/nodes/index.js @@ -64,11 +64,11 @@ function createNode(node,def) { } } -function init(_settings,storage) { - settings = _settings; - credentials.init(storage); - flows.init(_settings,storage); - registry.init(_settings); +function init(runtime) { + settings = runtime.settings; + credentials.init(runtime.storage); + flows.init(runtime.settings,runtime.storage); + registry.init(runtime); } function disableNode(id) { diff --git a/red/runtime/nodes/registry/index.js b/red/runtime/nodes/registry/index.js index af39bdca76..928fe7c76b 100644 --- a/red/runtime/nodes/registry/index.js +++ b/red/runtime/nodes/registry/index.js @@ -25,11 +25,11 @@ var installer = require("./installer"); var settings; -function init(_settings) { - settings = _settings; - installer.init(settings); - loader.init(settings); - registry.init(settings,loader); +function init(runtime) { + settings = runtime.settings; + installer.init(runtime.settings); + loader.init(runtime); + registry.init(runtime.settings,loader); } function addModule(module) { diff --git a/red/runtime/nodes/registry/loader.js b/red/runtime/nodes/registry/loader.js index 2cc57fc41b..1dfe2906fb 100644 --- a/red/runtime/nodes/registry/loader.js +++ b/red/runtime/nodes/registry/loader.js @@ -19,23 +19,25 @@ var fs = require("fs"); var path = require("path"); var semver = require("semver"); -var events = require("../../events"); - var localfilesystem = require("./localfilesystem"); var registry = require("./registry"); var RED; var settings; +var runtime; -var i18n = require("../../i18n"); - -events.on("node-locales-dir", function(info) { - i18n.registerMessageCatalog(info.namespace,info.dir,info.file); -}); +function registerMessageCatalog(info) { + runtime.i18n.registerMessageCatalog(info.namespace,info.dir,info.file); +} -function init(_settings) { - settings = _settings; - localfilesystem.init(settings); +function init(_runtime) { + runtime = _runtime; + settings = runtime.settings; + localfilesystem.init(runtime); + if (runtime.events) { + runtime.events.removeListener("node-locales-dir", registerMessageCatalog); + runtime.events.on("node-locales-dir", registerMessageCatalog); + } RED = require('../../../red'); } @@ -55,7 +57,7 @@ function loadNodeFiles(nodeFiles) { /* istanbul ignore else */ if (nodeFiles.hasOwnProperty(module)) { if (nodeFiles[module].redVersion && - !semver.satisfies(RED.version().replace("-git",""), nodeFiles[module].redVersion)) { + !semver.satisfies(runtime.version().replace("-git",""), nodeFiles[module].redVersion)) { //TODO: log it continue; } @@ -195,7 +197,7 @@ function loadNodeConfig(fileInfo) { fs.stat(path.join(path.dirname(file),"locales"),function(err,stat) { if (!err) { node.namespace = node.id; - i18n.registerMessageCatalog(node.id, + runtime.i18n.registerMessageCatalog(node.id, path.join(path.dirname(file),"locales"), path.basename(file,".js")+".json") .then(function() { @@ -211,20 +213,6 @@ function loadNodeConfig(fileInfo) { }); } - -//function getAPIForNode(node) { -// var red = { -// nodes: RED.nodes, -// library: RED.library, -// credentials: RED.credentials, -// events: RED.events, -// log: RED.log, -// -// } -// -//} - - /** * Loads the specified node into the runtime * @param node a node info object - see loadNodeConfig diff --git a/red/runtime/nodes/registry/localfilesystem.js b/red/runtime/nodes/registry/localfilesystem.js index dd81e14342..7cf2c5e6bc 100644 --- a/red/runtime/nodes/registry/localfilesystem.js +++ b/red/runtime/nodes/registry/localfilesystem.js @@ -18,15 +18,18 @@ var when = require("when"); var fs = require("fs"); var path = require("path"); -var events = require("../../events"); -var log = require("../../log"); +var events; +var log; var settings; var defaultNodesDir = path.resolve(path.join(__dirname,"..","..","..","..","nodes")); var disableNodePathScan = false; -function init(_settings,_defaultNodesDir,_disableNodePathScan) { - settings = _settings; +function init(runtime,_defaultNodesDir,_disableNodePathScan) { + settings = runtime.settings; + events = runtime.events; + log = runtime.log; + if (_disableNodePathScan) { disableNodePathScan = _disableNodePathScan; } diff --git a/test/red/runtime/nodes/credentials_spec.js b/test/red/runtime/nodes/credentials_spec.js index 3869404433..c0f10de715 100644 --- a/test/red/runtime/nodes/credentials_spec.js +++ b/test/red/runtime/nodes/credentials_spec.js @@ -213,7 +213,7 @@ describe('Credentials', function() { var settings = { available: function() { return false;} } - index.init(settings, storage); + index.init({settings:settings, storage:storage}); index.registerType('test', TestNode); index.loadFlows().then(function() { var testnode = new TestNode({id:'tab1',type:'test',name:'barney'}); diff --git a/test/red/runtime/nodes/index_spec.js b/test/red/runtime/nodes/index_spec.js index 3167c86a83..09dcb208e3 100644 --- a/test/red/runtime/nodes/index_spec.js +++ b/test/red/runtime/nodes/index_spec.js @@ -59,6 +59,11 @@ describe("red/nodes/index", function() { available: function() { return false } }; + var runtime = { + settings: settings, + storage: storage + }; + function TestNode(n) { index.createNode(this, n); var node = this; @@ -68,7 +73,7 @@ describe("red/nodes/index", function() { } it('nodes are initialised with credentials',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { var testnode = new TestNode({id:'tab1',type:'test',name:'barney'}); @@ -81,7 +86,7 @@ describe("red/nodes/index", function() { }); it('flows should be initialised',function(done) { - index.init(settings, storage); + index.init(runtime); index.loadFlows().then(function() { should.deepEqual(testFlows, index.getFlows()); done(); @@ -168,7 +173,7 @@ describe("red/nodes/index", function() { }); it(': allows an unused node type to be disabled',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { var info = index.disableNode("5678"); @@ -182,7 +187,7 @@ describe("red/nodes/index", function() { }); it(': prevents disabling a node type that is in use',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { /*jshint immed: false */ @@ -197,7 +202,7 @@ describe("red/nodes/index", function() { }); it(': prevents disabling a node type that is unknown',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { /*jshint immed: false */ @@ -250,7 +255,7 @@ describe("red/nodes/index", function() { }); it(': prevents removing a module that is in use',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { /*jshint immed: false */ @@ -265,7 +270,7 @@ describe("red/nodes/index", function() { }); it(': prevents removing a module that is unknown',function(done) { - index.init(settings, storage); + index.init(runtime); index.registerType('test', TestNode); index.loadFlows().then(function() { /*jshint immed: false */ diff --git a/test/red/runtime/nodes/registry/loader_spec.js b/test/red/runtime/nodes/registry/loader_spec.js index 39637d6f32..18e9e6ee51 100644 --- a/test/red/runtime/nodes/registry/loader_spec.js +++ b/test/red/runtime/nodes/registry/loader_spec.js @@ -44,7 +44,7 @@ describe("red/nodes/registry/loader",function() { }) describe("#init",function() { it("init",function() { - loader.init({}); + loader.init({events:{on:function(){},removeListener:function(){}}}); localfilesystem.init.called.should.be.true; }); }); @@ -53,7 +53,7 @@ describe("red/nodes/registry/loader",function() { it("load empty set without settings available", function(done) { stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); - loader.init({available:function(){return false;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return false;}}}); loader.load("foo",true).then(function() { localfilesystem.getNodeFiles.called.should.be.true; localfilesystem.getNodeFiles.lastCall.args[0].should.eql('foo'); @@ -65,7 +65,7 @@ describe("red/nodes/registry/loader",function() { it("load empty set with settings available triggers registery save", function(done) { stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){ return {};})); stubs.push(sinon.stub(registry,"saveNodeList", function(){ return {};})); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load("foo",true).then(function() { registry.saveNodeList.called.should.be.true; done(); @@ -96,7 +96,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { registry.addNodeSet.called.should.be.true; registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode1"); @@ -143,7 +143,7 @@ describe("red/nodes/registry/loader",function() { // This module isn't already loaded stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { registry.addNodeSet.called.should.be.true; registry.addNodeSet.lastCall.args[0].should.eql("node-red/MultipleNodes1"); @@ -194,7 +194,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { registry.addNodeSet.called.should.be.true; registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode2"); @@ -243,7 +243,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { registry.addNodeSet.called.should.be.true; registry.addNodeSet.lastCall.args[0].should.eql("node-red/TestNode3"); @@ -290,7 +290,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.load().then(function(result) { registry.addNodeSet.called.should.be.true; registry.addNodeSet.lastCall.args[0].should.eql("node-red/DoesNotExist"); @@ -317,7 +317,7 @@ describe("red/nodes/registry/loader",function() { describe("#addModule",function() { it("throws error if settings unavailable", function() { - loader.init({available:function(){return false;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return false;}}}); /*jshint immed: false */ (function(){ loader.addModule("test-module"); @@ -326,7 +326,7 @@ describe("red/nodes/registry/loader",function() { it("returns rejected error if module already loaded", function(done) { stubs.push(sinon.stub(registry,"getModuleInfo",function(){return{}})); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.addModule("test-module").otherwise(function(err) { err.code.should.eql("module_already_loaded"); @@ -338,7 +338,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(localfilesystem,"getModuleFiles",function() { throw new Error("failure"); })); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.addModule("test-module").otherwise(function(err) { err.message.should.eql("failure"); done(); @@ -370,7 +370,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},settings:{available:function(){return true;}}}); loader.addModule("TestNodeModule").then(function(result) { result.should.eql("a node list"); registry.addNodeSet.calledOnce.should.be.true; @@ -420,7 +420,7 @@ describe("red/nodes/registry/loader",function() { stubs.push(sinon.stub(registry,"saveNodeList", function(){ return "a node list" })); stubs.push(sinon.stub(registry,"addNodeSet", function(){ return })); stubs.push(sinon.stub(nodes,"registerType")); - loader.init({available:function(){return true;}}); + loader.init({events:{on:function(){},removeListener:function(){}},version: function() { return "0.12.0"}, settings:{available:function(){return true;}}}); loader.addModule("TestNodeModule").then(function(result) { result.should.eql("a node list"); registry.addNodeSet.called.should.be.false; diff --git a/test/red/runtime/nodes/registry/localfilesystem_spec.js b/test/red/runtime/nodes/registry/localfilesystem_spec.js index 60120740ea..aa0c864aa2 100644 --- a/test/red/runtime/nodes/registry/localfilesystem_spec.js +++ b/test/red/runtime/nodes/registry/localfilesystem_spec.js @@ -45,7 +45,7 @@ describe("red/nodes/registry/localfilesystem",function() { } describe("#getNodeFiles",function() { it("Finds all the node files in the resources tree",function(done) { - localfilesystem.init({}); + localfilesystem.init({events:{emit:function(){}},settings:{}}); var nodeList = localfilesystem.getNodeFiles(resourcesDir,true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -56,7 +56,7 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); it("Excludes node files from settings",function(done) { - localfilesystem.init({nodesExcludes:['TestNode1.js']}); + localfilesystem.init({events:{emit:function(){}},settings:{nodesExcludes:['TestNode1.js']}}); var nodeList = localfilesystem.getNodeFiles(resourcesDir,true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -66,7 +66,7 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); it("Finds nodes in userDir/nodes",function(done) { - localfilesystem.init({userDir:userDir}); + localfilesystem.init({events:{emit:function(){}},settings:{userDir:userDir}}); var nodeList = localfilesystem.getNodeFiles(__dirname,true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -77,7 +77,7 @@ describe("red/nodes/registry/localfilesystem",function() { }); it("Finds nodes in settings.nodesDir (string)",function(done) { - localfilesystem.init({nodesDir:userDir}); + localfilesystem.init({events:{emit:function(){}},settings:{nodesDir:userDir}}); var nodeList = localfilesystem.getNodeFiles(__dirname,true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -87,7 +87,7 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); it("Finds nodes in settings.nodesDir (array)",function(done) { - localfilesystem.init({nodesDir:[userDir]}); + localfilesystem.init({events:{emit:function(){}},settings:{nodesDir:[userDir]}}); var nodeList = localfilesystem.getNodeFiles(__dirname,true); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -106,7 +106,7 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({}); + localfilesystem.init({events:{emit:function(){}},settings:{}}); var nodeList = localfilesystem.getNodeFiles(moduleDir,false); nodeList.should.have.a.property("node-red"); var nm = nodeList['node-red']; @@ -126,6 +126,9 @@ describe("red/nodes/registry/localfilesystem",function() { done(); }); + it.skip("finds locales directory"); + it.skip("finds icon path directory"); + }); describe("#getModuleFiles",function() { it("gets a nodes module files",function(done) { @@ -138,7 +141,7 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({},moduleDir,true); + localfilesystem.init({events:{emit:function(){}},settings:{}},moduleDir,true); var nodeModule = localfilesystem.getModuleFiles('TestNodeModule'); nodeModule.should.have.a.property('TestNodeModule'); nodeModule['TestNodeModule'].should.have.a.property('name','TestNodeModule'); @@ -162,12 +165,14 @@ describe("red/nodes/registry/localfilesystem",function() { } return _join.apply(null,arguments); })); - localfilesystem.init({},moduleDir,true); + localfilesystem.init({events:{emit:function(){}},settings:{}},moduleDir,true); /*jshint immed: false */ (function(){ localfilesystem.getModuleFiles('WontExistModule'); }).should.throw(); done(); }); + it.skip("finds locales directory"); + it.skip("finds icon path directory"); }); });