@gregoriusrippenstein/node-red-contrib-introspection 0.3.5 → 0.4.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
CHANGED
|
@@ -89,9 +89,16 @@ Inspired by the [dsm](https://flows.nodered.org/node/node-red-contrib-dsm) packa
|
|
|
89
89
|
|
|
90
90
|
Send a flow to another Node-RED instance. This will replace **any existing** flows on the other server, use with care. Under the hood this uses the [Node-RED API](https://nodered.org/docs/api/admin/methods/post/flows/) to post a new flow to the server. This node also supports authentication if the other server happens to have some.
|
|
91
91
|
|
|
92
|
-
###
|
|
92
|
+
### ClientCode
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
ClientCode is a node for executing client side, i.e., in the editor, Javascript code triggered by a server side event. Any code that can be executed in the browseer console can be executed in the ClientCode node. It replaces the TriggerImport node by being more generic, TriggerImport executed very specific code for a server side event, ClientCode can emulate that behaviour.
|
|
95
|
+
|
|
96
|
+
The context for code execution includes the following:
|
|
97
|
+
|
|
98
|
+
- `payload` which is the the `msg.payload` value
|
|
99
|
+
- `topic` which is the `msg.topic` value
|
|
100
|
+
|
|
101
|
+
For more details, [client side code](https://github.com/gorenje/node-red-contrib-introspection/blob/2f5aca9374b28fcb6890c312f943f913ecb4cfce/nodes/60-client-code.html#L3-L8) with the context and [server side code](https://github.com/gorenje/node-red-contrib-introspection/blob/2f5aca9374b28fcb6890c312f943f913ecb4cfce/nodes/60-client-code.js#L13-L22).
|
|
95
102
|
|
|
96
103
|
## Node-RED Versions
|
|
97
104
|
|
|
@@ -106,7 +113,7 @@ There are [example flows](/examples) contained in the package, examples can also
|
|
|
106
113
|
- [Screenshot](https://flowhub.org/f/07b2d0f3b0445ab5)
|
|
107
114
|
- [DrawSVG](https://flowhub.org/f/141037dcda5b69fd)
|
|
108
115
|
- [GetFlows](https://flowhub.org/f/0b1bfbf6e540be66)
|
|
109
|
-
- [
|
|
116
|
+
- [ClientCode](https://flowhub.org/f/e02ba6e534f7a0f4)
|
|
110
117
|
|
|
111
118
|
## License
|
|
112
119
|
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
|
|
3
|
+
RED.comms.subscribe('introspect:client-code-perform', (event,data) => {
|
|
4
|
+
if ( data.msg == "execfunc" ) {
|
|
5
|
+
var payload = data.payload;
|
|
6
|
+
eval( data.func );
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
RED.nodes.registerType('ClientCode',{
|
|
11
|
+
color: '#e5e4ef',
|
|
12
|
+
icon: "icons/subflow.svg",
|
|
13
|
+
category: 'introspection',
|
|
14
|
+
paletteLabel: "ClientCode",
|
|
15
|
+
defaults: {
|
|
16
|
+
name: {
|
|
17
|
+
value:"",
|
|
18
|
+
},
|
|
19
|
+
clientcode: {
|
|
20
|
+
value: ""
|
|
21
|
+
},
|
|
22
|
+
format: {
|
|
23
|
+
value: ""
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
inputs:1,
|
|
27
|
+
outputs:1,
|
|
28
|
+
|
|
29
|
+
label: function() {
|
|
30
|
+
return (this.name || this._def.paletteLabel);
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
labelStyle: function() {
|
|
34
|
+
return this.name?"node_label_italic":"";
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
oneditsave: function() {
|
|
38
|
+
$('#node-input-clientcode').val(this.editor.getValue());
|
|
39
|
+
this.editor.destroy();
|
|
40
|
+
delete this.editor;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
oneditcancel: function() {
|
|
44
|
+
this.editor.destroy();
|
|
45
|
+
delete this.editor;
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
oneditprepare: function() {
|
|
49
|
+
const that = this;
|
|
50
|
+
const stateId = RED.editor.generateViewStateId("node", this, "");
|
|
51
|
+
|
|
52
|
+
this.editor = RED.editor.createEditor({
|
|
53
|
+
id: 'node-input-clientcode-editor',
|
|
54
|
+
mode: 'ace/mode/html',
|
|
55
|
+
stateId: stateId,
|
|
56
|
+
value: $("#node-input-screenshot").val()
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.editor.setValue( that.clientcode );
|
|
60
|
+
|
|
61
|
+
$("#node-input-format").on("change", function() {
|
|
62
|
+
var mod = "ace/mode/"+$("#node-input-format").val();
|
|
63
|
+
that.editor.getSession().setMode({
|
|
64
|
+
path: mod,
|
|
65
|
+
v: Date.now()
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
RED.popover.tooltip($("#node-clientcode-expand-editor"), RED._("node-red:common.label.expand"));
|
|
70
|
+
$("#node-clientcode-expand-editor").on("click", function (e) {
|
|
71
|
+
e.preventDefault();
|
|
72
|
+
const value = that.editor.getValue();
|
|
73
|
+
that.editor.saveView();
|
|
74
|
+
RED.editor.editText({
|
|
75
|
+
mode: $("#node-input-format").val(),
|
|
76
|
+
value: value,
|
|
77
|
+
stateId: stateId,
|
|
78
|
+
width: "Infinity",
|
|
79
|
+
focus: true,
|
|
80
|
+
complete: function (v, cursor) {
|
|
81
|
+
that.editor.setValue(v, -1);
|
|
82
|
+
setTimeout(function () {
|
|
83
|
+
that.editor.restoreView();
|
|
84
|
+
that.editor.focus();
|
|
85
|
+
}, 250);
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
oneditresize: function(size) {
|
|
93
|
+
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
|
|
94
|
+
var height = $("#dialog-form").height();
|
|
95
|
+
for (var i=0; i<rows.length; i++) {
|
|
96
|
+
height -= $(rows[i]).outerHeight(true);
|
|
97
|
+
}
|
|
98
|
+
var editorRow = $("#dialog-form>div.node-text-editor-row");
|
|
99
|
+
height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
|
|
100
|
+
$(".node-text-editor").css("height",height+"px");
|
|
101
|
+
this.editor.resize();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
</script>
|
|
105
|
+
|
|
106
|
+
<script type="text/html" data-template-name="ClientCode">
|
|
107
|
+
<div class="form-row">
|
|
108
|
+
<label for="node-input-name">
|
|
109
|
+
<i class="fa fa-tag"></i>
|
|
110
|
+
<span data-i18n="common.label.name">Name</span>
|
|
111
|
+
</label>
|
|
112
|
+
<input type="text" id="node-input-name" placeholder="Name">
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div class="form-row" style="position: relative; margin-bottom: 0px;">
|
|
116
|
+
<label for="node-input-clientcode">
|
|
117
|
+
<i class="fa fa-file-code-o"></i> Client Code
|
|
118
|
+
</label>
|
|
119
|
+
<input type="hidden" id="node-input-clientcode" autofocus="autofocus">
|
|
120
|
+
|
|
121
|
+
<div style="position: absolute; right:0;display:inline-block; text-align: right; font-size: 0.8em;">
|
|
122
|
+
Syntax:
|
|
123
|
+
<select id="node-input-format" style="width:110px; font-size: 10px !important; height: 24px; padding:0;">
|
|
124
|
+
<option value="handlebars">mustache</option>
|
|
125
|
+
<option value="html">HTML</option>
|
|
126
|
+
<option value="json">JSON</option>
|
|
127
|
+
<option value="javascript">JavaScript</option>
|
|
128
|
+
<option value="css">CSS</option>
|
|
129
|
+
<option value="markdown">Markdown</option>
|
|
130
|
+
<option value="php">PHP</option>
|
|
131
|
+
<option value="python">Python</option>
|
|
132
|
+
<option value="sql">SQL</option>
|
|
133
|
+
<option value="yaml">YAML</option>
|
|
134
|
+
<option value="text">None</option>
|
|
135
|
+
</select>
|
|
136
|
+
<button type="button" id="node-clientcode-expand-editor"
|
|
137
|
+
class="red-ui-button red-ui-button-small">
|
|
138
|
+
<i class="fa fa-expand"></i>
|
|
139
|
+
</button>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div class="form-row node-text-editor-row">
|
|
144
|
+
<div style="height: 250px; min-height:150px;"
|
|
145
|
+
class="node-text-editor"
|
|
146
|
+
id="node-input-clientcode-editor" ></div>
|
|
147
|
+
</div>
|
|
148
|
+
<input type="hidden" id="node-input-clientcode">
|
|
149
|
+
</script>
|
|
150
|
+
|
|
151
|
+
<script type="text/html" data-help-name="ClientCode">
|
|
152
|
+
<p>Execute Javascript code in the Node-RED frontend, triggered from the server.</p>
|
|
153
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module.exports = function(RED) {
|
|
2
|
+
function ClientCodeFunctionality(config) {
|
|
3
|
+
RED.nodes.createNode(this,config);
|
|
4
|
+
|
|
5
|
+
var node = this;
|
|
6
|
+
var cfg = config;
|
|
7
|
+
|
|
8
|
+
node.on('close', function() {
|
|
9
|
+
node.status({});
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
node.on("input", function(msg, send, done) {
|
|
13
|
+
RED.comms.publish(
|
|
14
|
+
"introspect:client-code-perform",
|
|
15
|
+
RED.util.encodeObject({
|
|
16
|
+
msg: "execfunc",
|
|
17
|
+
payload: msg.payload,
|
|
18
|
+
topic: msg.topic,
|
|
19
|
+
func: cfg.clientcode,
|
|
20
|
+
nodeid: node.id
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
send(msg);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
RED.nodes.registerType("ClientCode", ClientCodeFunctionality);
|
|
28
|
+
}
|
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
2
|
|
|
3
|
+
/*
|
|
4
|
+
* How to connect nodes:
|
|
5
|
+
var namesToId = {}
|
|
6
|
+
|
|
7
|
+
RED.nodes.eachNode((n) => {
|
|
8
|
+
if ( n._def.category == "rssfeeds") {
|
|
9
|
+
namesToId[n.name] = n.id
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
RED.nodes.eachNode((n) => {
|
|
14
|
+
if ( n._def.category == "rssfeeds" && n._def.label() == "Hacker News: New Comments") {
|
|
15
|
+
var title = n.name.match(/^New[ ]+comment[ ]+by.+\"(.*)\"/)[1];
|
|
16
|
+
var tgtId = namesToId[title];
|
|
17
|
+
if ( tgtId ) {
|
|
18
|
+
var t = RED.nodes.node(tgtId);
|
|
19
|
+
RED.nodes.addLink( { source: n, sourcePort: 0, target: t});
|
|
20
|
+
RED.view.select([t,n])
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
* How to move
|
|
26
|
+
|
|
27
|
+
var t = RED.nodes.node("23e18922a0b896f1")
|
|
28
|
+
t.x = XXXX;
|
|
29
|
+
t.y = YYYY;
|
|
30
|
+
t.dirty = true;
|
|
31
|
+
RED.view.redraw(true)
|
|
32
|
+
|
|
33
|
+
*/
|
|
34
|
+
|
|
3
35
|
RED.comms.subscribe('introspect:trigger-import-delete', (event,data) => {
|
|
4
36
|
if ( data.msg == "delete-old-nodes" ) {
|
|
5
37
|
RED.view.select(false)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gregoriusrippenstein/node-red-contrib-introspection",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"got": "latest"
|
|
6
6
|
},
|
|
@@ -16,16 +16,16 @@
|
|
|
16
16
|
"node-red": {
|
|
17
17
|
"version": ">=2.0.0",
|
|
18
18
|
"nodes": {
|
|
19
|
-
"seeker":
|
|
20
|
-
"sink":
|
|
21
|
-
"screenshot":
|
|
22
|
-
"orphans":
|
|
23
|
-
"ismobile":
|
|
24
|
-
"navigator":
|
|
25
|
-
"drawsvg":
|
|
26
|
-
"getflows":
|
|
27
|
-
"sendflow":
|
|
28
|
-
"
|
|
19
|
+
"seeker": "nodes/05-seeker.js",
|
|
20
|
+
"sink": "nodes/10-sink.js",
|
|
21
|
+
"screenshot": "nodes/15-screenshot.js",
|
|
22
|
+
"orphans": "nodes/20-orphans.js",
|
|
23
|
+
"ismobile": "nodes/25-ismobile.js",
|
|
24
|
+
"navigator": "nodes/30-navigator.js",
|
|
25
|
+
"drawsvg": "nodes/40-drawsvg.js",
|
|
26
|
+
"getflows": "nodes/45-get-flows.js",
|
|
27
|
+
"sendflow": "nodes/50-send-flow.js",
|
|
28
|
+
"clientcode": "nodes/60-client-code.js"
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"description": "Node-RED Editor-only nodes for introspecting flows.",
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module.exports = function(RED) {
|
|
2
|
-
function TriggerImportFunctionality(config) {
|
|
3
|
-
RED.nodes.createNode(this,config);
|
|
4
|
-
|
|
5
|
-
var node = this;
|
|
6
|
-
var cfg = config;
|
|
7
|
-
|
|
8
|
-
node.on('close', function() {
|
|
9
|
-
node.status({});
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
node.on("input", function(msg, send, done) {
|
|
13
|
-
if ( msg.payload && msg.payload.cmd == "delete-nodes" ) {
|
|
14
|
-
RED.comms.publish('introspect:trigger-import-delete',
|
|
15
|
-
RED.util.encodeObject({
|
|
16
|
-
msg: "delete-old-nodes",
|
|
17
|
-
payload: msg.payload,
|
|
18
|
-
})
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
send(msg);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
RED.comms.publish("introspect:trigger-import-tripped",
|
|
26
|
-
RED.util.encodeObject({
|
|
27
|
-
flowContent: msg.payload,
|
|
28
|
-
msg: "import-flow",
|
|
29
|
-
autoimport: cfg.autoimport,
|
|
30
|
-
removeduplicates: cfg.removeduplicates,
|
|
31
|
-
})
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
send(msg);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
RED.nodes.registerType("TriggerImport", TriggerImportFunctionality);
|
|
38
|
-
}
|