Skip to content

Commit

Permalink
Skip loading node html if disableEditor set
Browse files Browse the repository at this point in the history
  • Loading branch information
knolleary committed Aug 13, 2020
1 parent dc81b7a commit 33855bc
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 110 deletions.
211 changes: 108 additions & 103 deletions packages/node_modules/@node-red/registry/lib/loader.js
Expand Up @@ -15,7 +15,7 @@
**/

var when = require("when");
var fs = require("fs");
var fs = require("fs-extra");
var path = require("path");
var semver = require("semver");

Expand Down Expand Up @@ -113,118 +113,123 @@ function loadNodeFiles(nodeFiles) {
});
}

function loadNodeConfig(fileInfo) {
return new Promise(function(resolve) {
var file = fileInfo.file;
var module = fileInfo.module;
var name = fileInfo.name;
var version = fileInfo.version;
async function loadNodeTemplate(node) {
return fs.readFile(node.template,'utf8').then(content => {
var types = [];

var id = module + "/" + name;
var info = registry.getNodeInfo(id);
var isEnabled = true;
if (info) {
if (info.hasOwnProperty("loaded")) {
throw new Error(file+" already loaded");
}
isEnabled = info.enabled;
}
var regExp = /<script (?:[^>]*)data-template-name\s*=\s*['"]([^'"]*)['"]/gi;
var match = null;

var node = {
id: id,
module: module,
name: name,
file: file,
template: file.replace(/\.js$/,".html"),
enabled: isEnabled,
loaded:false,
version: version,
local: fileInfo.local
};
if (fileInfo.hasOwnProperty("types")) {
node.types = fileInfo.types;
while ((match = regExp.exec(content)) !== null) {
types.push(match[1]);
}
node.types = types;

fs.readFile(node.template,'utf8', function(err,content) {
if (err) {
node.types = [];
if (err.code === 'ENOENT') {
if (!node.types) {
node.types = [];
}
node.err = "Error: "+node.template+" does not exist";
} else {
node.types = [];
node.err = err.toString();
}
resolve(node);
} else {
var types = [];
var langRegExp = /^<script[^>]* data-lang\s*=\s*['"](.+?)['"]/i;
regExp = /(<script[^>]* data-help-name=[\s\S]*?<\/script>)/gi;
match = null;
var mainContent = "";
var helpContent = {};
var index = 0;
while ((match = regExp.exec(content)) !== null) {
mainContent += content.substring(index,regExp.lastIndex-match[1].length);
index = regExp.lastIndex;
var help = content.substring(regExp.lastIndex-match[1].length,regExp.lastIndex);

var regExp = /<script (?:[^>]*)data-template-name\s*=\s*['"]([^'"]*)['"]/gi;
var match = null;
var lang = i18n.defaultLang;
if ((match = langRegExp.exec(help)) !== null) {
lang = match[1];
}
if (!helpContent.hasOwnProperty(lang)) {
helpContent[lang] = "";
}

while ((match = regExp.exec(content)) !== null) {
types.push(match[1]);
}
node.types = types;
helpContent[lang] += help;
}
mainContent += content.substring(index);

var langRegExp = /^<script[^>]* data-lang\s*=\s*['"](.+?)['"]/i;
regExp = /(<script[^>]* data-help-name=[\s\S]*?<\/script>)/gi;
match = null;
var mainContent = "";
var helpContent = {};
var index = 0;
while ((match = regExp.exec(content)) !== null) {
mainContent += content.substring(index,regExp.lastIndex-match[1].length);
index = regExp.lastIndex;
var help = content.substring(regExp.lastIndex-match[1].length,regExp.lastIndex);
node.config = mainContent;
node.help = helpContent;
// TODO: parse out the javascript portion of the template
//node.script = "";
for (var i=0;i<node.types.length;i++) {
if (registry.getTypeId(node.types[i])) {
node.err = node.types[i]+" already registered";
break;
}
}
return node
}).catch(err => {
node.types = [];
if (err.code === 'ENOENT') {
if (!node.types) {
node.types = [];
}
node.err = "Error: "+node.template+" does not exist";
} else {
node.types = [];
node.err = err.toString();
}
return node;
});
}

var lang = i18n.defaultLang;
if ((match = langRegExp.exec(help)) !== null) {
lang = match[1];
}
if (!helpContent.hasOwnProperty(lang)) {
helpContent[lang] = "";
}
async function loadNodeLocales(node) {
if (node.module === 'node-red') {
// do not look up locales directory for core nodes
node.namespace = node.module;
return node
}
return fs.stat(path.join(path.dirname(node.file),"locales")).then(stat => {
node.namespace = node.id;
return i18n.registerMessageCatalog(node.id,
path.join(path.dirname(node.file),"locales"),
path.basename(node.file,".js")+".json")
.then(() => node);
}).catch(err => {
node.namespace = node.module;
return node;
});
}

helpContent[lang] += help;
}
mainContent += content.substring(index);
async function loadNodeConfig(fileInfo) {
var file = fileInfo.file;
var module = fileInfo.module;
var name = fileInfo.name;
var version = fileInfo.version;

node.config = mainContent;
node.help = helpContent;
// TODO: parse out the javascript portion of the template
//node.script = "";
for (var i=0;i<node.types.length;i++) {
if (registry.getTypeId(node.types[i])) {
node.err = node.types[i]+" already registered";
break;
}
}
if (node.module === 'node-red') {
// do not look up locales directory for core nodes
node.namespace = node.module;
resolve(node);
return;
}
fs.stat(path.join(path.dirname(file),"locales"),function(err,stat) {
if (!err) {
node.namespace = node.id;
i18n.registerMessageCatalog(node.id,
path.join(path.dirname(file),"locales"),
path.basename(file,".js")+".json")
.then(function() {
resolve(node);
});
} else {
node.namespace = node.module;
resolve(node);
}
});
}
});
});
var id = module + "/" + name;
var info = registry.getNodeInfo(id);
var isEnabled = true;
if (info) {
if (info.hasOwnProperty("loaded")) {
throw new Error(file+" already loaded");
}
isEnabled = info.enabled;
}

var node = {
id: id,
module: module,
name: name,
file: file,
template: file.replace(/\.js$/,".html"),
enabled: isEnabled,
loaded:false,
version: version,
local: fileInfo.local,
types: [],
config: "",
help: {}
};
if (fileInfo.hasOwnProperty("types")) {
node.types = fileInfo.types;
}
await loadNodeLocales(node)
if (!settings.disableEditor) {
return loadNodeTemplate(node);
}
return node;
}

/**
Expand Down
80 changes: 73 additions & 7 deletions test/unit/@node-red/registry/lib/loader_spec.js
Expand Up @@ -18,7 +18,7 @@ var should = require("should");
var when = require("when");
var sinon = require("sinon");
var path = require("path");
var fs = require("fs");
var fs = require("fs-extra");

var NR_TEST_UTILS = require("nr-test-utils");

Expand Down Expand Up @@ -111,7 +111,73 @@ describe("red/nodes/registry/loader",function() {
module.nodes.TestNode1.types.should.have.a.length(1);
module.nodes.TestNode1.types[0].should.eql('test-node-1');
module.nodes.TestNode1.should.have.property("config");
module.nodes.TestNode1.config.should.not.eql("");
module.nodes.TestNode1.should.have.property("help");
module.nodes.TestNode1.help.should.have.property("en-US");
module.nodes.TestNode1.should.have.property("namespace","node-red");

nodes.registerType.calledOnce.should.be.true();
nodes.registerType.lastCall.args[0].should.eql('node-red/TestNode1');
nodes.registerType.lastCall.args[1].should.eql('test-node-1');

done();
}).catch(function(err) {
done(err);
});
});

it("load core node files scanned by lfs - ignore html if disableEditor true", function(done) {
stubs.push(sinon.stub(localfilesystem,"getNodeFiles", function(){
var result = {};
result["node-red"] = {
"name": "node-red",
"version": "1.2.3",
"nodes": {
"TestNode1": {
"file": path.join(resourcesDir,"TestNode1","TestNode1.js"),
"module": "node-red",
"name": "TestNode1"
}
}
};
return result;
}));

stubs.push(sinon.stub(registry,"saveNodeList", function(){ return }));
stubs.push(sinon.stub(registry,"addModule", function(){ return }));
// This module isn't already loaded
stubs.push(sinon.stub(registry,"getNodeInfo", function(){ return null; }));

stubs.push(sinon.stub(nodes,"registerType"));
loader.init({nodes:nodes,log:{info:function(){},_:function(){}},settings:{disableEditor: true, available:function(){return true;}}});
loader.load().then(function(result) {
registry.addModule.called.should.be.true();
var module = registry.addModule.lastCall.args[0];
module.should.have.property("name","node-red");
module.should.have.property("version","1.2.3");
module.should.have.property("nodes");
module.nodes.should.have.property("TestNode1");
module.nodes.TestNode1.should.have.property("id","node-red/TestNode1");
module.nodes.TestNode1.should.have.property("module","node-red");
module.nodes.TestNode1.should.have.property("name","TestNode1");
module.nodes.TestNode1.should.have.property("file");
module.nodes.TestNode1.should.have.property("template");
module.nodes.TestNode1.should.have.property("enabled",true);
module.nodes.TestNode1.should.have.property("loaded",true);
// With disableEditor true, the types property is not populated by the
// html file - but instead is populated as nodes register themselves.
// But for this test, we have stubbed out registerType, so we won't get any types
// module.nodes.TestNode1.should.have.property("types");
// module.nodes.TestNode1.types.should.have.a.length(1);
// module.nodes.TestNode1.types[0].should.eql('test-node-1');

// With disableEditor set, config should be blank
module.nodes.TestNode1.should.have.property("config");
module.nodes.TestNode1.config.should.eql("");

// help should be an empty object
module.nodes.TestNode1.should.have.property("help");
module.nodes.TestNode1.help.should.eql({})
module.nodes.TestNode1.should.have.property("namespace","node-red");

nodes.registerType.calledOnce.should.be.true();
Expand Down Expand Up @@ -336,9 +402,9 @@ describe("red/nodes/registry/loader",function() {
module.nodes.DoesNotExist.should.have.property("loaded",false);
module.nodes.DoesNotExist.should.have.property("types");
module.nodes.DoesNotExist.types.should.have.a.length(0);
module.nodes.DoesNotExist.should.not.have.property("config");
module.nodes.DoesNotExist.should.not.have.property("help");
module.nodes.DoesNotExist.should.not.have.property("namespace","node-red");
module.nodes.DoesNotExist.should.have.property("config","");
module.nodes.DoesNotExist.should.have.property("help",{});
module.nodes.DoesNotExist.should.have.property("namespace","node-red");
module.nodes.DoesNotExist.should.have.property('err');

nodes.registerType.called.should.be.false();
Expand Down Expand Up @@ -390,9 +456,9 @@ describe("red/nodes/registry/loader",function() {
module.nodes.DuffNode.should.have.property("loaded",false);
module.nodes.DuffNode.should.have.property("types");
module.nodes.DuffNode.types.should.have.a.length(0);
module.nodes.DuffNode.should.not.have.property("config");
module.nodes.DuffNode.should.not.have.property("help");
module.nodes.DuffNode.should.not.have.property("namespace","node-red");
module.nodes.DuffNode.should.have.property("config","");
module.nodes.DuffNode.should.have.property("help",{});
module.nodes.DuffNode.should.have.property("namespace","node-red");
module.nodes.DuffNode.should.have.property('err');
module.nodes.DuffNode.err.should.endWith("DuffNode.html does not exist");

Expand Down

0 comments on commit 33855bc

Please sign in to comment.