@gregoriusrippenstein/node-red-contrib-nodedev 0.4.7 → 0.5.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 +7 -6
- package/nodes/20-pkg-file.html +2 -0
- package/nodes/lib/tarhelpers.js +7 -0
- package/package.json +3 -2
- package/plugins/support-drag-and-drop.html +142 -0
package/README.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
*What?*
|
|
4
4
|
|
|
5
|
-
The idea behind this collection of nodes to democratise the development of Node-RED nodes. Normally the development of your [own nodes](https://nodered.org/docs/creating-nodes/) will require the use of a third-party editor. Something like VSCode or Vim or Atom or
|
|
5
|
+
The idea behind this collection of nodes to democratise the development of Node-RED nodes. Normally the development of your [own nodes](https://nodered.org/docs/creating-nodes/) will require the use of a third-party editor. Something like VSCode or Vim or Atom or [Emacs](https://discourse.nodered.org/t/node-red-node-development-in-node-red/81525/2). This requirement makes creating nodes that much harder. So why not create nodes for Node-RED in Node-RED? After all, if you are using Node-RED, you probably understand how to use Node-RED.
|
|
6
6
|
|
|
7
|
-
So this package tries to provide some supporting nodes for making node development in Node-RED possible and simpler. I have created a set of nodes that fulfill my needs, everything else is bound my imagination.
|
|
7
|
+
So this package tries to provide some supporting nodes for making node development in Node-RED possible and simpler. I have created a set of nodes that fulfill my needs, everything else is bound my imagination.
|
|
8
|
+
|
|
9
|
+
Imagine a [continous integration](https://en.wikipedia.org/wiki/Continuous_integration) server combined with an editor. This can be done because Node-RED can both editor code (using something like a function node) and also perform actions such as posting data off to servers (http request node).
|
|
8
10
|
|
|
9
11
|
*What do these nodes provide?*
|
|
10
12
|
|
|
@@ -14,14 +16,13 @@ So this package tries to provide some supporting nodes for making node developme
|
|
|
14
16
|
- A `NodeFactory` node that can create templates for node development. It also converts existing `.tgz` packages to `PkgFile` nodes, meaning that existing packages can easily be ported to this style of development.
|
|
15
17
|
- A `NpmPublish` allows node packages to be published to a node registry, for example [npmjs](https://www.npmjs.com/). The NpmPublish can also be used to publish to private registries, for example, those based on [Verdaccio](https://verdaccio.org/).
|
|
16
18
|
- A `OTPGenerate` node can be used to generate an One Time Password (OTP) for publishing nodes to registries. For example the NPMjs.com registry.
|
|
19
|
+
- The `NodeDevOps` node controls what is done, i.e., install package locally, commit to GitHub or publish to Npm. For these operations to work, a support [flow](https://flowhub.org/f/d0506e991d512ace) needs to be installed in Node-RED. This can be done using the [FlowHub nodes](https://flows.nodered.org/node/@gregoriusrippenstein/node-red-contrib-flowhub).
|
|
17
20
|
|
|
18
21
|
*This is all very confusing?*
|
|
19
22
|
|
|
20
|
-
Of course, all this is very meta and it gets worse since these nodes are maintained by this [flow](https://flowhub.org/f/b92be5062203ff69). These nodes are
|
|
21
|
-
|
|
22
|
-
This is not an inbuilt extension of Node-RED and obviously a more integrated workflow would be simpler. This is a attempt to find a better solution to node development, one by which testing and fixing nodes becomes faster.
|
|
23
|
+
Of course, all this is very meta and it gets worse since these nodes are maintained by this [flow](https://flowhub.org/f/b92be5062203ff69). These nodes are bootstrapped in Node-RED to aid Node-RED node development within Node-RED. On the other hand, Node-RED node [development](https://nodered.org/docs/creating-nodes/) is initially also confusing (requiring at least three different files). That's why the NodeFactory provides templates for various types of nodes.
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
This is not an inbuilt extension of Node-RED and obviously a more integrated workflow would be simpler. This is a attempt to find a better solution to Node-RED node development (*not* NodeJS development), one by which testing and fixing nodes becomes faster because everything is done in Node-RED.
|
|
25
26
|
|
|
26
27
|
### Screencast
|
|
27
28
|
|
package/nodes/20-pkg-file.html
CHANGED
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
<option value="lexon">Lexon</option>
|
|
72
72
|
<option value="liquid">Liquid</option>
|
|
73
73
|
<option value="lua">Lua</option>
|
|
74
|
+
<option value="mdx">MDX</option>
|
|
74
75
|
<option value="mips">MIPS</option>
|
|
75
76
|
<option value="markdown">Markdown</option>
|
|
76
77
|
<option value="m3">Modula-3</option>
|
|
@@ -103,6 +104,7 @@
|
|
|
103
104
|
<option value="hcl">Terraform</option>
|
|
104
105
|
<option value="twig">Twig</option>
|
|
105
106
|
<option value="typescript">TypeScript</option>
|
|
107
|
+
<option value="typespec">TypeSpec</option>
|
|
106
108
|
<option value="verilog">V</option>
|
|
107
109
|
<option value="vb">Visual Basic</option>
|
|
108
110
|
<option value="wgsl">WebGPU Shading Language</option>
|
package/nodes/lib/tarhelpers.js
CHANGED
|
@@ -86,6 +86,7 @@ module.exports = (function () {
|
|
|
86
86
|
"liquid": "liquid",
|
|
87
87
|
"html.liquid": "liquid",
|
|
88
88
|
"lua": "lua",
|
|
89
|
+
"mdx": "mdx",
|
|
89
90
|
"s": "mips",
|
|
90
91
|
"md": "markdown",
|
|
91
92
|
"markdown": "markdown",
|
|
@@ -153,6 +154,10 @@ module.exports = (function () {
|
|
|
153
154
|
"iecst": "st",
|
|
154
155
|
"iecplc": "st",
|
|
155
156
|
"lc3lib": "st",
|
|
157
|
+
"TcPOU": "st",
|
|
158
|
+
"TcDUT": "st",
|
|
159
|
+
"TcGVL": "st",
|
|
160
|
+
"TcIO": "st",
|
|
156
161
|
"swift": "swift",
|
|
157
162
|
"tf": "hcl",
|
|
158
163
|
"tfvars": "hcl",
|
|
@@ -162,6 +167,7 @@ module.exports = (function () {
|
|
|
162
167
|
"tsx": "typescript",
|
|
163
168
|
"cts": "typescript",
|
|
164
169
|
"mts": "typescript",
|
|
170
|
+
"tsp": "typespec",
|
|
165
171
|
"v": "verilog",
|
|
166
172
|
"vh": "verilog",
|
|
167
173
|
"vb": "vb",
|
|
@@ -219,6 +225,7 @@ module.exports = (function () {
|
|
|
219
225
|
"xml": "xml",
|
|
220
226
|
"ts": "typescript",
|
|
221
227
|
"sql": "sql",
|
|
228
|
+
"sh": "shell",
|
|
222
229
|
|
|
223
230
|
|
|
224
231
|
/* binary formats are encoded in base64 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name" : "@gregoriusrippenstein/node-red-contrib-nodedev",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"pako": "^2.1.0",
|
|
6
6
|
"tar-stream": "^3.1.6",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"node-red" : {
|
|
32
32
|
"version": ">=3.0.0",
|
|
33
33
|
"plugins": {
|
|
34
|
-
"nodefactory_sidebar": "plugins/node-factory-sidebar.html"
|
|
34
|
+
"nodefactory_sidebar": "plugins/node-factory-sidebar.html",
|
|
35
|
+
"supportdraganddrop": "plugins/support-drag-and-drop.html"
|
|
35
36
|
},
|
|
36
37
|
"nodes": {
|
|
37
38
|
"nodedevops": "nodes/05-node-dev-ops.js",
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
(function () {
|
|
3
|
+
var initialiseConfigNodeOnce = () => {
|
|
4
|
+
RED.events.off('runtime-state', initialiseConfigNodeOnce);
|
|
5
|
+
|
|
6
|
+
let customDropHandler = (event) => {
|
|
7
|
+
/* for debugging purposes - inspect the original Event to discover the type:
|
|
8
|
+
* console> window.ddEvent.originalEvent.dataTransfer.items[0].type
|
|
9
|
+
*/
|
|
10
|
+
window.ddEvent = event
|
|
11
|
+
|
|
12
|
+
let itemPtr = event.originalEvent.dataTransfer.items
|
|
13
|
+
let itemCount = itemPtr.length
|
|
14
|
+
|
|
15
|
+
let nodesToBeImported = []
|
|
16
|
+
let waitingOnNode = 0;
|
|
17
|
+
|
|
18
|
+
let file2base64Image = (file, cb) => {
|
|
19
|
+
var reader = new FileReader();
|
|
20
|
+
reader.onload = (function (fd) {
|
|
21
|
+
return function (e) {
|
|
22
|
+
cb(e.target.result);
|
|
23
|
+
};
|
|
24
|
+
})(file);
|
|
25
|
+
reader.readAsDataURL(file);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (let idx = 0; idx < itemCount; idx++) {
|
|
29
|
+
let itm = itemPtr[idx]
|
|
30
|
+
|
|
31
|
+
if (itm.type.startsWith("image/")) {
|
|
32
|
+
waitingOnNode++
|
|
33
|
+
|
|
34
|
+
let file = event.originalEvent.dataTransfer.files[idx]
|
|
35
|
+
let yPos = waitingOnNode * 40
|
|
36
|
+
|
|
37
|
+
file2base64Image(file, dataUrl => {
|
|
38
|
+
nodesToBeImported.push({
|
|
39
|
+
"id": RED.nodes.id(),
|
|
40
|
+
"type": "PkgFile",
|
|
41
|
+
"name": file.name,
|
|
42
|
+
"filename": file.name,
|
|
43
|
+
"dirname": "",
|
|
44
|
+
"format": "base64",
|
|
45
|
+
"syntax": "plain",
|
|
46
|
+
"template": dataUrl.replace(/^data:[^;]+;base64,/,""),
|
|
47
|
+
"output": "str",
|
|
48
|
+
"y": yPos,
|
|
49
|
+
"x": 0,
|
|
50
|
+
"wires": [[]]
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
} else if ( (itm.type == "text/xml" ||
|
|
54
|
+
itm.type == "text/css" ||
|
|
55
|
+
itm.type == "text/plain" ||
|
|
56
|
+
itm.type == "text/html" ||
|
|
57
|
+
itm.type == "text/x-python-script" ||
|
|
58
|
+
itm.type == "text/markdown" ||
|
|
59
|
+
itm.type == "application/x-javascript" ||
|
|
60
|
+
itm.type == "application/x-yaml" ||
|
|
61
|
+
itm.type == "application/x-sh" ||
|
|
62
|
+
itm.type == "application/json"
|
|
63
|
+
) && (
|
|
64
|
+
event.originalEvent.dataTransfer.files && event.originalEvent.dataTransfer.files[idx]
|
|
65
|
+
)) {
|
|
66
|
+
/*
|
|
67
|
+
* Why is there a checking for existence of file data?
|
|
68
|
+
*
|
|
69
|
+
* Because text/plain is supported here BUT it's assumed that there is a
|
|
70
|
+
* corresponding file, ensure that there is, else ignore text/plain.
|
|
71
|
+
* text/plain also occurs without having a file attached.
|
|
72
|
+
*/
|
|
73
|
+
waitingOnNode++
|
|
74
|
+
|
|
75
|
+
let file = event.originalEvent.dataTransfer.files[idx]
|
|
76
|
+
let yPos = waitingOnNode * 40
|
|
77
|
+
|
|
78
|
+
let mapMineTypeToFormat = (minetype) => {
|
|
79
|
+
let type = minetype.split("/")[1].replace("x-","")
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
"plain": "text",
|
|
83
|
+
"python-script": "python",
|
|
84
|
+
"sh": "shell"
|
|
85
|
+
}[type] || type;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
file.arrayBuffer().then( d => {
|
|
89
|
+
nodesToBeImported.push({
|
|
90
|
+
"id": RED.nodes.id(),
|
|
91
|
+
"type": "PkgFile",
|
|
92
|
+
"name": file.name,
|
|
93
|
+
"filename": file.name,
|
|
94
|
+
"dirname": "",
|
|
95
|
+
"format": mapMineTypeToFormat(itm.type),
|
|
96
|
+
"syntax": "plain",
|
|
97
|
+
"template": new TextDecoder().decode(d),
|
|
98
|
+
"output": "str",
|
|
99
|
+
"y": yPos,
|
|
100
|
+
"x": 0,
|
|
101
|
+
"wires": [[]]
|
|
102
|
+
})
|
|
103
|
+
}).catch( ex => { console.log(ex) })
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let checkIfAllIsThere = () => {
|
|
108
|
+
if (waitingOnNode > 0 && nodesToBeImported.length == waitingOnNode) {
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
try {
|
|
111
|
+
RED.view.importNodes(nodesToBeImported)
|
|
112
|
+
} catch (ex) { /*keep quiet*/ }
|
|
113
|
+
}, 400);
|
|
114
|
+
} else {
|
|
115
|
+
setTimeout(checkIfAllIsThere, 400)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (waitingOnNode > 0) {
|
|
120
|
+
setTimeout(checkIfAllIsThere, 200)
|
|
121
|
+
setTimeout(() => { nodesToBeImported.length = waitingOnNode }, 4000)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* Because this happens before the workspace is setup, we set the drop listen
|
|
127
|
+
* when the target becomes available.
|
|
128
|
+
*/
|
|
129
|
+
let defineCustomDropHandler = () => {
|
|
130
|
+
if ($('#red-ui-drop-target').length > 0) {
|
|
131
|
+
$('#red-ui-drop-target').on("drop", customDropHandler)
|
|
132
|
+
} else {
|
|
133
|
+
setTimeout(defineCustomDropHandler, 300)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
setTimeout(defineCustomDropHandler, 300)
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
RED.events.on('runtime-state', initialiseConfigNodeOnce);
|
|
140
|
+
})();
|
|
141
|
+
|
|
142
|
+
</script>
|