From 1c424463c4a77f0db5e14234d4acc2b6fbc10cdb Mon Sep 17 00:00:00 2001 From: Razvan Bordeanu Date: Wed, 28 Feb 2018 15:47:09 +0200 Subject: [PATCH 1/4] enable override of node properties and allow mustache templating --- lib/nodegen.js | 10 ++++++++ templates/swagger/node.js.mustache | 34 ++++++++++++++++--------- templates/swagger/package.json.mustache | 3 ++- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/lib/nodegen.js b/lib/nodegen.js index 005fd75..f516406 100644 --- a/lib/nodegen.js +++ b/lib/nodegen.js @@ -297,6 +297,16 @@ function swagger2node(data, options) { }, mustache: { nodeName: data.name, + isBodyParam: function() { + return function(param, render) { + return render('{{camelCaseName}}') === 'body' ? render(param) : ''; + } + }, + isNotBodyParam: function() { + return function(param, render) { + return render('{{camelCaseName}}') !== 'body' ? render(param) : ''; + } + } }, lint: false, beautify: false diff --git a/templates/swagger/node.js.mustache b/templates/swagger/node.js.mustache index 604fe1f..5211806 100644 --- a/templates/swagger/node.js.mustache +++ b/templates/swagger/node.js.mustache @@ -1,5 +1,6 @@ "use strict"; var lib = require('./lib.js'); +var mustache = require("mustache"); module.exports = function (RED) { function {{&className}}Node(config) { @@ -61,19 +62,28 @@ module.exports = function (RED) { var errorFlag = false; {{#methods}} if (node.method === '{{&methodName}}') { - var parameters = []; + var parameters = [], nodeParam, isTemplatedParam, param; {{#parameters}} - if ('{{&camelCaseName}}' === 'body') { - if (typeof msg.payload === 'object') { - parameters.{{&camelCaseName}} = msg.payload; - } else { - node.error('Unsupported type: \'' + (typeof msg.payload) + '\', ' - + 'msg.payload must be JSON object or buffer.'); - errorFlag = true; - } - } else { - parameters.{{&camelCaseName}} = node.{{&methodName}}_{{&camelCaseName}}; - } + {{#isBodyParam}} + if (typeof msg.payload === 'object') { + parameters.{{&camelCaseName}} = msg.payload; + } else { + node.error('Unsupported type: \'' + (typeof msg.payload) + '\', ' + + 'msg.payload must be JSON object or buffer.'); + errorFlag = true; + } + {{/isBodyParam}} + {{#isNotBodyParam}} + nodeParam = node.{{&methodName}}_{{&camelCaseName}}; + {{=<% %>=}} + isTemplatedParam = nodeParam.indexOf('{{') != -1; + <%={{ }}=%> + param = nodeParam || msg.{{&camelCaseName}}; + if (isTemplatedParam) { + param = mustache.render(nodeParam, msg); + } + parameters.{{&camelCaseName}} = param || ''; + {{/isNotBodyParam}} {{/parameters}} result = client.{{&methodName}}(parameters); } diff --git a/templates/swagger/package.json.mustache b/templates/swagger/package.json.mustache index 05914ae..d341a3d 100644 --- a/templates/swagger/package.json.mustache +++ b/templates/swagger/package.json.mustache @@ -15,7 +15,8 @@ ], "dependencies": { "q": "1.5.1", - "request": "2.83.0" + "request": "2.83.0", + "mustache": "2.3.0" }, "author": "{{&contactName}}", "license": "{{&licenseName}}" From c4cf5b09e1554b35cc9b15e49da7663c3b4d4c65 Mon Sep 17 00:00:00 2001 From: Razvan Bordeanu Date: Fri, 2 Mar 2018 02:23:32 +0200 Subject: [PATCH 2/4] change param fields to typedInput + cleanup code generation --- lib/nodegen.js | 54 +++++++++++-------- .../swagger/locales/en-US/node.json.mustache | 2 +- templates/swagger/node.html.mustache | 49 ++++++++--------- templates/swagger/node.js.mustache | 39 ++++++-------- 4 files changed, 76 insertions(+), 68 deletions(-) diff --git a/lib/nodegen.js b/lib/nodegen.js index f516406..3717952 100644 --- a/lib/nodegen.js +++ b/lib/nodegen.js @@ -90,7 +90,7 @@ function runNpmPack(data) { function extractKeywords(keywordsStr) { var keywords = ["node-red-nodegen"]; - keywords = keywordsStr ? keywords.concat(csv.parse(keywordsStr)[0]) : keywords; + keywords = keywordsStr ? keywords.concat(csv.parse(keywordsStr)[0]) : keywords; keywords = keywords.map(k => ({ name: k })); keywords[keywords.length - 1].last = true; return keywords; @@ -200,7 +200,7 @@ function swagger2node(data, options) { } else if (key === 'default') { // 3. Handle swagger-js-codegen bug return undefined; } else if (key === 'operationId') { // 4. Sanitize 'operationId' (remove special chars) - return value.replace(/(?!\w|\s)./g, ''); + return value.replace(/(?!\w|\s)./g, ''); } else { return value; } @@ -257,7 +257,7 @@ function swagger2node(data, options) { nodejsSourceCode = obfuscator.obfuscate(nodejsSourceCode, { stringArrayEncoding: 'rc4' }); } fs.writeFileSync(data.dst + '/' + data.module + '/lib.js', nodejsSourceCode); - + // Create package.json var packageSourceCode = CodeGen.getCustomCode({ className: className, @@ -286,6 +286,24 @@ function swagger2node(data, options) { }); fs.writeFileSync(data.dst + '/' + data.module + '/package.json', packageSourceCode); + // Mustache helpers + var isNotBodyParam = function () { + return function (content, render) { + return render('{{camelCaseName}}') !== 'body' ? render(content) : ''; + } + }; + var isBodyParam = function () { + return function (content, render) { + return render('{{camelCaseName}}') === 'body' ? render(content) : ''; + } + }; + var hasOptionalParams = function () { + return function (content, render) { + var params = render('{{#parameters}}{{^required}}{{camelCaseName}},{{/required}}{{/parameters}}'); + return params.split(',').filter(p => p).some(p => p !== 'body') ? render(content) : ''; + } + }; + // Create node.js var nodeSourceCode = CodeGen.getCustomCode({ className: className, @@ -297,16 +315,8 @@ function swagger2node(data, options) { }, mustache: { nodeName: data.name, - isBodyParam: function() { - return function(param, render) { - return render('{{camelCaseName}}') === 'body' ? render(param) : ''; - } - }, - isNotBodyParam: function() { - return function(param, render) { - return render('{{camelCaseName}}') !== 'body' ? render(param) : ''; - } - } + isBodyParam: isBodyParam, + isNotBodyParam: isNotBodyParam }, lint: false, beautify: false @@ -327,7 +337,9 @@ function swagger2node(data, options) { }, mustache: { nodeName: data.name, - category: data.category || 'function' + category: data.category || 'function', + isNotBodyParam: isNotBodyParam, + hasOptionalParams: hasOptionalParams }, lint: false, beautify: false @@ -436,7 +448,7 @@ function widget2node(data, options) { } } else { - new_src = new_src +part +"\n"; + new_src = new_src + part + "\n"; } }); @@ -478,33 +490,33 @@ function widget2node(data, options) { params[name] = conf.vars[name]; } } - + var basedir = __dirname + '/../templates/widget'; createCommonFiles(basedir, data); // Create package.json - var packageTemplate = fs.readFileSync(basedir+'/package.json.mustache', 'utf-8'); + var packageTemplate = fs.readFileSync(basedir + '/package.json.mustache', 'utf-8'); var packageSourceCode = mustache.render(packageTemplate, params); fs.writeFileSync(data.dst + '/' + data.module + '/package.json', packageSourceCode); // Create node.js - var nodeTemplate = fs.readFileSync(basedir+'/node.js.mustache', 'utf-8'); + var nodeTemplate = fs.readFileSync(basedir + '/node.js.mustache', 'utf-8'); var nodeSourceCode = mustache.render(nodeTemplate, params); fs.writeFileSync(data.dst + '/' + data.module + '/node.js', nodeSourceCode); // Create node.html - var htmlTemplate = fs.readFileSync(basedir+'/node.html.mustache', 'utf-8'); + var htmlTemplate = fs.readFileSync(basedir + '/node.html.mustache', 'utf-8'); var htmlSourceCode = mustache.render(htmlTemplate, params); fs.writeFileSync(data.dst + '/' + data.module + '/node.html', htmlSourceCode); // Create README.md - var readmeTemplate = fs.readFileSync(basedir+'/README.md.mustache', 'utf-8'); + var readmeTemplate = fs.readFileSync(basedir + '/README.md.mustache', 'utf-8'); var readmeSourceCode = mustache.render(readmeTemplate, params); fs.writeFileSync(data.dst + '/' + data.module + '/README.md', readmeSourceCode); // Create LICENSE file - var licenseTemplate = fs.readFileSync(basedir+'/LICENSE.mustache', 'utf-8'); + var licenseTemplate = fs.readFileSync(basedir + '/LICENSE.mustache', 'utf-8'); var licenseSourceCode = mustache.render(licenseTemplate, params); fs.writeFileSync(data.dst + '/' + data.module + '/LICENSE', licenseSourceCode); diff --git a/templates/swagger/locales/en-US/node.json.mustache b/templates/swagger/locales/en-US/node.json.mustache index d86cdc0..b03633b 100644 --- a/templates/swagger/locales/en-US/node.json.mustache +++ b/templates/swagger/locales/en-US/node.json.mustache @@ -17,7 +17,7 @@ "{{&camelCaseName}}": "{{&camelCaseName}}", {{/parameters}} {{/methods}} - "optionalParameters": "Option" + "optionalParameters": "Options" } } } diff --git a/templates/swagger/node.html.mustache b/templates/swagger/node.html.mustache index 462c4d5..54a58ca 100644 --- a/templates/swagger/node.html.mustache +++ b/templates/swagger/node.html.mustache @@ -9,13 +9,14 @@ {{#methods}} {{#parameters}} {{&methodName}}_{{&camelCaseName}}: { value: "" }, + {{&methodName}}_{{&camelCaseName}}Type: {value: "str"}, {{/parameters}} {{/methods}} name: { value: "" } }, - inputs:1, - outputs:1, + inputs: 1, + outputs: 1, icon: "icon.png", label: function() { return this.name || "{{&nodeName}}"; @@ -31,7 +32,13 @@ var showParameters = function() { {{#methods}} {{#parameters}} + $("#node-input-{{&methodName}}_{{&camelCaseName}}").typedInput({ + default: 'str', + typeField: $("#node-input-{{&methodName}}_{{&camelCaseName}}Type"), + types: ['str', 'msg'] + }); $("#{{&methodName}}_{{&camelCaseName}}").hide(); + {{/parameters}} {{/methods}} @@ -39,24 +46,20 @@ $("#optional-parameters-label").hide(); {{#methods}} if ($("#node-input-method").val() === '{{&methodName}}') { - {{#parameters}} - {{^required}} - if ('{{&camelCaseName}}' !== 'body') { - $("#optional-parameters").show(); - $("#optional-parameters-label").show(); - } - {{/required}} - {{/parameters}} + {{#hasOptionalParams}} + $("#optional-parameters").show(); + $("#optional-parameters-label").show(); + {{/hasOptionalParams}} } {{/methods}} - + if ($("#optional-parameters").prop('checked')) { {{#methods}} if ($("#node-input-method").val() === '{{&methodName}}') { {{#parameters}} - if ('{{&camelCaseName}}' !== 'body') { - $("#{{&methodName}}_{{&camelCaseName}}").show(); - } + {{#isNotBodyParam}} + $("#{{&methodName}}_{{&camelCaseName}}").show(); + {{/isNotBodyParam}} {{/parameters}} } {{/methods}} @@ -65,9 +68,9 @@ if ($("#node-input-method").val() === '{{&methodName}}') { {{#parameters}} {{#required}} - if ('{{&camelCaseName}}' !== 'body') { - $("#{{&methodName}}_{{&camelCaseName}}").show(); - } + {{#isNotBodyParam}} + $("#{{&methodName}}_{{&camelCaseName}}").show(); + {{/isNotBodyParam}} {{/required}} {{/parameters}} } @@ -115,7 +118,7 @@ {{/methods}}   - + @@ -123,17 +126,14 @@ {{#parameters}}
- {{#tsType}} {{#isEnum}} @@ -142,13 +142,15 @@ {{#tsType}} {{^isEnum}} - + + {{/isEnum}} {{/tsType}}
+ {{/parameters}} {{/methods}} - +
@@ -301,4 +303,3 @@ {{/isSecureBasic}} {{/isSecure}} - diff --git a/templates/swagger/node.js.mustache b/templates/swagger/node.js.mustache index 5211806..9c8cdcc 100644 --- a/templates/swagger/node.js.mustache +++ b/templates/swagger/node.js.mustache @@ -11,6 +11,7 @@ module.exports = function (RED) { {{#methods}} {{#parameters}} this.{{&methodName}}_{{&camelCaseName}} = config.{{&methodName}}_{{&camelCaseName}}; + this.{{&methodName}}_{{&camelCaseName}}Type = config.{{&methodName}}_{{&camelCaseName}}Type || 'str'; {{/parameters}} {{/methods}} @@ -62,31 +63,26 @@ module.exports = function (RED) { var errorFlag = false; {{#methods}} if (node.method === '{{&methodName}}') { - var parameters = [], nodeParam, isTemplatedParam, param; + var parameters = [], nodeParam, nodeParamType, param; {{#parameters}} - {{#isBodyParam}} - if (typeof msg.payload === 'object') { - parameters.{{&camelCaseName}} = msg.payload; - } else { - node.error('Unsupported type: \'' + (typeof msg.payload) + '\', ' - + 'msg.payload must be JSON object or buffer.'); - errorFlag = true; - } - {{/isBodyParam}} - {{#isNotBodyParam}} - nodeParam = node.{{&methodName}}_{{&camelCaseName}}; - {{=<% %>=}} - isTemplatedParam = nodeParam.indexOf('{{') != -1; - <%={{ }}=%> - param = nodeParam || msg.{{&camelCaseName}}; - if (isTemplatedParam) { - param = mustache.render(nodeParam, msg); - } - parameters.{{&camelCaseName}} = param || ''; - {{/isNotBodyParam}} + {{#isBodyParam}} + if (typeof msg.payload === 'object') { + parameters.{{&camelCaseName}} = msg.payload; + } else { + node.error('Unsupported type: \'' + (typeof msg.payload) + '\', ' + + 'msg.payload must be JSON object or buffer.'); + errorFlag = true; + } + {{/isBodyParam}} + {{#isNotBodyParam}} + nodeParam = node.{{&methodName}}_{{&camelCaseName}}; + nodeParamType = node.{{&methodName}}_{{&camelCaseName}}Type; + parameters.{{&camelCaseName}} = nodeParamType === 'str' ? nodeParam || '' : msg[nodeParam]; + {{/isNotBodyParam}} {{/parameters}} result = client.{{&methodName}}(parameters); } + {{/methods}} if (!errorFlag) { node.status({ fill: "blue", shape: "dot", text: "{{&className}}.status.requesting" }); @@ -150,4 +146,3 @@ module.exports = function (RED) { } }); }; - From 78d4e1f4d32dba172c7cd80437268b7235295c95 Mon Sep 17 00:00:00 2001 From: Razvan Bordeanu Date: Fri, 2 Mar 2018 02:28:49 +0200 Subject: [PATCH 3/4] cleanup --- templates/swagger/node.js.mustache | 3 +-- templates/swagger/package.json.mustache | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/templates/swagger/node.js.mustache b/templates/swagger/node.js.mustache index 9c8cdcc..4f92d55 100644 --- a/templates/swagger/node.js.mustache +++ b/templates/swagger/node.js.mustache @@ -1,6 +1,5 @@ "use strict"; var lib = require('./lib.js'); -var mustache = require("mustache"); module.exports = function (RED) { function {{&className}}Node(config) { @@ -63,7 +62,7 @@ module.exports = function (RED) { var errorFlag = false; {{#methods}} if (node.method === '{{&methodName}}') { - var parameters = [], nodeParam, nodeParamType, param; + var parameters = [], nodeParam, nodeParamType; {{#parameters}} {{#isBodyParam}} if (typeof msg.payload === 'object') { diff --git a/templates/swagger/package.json.mustache b/templates/swagger/package.json.mustache index d341a3d..05914ae 100644 --- a/templates/swagger/package.json.mustache +++ b/templates/swagger/package.json.mustache @@ -15,8 +15,7 @@ ], "dependencies": { "q": "1.5.1", - "request": "2.83.0", - "mustache": "2.3.0" + "request": "2.83.0" }, "author": "{{&contactName}}", "license": "{{&licenseName}}" From b3a3802507ce38f171d4b007e161350ae372795c Mon Sep 17 00:00:00 2001 From: Razvan Bordeanu Date: Sat, 3 Mar 2018 02:08:29 +0200 Subject: [PATCH 4/4] fix message property retrieval --- templates/swagger/node.js.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/swagger/node.js.mustache b/templates/swagger/node.js.mustache index 4f92d55..4a11060 100644 --- a/templates/swagger/node.js.mustache +++ b/templates/swagger/node.js.mustache @@ -76,7 +76,7 @@ module.exports = function (RED) { {{#isNotBodyParam}} nodeParam = node.{{&methodName}}_{{&camelCaseName}}; nodeParamType = node.{{&methodName}}_{{&camelCaseName}}Type; - parameters.{{&camelCaseName}} = nodeParamType === 'str' ? nodeParam || '' : msg[nodeParam]; + parameters.{{&camelCaseName}} = nodeParamType === 'str' ? nodeParam || '' : RED.util.getMessageProperty(msg, nodeParam); {{/isNotBodyParam}} {{/parameters}} result = client.{{&methodName}}(parameters);