@gregoriusrippenstein/node-red-contrib-nodedev 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/nodes/10-node-factory.js +34 -2
- package/nodes/20-pkg-file.html +39 -0
- package/nodes/node-factory-sidebar-cfg.js +21 -3
- package/nodes/templates/locale/en-US/tmpl.html +4 -0
- package/nodes/templates/locale/en-US/tmpl.json +45 -0
- package/nodes/templates/tmpl.html +7 -12
- package/nodes/templates/tmpl.js +3 -3
- package/package.json +1 -1
- package/plugins/node-factory-sidebar.html +15 -11
package/README.md
CHANGED
|
@@ -62,10 +62,14 @@ Since all this happens in the browser, there is no leaving Node-RED, making it m
|
|
|
62
62
|
### Artifacts
|
|
63
63
|
|
|
64
64
|
- [Flow that maintains](https://flowhub.org/f/b92be5062203ff69) this codebase
|
|
65
|
-
- [GitHub repo](https://
|
|
65
|
+
- [GitHub repo](https://github.com/gorenje/node-red-contrib-nodedev)
|
|
66
66
|
- [NPMjs node package](https://www.npmjs.com/package/@gregoriusrippenstein/node-red-contrib-nodedev)
|
|
67
67
|
- [Node-RED node package](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-nodedev)
|
|
68
68
|
|
|
69
|
+
### Similar Projects
|
|
70
|
+
|
|
71
|
+
- [node-maker](https://github.com/steveorevo/node-maker) which helps to make UI components for nodes in Node-RED.
|
|
72
|
+
|
|
69
73
|
### Outlook
|
|
70
74
|
|
|
71
75
|
Wherever the road shall lead, there it will go.
|
package/nodes/10-node-factory.js
CHANGED
|
@@ -226,16 +226,22 @@ module.exports = function (RED) {
|
|
|
226
226
|
function createSimpleNodeDefintions(msg,node) {
|
|
227
227
|
var htmlPath = path.join(__dirname, 'templates', 'tmpl.html');
|
|
228
228
|
var jsPath = path.join(__dirname, 'templates', 'tmpl.js');
|
|
229
|
+
var localeJsonPath = path.join(__dirname, 'templates', 'locale', 'en-US', 'tmpl.json')
|
|
230
|
+
var localeHtmlPath = path.join(__dirname, 'templates', 'locale', 'en-US', 'tmpl.html')
|
|
229
231
|
|
|
230
232
|
var content = {};
|
|
231
233
|
|
|
232
234
|
var promises = [
|
|
233
235
|
handleTemplate(msg, node, fs.readFileSync(htmlPath, 'utf8')).then((c) => { content["html"] = c }),
|
|
234
236
|
handleTemplate(msg, node, fs.readFileSync(jsPath, 'utf8')).then((c) => { content["jasc"] = c }),
|
|
237
|
+
handleTemplate(msg, node, fs.readFileSync(localeJsonPath, 'utf8')).then((c) => { content["ljsn"] = c }),
|
|
238
|
+
handleTemplate(msg, node, fs.readFileSync(localeHtmlPath, 'utf8')).then((c) => { content["lhtm"] = c }),
|
|
235
239
|
];
|
|
236
240
|
|
|
237
241
|
return Promise.all(promises).then(() => {
|
|
238
242
|
var secondId = RED.util.generateId();
|
|
243
|
+
var thirdId = RED.util.generateId();
|
|
244
|
+
var fourthId = RED.util.generateId();
|
|
239
245
|
|
|
240
246
|
return [{
|
|
241
247
|
id: RED.util.generateId(),
|
|
@@ -250,7 +256,6 @@ module.exports = function (RED) {
|
|
|
250
256
|
y: 50,
|
|
251
257
|
wires: [[secondId]]
|
|
252
258
|
},
|
|
253
|
-
|
|
254
259
|
{
|
|
255
260
|
id: secondId,
|
|
256
261
|
type: "PkgFile",
|
|
@@ -262,8 +267,35 @@ module.exports = function (RED) {
|
|
|
262
267
|
output: "str",
|
|
263
268
|
x: 100,
|
|
264
269
|
y: 100,
|
|
270
|
+
wires: [[thirdId]]
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
id: thirdId,
|
|
274
|
+
type: "PkgFile",
|
|
275
|
+
name: "Locale: " + msg.node.name + ".json",
|
|
276
|
+
filename: "nodes/locales/en-US/" + msg.node.namelwr + ".json",
|
|
277
|
+
template: content["ljsn"],
|
|
278
|
+
syntax: "mustache",
|
|
279
|
+
format: "json",
|
|
280
|
+
output: "str",
|
|
281
|
+
x: 120,
|
|
282
|
+
y: 150,
|
|
283
|
+
wires: [[fourthId]]
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: fourthId,
|
|
287
|
+
type: "PkgFile",
|
|
288
|
+
name: "Locale: " + msg.node.name + ".html",
|
|
289
|
+
filename: "nodes/locales/en-US/" + msg.node.namelwr + ".html",
|
|
290
|
+
template: content["lhtm"],
|
|
291
|
+
syntax: "mustache",
|
|
292
|
+
format: "html",
|
|
293
|
+
output: "str",
|
|
294
|
+
x: 120,
|
|
295
|
+
y: 200,
|
|
265
296
|
wires: [[]]
|
|
266
|
-
}
|
|
297
|
+
}
|
|
298
|
+
]
|
|
267
299
|
})
|
|
268
300
|
}
|
|
269
301
|
|
package/nodes/20-pkg-file.html
CHANGED
|
@@ -47,6 +47,39 @@
|
|
|
47
47
|
</script>
|
|
48
48
|
|
|
49
49
|
<script type="text/javascript">
|
|
50
|
+
(function(){
|
|
51
|
+
|
|
52
|
+
var returnInfo = (that) => {
|
|
53
|
+
const escapeHTML = str =>
|
|
54
|
+
str.replace(
|
|
55
|
+
/[&<>'"]/g,
|
|
56
|
+
tag =>
|
|
57
|
+
({
|
|
58
|
+
'&': '&',
|
|
59
|
+
'<': '<',
|
|
60
|
+
'>': '>',
|
|
61
|
+
"'": ''',
|
|
62
|
+
'"': '"'
|
|
63
|
+
}[tag] || tag)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
switch(that.format) {
|
|
67
|
+
case 'markdown':
|
|
68
|
+
case 'text':
|
|
69
|
+
return that.template
|
|
70
|
+
|
|
71
|
+
case "json":
|
|
72
|
+
case "yaml":
|
|
73
|
+
case "javascript":
|
|
74
|
+
case "css":
|
|
75
|
+
return ["```" + that.format, that.template, "```"].join("\n")
|
|
76
|
+
|
|
77
|
+
case "html":
|
|
78
|
+
return ["```" + that.format, escapeHTML(that.template), "```"].join("\n")
|
|
79
|
+
}
|
|
80
|
+
return ""
|
|
81
|
+
};
|
|
82
|
+
|
|
50
83
|
RED.nodes.registerType('PkgFile',{
|
|
51
84
|
color:"#e5e4ef",
|
|
52
85
|
category: 'nodedev',
|
|
@@ -58,15 +91,20 @@
|
|
|
58
91
|
template: {value:""},
|
|
59
92
|
output: {value:"str"},
|
|
60
93
|
},
|
|
94
|
+
|
|
61
95
|
inputs:1,
|
|
62
96
|
outputs:1,
|
|
63
97
|
icon: "font-awesome/fa-file-o",
|
|
98
|
+
info: function() { return returnInfo(this) },
|
|
99
|
+
|
|
64
100
|
label: function() {
|
|
65
101
|
return this.name || this.filename || this._def.paletteLabel;
|
|
66
102
|
},
|
|
103
|
+
|
|
67
104
|
labelStyle: function() {
|
|
68
105
|
return this.name?"node_label_italic":"";
|
|
69
106
|
},
|
|
107
|
+
|
|
70
108
|
oneditprepare: function() {
|
|
71
109
|
const that = this;
|
|
72
110
|
const stateId = RED.editor.generateViewStateId("node", this, "");
|
|
@@ -132,4 +170,5 @@
|
|
|
132
170
|
this.editor.resize();
|
|
133
171
|
}
|
|
134
172
|
});
|
|
173
|
+
})();
|
|
135
174
|
</script>
|
|
@@ -66,6 +66,20 @@ module.exports = function (RED) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function createGroup(pkgname, pversion, allFiles) {
|
|
70
|
+
return {
|
|
71
|
+
"id": RED.util.generateId(),
|
|
72
|
+
"type": "group",
|
|
73
|
+
"name": "Package: " + pkgname + "@" + pversion,
|
|
74
|
+
"style": {
|
|
75
|
+
"label": true,
|
|
76
|
+
"label-position": "ne",
|
|
77
|
+
"color": "#001f60"
|
|
78
|
+
},
|
|
79
|
+
"nodes": allFiles.map( d => d.id )
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
69
83
|
RED.httpAdmin.post("/NodeFactorySidebarCfg",
|
|
70
84
|
RED.auth.needsPermission("nodedev.write"),
|
|
71
85
|
(req, res) => {
|
|
@@ -101,9 +115,13 @@ module.exports = function (RED) {
|
|
|
101
115
|
lastNode.wires[0].push(tarballNode.id)
|
|
102
116
|
|
|
103
117
|
allFiles.push(nodeDevOp);
|
|
104
|
-
allFiles.push(tarballNode)
|
|
105
|
-
allFiles.push(nrInstallNode)
|
|
106
|
-
|
|
118
|
+
allFiles.push(tarballNode);
|
|
119
|
+
allFiles.push(nrInstallNode);
|
|
120
|
+
|
|
121
|
+
allFiles = [
|
|
122
|
+
createGroup(msg.pkgname, nodeDevOp.pversion || msg.pkgversion, allFiles)
|
|
123
|
+
].concat(allFiles);
|
|
124
|
+
|
|
107
125
|
RED.comms.publish(
|
|
108
126
|
"nodedev:perform-autoimport-nodes",
|
|
109
127
|
RED.util.encodeObject({
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"{{ node.name }}": {
|
|
3
|
+
{{#node.bak2frtcomm}}
|
|
4
|
+
"label": {
|
|
5
|
+
"commfrombackend": "Backend sent something to the frontend - check browser console.",
|
|
6
|
+
"msgfrombackend": "message from backend"
|
|
7
|
+
{{ #node.frt2bakcomm }}
|
|
8
|
+
,
|
|
9
|
+
"submissionfailed": "submission failed",
|
|
10
|
+
"buttonpressed": "button pressed on frontend",
|
|
11
|
+
"success": "Successfully sent something to the backend"
|
|
12
|
+
{{ /node.frt2bakcomm }}
|
|
13
|
+
},
|
|
14
|
+
{{/node.bak2frtcomm}}
|
|
15
|
+
|
|
16
|
+
{{^node.bak2frtcomm}}
|
|
17
|
+
{{#node.frt2bakcomm }}
|
|
18
|
+
"label": {
|
|
19
|
+
"submissionfailed": "submission failed",
|
|
20
|
+
"buttonpressed": "button pressed on frontend",
|
|
21
|
+
"success": "Successfully sent something to the backend"
|
|
22
|
+
},
|
|
23
|
+
{{/node.frt2bakcomm }}
|
|
24
|
+
{{/node.bak2frtcomm}}
|
|
25
|
+
|
|
26
|
+
{{^node.bak2frtcomm}}
|
|
27
|
+
{{^node.frt2bakcomm }}
|
|
28
|
+
"label": {
|
|
29
|
+
"hello": "world"
|
|
30
|
+
},
|
|
31
|
+
{{/node.frt2bakcomm }}
|
|
32
|
+
{{/node.bak2frtcomm}}
|
|
33
|
+
|
|
34
|
+
"errors": {
|
|
35
|
+
|
|
36
|
+
},
|
|
37
|
+
"tip": {
|
|
38
|
+
|
|
39
|
+
},
|
|
40
|
+
"status": {
|
|
41
|
+
"waiting": "Waiting for Godot",
|
|
42
|
+
"timeout": "No more time to waiting"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}),
|
|
16
16
|
|
|
17
17
|
success: function (resp) {
|
|
18
|
-
RED.notify("
|
|
18
|
+
RED.notify( RED._("{{ node.name}}.label.success"), {
|
|
19
19
|
type: "warning",
|
|
20
20
|
id: "{{node.name}}",
|
|
21
21
|
timeout: 2000
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
this.messageFromBackendHandler = (topic,dataobj) => {
|
|
85
85
|
console.log( "here goes the code for handling a message from the backend", topic, dataobj);
|
|
86
86
|
|
|
87
|
-
RED.notify("
|
|
87
|
+
RED.notify(RED._("{{ node.name}}.label.commfrombackend"), {
|
|
88
88
|
type: "success",
|
|
89
89
|
id: "{{node.name}}",
|
|
90
90
|
timeout: 2000
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
|
|
126
126
|
{{ #node.frt2bakcomm }}
|
|
127
127
|
var that = this;
|
|
128
|
-
sendToBackend(that, {"payload": "
|
|
128
|
+
sendToBackend(that, {"payload": RED._("{{ node.name}}.label.buttonpressed")})
|
|
129
129
|
{{ /node.frt2bakcomm }}
|
|
130
130
|
|
|
131
131
|
/* here goes the button code to be executed on click */
|
|
@@ -138,13 +138,8 @@
|
|
|
138
138
|
</script>
|
|
139
139
|
|
|
140
140
|
<script type="text/html" data-template-name="{{ node.name }}">
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
</script>
|
|
146
|
-
|
|
147
|
-
<script type="text/html" data-help-name="{{ node.name }}">
|
|
148
|
-
<p>{{{ node.summary }}}</p>
|
|
149
|
-
{{{ node.description }}}
|
|
141
|
+
<div class="form-row">
|
|
142
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
|
143
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
|
144
|
+
</div>
|
|
150
145
|
</script>
|
package/nodes/templates/tmpl.js
CHANGED
|
@@ -14,8 +14,8 @@ module.exports = function(RED) {
|
|
|
14
14
|
{{#node.bak2frtcomm}}
|
|
15
15
|
RED.comms.publish("{{node.name}}:message-from-backend",
|
|
16
16
|
RED.util.encodeObject({
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
...msg,
|
|
18
|
+
"data": RED._("{{ node.name}}.label.msgfrombackend"),
|
|
19
19
|
})
|
|
20
20
|
);
|
|
21
21
|
{{/node.bak2frtcomm}}
|
|
@@ -49,7 +49,7 @@ module.exports = function(RED) {
|
|
|
49
49
|
} catch (err) {
|
|
50
50
|
console.error(err);
|
|
51
51
|
res.status(500).send(err.toString());
|
|
52
|
-
node.error("{{ node.name }}:
|
|
52
|
+
node.error("{{ node.name }}: " + RED._("{{ node.name }}.label.submissionfailed") + ": " + err.toString())
|
|
53
53
|
}
|
|
54
54
|
} else {
|
|
55
55
|
res.sendStatus(404);
|
package/package.json
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
contentType: "application/json; charset=utf-8",
|
|
12
12
|
|
|
13
13
|
data: JSON.stringify({
|
|
14
|
-
pkgname: $("#node-input-nodefactorysidebar-package-name").val(),
|
|
15
|
-
pkgversion: $("#node-input-nodefactorysidebar-package-version").val()
|
|
14
|
+
pkgname: $("#node-input-nodefactorysidebar-package-name").val().trim(),
|
|
15
|
+
pkgversion: $("#node-input-nodefactorysidebar-package-version").val().trim()
|
|
16
16
|
}),
|
|
17
17
|
|
|
18
18
|
success: function (resp) {
|
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
// --> more details: https://nodered.org/docs/api/ui/sidebar/
|
|
105
105
|
RED.sidebar.addTab({
|
|
106
106
|
id: "NodeFactorySidebar",
|
|
107
|
-
label: "
|
|
108
|
-
name: "
|
|
107
|
+
label: "Pkg Import", // short name for the tab
|
|
108
|
+
name: "Package Import", // long name for the menu
|
|
109
109
|
content: content,
|
|
110
110
|
closeable: true,
|
|
111
111
|
// disableOnEdit: true,
|
|
@@ -122,19 +122,17 @@
|
|
|
122
122
|
|
|
123
123
|
$('#node-input-nodefactorysidebar-generate-btn').on('click', doSomething );
|
|
124
124
|
|
|
125
|
-
$("#node-input-nodefactorysidebar-package-version").val(globalYourConfigNode.pkgversion);
|
|
126
|
-
|
|
127
125
|
$("#node-input-nodefactorysidebar-package-version").on("change", function() {
|
|
128
126
|
ensureYourConfigNodeExists();
|
|
129
127
|
|
|
130
128
|
let data = $(this).val();
|
|
131
129
|
|
|
132
130
|
if (globalYourConfigNode.pkgversion != data) {
|
|
133
|
-
globalYourConfigNode.pkgversion = data;
|
|
131
|
+
globalYourConfigNode.pkgversion = data.trim();
|
|
134
132
|
RED.nodes.dirty(true);
|
|
135
133
|
}
|
|
136
134
|
})
|
|
137
|
-
$("#node-input-nodefactorysidebar-package-
|
|
135
|
+
$("#node-input-nodefactorysidebar-package-version").val(globalYourConfigNode.pkgversion);
|
|
138
136
|
|
|
139
137
|
$("#node-input-nodefactorysidebar-package-name").on("change", function() {
|
|
140
138
|
ensureYourConfigNodeExists();
|
|
@@ -142,11 +140,11 @@
|
|
|
142
140
|
let data = $(this).val();
|
|
143
141
|
|
|
144
142
|
if (globalYourConfigNode.pkgname != data) {
|
|
145
|
-
globalYourConfigNode.pkgname = data;
|
|
143
|
+
globalYourConfigNode.pkgname = data.trim();
|
|
146
144
|
RED.nodes.dirty(true);
|
|
147
145
|
}
|
|
148
146
|
})
|
|
149
|
-
|
|
147
|
+
$("#node-input-nodefactorysidebar-package-name").val(globalYourConfigNode.pkgname);
|
|
150
148
|
};
|
|
151
149
|
|
|
152
150
|
RED.events.on('runtime-state', initialiseConfigNodeOnce);
|
|
@@ -156,6 +154,12 @@
|
|
|
156
154
|
<!-- The html for the right sidebar plugin screen -->
|
|
157
155
|
<script type="text/x-red" data-template-name="NodeFactorySidebar">
|
|
158
156
|
<div class="form-row" style="margin-left: 10px; margin-top: 30px;">
|
|
157
|
+
Import <a href="https://npmjs.com" target=_blank>npmJs.com</a> packages as a flow. packages
|
|
158
|
+
are imported as a collection of PkgFile nodes. This can help to learn from other
|
|
159
|
+
peoples experiences and code.
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<div class="form-row" style="margin-left: 10px;">
|
|
159
163
|
Enter package details here:
|
|
160
164
|
</div>
|
|
161
165
|
|
|
@@ -181,7 +185,7 @@
|
|
|
181
185
|
<div style="position: relative; height: 100%; margin: 15px;">
|
|
182
186
|
<button id="node-input-nodefactorysidebar-generate-btn"
|
|
183
187
|
class="red-ui-button"
|
|
184
|
-
style="width: 100%; margin-top: 30px">
|
|
188
|
+
style="width: 100%; margin-top: 30px">Import Package</button>
|
|
185
189
|
</div>
|
|
186
190
|
</div>
|
|
187
191
|
|