@gregoriusrippenstein/node-red-contrib-introspection 0.9.20 → 0.10.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/nodes/45-get-flows.html +4 -1
- package/nodes/50-send-flow.html +19 -3
- package/nodes/50-send-flow.js +62 -48
- package/nodes/51-install-package.html +35 -3
- package/nodes/51-install-package.js +65 -43
- package/package.json +1 -1
- package/plugins/sidebar.html +1 -1
package/nodes/45-get-flows.html
CHANGED
|
@@ -114,5 +114,8 @@
|
|
|
114
114
|
</script>
|
|
115
115
|
|
|
116
116
|
<script type="text/html" data-help-name="GetFlows">
|
|
117
|
-
<p>Retrieves the current flow file from
|
|
117
|
+
<p>Retrieves the current flow file from this server. This uses the Node-RED API and is therefore storage-method independent. Payload becomes a Json string.</p>
|
|
118
|
+
|
|
119
|
+
If the response is to sent to another host, then insert a JSON node to convert the response of this node to a Javascript array which can be passed as payload
|
|
120
|
+
to the SendFlow node.
|
|
118
121
|
</script>
|
package/nodes/50-send-flow.html
CHANGED
|
@@ -7,9 +7,15 @@
|
|
|
7
7
|
name: {
|
|
8
8
|
value:"",
|
|
9
9
|
},
|
|
10
|
+
|
|
10
11
|
hostUrl: {
|
|
11
|
-
value:
|
|
12
|
+
value:"hostUrl",
|
|
13
|
+
required:true
|
|
14
|
+
},
|
|
15
|
+
hostUrlType: {
|
|
16
|
+
value:"str"
|
|
12
17
|
},
|
|
18
|
+
|
|
13
19
|
flowVersion: {
|
|
14
20
|
value: "v1"
|
|
15
21
|
},
|
|
@@ -29,6 +35,7 @@
|
|
|
29
35
|
value: "env",
|
|
30
36
|
},
|
|
31
37
|
},
|
|
38
|
+
|
|
32
39
|
inputs:1,
|
|
33
40
|
outputs:1,
|
|
34
41
|
|
|
@@ -39,6 +46,7 @@
|
|
|
39
46
|
labelStyle: function() {
|
|
40
47
|
return this.name?"node_label_italic":"";
|
|
41
48
|
},
|
|
49
|
+
|
|
42
50
|
oneditprepare: function() {
|
|
43
51
|
$("#node-input-apiUsername").typedInput({
|
|
44
52
|
types:["env", "msg", "flow","global", "cred"],
|
|
@@ -46,10 +54,15 @@
|
|
|
46
54
|
});
|
|
47
55
|
|
|
48
56
|
$("#node-input-apiPassword").typedInput({
|
|
49
|
-
types:["env", "msg", "flow","global", "
|
|
57
|
+
types:["env", "msg", "flow","global", "cred"],
|
|
50
58
|
typeField: "#node-input-apiPasswordType"
|
|
51
59
|
});
|
|
52
60
|
|
|
61
|
+
$("#node-input-hostUrl").typedInput({
|
|
62
|
+
types:["str", "msg", "flow", "global", "env"],
|
|
63
|
+
typeField: "#node-input-hostUrlType"
|
|
64
|
+
});
|
|
65
|
+
|
|
53
66
|
if ( $('#node-input-useAuthentication').is(":checked") ) {
|
|
54
67
|
$('#useAuthentication-input-fields').show();
|
|
55
68
|
} else {
|
|
@@ -75,7 +88,8 @@
|
|
|
75
88
|
|
|
76
89
|
<div class="form-row">
|
|
77
90
|
<label for="node-input-hostUrl"><i class="fa fa-tag"></i> Host</label>
|
|
78
|
-
<input type="text" id="node-input-hostUrl" placeholder="
|
|
91
|
+
<input type="text" id="node-input-hostUrl" placeholder="hostUrl">
|
|
92
|
+
<input type="hidden" id="node-input-hostUrlType" value="str">
|
|
79
93
|
</div>
|
|
80
94
|
|
|
81
95
|
<div class="form-row">
|
|
@@ -123,4 +137,6 @@
|
|
|
123
137
|
|
|
124
138
|
<script type="text/html" data-help-name="SendFlow">
|
|
125
139
|
<p>Send flow to another Node-RED instance.</p>
|
|
140
|
+
|
|
141
|
+
Payload is assumed to be a Javascript array containing flow data.
|
|
126
142
|
</script>
|
package/nodes/50-send-flow.js
CHANGED
|
@@ -11,29 +11,37 @@ module.exports = function(RED) {
|
|
|
11
11
|
|
|
12
12
|
node.on("input", function(msg, send, done) {
|
|
13
13
|
var sendFlow = (hdrs, got) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
14
|
+
|
|
15
|
+
RED.util.evaluateNodeProperty(cfg.hostUrl, cfg.hostUrlType, node, msg, (err, result) => {
|
|
16
|
+
if (err) {
|
|
17
|
+
node.status({ fill: "red", shape: "dot", text: "Failed" });
|
|
18
|
+
node.error("unable to obtain host url", { ...msg, _err: err })
|
|
19
|
+
} else {
|
|
20
|
+
got.post( result + "/flows", {
|
|
21
|
+
headers: {
|
|
22
|
+
"Node-RED-API-Version": cfg.flowVersion,
|
|
23
|
+
"Content-type": "application/json",
|
|
24
|
+
"Node-RED-Deployment-Type": "full",
|
|
25
|
+
...hdrs
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(msg.payload)
|
|
28
|
+
}).then( res => {
|
|
29
|
+
send({
|
|
30
|
+
...msg,
|
|
31
|
+
payload: res.body
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
node.status({fill:"green",shape:"dot",text:"Good"});
|
|
35
|
+
setTimeout( function() {
|
|
36
|
+
node.status({})
|
|
37
|
+
}, 450);
|
|
38
|
+
|
|
39
|
+
}).catch( err => {
|
|
40
|
+
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
41
|
+
node.error("posting data to host", { ...msg, _err: err})
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
})
|
|
37
45
|
};
|
|
38
46
|
|
|
39
47
|
/**
|
|
@@ -45,19 +53,17 @@ module.exports = function(RED) {
|
|
|
45
53
|
|
|
46
54
|
node.status({fill:"blue",shape:"dot",text:"Requesting token"});
|
|
47
55
|
|
|
48
|
-
RED.util.evaluateNodeProperty(cfg.apiUsername, cfg.apiUsernameType,
|
|
49
|
-
node, msg, (err, result) => {
|
|
56
|
+
RED.util.evaluateNodeProperty(cfg.apiUsername, cfg.apiUsernameType, node, msg, (err, result) => {
|
|
50
57
|
if (err) {
|
|
51
58
|
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
52
|
-
node.error("
|
|
59
|
+
node.error("unable to obtain api username", { ...msg, _err: err})
|
|
53
60
|
} else {
|
|
54
61
|
username = result;
|
|
55
62
|
|
|
56
|
-
RED.util.evaluateNodeProperty(cfg.apiPassword, cfg.apiPasswordType,
|
|
57
|
-
node, msg, (err, result) => {
|
|
63
|
+
RED.util.evaluateNodeProperty(cfg.apiPassword, cfg.apiPasswordType, node, msg, (err, result) => {
|
|
58
64
|
if (err) {
|
|
59
65
|
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
60
|
-
node.error("
|
|
66
|
+
node.error("unable to obtain api password", {...msg, _err: err})
|
|
61
67
|
} else {
|
|
62
68
|
password = result;
|
|
63
69
|
|
|
@@ -69,31 +75,39 @@ module.exports = function(RED) {
|
|
|
69
75
|
"password": password
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
RED.util.evaluateNodeProperty(cfg.hostUrl, cfg.hostUrlType, node, msg, (err, result) => {
|
|
79
|
+
if (err) {
|
|
80
|
+
node.status({ fill: "red", shape: "dot", text: "Failed" });
|
|
81
|
+
node.error("error occurred", { ...msg, _err: err })
|
|
82
|
+
} else {
|
|
83
|
+
|
|
84
|
+
import('got').then( (module) => {
|
|
85
|
+
module.got.post( result + "/auth/token", {
|
|
86
|
+
json: data
|
|
87
|
+
}).then( res => {
|
|
88
|
+
node.status({
|
|
89
|
+
fill:"blue",
|
|
90
|
+
shape:"dot",
|
|
91
|
+
text:"Sending flow"
|
|
92
|
+
});
|
|
81
93
|
|
|
82
|
-
|
|
94
|
+
var access_token = JSON.parse(res.body).access_token;
|
|
83
95
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
sendFlow({
|
|
97
|
+
"Authorization": "Bearer " + access_token
|
|
98
|
+
}, module.got);
|
|
87
99
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
}).catch((err) => {
|
|
101
|
+
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
102
|
+
node.error( "unable to obtain api auth token", { ...msg, _err: err });
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
})
|
|
93
107
|
}
|
|
94
108
|
})
|
|
95
109
|
}
|
|
96
|
-
})
|
|
110
|
+
})
|
|
97
111
|
} else {
|
|
98
112
|
/*
|
|
99
113
|
* Authentication free zone...
|
|
@@ -8,9 +8,15 @@
|
|
|
8
8
|
name: {
|
|
9
9
|
value:"",
|
|
10
10
|
},
|
|
11
|
+
|
|
11
12
|
hostUrl: {
|
|
12
|
-
value:
|
|
13
|
+
value:"hostUrl",
|
|
14
|
+
required:true
|
|
15
|
+
},
|
|
16
|
+
hostUrlType: {
|
|
17
|
+
value:"str"
|
|
13
18
|
},
|
|
19
|
+
|
|
14
20
|
useAuthentication: {
|
|
15
21
|
value:false
|
|
16
22
|
},
|
|
@@ -30,6 +36,7 @@
|
|
|
30
36
|
value: false
|
|
31
37
|
}
|
|
32
38
|
},
|
|
39
|
+
|
|
33
40
|
inputs:1,
|
|
34
41
|
outputs:1,
|
|
35
42
|
|
|
@@ -40,6 +47,7 @@
|
|
|
40
47
|
labelStyle: function() {
|
|
41
48
|
return this.name?"node_label_italic":"";
|
|
42
49
|
},
|
|
50
|
+
|
|
43
51
|
oneditprepare: function() {
|
|
44
52
|
$("#node-input-apiUsername").typedInput({
|
|
45
53
|
types:["env", "msg", "flow","global", "cred"],
|
|
@@ -51,6 +59,11 @@
|
|
|
51
59
|
typeField: "#node-input-apiPasswordType"
|
|
52
60
|
});
|
|
53
61
|
|
|
62
|
+
$("#node-input-hostUrl").typedInput({
|
|
63
|
+
types:["str", "msg", "flow", "global", "env"],
|
|
64
|
+
typeField: "#node-input-hostUrlType"
|
|
65
|
+
});
|
|
66
|
+
|
|
54
67
|
if ( $('#node-input-useAuthentication').is(":checked") ) {
|
|
55
68
|
$('#useAuthentication-input-fields').show();
|
|
56
69
|
} else {
|
|
@@ -97,8 +110,9 @@
|
|
|
97
110
|
-->
|
|
98
111
|
|
|
99
112
|
<div class="form-row hostUrl-row">
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
<label for="node-input-hostUrl"><i class="fa fa-tag"></i> Host</label>
|
|
114
|
+
<input type="text" id="node-input-hostUrl" placeholder="hostUrl">
|
|
115
|
+
<input type="hidden" id="node-input-hostUrlType" value="str">
|
|
102
116
|
</div>
|
|
103
117
|
|
|
104
118
|
<div class="form-row">
|
|
@@ -134,4 +148,22 @@
|
|
|
134
148
|
|
|
135
149
|
<script type="text/html" data-help-name="InstallPackage">
|
|
136
150
|
<p>Install package on another Node-RED instance.</p>
|
|
151
|
+
|
|
152
|
+
<p>This takes two forms, it can either install a package by name and version (defaults to "latest") or it can
|
|
153
|
+
accept a buffer object containing a .tgz package file.</p>
|
|
154
|
+
|
|
155
|
+
<p></p>For the first case:
|
|
156
|
+
<pre>
|
|
157
|
+
msg.payload = {
|
|
158
|
+
module: "@gregoriusrippenstein/node-red-contrib-introspection",
|
|
159
|
+
version: "0.10.0"
|
|
160
|
+
}
|
|
161
|
+
</pre>
|
|
162
|
+
|
|
163
|
+
<p>To install a .tgz file, read it into a Buffer object and set the payload to:</p>
|
|
164
|
+
<pre>
|
|
165
|
+
msg.payload = {
|
|
166
|
+
data: new Buffer("ddd")
|
|
167
|
+
}
|
|
168
|
+
</pre>
|
|
137
169
|
</script>
|
|
@@ -15,10 +15,17 @@ module.exports = function(RED) {
|
|
|
15
15
|
return node.error("msg.payload missing or payload not hash", msg)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/*
|
|
19
|
+
* This defines the helper function - installPackage - that is called either with
|
|
20
|
+
* an authentication token or without. That is determined below.
|
|
21
|
+
*/
|
|
18
22
|
var installPackage = (hdrs, got) => {
|
|
19
23
|
let body = undefined
|
|
20
24
|
let headers = {}
|
|
21
25
|
|
|
26
|
+
/*
|
|
27
|
+
* Check the Payload - either module name or .tgz buffer.
|
|
28
|
+
*/
|
|
22
29
|
if ( msg.payload.module ) {
|
|
23
30
|
body = JSON.stringify({
|
|
24
31
|
module: msg.payload.module,
|
|
@@ -40,27 +47,35 @@ module.exports = function(RED) {
|
|
|
40
47
|
return node.error("msg.payload not well defined", msg)
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
/*
|
|
51
|
+
* Connect and send to host.
|
|
52
|
+
*/
|
|
53
|
+
RED.util.evaluateNodeProperty(cfg.hostUrl, cfg.hostUrlType, node, msg, (err, result) => {
|
|
54
|
+
if (err) {
|
|
55
|
+
node.status({ fill: "red", shape: "dot", text: "Failed" });
|
|
56
|
+
node.error("unable to obtain host url", { ...msg, _err: err })
|
|
57
|
+
} else {
|
|
58
|
+
got.post( result + "/nodes", {
|
|
59
|
+
headers: {
|
|
60
|
+
...headers,
|
|
61
|
+
...hdrs
|
|
62
|
+
},
|
|
63
|
+
body: body
|
|
64
|
+
}).then( res => {
|
|
65
|
+
send({
|
|
66
|
+
...msg,
|
|
67
|
+
payload: JSON.parse(res.body)
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
node.status({fill:"green",shape:"dot",text:"Good"});
|
|
71
|
+
setTimeout( function() { node.status({}) }, 450);
|
|
72
|
+
|
|
73
|
+
}).catch( err => {
|
|
74
|
+
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
75
|
+
node.error("unable to connect to host", { ...msg, _err: err })
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
})
|
|
64
79
|
};
|
|
65
80
|
|
|
66
81
|
/**
|
|
@@ -76,7 +91,7 @@ module.exports = function(RED) {
|
|
|
76
91
|
node, msg, (err, result) => {
|
|
77
92
|
if (err) {
|
|
78
93
|
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
79
|
-
node.error("
|
|
94
|
+
node.error("unable to obtain api username", { ...msg, _err: err})
|
|
80
95
|
} else {
|
|
81
96
|
username = result;
|
|
82
97
|
|
|
@@ -84,7 +99,7 @@ module.exports = function(RED) {
|
|
|
84
99
|
node, msg, (err, result) => {
|
|
85
100
|
if (err) {
|
|
86
101
|
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
87
|
-
node.error("
|
|
102
|
+
node.error("unable to obtain api password", { ...msg, _err: err} )
|
|
88
103
|
} else {
|
|
89
104
|
password = result;
|
|
90
105
|
|
|
@@ -96,27 +111,34 @@ module.exports = function(RED) {
|
|
|
96
111
|
"password": password
|
|
97
112
|
}
|
|
98
113
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
RED.util.evaluateNodeProperty(cfg.hostUrl, cfg.hostUrlType, node, msg, (err, result) => {
|
|
115
|
+
if (err) {
|
|
116
|
+
node.status({ fill: "red", shape: "dot", text: "Failed" });
|
|
117
|
+
node.error("unable to obtain api host url", { ...msg, _err: err })
|
|
118
|
+
} else {
|
|
119
|
+
import('got').then( (module) => {
|
|
120
|
+
module.got.post( result + "/auth/token", {
|
|
121
|
+
json: data
|
|
122
|
+
}).then( res => {
|
|
123
|
+
node.status({
|
|
124
|
+
fill:"blue",
|
|
125
|
+
shape:"dot",
|
|
126
|
+
text:"Installing packages"
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
var access_token = JSON.parse(res.body).access_token;
|
|
130
|
+
|
|
131
|
+
installPackage({
|
|
132
|
+
"Authorization": "Bearer " + access_token
|
|
133
|
+
}, module.got);
|
|
134
|
+
|
|
135
|
+
}).catch((err) => {
|
|
136
|
+
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
137
|
+
node.error( "error occured", { ...msg, _err: err } );
|
|
138
|
+
});
|
|
107
139
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
installPackage({
|
|
112
|
-
"Authorization": "Bearer " + access_token
|
|
113
|
-
}, module.got);
|
|
114
|
-
|
|
115
|
-
}).catch((err) => {
|
|
116
|
-
node.status({fill:"red",shape:"dot",text:"Failed"});
|
|
117
|
-
node.error( "error occured", { ...msg, _err: err } );
|
|
118
|
-
});
|
|
119
|
-
});
|
|
140
|
+
}
|
|
141
|
+
})
|
|
120
142
|
}
|
|
121
143
|
})
|
|
122
144
|
}
|
package/package.json
CHANGED
package/plugins/sidebar.html
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){let t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{(!t.has(e)||"link out"==e.type&&"link"==e.mode&&0==e.links.reduce((e,t)=>e||!!RED.nodes.node(t),!1))&&n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
|
|
8
8
|
|
|
9
|
-
function nr_intro_generate_svg_4_0(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_1(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r,t){return e=>{try{handleSvgObject($($("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(a,t,e){var n=a.clone(),r=(n.find("foreignObject").remove(),n.find("svg.__screenshot").remove(),'width="'+a.attr("width")+'" height="'+a.attr("height")+'"'),s=RED.settings.version.split("."),i=parseInt(s[0]),s=parseInt(s[1]);if(3<=i&&1<=s||4<=i){var o=$($($(a).children("g")[0]).children("g")[0]).children("g"),l={x:8e3,y:8e3,w:-1,h:-1};for(let t=1;t<o.length;t++){var g=o[t].getBBox();0==g.width&&0==g.height||(l.x=Math.min(g.x,l.x),l.y=Math.min(g.y,l.y),l.w=Math.max(g.width,l.w),l.h=Math.max(g.height,l.h))}r+=` viewBox='${l.x} ${l.y} ${l.w} ${l.h}'`}function c(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var s='<?xml version="1.0" standalone="no"?>\r\n<svg '+r+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',i=n.html(),h=(new DOMParser).parseFromString(s+i+"\r\n</svg>","image/svg+xml"),v=t=>t,f=(e.rmidsandclasses&&(v=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e)),["g","rect","line","path","circle","image"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t))}),["text"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t));for(var e=h.getElementsByTagName(t),n=a.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),h.getElementsByTagName("image")),w={},m=(n,r,s)=>{var i=n.getAttribute("xlink:href")||n.getAttribute("href"),a=i.substr(-4,4).toLowerCase(),o={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(w[i])return n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+w[i]),s(r-1);switch(a){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onerror=function(t){s(r-1)},l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),w[i]=e,n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));w[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)})}},d=e=>{if(e<0)t((new XMLSerializer).serializeToString(v(h)));else try{m(f.item(e),e,d)}catch(t){d(e-1)}};0<f.length?m(f.item(f.length-1),f.length-1,d):t((new XMLSerializer).serializeToString(v(h)))}function generatorFunctionForVersion(t,e){var n,r=t.settings.version.split("."),s=r[0],r=r[1];if("3"==s){if("0"==r)return nr_intro_generate_svg_3_0(t,e);if("1"==r)return nr_intro_generate_svg_3_1(t,e)}return"4"==s&&"0"==r?nr_intro_generate_svg_4_0(t,e):(n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")})}function addPanZoom(){var t=d3.select("#node-input-screenshot-svgcontainer svg"),e=(t.html("<g>"+t.html()+"</g>"),setTimeout(()=>{var t=$("#node-input-screenshot-svgcontainer svg"),e=$(t).attr("viewBox").split(" ");t.animate({height:parseInt(e[3]),width:parseInt(e[2])},800,"swing")},100),t.select("g")),n=d3.behavior.zoom().scaleExtent([.1,200]).on("zoom",function(t){e.attr({transform:"translate("+n.translate()+") scale("+n.scale()+")"})});t.call(n)}
|
|
9
|
+
function nr_intro_generate_svg_4_0(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_1(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r,t){return e=>{try{handleSvgObject($($("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(a,t,e){var n=a.clone(),r=(n.find("foreignObject").remove(),n.find("svg.__screenshot").remove(),'width="'+a.attr("width")+'" height="'+a.attr("height")+'"'),s=RED.settings.version.split("."),i=parseInt(s[0]),s=parseInt(s[1]);if(3<=i&&1<=s||4<=i){var o=$($($(a).children("g")[0]).children("g")[0]).children("g"),l={x:8e3,y:8e3,w:-1,h:-1};for(let t=1;t<o.length;t++){var g=o[t].getBBox();0==g.width&&0==g.height||(l.x=Math.min(g.x,l.x),l.y=Math.min(g.y,l.y),l.w=Math.max(g.width,l.w),l.h=Math.max(g.height,l.h))}r+=` viewBox='${l.x} ${l.y} ${l.w} ${l.h}'`}function c(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var s='<?xml version="1.0" standalone="no"?>\r\n<svg '+r+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',i=n.html(),h=(new DOMParser).parseFromString(s+i+"\r\n</svg>","image/svg+xml"),v=t=>t,f=(e.rmidsandclasses&&(v=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e)),["g","rect","line","path","circle","image"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t))}),["text"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t));for(var e=h.getElementsByTagName(t),n=a.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),h.getElementsByTagName("image")),w={},m=(n,r,s)=>{var i=n.getAttribute("xlink:href")||n.getAttribute("href"),a=i.substr(-4,4).toLowerCase(),o={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(w[i])return n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+w[i]),s(r-1);switch(a){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onerror=function(t){s(r-1)},l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),w[i]=e,n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));w[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)});break;default:console.log("SVG Capture ignoring file prefix: "+a),s(r-1)}},d=e=>{if(e<0)t((new XMLSerializer).serializeToString(v(h)));else try{m(f.item(e),e,d)}catch(t){d(e-1)}};0<f.length?m(f.item(f.length-1),f.length-1,d):t((new XMLSerializer).serializeToString(v(h)))}function generatorFunctionForVersion(t,e){var n,r=t.settings.version.split("."),s=r[0],r=r[1];if("3"==s){if("0"==r)return nr_intro_generate_svg_3_0(t,e);if("1"==r)return nr_intro_generate_svg_3_1(t,e)}return"4"==s&&"0"==r?nr_intro_generate_svg_4_0(t,e):(n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")})}function addPanZoom(){var t=d3.select("#node-input-screenshot-svgcontainer svg"),e=(t.html("<g>"+t.html()+"</g>"),setTimeout(()=>{var t=$("#node-input-screenshot-svgcontainer svg"),e=$(t).attr("viewBox").split(" ");t.animate({height:parseInt(e[3]),width:parseInt(e[2])},800,"swing")},100),t.select("g")),n=d3.behavior.zoom().scaleExtent([.1,200]).on("zoom",function(t){e.attr({transform:"translate("+n.translate()+") scale("+n.scale()+")"})});t.call(n)}
|
|
10
10
|
|
|
11
11
|
function setupTreelistInfoness(){var e=collectUndocumentedNodes();if(0==e.length){RED.notify("All nodes documented",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var i;t.node&&(i=t.node.id,setTimeout(()=>{var e=RED.nodes.node(i);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e,"editor-tab-description")),i==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var i=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),i.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),i.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectUndocumentedNodes(){let t=[];RED.nodes.eachNode(e=>{if($("#"+e.id).find(".red-ui-info-available-indicator").remove(),e.info&&e.info.trim()&&$("#"+e.id)[0]){var i=document.createElementNS("http://www.w3.org/2000/svg","g"),n=(i.setAttribute("class","red-ui-info-available-indicator"),i.setAttribute("transform","translate(20,10)"),i.setAttribute("id","infoclk-"+e.id),document.createElementNS("http://www.w3.org/2000/svg","g")),o=(n.setAttribute("class","tip"),n.setAttribute("fill","lightyellow"),document.createElementNS("http://www.w3.org/2000/svg","rect")),o=(o.setAttribute("width","30"),o.setAttribute("height","20"),o.setAttribute("x",$("#"+e.id)[0].getBBox().width-60),o.setAttribute("y","-15"),o.setAttribute("rx","2"),o.setAttribute("style","cursor: pointer;"),n.append(o),document.createElementNS("http://www.w3.org/2000/svg","text"));o.setAttribute("x",$("#"+e.id)[0].getBBox().width-55),o.setAttribute("y","-6"),o.appendChild(document.createTextNode("docs")),n.append(o),i.append(n),$(i).insertBefore($("#"+e.id).find(".red-ui-flow-node"));let t=e.id;$("#infoclk-"+e.id).on("click",e=>{e&&e.preventDefault();e=RED.nodes.node(t);RED.editor.edit(e,"editor-tab-description"),RED.sidebar.show("info")})}else e.z==RED.workspaces.active()&&["link in","link out","link call"].indexOf(e.type)<0&&t.push(e)});var o=[],r={};return t.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var i,n=t.label,n=("function"==typeof n?n.call(e):n)||"";if(0===(i=e.type).indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:i,selected:!1,checkbox:!1},o.push(r[e.id])}),o}
|
|
12
12
|
|