@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.
Files changed (42) hide show
  1. package/README.md +5 -2
  2. package/build/Nodes.html +23 -21
  3. package/build/Plugins.js +0 -1
  4. package/build/core/NodeConstructor.d.ts +1 -0
  5. package/build/core/NodeConstructor.d.ts.map +1 -1
  6. package/build/core/NodeConstructor.js +5 -12
  7. package/build/core/NodeGenerator.d.ts.map +1 -1
  8. package/build/core/NodeGenerator.js +0 -1
  9. package/build/core/webhook/WebhookDecorator.d.ts.map +1 -1
  10. package/build/core/webhook/WebhookDecorator.js +43 -6
  11. package/build/core/webhook/service/ReverseProxyTypeService.d.ts +1 -0
  12. package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
  13. package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
  14. package/build/core/webhook/service/WebhookServerService.js +0 -5
  15. package/package.json +2 -3
  16. package/src/core/NodeConstructor.ts +6 -13
  17. package/src/core/NodeGenerator.ts +0 -1
  18. package/src/core/logger/template/LoggerTemplate.html +2 -2
  19. package/src/core/metrics/node/TimerMetricConfigNode.html +2 -2
  20. package/src/core/other/template/BasicTemplate.html +5 -2
  21. package/src/core/webhook/WebhookDecorator.ts +53 -10
  22. package/src/core/webhook/service/ReverseProxyTypeService.ts +1 -0
  23. package/src/core/webhook/service/WebhookServerService.ts +0 -5
  24. package/src/core/webhook/template/WebhookTemplate.html +1 -1
  25. package/build/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
  26. package/build/core/logger/node/RestLoggerConfigNode.html +0 -183
  27. package/build/core/logger/template/LoggerTemplate.html +0 -331
  28. package/build/core/metrics/node/CounterMetricConfigNode.html +0 -48
  29. package/build/core/metrics/node/GaugeMetricConfigNode.html +0 -48
  30. package/build/core/metrics/node/MetricsConfigNode.html +0 -21
  31. package/build/core/metrics/node/TimerMetricConfigNode.html +0 -190
  32. package/build/core/metrics/template/CounterMetricTemplate.html +0 -40
  33. package/build/core/metrics/template/GaugeMetricTemplate.html +0 -39
  34. package/build/core/metrics/template/MetricsTemplate.html +0 -54
  35. package/build/core/metrics/template/TimerMetricTemplate.html +0 -39
  36. package/build/core/other/node/DelegatedConfigReferenceNode.html +0 -1
  37. package/build/core/other/template/BasicTemplate.html +0 -76
  38. package/build/core/other/template/SettingsTemplate.html +0 -128
  39. package/build/core/ui/template/ScriptEditorTemplate.html +0 -50
  40. package/build/core/ui/template/UIHelperTemplate.html +0 -229
  41. package/build/core/webhook/node/WebhookServerConfigNode.html +0 -61
  42. 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. Extends the logging infrastructure provided by this package with a Loki transport, enabling log delivery directly to a Loki instance from any node built with the `@Logger` decorator. |
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 transformation nodes powered by the TC39 Temporal API. Parse, convert, adjust, and format date/time values across timezones using named presets or Moment.js-style custom format strings. |
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: true,
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 class="towb_editorfield" type="text" id="node-config-input-metricType" />
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 class="towb_editorfield" type="text" id="node-config-input-buckettype" />
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.
@@ -136,6 +136,7 @@ export type DefaultTemplateType = {
136
136
  minInstances?: number;
137
137
  maxInstances?: number;
138
138
  validate?: Function;
139
+ list?: boolean;
139
140
  };
