@theotherwillembotha/node-red-plugincore 0.0.55 → 0.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/README.md +5 -2
- package/build/Nodes.html +23 -21
- package/build/Plugins.js +0 -1
- package/build/core/NodeConstructor.d.ts +1 -0
- package/build/core/NodeConstructor.d.ts.map +1 -1
- package/build/core/NodeConstructor.js +5 -12
- package/build/core/NodeGenerator.d.ts.map +1 -1
- package/build/core/NodeGenerator.js +0 -1
- package/build/core/webhook/WebhookDecorator.d.ts.map +1 -1
- package/build/core/webhook/WebhookDecorator.js +43 -6
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts +1 -0
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.js +0 -5
- package/package.json +2 -3
- package/src/core/NodeConstructor.ts +6 -13
- package/src/core/NodeGenerator.ts +0 -1
- package/src/core/logger/template/LoggerTemplate.html +2 -2
- package/src/core/metrics/node/TimerMetricConfigNode.html +2 -2
- package/src/core/other/template/BasicTemplate.html +5 -2
- package/src/core/webhook/WebhookDecorator.ts +53 -10
- package/src/core/webhook/service/ReverseProxyTypeService.ts +1 -0
- package/src/core/webhook/service/WebhookServerService.ts +0 -5
- package/src/core/webhook/template/WebhookTemplate.html +1 -1
- package/build/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
- package/build/core/logger/node/RestLoggerConfigNode.html +0 -183
- package/build/core/logger/template/LoggerTemplate.html +0 -331
- package/build/core/metrics/node/CounterMetricConfigNode.html +0 -48
- package/build/core/metrics/node/GaugeMetricConfigNode.html +0 -48
- package/build/core/metrics/node/MetricsConfigNode.html +0 -21
- package/build/core/metrics/node/TimerMetricConfigNode.html +0 -190
- package/build/core/metrics/template/CounterMetricTemplate.html +0 -40
- package/build/core/metrics/template/GaugeMetricTemplate.html +0 -39
- package/build/core/metrics/template/MetricsTemplate.html +0 -54
- package/build/core/metrics/template/TimerMetricTemplate.html +0 -39
- package/build/core/other/node/DelegatedConfigReferenceNode.html +0 -1
- package/build/core/other/template/BasicTemplate.html +0 -76
- package/build/core/other/template/SettingsTemplate.html +0 -128
- package/build/core/ui/template/ScriptEditorTemplate.html +0 -50
- package/build/core/ui/template/UIHelperTemplate.html +0 -229
- package/build/core/webhook/node/WebhookServerConfigNode.html +0 -61
- package/build/core/webhook/template/WebhookTemplate.html +0 -442
package/README.md
CHANGED
|
@@ -16,11 +16,14 @@ This framework is the foundation for a growing set of Node-RED plugins. The foll
|
|
|
16
16
|
| Plugin | Description |
|
|
17
17
|
|--------|-------------|
|
|
18
18
|
| [@theotherwillembotha/node-red-telemetry](https://github.com/theotherwillembotha/nodered_telemetry) | Ready-to-use flow nodes for structured logging and Prometheus metrics — Logger, Counter, Gauge, and Timer nodes that attach to the config nodes provided by this package. |
|
|
19
|
-
| [@theotherwillembotha/node-red-loki](https://github.com/theotherwillembotha/nodered_loki) | Grafana Loki logger config node
|
|
19
|
+
| [@theotherwillembotha/node-red-loki](https://github.com/theotherwillembotha/nodered_loki) | Grafana Loki integration for Node-RED. Provides a Loki service config node, a Loki logger config node that plugs into the logging infrastructure provided by this package, and a LogQL query node for reading log streams from Loki. |
|
|
20
20
|
| [@theotherwillembotha/node-red-nginxproxymanager](https://github.com/theotherwillembotha/nodered_nginxproxymanager) | Node-RED nodes for managing Nginx Proxy Manager hosts directly from your flows. Includes a config node that registers as a reverse proxy provider, an Update Host node for creating and updating proxy entries, and a Get Hosts node for retrieving the current host list. |
|
|
21
21
|
| [@theotherwillembotha/node-red-circuitbreaker](https://github.com/theotherwillembotha/nodered_circuitbreaker) | Circuit Breaker nodes for building resilient flows. Detects faults in external integrations using configurable fault and trip functions, routes messages based on breaker state, and supports event-driven recovery flows. |
|
|
22
|
-
| [@theotherwillembotha/node-red-temporal](https://github.com/theotherwillembotha/nodered_temporal) | Date/time
|
|
22
|
+
| [@theotherwillembotha/node-red-temporal](https://github.com/theotherwillembotha/nodered_temporal) | Date/time nodes powered by the TC39 Temporal API. Transform, adjust, and format date/time values across timezones, or compute the duration between two points in time — with multiple output modes, offset support, and a Moment.js-style custom format system. |
|
|
23
23
|
| [@theotherwillembotha/node-red-zookeeper](https://github.com/theotherwillembotha/nodered_zookeeper) | Apache ZooKeeper integration nodes. Subscribe to ZooKeeper node change events, read node values on demand, and write data to ZooKeeper nodes from your flows. |
|
|
24
|
+
| [@theotherwillembotha/node-red-whatsapp](https://github.com/theotherwillembotha/nodered_whatsapp) | WhatsApp messaging nodes for Node-RED. Send and receive WhatsApp messages from your flows using the Baileys library — no cloud API or paid subscription required. |
|
|
25
|
+
| [@theotherwillembotha/node-red-cluster](https://github.com/theotherwillembotha/nodered_cluster) | Clustering plugin for Node-RED. Connect multiple Node-RED instances into a coordinated cluster using NATS JetStream for reliable message transport and NATS KV for shared state, with ZooKeeper-based instance discovery and endpoint registration. |
|
|
26
|
+
| [@theotherwillembotha/node-red-kafka](https://github.com/theotherwillembotha/nodered_kafka) | Apache Kafka producer and consumer nodes for Node-RED. Publish messages to Kafka topics and subscribe to incoming records directly from your flows. |
|
|
24
27
|
|
|
25
28
|
Additional plugins will be listed here as they are published.
|
|
26
29
|
|
package/build/Nodes.html
CHANGED
|
@@ -440,50 +440,59 @@ Mustache/Handlebars templates build the message string POSTed to the endpoint.
|
|
|
440
440
|
required: false
|
|
441
441
|
},
|
|
442
442
|
reverseProxies_connections: {
|
|
443
|
-
type: 'ReverseProxyType[]',
|
|
444
443
|
value: '',
|
|
445
|
-
required:
|
|
444
|
+
required: false,
|
|
446
445
|
maxInstances: 10
|
|
447
446
|
},
|
|
448
447
|
_reverseProxies_connections_0: {
|
|
449
448
|
value: '',
|
|
450
|
-
required: false
|
|
449
|
+
required: false,
|
|
450
|
+
type: 'DelegatedConfigReferenceNode'
|
|
451
451
|
},
|
|
452
452
|
_reverseProxies_connections_1: {
|
|
453
453
|
value: '',
|
|
454
|
-
required: false
|
|
454
|
+
required: false,
|
|
455
|
+
type: 'DelegatedConfigReferenceNode'
|
|
455
456
|
},
|
|
456
457
|
_reverseProxies_connections_2: {
|
|
457
458
|
value: '',
|
|
458
|
-
required: false
|
|
459
|
+
required: false,
|
|
460
|
+
type: 'DelegatedConfigReferenceNode'
|
|
459
461
|
},
|
|
460
462
|
_reverseProxies_connections_3: {
|
|
461
463
|
value: '',
|
|
462
|
-
required: false
|
|
464
|
+
required: false,
|
|
465
|
+
type: 'DelegatedConfigReferenceNode'
|
|
463
466
|
},
|
|
464
467
|
_reverseProxies_connections_4: {
|
|
465
468
|
value: '',
|
|
466
|
-
required: false
|
|
469
|
+
required: false,
|
|
470
|
+
type: 'DelegatedConfigReferenceNode'
|
|
467
471
|
},
|
|
468
472
|
_reverseProxies_connections_5: {
|
|
469
473
|
value: '',
|
|
470
|
-
required: false
|
|
474
|
+
required: false,
|
|
475
|
+
type: 'DelegatedConfigReferenceNode'
|
|
471
476
|
},
|
|
472
477
|
_reverseProxies_connections_6: {
|
|
473
478
|
value: '',
|
|
474
|
-
required: false
|
|
479
|
+
required: false,
|
|
480
|
+
type: 'DelegatedConfigReferenceNode'
|
|
475
481
|
},
|
|
476
482
|
_reverseProxies_connections_7: {
|
|
477
483
|
value: '',
|
|
478
|
-
required: false
|
|
484
|
+
required: false,
|
|
485
|
+
type: 'DelegatedConfigReferenceNode'
|
|
479
486
|
},
|
|
480
487
|
_reverseProxies_connections_8: {
|
|
481
488
|
value: '',
|
|
482
|
-
required: false
|
|
489
|
+
required: false,
|
|
490
|
+
type: 'DelegatedConfigReferenceNode'
|
|
483
491
|
},
|
|
484
492
|
_reverseProxies_connections_9: {
|
|
485
493
|
value: '',
|
|
486
|
-
required: false
|
|
494
|
+
required: false,
|
|
495
|
+
type: 'DelegatedConfigReferenceNode'
|
|
487
496
|
},
|
|
488
497
|
},
|
|
489
498
|
oneditprepare: function() {
|
|
@@ -743,13 +752,6 @@ Mustache/Handlebars templates build the message string POSTed to the endpoint.
|
|
|
743
752
|
});
|
|
744
753
|
console.log(node.reverseProxies_connections);
|
|
745
754
|
}
|
|
746
|
-
// **** MetricsConfigNode_shaddowDefaults **** //
|
|
747
|
-
{
|
|
748
|
-
let node = this;
|
|
749
|
-
for (let i = 0; i < 10; i++) {
|
|
750
|
-
node["_reverseProxies_connections_" + i] = (node.reverseProxies_connections[i] || {}).proxy || "";
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
755
|
},
|
|
754
756
|
oneditcancel: function() {},
|
|
755
757
|
oneditdelete: function() {},
|
|
@@ -1316,13 +1318,13 @@ Configuration node for the Gauge Metrics
|
|
|
1316
1318
|
|
|
1317
1319
|
<div class="form-row">
|
|
1318
1320
|
<label class="towb_editorlabel" for="node-config-input-metricType"><i class="fa fa-bar-chart"></i> Type</label>
|
|
1319
|
-
<input
|
|
1321
|
+
<input type="text" id="node-config-input-metricType" />
|
|
1320
1322
|
</div>
|
|
1321
1323
|
|
|
1322
1324
|
<div class="metrictype metrictype_histogram">
|
|
1323
1325
|
<div class="form-row">
|
|
1324
1326
|
<label class="towb_editorlabel" for="node-config-input-buckettype"><i class="fa fa-sliders"></i> Bucket Type</label>
|
|
1325
|
-
<input
|
|
1327
|
+
<input type="text" id="node-config-input-buckettype" />
|
|
1326
1328
|
</div>
|
|
1327
1329
|
|
|
1328
1330
|
<div class="metricsconfig_buckets metricsconfig_buckets_default">
|
package/build/Plugins.js
CHANGED
|
@@ -30,7 +30,6 @@ module.exports = function (RED) {
|
|
|
30
30
|
let plugin = RED.plugins.get(pluginID);
|
|
31
31
|
|
|
32
32
|
if(addedPlugin && plugin.instantiate && !plugin.instance){
|
|
33
|
-
console.log("Deploying instance of: " + plugin.id);
|
|
34
33
|
plugin.instance = new plugin.class();
|
|
35
34
|
|
|
36
35
|
// instantiate the plugin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeConstructor.d.ts","sourceRoot":"","sources":["../../src/core/NodeConstructor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAW,uBAAuB,EAAC,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"NodeConstructor.d.ts","sourceRoot":"","sources":["../../src/core/NodeConstructor.ts"],"names":[],"mappings":"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"}
|
|
@@ -290,12 +290,7 @@ class NodeManager {
|
|
|
290
290
|
};
|
|
291
291
|
// check if the reverserproxyttypesewrvice is installed yet.
|
|
292
292
|
this.nodeTypeService = RED.plugins.get("@theotherwillembotha/nodetypeservice").instance;
|
|
293
|
-
if (this.nodeTypeService) {
|
|
294
|
-
console.log("NodeTypeService installed!");
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
// Register a listener to trigger when the RegerseProxyTypService gets installed.
|
|
298
|
-
console.log("nodetypeservice not installed yet. waiting for it to be installed");
|
|
293
|
+
if (!this.nodeTypeService) {
|
|
299
294
|
RED.events.on('plugin.instantiated', nodeTypeServiceListener);
|
|
300
295
|
}
|
|
301
296
|
}
|
|
@@ -342,7 +337,6 @@ class NodeManager {
|
|
|
342
337
|
}
|
|
343
338
|
};
|
|
344
339
|
try {
|
|
345
|
-
console.log("registering node " + typeName);
|
|
346
340
|
NodeManager.RED.nodes.registerType(typeName, nodeConstructor, { settings: {} });
|
|
347
341
|
let nodeDescription = type.getNodeDescriptor();
|
|
348
342
|
// registger the node tags.
|
|
@@ -354,7 +348,6 @@ class NodeManager {
|
|
|
354
348
|
else {
|
|
355
349
|
this.typeBacklog.push(type);
|
|
356
350
|
}
|
|
357
|
-
console.log("registered node " + typeName);
|
|
358
351
|
}
|
|
359
352
|
catch (error) {
|
|
360
353
|
console.error("registering node: " + typeName + " failed", error);
|
|
@@ -430,12 +423,12 @@ class NodeBuilder {
|
|
|
430
423
|
this._category = category;
|
|
431
424
|
}
|
|
432
425
|
addDefault(name, template) {
|
|
433
|
-
// if
|
|
434
|
-
if (template.
|
|
426
|
+
// if list:true, this is an array of config references — generate shadow defaults for each slot.
|
|
427
|
+
if (template.list === true) {
|
|
435
428
|
template.maxInstances = template.maxInstances ? template.maxInstances : 10;
|
|
436
|
-
this._defaults[name] = {
|
|
429
|
+
this._defaults[name] = { value: "", required: (template.required) ? template.required : false, maxInstances: template.maxInstances };
|
|
437
430
|
for (let i = 0; i < template.maxInstances; i++) {
|
|
438
|
-
this._defaults["_" + name + "_" + i] = { value: "", required: false };
|
|
431
|
+
this._defaults["_" + name + "_" + i] = { value: "", required: false, type: template.type };
|
|
439
432
|
}
|
|
440
433
|
}
|
|
441
434
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeGenerator.d.ts","sourceRoot":"","sources":["../../src/core/NodeGenerator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,QAAQ,EAAE,cAAc,EAAe,iBAAiB,EAA4B,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAIrJ,MAAM,WAAW,cAAc;IAC3B,QAAQ,QAAQ,CAAC;IACjB,qBAAqB,IAAI,kBAAkB,CAAC;CAC/C;AAED,MAAM,WAAW,UAAU;IACvB,iBAAiB,IAAG,cAAc,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC1B,oBAAoB,IAAG,iBAAiB,CAAC;CAC5C;AAED,cAAM,aAAa;IAEf,OAAO,CAAC,MAAM,CAAC,WAAW,CAAM;IAChC,OAAO,CAAC,MAAM,CAAC,OAAO,CAKpB;IAEF,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAA4E;IAC1F,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,UAAU,CAA2B;gBAE1B,UAAU,EAAC,MAAM;IAIpC,OAAO,CAAC,aAAa;IAmBd,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,aAAa;IAiBzD,YAAY,CAAC,IAAI,EAAC,UAAU,GAAE,aAAa;IAiB3C,eAAe,CAAC,OAAO,EAAE,aAAa,GAAE,aAAa;IAerD,QAAQ,CAAC,eAAe,EAAC,MAAM,EAAE,iBAAiB,EAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"NodeGenerator.d.ts","sourceRoot":"","sources":["../../src/core/NodeGenerator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,QAAQ,EAAE,cAAc,EAAe,iBAAiB,EAA4B,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAIrJ,MAAM,WAAW,cAAc;IAC3B,QAAQ,QAAQ,CAAC;IACjB,qBAAqB,IAAI,kBAAkB,CAAC;CAC/C;AAED,MAAM,WAAW,UAAU;IACvB,iBAAiB,IAAG,cAAc,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC1B,oBAAoB,IAAG,iBAAiB,CAAC;CAC5C;AAED,cAAM,aAAa;IAEf,OAAO,CAAC,MAAM,CAAC,WAAW,CAAM;IAChC,OAAO,CAAC,MAAM,CAAC,OAAO,CAKpB;IAEF,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAA4E;IAC1F,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,UAAU,CAA2B;gBAE1B,UAAU,EAAC,MAAM;IAIpC,OAAO,CAAC,aAAa;IAmBd,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,aAAa;IAiBzD,YAAY,CAAC,IAAI,EAAC,UAAU,GAAE,aAAa;IAiB3C,eAAe,CAAC,OAAO,EAAE,aAAa,GAAE,aAAa;IAerD,QAAQ,CAAC,eAAe,EAAC,MAAM,EAAE,iBAAiB,EAAC,MAAM;IAyIhE,OAAO,CAAC,MAAM,CAAC,cAAc;CAQhC;AAID,OAAO,EACH,aAAa,EAChB,CAAA;AAED,MAAM,WAAW,UAAU;IACvB,IAAI,EAAC,MAAM,CAAC;CACf;AAmCD,qBAAa,aAAa;WAER,aAAa,CAAC,SAAS,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,GAAE,MAAM;CA2B1E;AAED,MAAM,MAAM,OAAO,GAAG;IAClB,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAC;CACpB,CAAA"}
|
|
@@ -191,7 +191,6 @@ module.exports = function (RED) {
|
|
|
191
191
|
let plugin = RED.plugins.get(pluginID);
|
|
192
192
|
|
|
193
193
|
if(addedPlugin && plugin.instantiate && !plugin.instance){
|
|
194
|
-
console.log("Deploying instance of: " + plugin.id);
|
|
195
194
|
plugin.instance = new plugin.class();
|
|
196
195
|
|
|
197
196
|
// instantiate the plugin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebhookDecorator.d.ts","sourceRoot":"","sources":["../../../src/core/webhook/WebhookDecorator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WebhookDecorator.d.ts","sourceRoot":"","sources":["../../../src/core/webhook/WebhookDecorator.ts"],"names":[],"mappings":"AAqBA,QAAA,MAAM,OAAO,KAoFD,CAAC;AAGb,OAAO,EACH,OAAO,EACV,CAAA"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Webhook = void 0;
|
|
7
|
+
const os_1 = __importDefault(require("os"));
|
|
4
8
|
const LoggerService_1 = require("../logger/service/LoggerService");
|
|
5
9
|
const NodeConstructor_1 = require("../NodeConstructor");
|
|
10
|
+
const ReverseProxyTypeService_1 = require("./service/ReverseProxyTypeService");
|
|
11
|
+
// In-memory registry: nodeId → managed proxy host entries from the last deploy.
|
|
12
|
+
const managedProxyHosts = new Map();
|
|
6
13
|
const Webhook = (0, NodeConstructor_1.createPostConstructDecorator)('Webhook')
|
|
7
14
|
.withInitLogic(async (instance, propertyKey, webhookconfig) => {
|
|
8
15
|
//console.log(`Registering webhook callback`, "PROPERTYKEY", propertyKey, "WEBHOOK CONFIG", webhookconfig, "THIS", this);
|
|
@@ -21,20 +28,50 @@ const Webhook = (0, NodeConstructor_1.createPostConstructDecorator)('Webhook')
|
|
|
21
28
|
let webhookServer = NodeConstructor_1.NodeManager.RED.nodes.getNode(nodeConfig.webhook).node().server();
|
|
22
29
|
webhookServer.attach(endpointConfig, (request, respponse) => instance[propertyKey](request, respponse));
|
|
23
30
|
if (nodeConfig.reverseProxies_enabled) {
|
|
31
|
+
let targetPort = webhookServer.config().port;
|
|
32
|
+
let targetHost = os_1.default.hostname();
|
|
33
|
+
let nodeId = nodeConfig.id;
|
|
34
|
+
let newlyManaged = [];
|
|
24
35
|
await Promise.all(nodeConfig.reverseProxies_connections.map(async (proxy) => {
|
|
25
36
|
try {
|
|
26
|
-
// get a n instance of reverseProxNode.
|
|
27
|
-
let reverseProxyNode = NodeConstructor_1.NodeManager.RED.nodes.getNode(proxy.proxy).node();
|
|
28
37
|
// TODO: ReverseProxyConfigNodes need to become their own subtype of config nodes so we can enforce the ".client()" method.
|
|
38
|
+
let reverseProxyNode = NodeConstructor_1.NodeManager.RED.nodes.getNode(proxy.proxy).node();
|
|
39
|
+
let proxyClient = reverseProxyNode.client();
|
|
40
|
+
let hosts = await proxyClient.getHosts();
|
|
41
|
+
let matchingHost = hosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
42
|
+
if (!matchingHost) {
|
|
43
|
+
await proxyClient.updateHost({ domainNames: [proxy.domainname], forwardHost: targetHost, forwardPort: targetPort, scheme: ReverseProxyTypeService_1.HTTPScheme.HTTP });
|
|
44
|
+
// Fetch again to get the assigned ID of the newly created entry.
|
|
45
|
+
let updatedHosts = await proxyClient.getHosts();
|
|
46
|
+
matchingHost = updatedHosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
47
|
+
}
|
|
48
|
+
else if (matchingHost.forwardHost !== targetHost || matchingHost.forwardPort !== targetPort) {
|
|
49
|
+
await proxyClient.updateHost({ id: matchingHost.id, forwardHost: targetHost, forwardPort: targetPort, scheme: ReverseProxyTypeService_1.HTTPScheme.HTTP });
|
|
50
|
+
}
|
|
51
|
+
if (matchingHost?.id !== undefined) {
|
|
52
|
+
newlyManaged.push({ proxyNodeId: proxy.proxy, hostId: matchingHost.id });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.error(e);
|
|
57
|
+
}
|
|
58
|
+
}));
|
|
59
|
+
// Remove any stale proxy host entries that were managed last deploy but are no longer in the current config.
|
|
60
|
+
let previouslyManaged = managedProxyHosts.get(nodeId) ?? [];
|
|
61
|
+
let newHostIds = new Set(newlyManaged.map(m => m.hostId));
|
|
62
|
+
await Promise.all(previouslyManaged
|
|
63
|
+
.filter(m => !newHostIds.has(m.hostId))
|
|
64
|
+
.map(async (stale) => {
|
|
65
|
+
try {
|
|
66
|
+
let reverseProxyNode = NodeConstructor_1.NodeManager.RED.nodes.getNode(stale.proxyNodeId).node();
|
|
29
67
|
let proxyClient = reverseProxyNode.client();
|
|
30
|
-
|
|
31
|
-
//console.log("ADD REVERSE PROXY:" + proxy.proxy + " to " + node.id(), proxyClient);
|
|
68
|
+
await proxyClient.deleteHost(stale.hostId);
|
|
32
69
|
}
|
|
33
70
|
catch (e) {
|
|
34
|
-
console.
|
|
71
|
+
console.error(e);
|
|
35
72
|
}
|
|
36
|
-
return Promise.resolve();
|
|
37
73
|
}));
|
|
74
|
+
managedProxyHosts.set(nodeId, newlyManaged);
|
|
38
75
|
}
|
|
39
76
|
// register a close listener to the node.
|
|
40
77
|
node.node().on("close", () => {
|
|
@@ -8,6 +8,7 @@ export declare abstract class ReverseProxyType {
|
|
|
8
8
|
export interface ProxyManagerClient {
|
|
9
9
|
updateHost(data: Partial<HostEntry>): Promise<void>;
|
|
10
10
|
getHosts(): Promise<Partial<HostEntry>[]>;
|
|
11
|
+
deleteHost(id: number): Promise<void>;
|
|
11
12
|
}
|
|
12
13
|
export type HostEntry = {
|
|
13
14
|
id: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReverseProxyTypeService.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/service/ReverseProxyTypeService.ts"],"names":[],"mappings":"AAGA,8BAAsB,gBAAgB;IAElC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAS;gBAEV,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM;IAK3B,EAAE,IAAG,MAAM;IAGX,IAAI,IAAG,MAAM;CAGvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,IAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ReverseProxyTypeService.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/service/ReverseProxyTypeService.ts"],"names":[],"mappings":"AAGA,8BAAsB,gBAAgB;IAElC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAS;gBAEV,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM;IAK3B,EAAE,IAAG,MAAM;IAGX,IAAI,IAAG,MAAM;CAGvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,IAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,MAAM,SAAS,GAAG;IACpB,EAAE,EAAC,MAAM,CAAC;IACV,WAAW,EAAC,MAAM,EAAE,CAAC;IACrB,MAAM,EAAC,UAAU,CAAC;IAClB,WAAW,EAAC,MAAM,CAAC;IACnB,WAAW,EAAC,MAAM,CAAC;IACnB,UAAU,EAAC,MAAM,CAAC;IAClB,WAAW,EAAC,OAAO,CAAC;IACpB,mBAAmB,EAAC,OAAO,CAAC;IAC5B,gBAAgB,EAAC,OAAO,CAAC;CAC5B,CAAA;AAED,oBAAY,UAAU;IAClB,IAAI,SAAS;IACb,KAAK,UAAU;CAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebhookServerService.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/service/WebhookServerService.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5D,OAAgB,EAAU,OAAO,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE5D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAIvF,oBAAY,kBAAkB;IAC1B,GAAG,QAAQ;IACX,IAAI,SAAS;CAChB;AAED,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAC,YAAY,CAAC,IAAI,CAAC;CAC1B,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,IAAI,EAAC,YAAY,CAAC,KAAK,CAAA;IACvB,QAAQ,EAAC,MAAM,CAAC;IAChB,QAAQ,EAAC,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,IAAI,EAAC,YAAY,CAAC,MAAM,CAAC;IACzB,SAAS,EAAC,mBAAmB,CAAC;IAC9B,GAAG,EAAC,MAAM,CAAC;IACX,KAAK,EAAC,MAAM,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAC,kBAAkB,EAAE,CAAC;IAC7B,cAAc,EAAE,sBAAsB,GAAG,yBAAyB,GAAG,0BAA0B,CAAC;CACnG,CAAA;AAED,qBAAa,aAAa;IAEtB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,SAAS,CAAS;gBAEP,MAAM,EAAC,mBAAmB;IAQtC,MAAM,CAAC,QAAQ,EAAC,cAAc,EAAE,QAAQ,EAAC,CAAC,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,QAAQ,KAAK,GAAG;
|
|
1
|
+
{"version":3,"file":"WebhookServerService.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/service/WebhookServerService.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAG5D,OAAgB,EAAU,OAAO,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE5D,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAIvF,oBAAY,kBAAkB;IAC1B,GAAG,QAAQ;IACX,IAAI,SAAS;CAChB;AAED,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAC,YAAY,CAAC,IAAI,CAAC;CAC1B,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACpC,IAAI,EAAC,YAAY,CAAC,KAAK,CAAA;IACvB,QAAQ,EAAC,MAAM,CAAC;IAChB,QAAQ,EAAC,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACrC,IAAI,EAAC,YAAY,CAAC,MAAM,CAAC;IACzB,SAAS,EAAC,mBAAmB,CAAC;IAC9B,GAAG,EAAC,MAAM,CAAC;IACX,KAAK,EAAC,MAAM,CAAC;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAC,kBAAkB,EAAE,CAAC;IAC7B,cAAc,EAAE,sBAAsB,GAAG,yBAAyB,GAAG,0BAA0B,CAAC;CACnG,CAAA;AAED,qBAAa,aAAa;IAEtB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,SAAS,CAAS;gBAEP,MAAM,EAAC,mBAAmB;IAQtC,MAAM,CAAC,QAAQ,EAAC,cAAc,EAAE,QAAQ,EAAC,CAAC,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,QAAQ,KAAK,GAAG;IA8CpF,MAAM,CAAC,aAAa,EAAC,cAAc;IAoBnC,MAAM,IAAG,mBAAmB;CAGtC;AAED,MAAM,MAAO,mBAAmB,GAAG;IAC/B,EAAE,EAAC,MAAM,CAAA;IACT,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAC,MAAM,CAAC;IACpB,YAAY,EAAC,MAAM,CAAC;CACvB,CAAA;AAED,qBAAa,oBAAqB,SAAQ,WAAW;IAEjD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAmC;;IAMzD,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjE,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAInE,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;WAuCvD,GAAG,CAAE,MAAM,EAAC,mBAAmB,GAAG,aAAa;WAS7C,oBAAoB,IAAG,iBAAiB;CAU3D"}
|
|
@@ -58,7 +58,6 @@ class WebhookServer {
|
|
|
58
58
|
if (endpoint.methods.includes(EndpointMethodType.POST)) {
|
|
59
59
|
this._app.post(endpoint.path, handlerChain);
|
|
60
60
|
}
|
|
61
|
-
console.log("added endpoint to " + endpoint.path);
|
|
62
61
|
}
|
|
63
62
|
detach(configuration) {
|
|
64
63
|
configuration.methods.forEach(method => {
|
|
@@ -78,8 +77,6 @@ class WebhookServer {
|
|
|
78
77
|
;
|
|
79
78
|
});
|
|
80
79
|
});
|
|
81
|
-
console.log("ROUTES REMOVED!");
|
|
82
|
-
this._app.router.stack.forEach(route => console.log("KNOWN ROUTE", route, route.route?.path, route.route.methods.post));
|
|
83
80
|
}
|
|
84
81
|
config() {
|
|
85
82
|
return this._config;
|
|
@@ -108,7 +105,6 @@ class WebhookServerService extends NodeConstructor_1.BaseService {
|
|
|
108
105
|
// compare the properties.
|
|
109
106
|
if (!webhookServerNode) {
|
|
110
107
|
// the node has been removed: TODO: alert the listeners that it has been removed.
|
|
111
|
-
console.log("Webhook Service Removed", serverServiceConfig);
|
|
112
108
|
removedServers.push(serverServiceConfig);
|
|
113
109
|
}
|
|
114
110
|
else {
|
|
@@ -118,7 +114,6 @@ class WebhookServerService extends NodeConstructor_1.BaseService {
|
|
|
118
114
|
webhookServerNode.externalPort !== serverServiceConfig.externalPort;
|
|
119
115
|
if (serviceChanged) {
|
|
120
116
|
// TODO: notify the subscribers that the server has chaned.
|
|
121
|
-
console.log("Notify the subscribers WebhookServer has changed.", serverServiceConfig, webhookServerNode);
|
|
122
117
|
removedServers.push(serverServiceConfig);
|
|
123
118
|
addedServers.push(webhookServerNode);
|
|
124
119
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theotherwillembotha/node-red-plugincore",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "A core framework for building production-grade Node-RED plugins, with built-in support for structured logging, metrics, and webhook ingestion.",
|
|
5
5
|
"author": "Willem Botha (@theotherwillembotha)",
|
|
6
6
|
"license": "ISC",
|
|
@@ -17,9 +17,8 @@
|
|
|
17
17
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
18
18
|
"prepare": "npm run build",
|
|
19
19
|
"clean": "rm -rf ./build && rm -rf ./resources",
|
|
20
|
-
"build": "npm run clean && tsc && npm run
|
|
20
|
+
"build": "npm run clean && tsc && npm run generate-nodes && npm run copy-files",
|
|
21
21
|
"generate-nodes": "node build/GenerateNodes.js",
|
|
22
|
-
"copy-html": "cd src && find -type f -name '*Template.html' -exec cp --parents '{}' ../build/ ';' && find -type f -name '*Node.html' -exec cp --parents '{}' ../build/ ';' && cd ..",
|
|
23
22
|
"copy-files": "cp -r ./icons ./build && mkdir -p ./resources && cp -r ./build/resources/. ./resources/"
|
|
24
23
|
},
|
|
25
24
|
"repository": {
|
|
@@ -9,7 +9,6 @@ import beautify from 'js-beautify';
|
|
|
9
9
|
import markdownit from 'markdown-it'
|
|
10
10
|
import Handlebars, { template } from "handlebars";
|
|
11
11
|
import { NodeTypeService } from "./tagging/service/NodeTypeService";
|
|
12
|
-
import { NodeDescriptionConfig } from "./tagging/NodeDescriptionDecorator";
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
|
|
@@ -400,12 +399,7 @@ export class NodeManager{
|
|
|
400
399
|
|
|
401
400
|
// check if the reverserproxyttypesewrvice is installed yet.
|
|
402
401
|
this.nodeTypeService = (RED.plugins.get("@theotherwillembotha/nodetypeservice") as any).instance as NodeTypeService;
|
|
403
|
-
if(this.nodeTypeService) {
|
|
404
|
-
console.log("NodeTypeService installed!")
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
// Register a listener to trigger when the RegerseProxyTypService gets installed.
|
|
408
|
-
console.log("nodetypeservice not installed yet. waiting for it to be installed");
|
|
402
|
+
if(!this.nodeTypeService) {
|
|
409
403
|
RED.events.on('plugin.instantiated', nodeTypeServiceListener);
|
|
410
404
|
}
|
|
411
405
|
}
|
|
@@ -462,7 +456,6 @@ export class NodeManager{
|
|
|
462
456
|
}
|
|
463
457
|
|
|
464
458
|
try{
|
|
465
|
-
console.log("registering node " + typeName);
|
|
466
459
|
NodeManager.RED.nodes.registerType(typeName, nodeConstructor, { settings: {}});
|
|
467
460
|
|
|
468
461
|
let nodeDescription = type.getNodeDescriptor();
|
|
@@ -477,7 +470,6 @@ export class NodeManager{
|
|
|
477
470
|
this.typeBacklog.push(type);
|
|
478
471
|
}
|
|
479
472
|
|
|
480
|
-
console.log("registered node " + typeName);
|
|
481
473
|
}
|
|
482
474
|
catch(error){
|
|
483
475
|
console.error("registering node: " + typeName + " failed", error);
|
|
@@ -569,6 +561,7 @@ export type DefaultTemplateType = {
|
|
|
569
561
|
minInstances?:number;
|
|
570
562
|
maxInstances?:number;
|
|
571
563
|
validate?:Function;
|
|
564
|
+
list?:boolean;
|
|
572
565
|
}
|
|
573
566
|
|
|
574
567
|
export class NodeBuilder {
|
|
@@ -598,12 +591,12 @@ export class NodeBuilder {
|
|
|
598
591
|
}
|
|
599
592
|
|
|
600
593
|
public addDefault(name:string, template:DefaultTemplateType):NodeBuilder{
|
|
601
|
-
// if
|
|
602
|
-
if(template.
|
|
594
|
+
// if list:true, this is an array of config references — generate shadow defaults for each slot.
|
|
595
|
+
if(template.list === true) {
|
|
603
596
|
template.maxInstances = template.maxInstances ? template.maxInstances : 10;
|
|
604
|
-
this._defaults[name] = {
|
|
597
|
+
this._defaults[name] = {value:"", required:(template.required) ? template.required : false, maxInstances:template.maxInstances};
|
|
605
598
|
for(let i = 0; i < template.maxInstances; i++){
|
|
606
|
-
this._defaults["_" + name + "_" + i] = {value:"", required:false};
|
|
599
|
+
this._defaults["_" + name + "_" + i] = {value:"", required:false, type: template.type};
|
|
607
600
|
}
|
|
608
601
|
}
|
|
609
602
|
else{
|
|
@@ -195,7 +195,6 @@ module.exports = function (RED) {
|
|
|
195
195
|
let plugin = RED.plugins.get(pluginID);
|
|
196
196
|
|
|
197
197
|
if(addedPlugin && plugin.instantiate && !plugin.instance){
|
|
198
|
-
console.log("Deploying instance of: " + plugin.id);
|
|
199
198
|
plugin.instance = new plugin.class();
|
|
200
199
|
|
|
201
200
|
// instantiate the plugin.
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
.towb_editorlabel {
|
|
60
60
|
width: 120px !important;
|
|
61
61
|
}
|
|
62
|
-
.towb_editorfield {
|
|
62
|
+
input.towb_editorfield, select.towb_editorfield, textarea.towb_editorfield {
|
|
63
63
|
width: 70% !important;
|
|
64
64
|
}
|
|
65
|
-
.towb_editorfield_short {
|
|
65
|
+
input.towb_editorfield_short, select.towb_editorfield_short {
|
|
66
66
|
width: 30% !important;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -99,13 +99,13 @@
|
|
|
99
99
|
|
|
100
100
|
<div class="form-row">
|
|
101
101
|
<label class="towb_editorlabel" for="node-config-input-metricType"><i class="fa fa-bar-chart"></i> Type</label>
|
|
102
|
-
<input
|
|
102
|
+
<input type="text" id="node-config-input-metricType" />
|
|
103
103
|
</div>
|
|
104
104
|
|
|
105
105
|
<div class="metrictype metrictype_histogram">
|
|
106
106
|
<div class="form-row">
|
|
107
107
|
<label class="towb_editorlabel" for="node-config-input-buckettype"><i class="fa fa-sliders"></i> Bucket Type</label>
|
|
108
|
-
<input
|
|
108
|
+
<input type="text" id="node-config-input-buckettype" />
|
|
109
109
|
</div>
|
|
110
110
|
|
|
111
111
|
<div class="metricsconfig_buckets metricsconfig_buckets_default">
|
|
@@ -63,13 +63,16 @@
|
|
|
63
63
|
.towb_editorlabel {
|
|
64
64
|
width: 120px !important;
|
|
65
65
|
}
|
|
66
|
-
.towb_editorfield {
|
|
66
|
+
input.towb_editorfield, select.towb_editorfield, textarea.towb_editorfield {
|
|
67
67
|
width: 70% !important;
|
|
68
68
|
}
|
|
69
|
-
.towb_editorfield_short {
|
|
69
|
+
input.towb_editorfield_short, select.towb_editorfield_short {
|
|
70
70
|
width: 30% !important;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/* Node label colour helpers — use via .setLabelStyle() in onCompose */
|
|
74
|
+
.node_label_white { fill: white; }
|
|
75
|
+
.node_label_black { fill: black; }
|
|
73
76
|
</style>
|
|
74
77
|
|
|
75
78
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import os from "os";
|
|
1
2
|
import { RestAuthType } from "../logger/service/LoggerService";
|
|
2
3
|
import { BaseNode, createPostConstructDecorator, NodeManager } from "../NodeConstructor";
|
|
3
|
-
import { ProxyManagerClient } from "./service/ReverseProxyTypeService";
|
|
4
|
+
import { HTTPScheme, ProxyManagerClient } from "./service/ReverseProxyTypeService";
|
|
4
5
|
import { ApiKeyAuthenticationConfig, BasicAuthenticationConfig, EndpointConfig, EndpointMethodType, NoAuthenticationConfig, WebhookServer } from "./service/WebhookServerService";
|
|
5
6
|
import { WebhookTemplateConfig } from "./template/WebhookTemplate";
|
|
6
7
|
|
|
@@ -10,6 +11,14 @@ type WebhookConfig = {
|
|
|
10
11
|
methods:EndpointMethodType[],
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
type ManagedProxyHost = {
|
|
15
|
+
proxyNodeId: string;
|
|
16
|
+
hostId: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// In-memory registry: nodeId → managed proxy host entries from the last deploy.
|
|
20
|
+
const managedProxyHosts = new Map<string, ManagedProxyHost[]>();
|
|
21
|
+
|
|
13
22
|
const Webhook = createPostConstructDecorator<WebhookConfig>('Webhook')
|
|
14
23
|
.withInitLogic(async (instance, propertyKey, webhookconfig:WebhookConfig) => {
|
|
15
24
|
//console.log(`Registering webhook callback`, "PROPERTYKEY", propertyKey, "WEBHOOK CONFIG", webhookconfig, "THIS", this);
|
|
@@ -35,24 +44,58 @@ const Webhook = createPostConstructDecorator<WebhookConfig>('Webhook')
|
|
|
35
44
|
|
|
36
45
|
if(nodeConfig.reverseProxies_enabled){
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
let targetPort = webhookServer.config().port;
|
|
48
|
+
let targetHost = os.hostname();
|
|
49
|
+
let nodeId = nodeConfig.id;
|
|
50
|
+
let newlyManaged: ManagedProxyHost[] = [];
|
|
39
51
|
|
|
52
|
+
await Promise.all(nodeConfig.reverseProxies_connections.map(async proxy => {
|
|
40
53
|
try{
|
|
41
|
-
// get a n instance of reverseProxNode.
|
|
42
|
-
let reverseProxyNode = (NodeManager.RED.nodes.getNode(proxy.proxy) as any).node();
|
|
43
|
-
|
|
44
54
|
// TODO: ReverseProxyConfigNodes need to become their own subtype of config nodes so we can enforce the ".client()" method.
|
|
55
|
+
let reverseProxyNode = (NodeManager.RED.nodes.getNode(proxy.proxy) as any).node();
|
|
45
56
|
let proxyClient = reverseProxyNode.client() as ProxyManagerClient;
|
|
46
57
|
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
let hosts = await proxyClient.getHosts();
|
|
59
|
+
let matchingHost = hosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
60
|
+
|
|
61
|
+
if (!matchingHost) {
|
|
62
|
+
await proxyClient.updateHost({ domainNames: [proxy.domainname], forwardHost: targetHost, forwardPort: targetPort, scheme: HTTPScheme.HTTP });
|
|
63
|
+
// Fetch again to get the assigned ID of the newly created entry.
|
|
64
|
+
let updatedHosts = await proxyClient.getHosts();
|
|
65
|
+
matchingHost = updatedHosts.find(h => h.domainNames?.includes(proxy.domainname));
|
|
66
|
+
}
|
|
67
|
+
else if (matchingHost.forwardHost !== targetHost || matchingHost.forwardPort !== targetPort) {
|
|
68
|
+
await proxyClient.updateHost({ id: matchingHost.id, forwardHost: targetHost, forwardPort: targetPort, scheme: HTTPScheme.HTTP });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (matchingHost?.id !== undefined) {
|
|
72
|
+
newlyManaged.push({ proxyNodeId: proxy.proxy, hostId: matchingHost.id });
|
|
73
|
+
}
|
|
49
74
|
}
|
|
50
75
|
catch(e){
|
|
51
|
-
console.
|
|
76
|
+
console.error(e);
|
|
52
77
|
}
|
|
53
|
-
|
|
54
|
-
return Promise.resolve();
|
|
55
78
|
}));
|
|
79
|
+
|
|
80
|
+
// Remove any stale proxy host entries that were managed last deploy but are no longer in the current config.
|
|
81
|
+
let previouslyManaged = managedProxyHosts.get(nodeId) ?? [];
|
|
82
|
+
let newHostIds = new Set(newlyManaged.map(m => m.hostId));
|
|
83
|
+
|
|
84
|
+
await Promise.all(previouslyManaged
|
|
85
|
+
.filter(m => !newHostIds.has(m.hostId))
|
|
86
|
+
.map(async stale => {
|
|
87
|
+
try{
|
|
88
|
+
let reverseProxyNode = (NodeManager.RED.nodes.getNode(stale.proxyNodeId) as any).node();
|
|
89
|
+
let proxyClient = reverseProxyNode.client() as ProxyManagerClient;
|
|
90
|
+
await proxyClient.deleteHost(stale.hostId);
|
|
91
|
+
}
|
|
92
|
+
catch(e){
|
|
93
|
+
console.error(e);
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
managedProxyHosts.set(nodeId, newlyManaged);
|
|
56
99
|
}
|
|
57
100
|
|
|
58
101
|
// register a close listener to the node.
|