@inteli.city/node-red-contrib-exec-collection 2.0.3 → 2.1.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/package.json +4 -6
- package/async.pg.html +0 -216
- package/async.pg.js +0 -117
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name" : "@inteli.city/node-red-contrib-exec-collection",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"fs": "*",
|
|
6
6
|
"tmp-promise": "*",
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
"queue": "^6.0.2",
|
|
11
11
|
"nunjucks": "^3.2.4",
|
|
12
12
|
"os": "*",
|
|
13
|
-
"terminate": "*"
|
|
14
|
-
|
|
15
|
-
},
|
|
13
|
+
"terminate": "*"
|
|
14
|
+
},
|
|
16
15
|
"keywords": [ "node-red" ],
|
|
17
16
|
"license": "Apache-2.0",
|
|
18
17
|
"node-red" : {
|
|
@@ -22,8 +21,7 @@
|
|
|
22
21
|
"exec service": "exec.service.js",
|
|
23
22
|
"python queue": "python.queue.js",
|
|
24
23
|
"python config": "python.config.js",
|
|
25
|
-
"node queue": "node.queue.js"
|
|
26
|
-
"async pg": "async.pg.js"
|
|
24
|
+
"node queue": "node.queue.js"
|
|
27
25
|
}
|
|
28
26
|
}
|
|
29
27
|
}
|
package/async.pg.html
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
<script type="text/x-red" data-template-name="postgresDB">
|
|
2
|
-
<div class="form-row">
|
|
3
|
-
<label for="node-config-input-name"><i class="fa fa-tag"></i> <span>Name</span></label>
|
|
4
|
-
<input type="text" id="node-config-input-name" placeholder="name">
|
|
5
|
-
</div>
|
|
6
|
-
<div class="form-row">
|
|
7
|
-
<ul style="background: #fff; min-width: 600px; margin-bottom: 20px;" id="async-pg-config-tabs"></ul>
|
|
8
|
-
</div>
|
|
9
|
-
<div id="async-pg-config-tabs-content" style="min-height: 170px;">
|
|
10
|
-
<div id="async-pg-config-tab-connection" style="display: none;">
|
|
11
|
-
<div class="form-row">
|
|
12
|
-
<label for="node-config-input-host"><i class="fa fa-server"></i> <span>Host</span></label>
|
|
13
|
-
<input class="input-append-left" type="text" id="node-config-input-host" placeholder="localhost" style="width: 40%;">
|
|
14
|
-
<label for="node-config-input-port" style="margin-left: 10px; width: 30px; "> <span>Port</span></label>
|
|
15
|
-
<input type="text" id="node-config-input-port" placeholder="5432" style="width:135px">
|
|
16
|
-
</div>
|
|
17
|
-
<div class="form-row">
|
|
18
|
-
<label for="node-config-input-database"><i class="fa fa-database"></i> <span>Database</span></label>
|
|
19
|
-
<input type="text" id="node-config-input-database" placeholder="postgres">
|
|
20
|
-
</div>
|
|
21
|
-
<div class="form-row">
|
|
22
|
-
<input type="checkbox" id="node-config-input-ssl" style="display: inline-block; width: auto; vertical-align: top;">
|
|
23
|
-
<label for="node-config-input-ssl" style="width: auto;"> <span>SSL</span></label>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
<div id="async-pg-config-tab-security" style="display: none;">
|
|
27
|
-
<div class="form-row">
|
|
28
|
-
<label for="node-config-input-user"><i class="fa fa-user"></i> <span>User</span></label>
|
|
29
|
-
<input type="text" id="node-config-input-user" placeholder="postgres">
|
|
30
|
-
</div>
|
|
31
|
-
<div class="form-row">
|
|
32
|
-
<label for="node-config-input-password"><i class="fa fa-lock"></i> <span>Password</span></label>
|
|
33
|
-
<input type="password" id="node-config-input-password" placeholder="postgres">
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
<div id="async-pg-config-tab-pool" style="display: none;">
|
|
37
|
-
<div class="form-row">
|
|
38
|
-
<label title="Maximum number of physical database connections that this connection pool can contain." for="node-config-input-max" style="width: 150px;"><i class="fa fa-thermometer-full"></i> <span>Maximum size</span></label>
|
|
39
|
-
<input type="text" id="node-config-input-max" placeholder="10">
|
|
40
|
-
</div>
|
|
41
|
-
<div class="form-row">
|
|
42
|
-
<label title="Minimum number of physical database connections that this connection pool can contain." for="node-config-input-min" style="width: 150px;"><i class="fa fa-thermometer-empty"></i> <span>Minimum size</span></label>
|
|
43
|
-
<input type="text" id="node-config-input-lin" placeholder="1">
|
|
44
|
-
</div>
|
|
45
|
-
<div class="form-row">
|
|
46
|
-
<label for="node-config-input-idle" style="width: 150px;"><i class="fa fa-hourglass-half"></i> <span>Idle Timeout</span></label>
|
|
47
|
-
<input type="text" id="node-config-input-idle" placeholder="1000 (Milliseconds)">
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
</script>
|
|
52
|
-
<script type="text/javascript">
|
|
53
|
-
RED.nodes.registerType('postgresDB', {
|
|
54
|
-
category: "config",
|
|
55
|
-
color: "#699ECA",
|
|
56
|
-
defaults: {
|
|
57
|
-
name: {
|
|
58
|
-
value: ""
|
|
59
|
-
},
|
|
60
|
-
host: {
|
|
61
|
-
value: "127.0.0.1",
|
|
62
|
-
required: true
|
|
63
|
-
},
|
|
64
|
-
port: {
|
|
65
|
-
value: 5432,
|
|
66
|
-
required: true
|
|
67
|
-
},
|
|
68
|
-
database: {
|
|
69
|
-
value: "postgres",
|
|
70
|
-
required: true
|
|
71
|
-
},
|
|
72
|
-
ssl: {
|
|
73
|
-
value: false
|
|
74
|
-
},
|
|
75
|
-
max: {
|
|
76
|
-
value: 10
|
|
77
|
-
},
|
|
78
|
-
min: {
|
|
79
|
-
value: 1
|
|
80
|
-
},
|
|
81
|
-
idle: {
|
|
82
|
-
value: 1000
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
icon: "leveldb.png",
|
|
86
|
-
credentials: {
|
|
87
|
-
user: {
|
|
88
|
-
type: "text"
|
|
89
|
-
},
|
|
90
|
-
password: {
|
|
91
|
-
type: "password"
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
label: function() {
|
|
95
|
-
if(!this.name) {
|
|
96
|
-
this.name = this.credentials.user + "@" + this.host + ":" + this.port + "/" + this.database;
|
|
97
|
-
}
|
|
98
|
-
return this.name;
|
|
99
|
-
},
|
|
100
|
-
labelStyle: function() {
|
|
101
|
-
return this.name ? "node_label_italic" : "";
|
|
102
|
-
},
|
|
103
|
-
oneditprepare: function() {
|
|
104
|
-
const tabs = RED.tabs.create({
|
|
105
|
-
id: "async-pg-config-tabs",
|
|
106
|
-
onchange: function(tab) {
|
|
107
|
-
$("#async-pg-config-tabs-content").children().hide();
|
|
108
|
-
$("#" + tab.id).show();
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
tabs.addTab({
|
|
112
|
-
id: "async-pg-config-tab-connection",
|
|
113
|
-
label: "Connection"
|
|
114
|
-
});
|
|
115
|
-
tabs.addTab({
|
|
116
|
-
id: "async-pg-config-tab-security",
|
|
117
|
-
label: "Security"
|
|
118
|
-
});
|
|
119
|
-
tabs.addTab({
|
|
120
|
-
id: "async-pg-config-tab-pool",
|
|
121
|
-
label: "Pool"
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
</script>
|
|
126
|
-
<script type="text/x-red" data-template-name="async.pg">
|
|
127
|
-
<div class="form-row">
|
|
128
|
-
<label for="node-input-name"><i class="icon-tag"></i> <span>Name</span></label>
|
|
129
|
-
<input type="text" id="node-input-name" placeholder="name"> </div>
|
|
130
|
-
<div class="form-row">
|
|
131
|
-
<label for="node-input-postgresDB"><i class="fa fa-server"></i> <span>Server</span></label>
|
|
132
|
-
<input type="text" id="node-input-postgresDB">
|
|
133
|
-
</div>
|
|
134
|
-
<div class="form-row" style="display: flex; align-items: center;">
|
|
135
|
-
<label for="node-input-query" style="margin-right: 10px;"><i class="fa fa-file-code-o"></i> <span>Query</span></label>
|
|
136
|
-
<input type="hidden" id="node-input-query" autofocus="autofocus">
|
|
137
|
-
<input type="checkbox" id="node-input-output" style="display: inline-block; width: auto;margin-left: 5px; vertical-align: top;">
|
|
138
|
-
<label for="node-input-output" style="width: auto; margin-left: 10px;margin-top: 10px;font-size:11px;"> <span>Receive output</span></label>
|
|
139
|
-
</div>
|
|
140
|
-
<div class="form-row node-text-editor-row">
|
|
141
|
-
<div style="height: calc(75vh); min-height: 150px;" class="node-text-editor" id="node-input-editor"></div>
|
|
142
|
-
</div>
|
|
143
|
-
</script>
|
|
144
|
-
<script type="text/javascript">
|
|
145
|
-
RED.nodes.registerType("async.pg", {
|
|
146
|
-
category: "function",
|
|
147
|
-
color: '#699ECA',
|
|
148
|
-
defaults: {
|
|
149
|
-
name: {
|
|
150
|
-
value: ""
|
|
151
|
-
},
|
|
152
|
-
query: {
|
|
153
|
-
value: "SELECT 1;"
|
|
154
|
-
},
|
|
155
|
-
postgresDB: {
|
|
156
|
-
type: "postgresDB",
|
|
157
|
-
required: true
|
|
158
|
-
},
|
|
159
|
-
output: {
|
|
160
|
-
value: true
|
|
161
|
-
},
|
|
162
|
-
outputs: {
|
|
163
|
-
value: 1
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
inputs: 1,
|
|
167
|
-
icon: "redis.png",
|
|
168
|
-
align: "left",
|
|
169
|
-
label: function() {
|
|
170
|
-
return this.name || "async.pg";
|
|
171
|
-
},
|
|
172
|
-
labelStyle: function() {
|
|
173
|
-
return this.name ? "node_label_italic" : "";
|
|
174
|
-
},
|
|
175
|
-
oneditprepare: function() {
|
|
176
|
-
$("#node-input-output").prop("checked", this.output);
|
|
177
|
-
this.editor = RED.editor.createEditor({
|
|
178
|
-
id: 'node-input-editor',
|
|
179
|
-
mode: 'ace/mode/sql',
|
|
180
|
-
value: $("#node-input-query").val()
|
|
181
|
-
});
|
|
182
|
-
this.editor.focus();
|
|
183
|
-
},
|
|
184
|
-
oneditsave: function() {
|
|
185
|
-
$("#node-input-query").val(this.editor.getValue());
|
|
186
|
-
delete this.editor;
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
</script>
|
|
190
|
-
<script type="text/x-red" data-help-name="async.pg">
|
|
191
|
-
<p>async.pg 👾 is a Node-RED node allowing basic access to PostgreSQL 🐘 database.</p>
|
|
192
|
-
<p>async.pg sets up a console to execute queries against the configured database.
|
|
193
|
-
</p>
|
|
194
|
-
<p><code>msg.payload</code> will contain the result object of the query. It has the following properties:
|
|
195
|
-
</p>
|
|
196
|
-
<ul>
|
|
197
|
-
<li><i>command</i>: The SQL command that was executed (e.g., "SELECT", "UPDATE", etc.)</li>
|
|
198
|
-
<li><i>rowCount</i>: The number of rows affected by the SQL statement</li>
|
|
199
|
-
<li><i>oid</i>: The OID returned</li>
|
|
200
|
-
<li><i>rows</i>: An array of rows</li>
|
|
201
|
-
</ul>
|
|
202
|
-
<p>async.pg implements a template engine using Nunjucks for parameterized queries:</p>
|
|
203
|
-
<pre>
|
|
204
|
-
{% raw %}{% block body %}
|
|
205
|
-
/* INTEGER id COLUMN */
|
|
206
|
-
SELECT *
|
|
207
|
-
FROM table
|
|
208
|
-
WHERE id = {{ msg.id }}
|
|
209
|
-
/* VARCHAR id COLUMN */
|
|
210
|
-
SELECT *
|
|
211
|
-
FROM table
|
|
212
|
-
WHERE id = '{{ msg.id }}'
|
|
213
|
-
{% endblock %}{% endraw %}
|
|
214
|
-
</pre>
|
|
215
|
-
<p>If <code>msg.payload</code> is not provided or is not an object, an empty object will be used by default.</p>
|
|
216
|
-
</script>
|
package/async.pg.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
module.exports = function(RED) {
|
|
2
|
-
"use strict";
|
|
3
|
-
const nunjucks = require("nunjucks");
|
|
4
|
-
const pgp = require('pg-promise')();
|
|
5
|
-
|
|
6
|
-
function PostgresDBNode(n) {
|
|
7
|
-
const node = this;
|
|
8
|
-
RED.nodes.createNode(this, n);
|
|
9
|
-
node.name = n.name;
|
|
10
|
-
node.host = n.host;
|
|
11
|
-
node.port = n.port;
|
|
12
|
-
node.database = n.database;
|
|
13
|
-
node.ssl = n.ssl;
|
|
14
|
-
node.max = n.max;
|
|
15
|
-
node.min = n.min;
|
|
16
|
-
node.idle = n.idle;
|
|
17
|
-
|
|
18
|
-
if (node.credentials) {
|
|
19
|
-
node.user = node.credentials.user;
|
|
20
|
-
node.password = node.credentials.password;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
node.dbConfig = {
|
|
24
|
-
host: node.host,
|
|
25
|
-
port: node.port,
|
|
26
|
-
database: node.database,
|
|
27
|
-
user: node.user,
|
|
28
|
-
password: node.password,
|
|
29
|
-
ssl: node.ssl,
|
|
30
|
-
max: node.max,
|
|
31
|
-
min: node.min,
|
|
32
|
-
idleTimeoutMillis: node.idle,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// node.warn("DB Config: " + JSON.stringify(node.dbConfig));
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
node.pgDatabase = pgp(node.dbConfig); // Instantiate pg-promise database
|
|
39
|
-
node.warn("Database instance created successfully.");
|
|
40
|
-
node.status({ fill: "green", shape: "dot", text: "connected" });
|
|
41
|
-
} catch (error) {
|
|
42
|
-
node.error('Failed to create database instance: ' + error.message);
|
|
43
|
-
node.status({ fill: "red", shape: "ring", text: "disconnected" });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
node.on('close', function(done) {
|
|
47
|
-
if (node.pgDatabase) {
|
|
48
|
-
pgp.end(); // Close the pg-promise connection pool
|
|
49
|
-
// node.warn("Database connection closed successfully.");
|
|
50
|
-
node.pgDatabase = null;
|
|
51
|
-
}
|
|
52
|
-
node.status({});
|
|
53
|
-
done();
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
RED.nodes.registerType('postgresDB', PostgresDBNode, {
|
|
58
|
-
credentials: {
|
|
59
|
-
user: { type: 'text' },
|
|
60
|
-
password: { type: 'password' }
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
function PostgrestorNode(config) {
|
|
65
|
-
const node = this;
|
|
66
|
-
RED.nodes.createNode(node, config);
|
|
67
|
-
node.topic = config.topic;
|
|
68
|
-
node.config = RED.nodes.getNode(config.postgresDB);
|
|
69
|
-
|
|
70
|
-
if (!node.config || !node.config.pgDatabase) {
|
|
71
|
-
node.error('Database configuration is missing');
|
|
72
|
-
node.status({ fill: "red", shape: "ring", text: "config missing" });
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// node.warn("PostgrestorNode initialized with config: " + JSON.stringify(config));
|
|
77
|
-
// node.warn("Database instance: " + (node.config.pgDatabase ? "exists" : "does not exist"));
|
|
78
|
-
|
|
79
|
-
node.on('input', async function(msg) {
|
|
80
|
-
try {
|
|
81
|
-
// If msg.payload is not an object, initialize it as an empty object
|
|
82
|
-
if (typeof msg.payload !== 'object' || msg.payload === null) {
|
|
83
|
-
msg.payload = {};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Simplify the context to check the structure
|
|
87
|
-
const templateContext = {
|
|
88
|
-
payload: msg.payload
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// Render the Nunjucks template using the simplified context
|
|
92
|
-
const query = nunjucks.renderString(config.query, templateContext);
|
|
93
|
-
// node.warn(query)
|
|
94
|
-
|
|
95
|
-
// Check if query has been properly substituted
|
|
96
|
-
if (query.includes('{{') || query.includes('}}')) {
|
|
97
|
-
node.error('Nunjucks substitution failed');
|
|
98
|
-
node.status({ fill: "red", shape: "ring", text: "template error" });
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
node.status({ fill: "blue", shape: "dot", text: "executing" });
|
|
103
|
-
|
|
104
|
-
// Execute the query
|
|
105
|
-
const result = await node.config.pgDatabase.any(query);
|
|
106
|
-
msg.payload = result;
|
|
107
|
-
node.send(msg);
|
|
108
|
-
node.status({ fill: "green", shape: "dot", text: "completed" });
|
|
109
|
-
} catch (error) {
|
|
110
|
-
node.error('Error executing query: ' + error.message);
|
|
111
|
-
node.status({ fill: "red", shape: "ring", text: "error" });
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
RED.nodes.registerType('async.pg', PostgrestorNode);
|
|
117
|
-
};
|