├── templates
├── webofthings
│ ├── icons
│ │ └── .gitkeep
│ ├── locales
│ │ └── .gitkeep
│ ├── LICENSE.mustache
│ ├── README.md.mustache
│ ├── package.json.mustache
│ └── node.html.mustache
├── subflow
│ ├── LICENSE.mustache
│ ├── README.md.mustache
│ ├── package.json.mustache
│ └── subflow.js.mustache
├── swagger
│ ├── LICENSE.mustache
│ ├── icons
│ │ └── icon.png
│ ├── locales
│ │ ├── ja
│ │ │ └── node.json.mustache
│ │ ├── zh-CN
│ │ │ └── node.json.mustache
│ │ ├── en-US
│ │ │ └── node.json.mustache
│ │ └── de-DE
│ │ │ └── node.json.mustache
│ ├── README.md.mustache
│ ├── package.json.mustache
│ ├── test
│ │ └── node_spec.js.mustache
│ ├── node.js.mustache
│ └── node.html.mustache
└── function
│ ├── README.md.mustache
│ ├── icons
│ └── icon.svg
│ ├── package.json.mustache
│ ├── examples
│ └── flow.json.mustache
│ ├── test
│ └── node_spec.js.mustache
│ ├── node.html.mustache
│ ├── LICENSE.mustache
│ └── node.js.mustache
├── docs
├── library.png
└── library_ja.png
├── samples
├── lower-case.js
├── MyLampThing.jsonld
├── qrcode.json
└── swagger.json
├── test
├── lib
│ ├── nodegen_spec.js
│ ├── webofthings_spec.js
│ ├── swagger_spec.js
│ ├── subflow_spec.js
│ └── function_spec.js
└── nodegen
│ ├── node-red-contrib-lowercase
│ └── node_spec.js
│ └── node-red-contrib-swagger-petstore
│ └── node_spec.js
├── .gitignore
├── .github
├── workflows
│ └── test.yml
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── lib
├── nodegen.js
├── subflow
│ └── index.js
├── util.js
├── function
│ └── index.js
├── webofthings
│ ├── index.js
│ └── wotutils.js
└── swagger
│ └── index.js
├── Gruntfile.js
├── package.json
├── README.md
├── bin
└── node-red-nodegen.js
└── LICENSE
/templates/webofthings/icons/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/webofthings/locales/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/templates/subflow/LICENSE.mustache:
--------------------------------------------------------------------------------
1 | {{&licenseName}}
2 |
--------------------------------------------------------------------------------
/templates/webofthings/LICENSE.mustache:
--------------------------------------------------------------------------------
1 | {{&licenseName}}
2 | {{&licenseUrl}}
3 |
--------------------------------------------------------------------------------
/templates/swagger/LICENSE.mustache:
--------------------------------------------------------------------------------
1 | #### {{&licenseName}}
2 |
3 | {{&licenseUrl}}
4 |
--------------------------------------------------------------------------------
/docs/library.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/node-red/node-red-nodegen/master/docs/library.png
--------------------------------------------------------------------------------
/docs/library_ja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/node-red/node-red-nodegen/master/docs/library_ja.png
--------------------------------------------------------------------------------
/samples/lower-case.js:
--------------------------------------------------------------------------------
1 | // name: lower-case
2 | // outputs: 1
3 | msg.payload = msg.payload.toLowerCase();
4 | return msg;
5 |
--------------------------------------------------------------------------------
/templates/swagger/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/node-red/node-red-nodegen/master/templates/swagger/icons/icon.png
--------------------------------------------------------------------------------
/test/lib/nodegen_spec.js:
--------------------------------------------------------------------------------
1 | const nodegen = require('../../lib/nodegen');
2 |
3 | describe('nodegen library', function () {
4 | });
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated files
2 | nodegen/*
3 |
4 | # Dependency directories
5 | node_modules
6 | node-red
7 |
8 | # Coverage result
9 | coverage
10 |
11 | # npm install log
12 | npm-debug.log.*
13 | package-lock.json
14 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 | on:
3 | push:
4 | branches: [ master ]
5 | pull_request:
6 | branches: [ master ]
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - uses: actions/setup-node@v2
13 | - run: npm install
14 | - run: npm test
15 |
--------------------------------------------------------------------------------
/templates/subflow/README.md.mustache:
--------------------------------------------------------------------------------
1 | {{&projectName}}
2 | =====================
3 |
4 | {{&description}}
5 |
6 | ## Install
7 |
8 | Run the following command in your Node-RED user directory - typically `~/.node-red`
9 |
10 | npm install {{&projectName}}
11 |
12 | {{#nodeRead}}
13 | ## Information
14 |
15 | {{&nodeRead}}
16 | {{/nodeRead}}
17 |
--------------------------------------------------------------------------------
/templates/function/README.md.mustache:
--------------------------------------------------------------------------------
1 | {{&projectName}}
2 | ================
3 |
4 | Node-RED node for {{&nodeName}}
5 |
6 | {{&description}}
7 |
8 | ## Install
9 |
10 | To install the stable version use the `Menu - Manage palette - Install`
11 | option and search for {{&projectName}}, or run the following
12 | command in your Node-RED user directory, typically `~/.node-red`
13 |
14 | npm install {{&projectName}}
15 |
16 | ## Information
17 |
18 | {{&nodeRead}}
--------------------------------------------------------------------------------
/templates/function/icons/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/templates/subflow/package.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{&projectName}}",
3 | "version": "{{&projectVersion}}",
4 | "description": "Node-RED node for {{&nodeName}}",
5 | "keywords": [
6 | {{#keywords}}
7 | "{{name}}"{{^last}}, {{/last}}
8 | {{/keywords}}
9 | ],
10 | "engines": {
11 | "node": ">=12.0.0"
12 | },
13 | "node-red": {
14 | "version": ">=1.3.7",
15 | "nodes": {
16 | "{{&nodeName}}": "subflow.js"
17 | }
18 | },
19 | {{#encoding}}
20 | "dependencies": {
21 | "crypto-js": "4.1.1"
22 | },
23 | {{/encoding}}
24 | "license": "{{&licenseName}}"
25 | }
26 |
--------------------------------------------------------------------------------
/templates/swagger/locales/ja/node.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "{{&className}}": {
3 | "label": {
4 | "service": "サービス",
5 | "method": "メソッド",
6 | "host": "ホスト",
7 | "header": "ヘッダ",
8 | "value": "値",
9 | "isQuery": "クエリ"
10 | },
11 | "status": {
12 | "requesting": "要求中"
13 | },
14 | "parameters": {
15 | {{#methods}}
16 | "{{&methodName}}": "{{&method}} {{&path}}",
17 | {{#parameters}}
18 | "{{&camelCaseName}}": "{{&name}}",
19 | {{/parameters}}
20 | {{/methods}}
21 | "optionalParameters": "任意項目"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/templates/swagger/locales/zh-CN/node.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "{{&className}}": {
3 | "label": {
4 | "service": "服务",
5 | "method": "方法",
6 | "host": "网络主机",
7 | "header": "字头段",
8 | "value": "值",
9 | "isQuery": "查询"
10 | },
11 | "status": {
12 | "requesting": "请求中"
13 | },
14 | "parameters": {
15 | {{#methods}}
16 | "{{&methodName}}": "{{&method}} {{&path}}",
17 | {{#parameters}}
18 | "{{&camelCaseName}}": "{{&name}}",
19 | {{/parameters}}
20 | {{/methods}}
21 | "optionalParameters": "可选项"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/templates/webofthings/README.md.mustache:
--------------------------------------------------------------------------------
1 | {{projectName}}
2 | ================
3 |
4 | Node-RED node for {{nodeName}}
5 |
6 | {{description}}
7 |
8 | ## Install
9 |
10 | To install the stable version use the `Menu - Manage palette - Install`
11 | option and search for {{projectName}}, or run the following
12 | command in your Node-RED user directory, typically `~/.node-red`
13 |
14 | npm install {{projectName}}
15 |
16 | ## Interactions
17 |
18 | ### Properties
19 |
20 | {{#properties}}
21 | - {{label}}: {{description}}
22 | {{/properties}}
23 |
24 | ### Actions
25 |
26 | {{#actions}}
27 | - {{label}}: {{description}}
28 | {{/actions}}
29 |
30 |
31 | ### Events
32 |
33 | {{#events}}
34 | - {{label}}: {{description}}
35 | {{/events}}
36 |
37 |
--------------------------------------------------------------------------------
/templates/swagger/locales/en-US/node.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "{{&className}}": {
3 | "label": {
4 | "service": "Service",
5 | "method": "Method",
6 | "host": "Host",
7 | "header": "Header",
8 | "value": "Value",
9 | "isQuery": "isQuery"
10 | },
11 | "status": {
12 | "requesting": "requesting"
13 | },
14 | "parameters": {
15 | {{#methods}}
16 | "{{&methodName}}": "{{&method}} {{&path}}",
17 | {{#parameters}}
18 | "{{&camelCaseName}}": "{{&name}}",
19 | {{/parameters}}
20 | {{/methods}}
21 | "optionalParameters": "Options"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/templates/function/package.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{&projectName}}",
3 | "version": "{{&projectVersion}}",
4 | "description": "Node-RED node for {{&nodeName}}",
5 | "main": "node.js",
6 | "scripts": {
7 | "test": "mocha \"test/**/*_spec.js\" --timeout 3000"
8 | },
9 | "engines": {
10 | "node": ">=12.0.0"
11 | },
12 | "node-red": {
13 | "version": ">=1.3.7",
14 | "nodes": {
15 | "{{&nodeName}}": "node.js"
16 | }
17 | },
18 | "keywords": [
19 | {{#keywords}}
20 | "{{name}}"{{^last}}, {{/last}}
21 | {{/keywords}}
22 | ],
23 | "devDependencies": {
24 | "mocha": "9.2.1",
25 | "node-red": "2.2.2",
26 | "node-red-node-test-helper": "0.2.7"
27 | },
28 | "license": "Apache-2.0"
29 | }
30 |
--------------------------------------------------------------------------------
/templates/swagger/locales/de-DE/node.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "{{&className}}": {
3 | "label": {
4 | "service": "Service",
5 | "method": "Methode",
6 | "host": "Host",
7 | "header": "Header",
8 | "value": "Wert",
9 | "isQuery": "Suchanfrage"
10 | },
11 | "status": {
12 | "requesting": "Anfrage..."
13 | },
14 | "parameters": {
15 | {{#methods}}
16 | "{{&methodName}}": "{{&method}} {{&path}}",
17 | {{#parameters}}
18 | "{{&camelCaseName}}": "{{&name}}",
19 | {{/parameters}}
20 | {{/methods}}
21 | "optionalParameters": "Optionen"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/templates/swagger/README.md.mustache:
--------------------------------------------------------------------------------
1 | {{&projectName}}
2 | ================
3 |
4 | Node-RED node for {{&nodeName}}
5 |
6 | {{&description}}
7 |
8 | ## Install
9 |
10 | To install the stable version use the `Menu - Manage palette - Install`
11 | option and search for {{&projectName}}, or run the following
12 | command in your Node-RED user directory, typically `~/.node-red`
13 |
14 | npm install {{&projectName}}
15 |
16 | ## Usage
17 |
18 | ### Methods
19 |
20 | {{#methods}}
21 | #### {{&method}} {{&path}}
22 |
23 | {{&summary}}
24 |
25 | {{#parameters}}
26 | {{&name}} : {{&type}}
27 | {{/parameters}}
28 |
29 | {{#headers}}
30 | {{&name}} : {{&value}}
31 | {{/headers}}
32 |
33 | {{/methods}}
34 |
35 | ## License
36 |
37 | #### {{&licenseName}}
38 |
39 | {{&licenseUrl}}
--------------------------------------------------------------------------------
/templates/swagger/package.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{&projectName}}",
3 | "version": "{{&projectVersion}}",
4 | "description": "Node-RED node for {{&nodeName}}",
5 | "main": "node.js",
6 | "scripts": {
7 | "test": "mocha \"test/**/*_spec.js\" --timeout 3000"
8 | },
9 | "engines": {
10 | "node": ">=12.0.0"
11 | },
12 | "node-red": {
13 | "version": ">=1.3.7",
14 | "nodes": {
15 | "{{&nodeName}}": "node.js"
16 | }
17 | },
18 | "keywords": [
19 | {{#keywords}}
20 | "{{name}}"{{^last}}, {{/last}}
21 | {{/keywords}}
22 | ],
23 | "dependencies": {
24 | "q": "1.5.1",
25 | "request": "2.88.2",
26 | "file-type": "16.5.3"
27 | },
28 | "devDependencies": {
29 | "mocha": "9.2.1",
30 | "node-red": "2.2.2",
31 | "node-red-node-test-helper": "0.2.7"
32 | },
33 | "author": "{{&contactName}}",
34 | "license": "{{&licenseName}}"
35 | }
36 |
--------------------------------------------------------------------------------
/templates/webofthings/package.json.mustache:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{&projectName}}",
3 | "version": "{{&projectVersion}}",
4 | "description": "Node-RED node for {{&nodeName}}",
5 | "main": "node.js",
6 | "scripts": {
7 | "test": "mocha \"test/**/*_spec.js\""
8 | },
9 | "engines": {
10 | "node": ">=12.0.0"
11 | },
12 | "node-red": {
13 | "version": ">=1.3.7",
14 | "nodes": {
15 | "{{&nodeName}}": "node.js"
16 | }
17 | },
18 | "keywords": [
19 | {{#keywords}}
20 | "{{name}}"{{^last}}, {{/last}}
21 | {{/keywords}}
22 | ],
23 | "dependencies": {
24 | "https-proxy-agent": "5.0.0",
25 | "request": "2.88.2",
26 | "ws": "8.5.0",
27 | "url-template": "2.0.8",
28 | "ajv": "8.11.0",
29 | "coap": "1.0.3",
30 | "mqtt": "4.3.7"
31 | },
32 | "devDependencies": {
33 | "node-red": "2.2.2",
34 | "node-red-node-test-helper": "0.2.7"
35 | },
36 | "license": "{{&licenseName}}",
37 | "wot": {
38 | {{#wotmeta}}
39 | "{{name}}": "{{value}}"{{^last}}, {{/last}}
40 | {{/wotmeta}}
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/samples/MyLampThing.jsonld:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://www.w3.org/2019/wot/td/v1",
4 | { "saref": "https://w3id.org/saref#" }
5 | ],
6 | "id": "urn:dev:ops:32473-WoTLamp-1234",
7 | "title": "MyLampThing",
8 | "@type": "saref:LightSwitch",
9 | "securityDefinitions": {"basic_sc": {
10 | "scheme": "basic",
11 | "in": "header"
12 | }},
13 | "security": ["basic_sc"],
14 | "properties": {
15 | "status": {
16 | "@type": "saref:OnOffState",
17 | "type": "string",
18 | "forms": [{
19 | "href": "https://mylamp.example.com/status"
20 | }]
21 | }
22 | },
23 | "actions": {
24 | "toggle": {
25 | "@type": "saref:ToggleCommand",
26 | "forms": [{
27 | "href": "https://mylamp.example.com/toggle"
28 | }]
29 | }
30 | },
31 | "events": {
32 | "overheating": {
33 | "data": {"type": "string"},
34 | "forms": [{
35 | "href": "https://mylamp.example.com/oh"
36 | }]
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/lib/nodegen.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright OpenJS Foundation and other contributors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | **/
16 |
17 | const FunctionNodeGenerator = require("./function");
18 | const SwaggerNodeGenerator = require("./swagger");
19 | const WebOfThingsGenerator = require("./webofthings");
20 | const SubflowNodeGenerator = require("./subflow");
21 |
22 | module.exports = {
23 | FunctionNodeGenerator: FunctionNodeGenerator,
24 | SwaggerNodeGenerator: SwaggerNodeGenerator,
25 | WebOfThingsGenerator: WebOfThingsGenerator,
26 | SubflowNodeGenerator: SubflowNodeGenerator
27 | };
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
21 |
22 | ### What are the steps to reproduce?
23 |
24 | ### What happens?
25 |
26 | ### What do you expect to happen?
27 |
28 | ### Please tell us about your environment:
29 |
30 | - [ ] Node generator version:
31 | - [ ] Node-RED version:
32 | - [ ] Node.js version:
33 | - [ ] npm version:
34 | - [ ] Platform/OS:
35 | - [ ] Browser:
36 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | grunt.initConfig({
3 | shell: {
4 | generateNode_Function: {
5 | command: 'node bin/node-red-nodegen.js samples/lower-case.js -o ./nodegen'
6 | },
7 | generateNode_Swagger: {
8 | command: 'node bin/node-red-nodegen.js samples/swagger.json -o ./nodegen'
9 | },
10 | generateNode_WebOfThings: {
11 | command: 'node bin/node-red-nodegen.js samples/MyLampThing.jsonld -o ./nodegen'
12 | }
13 | },
14 | simplemocha: {
15 | options: {
16 | timeout: 10000,
17 | retries: 10
18 | },
19 | all: {
20 | src: [ 'test/**/*_spec.js' ]
21 | }
22 | },
23 | mocha_istanbul: {
24 | options: {
25 | timeout: 10000
26 | },
27 | all: {
28 | src: [ 'test/**/*_spec.js' ]
29 | }
30 | }
31 | });
32 | grunt.file.mkdir('nodegen');
33 | grunt.loadNpmTasks('grunt-shell');
34 | grunt.loadNpmTasks('grunt-simple-mocha');
35 | grunt.registerTask('default', ['shell', 'simplemocha']);
36 | };
37 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
12 |
13 | - [ ] Bugfix (non-breaking change which fixes an issue)
14 | - [ ] New feature (non-breaking change which adds functionality)
15 |
16 |
23 |
24 | ## Proposed changes
25 |
26 |
27 |
28 | ## Checklist
29 |
30 |
31 | - [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
32 | - [ ] For non-bugfix PRs, I have discussed this change on the mailing list/slack team.
33 | - [ ] I have run `grunt` to verify the unit tests pass
34 | - [ ] I have added suitable unit tests to cover the new/changed functionality
35 |
--------------------------------------------------------------------------------
/templates/function/examples/flow.json.mustache:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "786d9ce1.c1c3a4",
4 | "type": "inject",
5 | "z": "7b8f4430.ec912c",
6 | "name": "",
7 | "props": [
8 | {
9 | "p": "payload"
10 | },
11 | {
12 | "p": "topic",
13 | "vt": "str"
14 | }
15 | ],
16 | "repeat": "",
17 | "crontab": "",
18 | "once": false,
19 | "onceDelay": 0.1,
20 | "topic": "",
21 | "payload": "",
22 | "payloadType": "date",
23 | "x": 0,
24 | "y": 0,
25 | "wires": [
26 | [
27 | "726f08b3.50bfd8"
28 | ]
29 | ]
30 | },
31 | {
32 | "id": "726f08b3.50bfd8",
33 | "type": "{{&nodeName}}",
34 | "z": "7b8f4430.ec912c",
35 | "name": "",
36 | "x": 200,
37 | "y": 0,
38 | "wires": [
39 | [
40 | "82d40348.2d47b"
41 | ]
42 | ]
43 | },
44 | {
45 | "id": "82d40348.2d47b",
46 | "type": "debug",
47 | "z": "7b8f4430.ec912c",
48 | "name": "",
49 | "active": true,
50 | "tosidebar": true,
51 | "console": false,
52 | "tostatus": false,
53 | "complete": "false",
54 | "statusVal": "",
55 | "statusType": "auto",
56 | "x": 400,
57 | "y": 0,
58 | "wires": []
59 | }
60 | ]
61 |
--------------------------------------------------------------------------------
/templates/function/test/node_spec.js.mustache:
--------------------------------------------------------------------------------
1 | var should = require("should");
2 | var helper = require("node-red-node-test-helper");
3 | var node = require("../node.js");
4 |
5 | helper.init(require.resolve('node-red'));
6 |
7 | describe('{{&nodeName}} node', function () {
8 |
9 | before(function (done) {
10 | helper.startServer(done);
11 | });
12 |
13 | after(function (done) {
14 | helper.stopServer(done);
15 | });
16 |
17 | afterEach(function () {
18 | helper.unload();
19 | });
20 |
21 | it('should be loaded', function (done) {
22 | var flow = [{ id: "n1", type: "{{&nodeName}}", name: "{{&nodeName}}" }];
23 | helper.load(node, flow, function () {
24 | var n1 = helper.getNode("n1");
25 | n1.should.have.property('name', '{{&nodeName}}');
26 | done();
27 | });
28 | });
29 |
30 | it('should have payload', function (done) {
31 | var flow = [
32 | { id: "n1", type: "{{&nodeName}}", name: "{{&nodeName}}", wires: [["n2"]] },
33 | { id: "n2", type: "helper" }
34 | ];
35 | helper.load(node, flow, function () {
36 | var n2 = helper.getNode("n2");
37 | var n1 = helper.getNode("n1");
38 | n2.on("input", function (msg) {
39 | msg.should.have.property('payload', '