140
141
  export declare class NodeBuilder {
141
142
  private _name;
@@ -1 +1 @@
1
- {"version":3,"file":"NodeConstructor.d.ts","sourceRoot":"","sources":["../../src/core/NodeConstructor.ts"],"names":[],"mappings":"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"}
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;AAU1B,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAC,MAAM,CAAC;IACV,IAAI,EAAC,MAAM,CAAC;IACZ,IAAI,EAAC,MAAM,CAAC;CACf;AAED,8BAAsB,QAAQ,CAAC,MAAM,SAAS,cAAc;IAExD,OAAO,CAAC,KAAK,CAAM;IACZ,IAAI;IAEX,OAAO,CAAC,OAAO,CAAQ;IAChB,MAAM;IAEb,OAAO,CAAC,KAAK,CAAO;IACb,IAAI;IAGJ,EAAE;IACF,IAAI;IACJ,IAAI;IAEX,SAAS,aAAa,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM;IAWhD,SAAS,CAAC,MAAM;WAGF,iBAAiB,IAAG,cAAc;CAGnD;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CACvD;AAED,8BAAsB,UAAU,CAAC,MAAM,SAAS,gBAAgB,CAAE,SAAQ,QAAQ,CAAC,MAAM,CAAC;IAEtF,SAAS,aAAa,IAAI,EAAC,IAAI,EAAE,MAAM,EAAE,MAAM;WAIjC,iBAAiB,IAAG,cAAc;CAGnD;AAED,MAAM,WAAW,SAAS;CAEzB;AAED,MAAM,WAAW,cAAc;CAC9B;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,CAAC,UAAU,GAAG,aAAa,CAAC,CAAC;AAE3E,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,UAAU,CAAyD;IAC3E,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAgB;gBAEjB,KAAK,EAAC,MAAM,EAAE,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,EAAE,GAAG,EAAC,MAAM;IASxE,aAAa,CAAC,UAAU,EAAC,kBAAkB,GAAE,cAAc;IAM3D,MAAM,CAAC,GAAG,EAAC,MAAM,GAAE,cAAc;IAMjC,WAAW,CAAC,QAAQ,EAAC,cAAc,EAAE,MAAM,EAAC,cAAc,GAAE,cAAc;IAO1E,KAAK;IACL,EAAE;IACF,IAAI;IACJ,UAAU;IACV,OAAO;IACP,YAAY,IAAG,cAAc,EAAE;IAC/B,SAAS,IAAG;QAAC,QAAQ,EAAC,cAAc,CAAC;QAAC,MAAM,EAAC,cAAc,CAAA;KAAC,EAAE;IAC9D,IAAI,IAAG,MAAM,EAAE;CACzB;AAED,UAAU,aAAa;IACnB,QAAQ,WAAW,CAAC;IACpB,oBAAoB,IAAG,iBAAiB,CAAC;CAC5C;AAED,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAAS;gBAElB,IAAI,EAAC,MAAM,EAAE,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,EAAE,YAAY,EAAC,cAAc,EAAE;IAOjG,IAAI,IAAI,MAAM;IAId,KAAK,IAAI,cAAc;IAIvB,YAAY,IAAG,cAAc,EAAE;IAI/B,YAAY,IAAG,MAAM;CAIxB;AAED,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAAkB;gBAEpB,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,EAAE,KAAK,EAAC,aAAa,EAAE,YAAY,CAAC,EAAC,cAAc,EAAE;IASvH,EAAE,IAAG,MAAM;IACX,IAAI,IAAG,MAAM;IACb,IAAI,IAAG,MAAM;IACb,UAAU,IAAG,MAAM;IACnB,KAAK,IAAG,aAAa;IACrB,YAAY;CACtB;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,CAAC,cAAc,GAAG,UAAU,GAAG,aAAa,CAAC,CAAC;AAExF,8BAAsB,QAAQ;WACZ,qBAAqB,IAAG,kBAAkB;CAG3D;AASD,cAAM,6BAA6B,CAAC,SAAS,GAAG,GAAG;IAC/C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAC,CAA8D;IAChF,OAAO,CAAC,SAAS,CAAC,CAA6E;IAC/F,OAAO,CAAC,aAAa,CAAC,CAAY;gBAEtB,aAAa,EAAE,MAAM;IAKjC,iBAAiB,CAAC,MAAM,EAAE,SAAS;IAMnC,aAAa,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,IAAI;IAMpF,aAAa,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,KAAK,IAAI;IAMnG,KAAK;CAwGR;AAGD,wBAAgB,4BAA4B,CAAC,SAAS,GAAG,GAAG,EAAE,aAAa,EAAE,MAAM,4CAElF;AA8BD,qBAAa,WAAW;IACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0D;IACjF,OAAO,CAAC,MAAM,CAAC,IAAI,CAAmC;IAEtD,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,WAAW,CAAkB;gBAElB,GAAG,EAAG,OAAO,CAAC,uBAAuB,CAAC;IA4BzD,WAAkB,GAAG,qCAEpB;IAEM,eAAe,CAAC,IAAI,EAAC,aAAa,GAAE,WAAW;IAY/C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAE,WAAW;CAwD1E;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,GAAG,EAAC,MAAM,CAAC;IACX,KAAK,EAAC,CAAC,WAAW,CAAC,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,EAAE,EAAC,MAAM,CAAC;IACV,IAAI,EAAC,MAAM,CAAC;CACb,CAAA;AAGH,8BAAsB,WAAW;IAE7B,OAAO,CAAC,KAAK,CAAS;gBAEV,IAAI,EAAC,MAAM;IAIhB,IAAI,IAAG,MAAM;aAIJ,IAAI,CAAC,GAAG,EAAC,OAAO,CAAC,uBAAuB,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC,GAAC,IAAI;aAC7D,MAAM,CAAC,GAAG,EAAC,OAAO,CAAC,uBAAuB,CAAC,GAAE,OAAO,CAAC,IAAI,CAAC,GAAC,IAAI;IAExE,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAE,OAAO,CAAC,IAAI,CAAC,GAAC,IAAI;WAIpD,oBAAoB,IAAG,iBAAiB;CAGzD;AA2CD,MAAM,MAAM,mBAAmB,GAAG;IAC9B,IAAI,CAAC,EAAC,MAAM,CAAC;IACb,KAAK,CAAC,EAAC,MAAM,CAAC;IACd,QAAQ,EAAC,OAAO,CAAC;IACjB,YAAY,CAAC,EAAC,MAAM,CAAC;IACrB,YAAY,CAAC,EAAC,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAC,QAAQ,CAAC;IACnB,IAAI,CAAC,EAAC,OAAO,CAAC;CACjB,CAAA;AAED,qBAAa,WAAW;IAEpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,qBAAqB,CAAuC;IACpE,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,uBAAuB,CAAuC;gBAE1D,IAAI,EAAC,MAAM,EAAE,QAAQ,EAAC,MAAM;IAKjC,UAAU,CAAC,IAAI,EAAC,MAAM,EAAE,QAAQ,EAAC,mBAAmB,GAAE,WAAW;IAejE,OAAO,CAAC,IAAI,EAAC,MAAM,GAAE,WAAW;IAKhC,QAAQ,CAAC,KAAK,EAAC,MAAM,GAAE,WAAW;IAKlC,QAAQ,CAAC,KAAK,EAAC,MAAM,EAAE,GAAE,WAAW;IAIpC,eAAe,CAAC,YAAY,EAAC,MAAM,GAAE,WAAW;IAKhD,aAAa,CAAC,UAAU,EAAC,MAAM,GAAE,WAAW;IAK5C,QAAQ,CAAC,KAAK,EAAC,MAAM,GAAE,WAAW;IAKlC,UAAU,CAAC,GAAG,OAAO,EAAC,MAAM,EAAE,GAAE,WAAW;IAK3C,WAAW,CAAC,QAAQ,EAAE;QAAE,QAAQ,EAAE,cAAc,CAAC;QAAC,MAAM,EAAE,cAAc,CAAC;KAAE,GAAG,WAAW;IAwBzF,cAAc,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAKxD,qBAAqB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAK/D,kBAAkB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAK5D,oBAAoB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAK9D,oBAAoB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAK9D,kBAAkB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAK5D,uBAAuB,CAAC,MAAM,EAAC,MAAM,EAAE,MAAM,EAAC,MAAM,GAAE,WAAW;IAKxE,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,2BAA2B;IAI5B,SAAS,IAAG,MAAM;IAiDlB,SAAS,IAAG,MAAM;IAQlB,kBAAkB,IAAG,MAAM;CASrC;AAiBD,QAAA,IAAI,SAAS,SAAiB,UAAU,WA4BvC,CAAA;AAED,OAAO,EACH,SAAS,EACZ,CAAA"}
@@ -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 the template type ends with squeare brackets, its an array type.
434
- if (template.type && template.type.endsWith("[]")) {
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] = { type: template.type, value: "", required: true, maxInstances: template.maxInstances };
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;IA0IhE,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"}
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":"AAYA,QAAA,MAAM,OAAO,KAkDD,CAAC;AAGb,OAAO,EACH,OAAO,EACV,CAAA"}
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
- console.log("List of known hosts: ", await proxyClient.getHosts());
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.log(e);
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;CAC5C;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
+ {"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;IA+CpF,MAAM,CAAC,aAAa,EAAC,cAAc;IAsBnC,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;WAyCvD,GAAG,CAAE,MAAM,EAAC,mBAAmB,GAAG,aAAa;WAS7C,oBAAoB,IAAG,iBAAiB;CAU3D"}
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.55",
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 copy-html && npm run generate-nodes && npm run copy-files",
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 the template type ends with squeare brackets, its an array type.
602
- if(template.type && template.type.endsWith("[]")) {
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] = {type:template.type, value:"", required:true, maxInstances:template.maxInstances};
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 class="towb_editorfield" type="text" id="node-config-input-metricType" />
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 class="towb_editorfield" type="text" id="node-config-input-buckettype" />
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
- await Promise.all(nodeConfig.reverseProxies_connections.map(async proxy => {
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
- console.log("List of known hosts: ", await proxyClient.getHosts());
48
- //console.log("ADD REVERSE PROXY:" + proxy.proxy + " to " + node.id(), proxyClient);
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.log(e);
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.
@@ -22,6 +22,7 @@ export abstract class ReverseProxyType {
22
22
  export interface ProxyManagerClient {
23
23
  updateHost(data: Partial<HostEntry>):Promise<void>;
24
24
  getHosts():Promise<Partial<HostEntry>[]>;
25
+ deleteHost(id: number):Promise<void>;
25
26
  }
26
27
 
27
28
  export type HostEntry = {