@theotherwillembotha/node-red-plugincore 0.2.0 → 0.3.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/build/GenerateNodes.js +9 -30
- package/build/Nodes.html +2 -4
- package/build/Nodes.js +2 -6
- package/build/Plugins.html +2 -218
- package/build/Plugins.js +1 -6
- package/build/core/NodeConstructor.d.ts +3 -0
- package/build/core/NodeConstructor.d.ts.map +1 -1
- package/build/core/NodeConstructor.js +19 -42
- package/build/core/NodeGenerator.d.ts +3 -1
- package/build/core/NodeGenerator.d.ts.map +1 -1
- package/build/core/NodeGenerator.js +76 -31
- package/build/core/logger/service/LoggerService.d.ts +2 -1
- package/build/core/logger/service/LoggerService.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.js +55 -8
- package/build/core/logger/template/LoggerTemplate.d.ts +1 -2
- package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -1
- package/build/core/logger/template/LoggerTemplate.js +18 -5
- package/build/core/metrics/template/CounterMetricTemplate.d.ts +1 -2
- package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/CounterMetricTemplate.js +16 -5
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts +1 -2
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/GaugeMetricTemplate.js +16 -5
- package/build/core/metrics/template/MetricsTemplate.d.ts +1 -2
- package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/MetricsTemplate.js +18 -5
- package/build/core/metrics/template/TimerMetricTemplate.d.ts +1 -2
- package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -1
- package/build/core/metrics/template/TimerMetricTemplate.js +16 -5
- package/build/core/other/template/BasicTemplate.d.ts +1 -2
- package/build/core/other/template/BasicTemplate.d.ts.map +1 -1
- package/build/core/other/template/BasicTemplate.js +15 -5
- package/build/core/other/template/SettingsTemplate.d.ts +1 -2
- package/build/core/other/template/SettingsTemplate.d.ts.map +1 -1
- package/build/core/other/template/SettingsTemplate.js +17 -5
- package/build/core/state/template/StateTemplate.d.ts +1 -2
- package/build/core/state/template/StateTemplate.d.ts.map +1 -1
- package/build/core/state/template/StateTemplate.js +19 -5
- package/build/core/tagging/TemplateDescriptionDecorator.d.ts +8 -0
- package/build/core/tagging/TemplateDescriptionDecorator.d.ts.map +1 -0
- package/build/core/tagging/TemplateDescriptionDecorator.js +10 -0
- package/build/core/ui/template/ScriptEditorTemplate.d.ts +1 -2
- package/build/core/ui/template/ScriptEditorTemplate.d.ts.map +1 -1
- package/build/core/ui/template/ScriptEditorTemplate.js +15 -5
- package/build/core/ui/template/UIHelperTemplate.d.ts +1 -2
- package/build/core/ui/template/UIHelperTemplate.d.ts.map +1 -1
- package/build/core/ui/template/UIHelperTemplate.js +15 -5
- package/build/core/webhook/template/WebhookTemplate.d.ts +1 -2
- package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -1
- package/build/core/webhook/template/WebhookTemplate.js +19 -6
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/package.json +1 -2
- package/src/GenerateNodes.ts +9 -35
- package/src/core/NodeConstructor.ts +23 -45
- package/src/core/NodeGenerator.ts +87 -33
- package/src/core/logger/service/LoggerService.ts +23 -8
- package/src/core/logger/template/LoggerTemplate.ts +9 -11
- package/src/core/metrics/template/CounterMetricTemplate.ts +8 -11
- package/src/core/metrics/template/GaugeMetricTemplate.ts +8 -11
- package/src/core/metrics/template/MetricsTemplate.ts +9 -9
- package/src/core/metrics/template/TimerMetricTemplate.ts +8 -10
- package/src/core/other/template/BasicTemplate.ts +6 -11
- package/src/core/other/template/SettingsTemplate.ts +8 -13
- package/src/core/state/template/StateTemplate.ts +10 -9
- package/src/core/tagging/TemplateDescriptionDecorator.ts +19 -0
- package/src/core/ui/template/ScriptEditorTemplate.ts +6 -10
- package/src/core/ui/template/UIHelperTemplate.ts +6 -10
- package/src/core/webhook/template/WebhookTemplate.ts +10 -12
- package/src/index.ts +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseNodeConfig, Template
|
|
1
|
+
import { BaseNodeConfig, Template } from "../../NodeConstructor";
|
|
2
2
|
import { RestAuthType, ApiKeyMechanismType } from "../../logger/service/LoggerService";
|
|
3
3
|
export interface WebhookTemplateConfig extends BaseNodeConfig {
|
|
4
4
|
webhook: string;
|
|
@@ -17,6 +17,5 @@ export type ReverseproxyConnection = {
|
|
|
17
17
|
domainname: string;
|
|
18
18
|
};
|
|
19
19
|
export declare class WebhookTemplate extends Template {
|
|
20
|
-
static getTemplateDescriptor(): TemplateDescriptor;
|
|
21
20
|
}
|
|
22
21
|
//# sourceMappingURL=WebhookTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebhookTemplate.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/template/WebhookTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"WebhookTemplate.d.ts","sourceRoot":"","sources":["../../../../src/core/webhook/template/WebhookTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAMhE,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEvF,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IACzD,OAAO,EAAC,MAAM,CAAC;IACf,WAAW,EAAC,MAAM,CAAC;IACnB,WAAW,EAAC,YAAY,CAAC;IACzB,0BAA0B,EAAC,MAAM,CAAC;IAClC,0BAA0B,EAAC,MAAM,CAAC;IAClC,4BAA4B,EAAC,mBAAmB,CAAC;IACjD,sBAAsB,EAAC,MAAM,CAAC;IAC9B,wBAAwB,EAAC,MAAM,CAAC;IAEhC,sBAAsB,EAAC,OAAO,CAAC;IAC/B,0BAA0B,EAAC,sBAAsB,EAAE,CAAC;CACvD;AAED,MAAM,MAAM,sBAAsB,GAAG;IACjC,KAAK,EAAC,MAAM,CAAC;IACb,UAAU,EAAC,MAAM,CAAA;CACpB,CAAA;AAED,qBAKa,eAAgB,SAAQ,QAAQ;CAC5C"}
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
2
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
9
|
exports.WebhookTemplate = void 0;
|
|
4
10
|
const NodeConstructor_1 = require("../../NodeConstructor");
|
|
5
|
-
const WebhookServerConfigNode_1 = require("../node/WebhookServerConfigNode");
|
|
6
11
|
const NodeGenerator_1 = require("../../NodeGenerator");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
const TemplateDescriptionDecorator_1 = require("../../tagging/TemplateDescriptionDecorator");
|
|
13
|
+
const DelegatedConfigReferenceNode_1 = require("../../other/node/DelegatedConfigReferenceNode");
|
|
14
|
+
const WebhookServerConfigNode_1 = require("../node/WebhookServerConfigNode");
|
|
15
|
+
const WebhookServerService_1 = require("../service/WebhookServerService");
|
|
16
|
+
let WebhookTemplate = class WebhookTemplate extends NodeConstructor_1.Template {
|
|
17
|
+
};
|
|
12
18
|
exports.WebhookTemplate = WebhookTemplate;
|
|
19
|
+
exports.WebhookTemplate = WebhookTemplate = __decorate([
|
|
20
|
+
(0, TemplateDescriptionDecorator_1.TemplateDescription)({
|
|
21
|
+
name: "webhook",
|
|
22
|
+
templateFile: NodeGenerator_1.SourceUtility.getSourcePath("/build/", "/src/") + "WebhookTemplate.html",
|
|
23
|
+
dependencies: [DelegatedConfigReferenceNode_1.DelegatedConfigReferenceNode, WebhookServerConfigNode_1.WebhookServerConfigNode, WebhookServerService_1.WebhookServerService],
|
|
24
|
+
})
|
|
25
|
+
], WebhookTemplate);
|
package/build/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export * from "./core/state/template/StateTemplate";
|
|
|
19
19
|
export * from "./core/tagging/service/NodeTypeService";
|
|
20
20
|
export * from "./core/tagging/NodeDescriptionDecorator";
|
|
21
21
|
export * from "./core/tagging/ServiceDescriptionDecorator";
|
|
22
|
+
export * from "./core/tagging/TemplateDescriptionDecorator";
|
|
22
23
|
export * from "./core/ui/template/UIHelperTemplate";
|
|
23
24
|
export * from "./core/ui/template/ScriptEditorTemplate";
|
|
24
25
|
export * from "./core/other/node/DelegatedConfigReferenceNode";
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AAItD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AAGpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AAItD,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,uCAAuC,CAAC;AACtD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,qCAAqC,CAAC;AAGpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,qCAAqC,CAAC;AACpD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mCAAmC,CAAC;AAClD,cAAc,sCAAsC,CAAC;AACrD,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AAGvD,cAAc,yCAAyC,CAAC;AACxD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -39,6 +39,7 @@ __exportStar(require("./core/state/template/StateTemplate"), exports);
|
|
|
39
39
|
__exportStar(require("./core/tagging/service/NodeTypeService"), exports);
|
|
40
40
|
__exportStar(require("./core/tagging/NodeDescriptionDecorator"), exports);
|
|
41
41
|
__exportStar(require("./core/tagging/ServiceDescriptionDecorator"), exports);
|
|
42
|
+
__exportStar(require("./core/tagging/TemplateDescriptionDecorator"), exports);
|
|
42
43
|
// UI
|
|
43
44
|
__exportStar(require("./core/ui/template/UIHelperTemplate"), exports);
|
|
44
45
|
__exportStar(require("./core/ui/template/ScriptEditorTemplate"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theotherwillembotha/node-red-plugincore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.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",
|
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
"js-beautify": "^1.15.4",
|
|
61
61
|
"jsdom": "^29.1.1",
|
|
62
62
|
"markdown-it": "^14.1.0",
|
|
63
|
-
"network": "^0.7.0",
|
|
64
63
|
"reflect-metadata": "^0.2.2"
|
|
65
64
|
},
|
|
66
65
|
"node-red": {
|
package/src/GenerateNodes.ts
CHANGED
|
@@ -1,42 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { NodeGenerator } from "./index.js"
|
|
3
3
|
import { NodeTypeService } from "./core/tagging/service/NodeTypeService.js";
|
|
4
|
-
import { NodeGenerator, SettingsService, BasicTemplate, SettingsTemplate, TimerMetricTemplate, UIHelperTemplate, ScriptEditorTemplate } from "./index.js"
|
|
5
|
-
import { WebhookServerConfigNode, WebhookServerService, WebhookTemplate, } from "./index.js"
|
|
6
|
-
|
|
7
|
-
import {LoggerService, LoggerTemplate } from "./index.js";
|
|
8
|
-
|
|
9
|
-
import { MetricsService, MetricsTemplate, CounterMetricTemplate, GaugeMetricTemplate} from "./index.js";
|
|
10
|
-
import { StateService, StateTemplate, InternalStateConfigNode } from "./index.js";
|
|
11
4
|
|
|
5
|
+
// Plugincore is a build framework — it has no leaf nodes of its own.
|
|
6
|
+
// Infrastructure nodes (DelegatedConfigReferenceNode, config nodes, etc.)
|
|
7
|
+
// are pulled in automatically via template dependencies when downstream
|
|
8
|
+
// packages register their nodes.
|
|
9
|
+
//
|
|
10
|
+
// NodeTypeService is the one service that must always be present because
|
|
11
|
+
// it powers the tag registry used by NodeManager at runtime.
|
|
12
12
|
new NodeGenerator("./src/core/")
|
|
13
|
-
// services.
|
|
14
|
-
.registerService(LoggerService)
|
|
15
|
-
.registerService(MetricsService)
|
|
16
|
-
.registerService(SettingsService)
|
|
17
|
-
.registerService(WebhookServerService)
|
|
18
13
|
.registerService(NodeTypeService)
|
|
19
|
-
.
|
|
20
|
-
|
|
21
|
-
// templates.
|
|
22
|
-
.registerTemplate(BasicTemplate)
|
|
23
|
-
.registerTemplate(LoggerTemplate)
|
|
24
|
-
.registerTemplate(SettingsTemplate)
|
|
25
|
-
.registerTemplate(MetricsTemplate)
|
|
26
|
-
.registerTemplate(CounterMetricTemplate)
|
|
27
|
-
.registerTemplate(GaugeMetricTemplate)
|
|
28
|
-
.registerTemplate(TimerMetricTemplate)
|
|
29
|
-
.registerTemplate(WebhookTemplate)
|
|
30
|
-
.registerTemplate(UIHelperTemplate)
|
|
31
|
-
.registerTemplate(ScriptEditorTemplate)
|
|
32
|
-
.registerTemplate(StateTemplate)
|
|
33
|
-
|
|
34
|
-
// nodes
|
|
35
|
-
.registerNode(DelegatedConfigReferenceNode)
|
|
36
|
-
.registerNode(WebhookServerConfigNode)
|
|
37
|
-
.registerNode(InternalStateConfigNode)
|
|
38
|
-
|
|
39
|
-
// done.
|
|
40
|
-
.generate("./build/Nodes", "./build/Plugins");
|
|
14
|
+
.generate("./build/Nodes", "./build/Plugins", "@theotherwillembotha/node-red-plugincore");
|
|
41
15
|
|
|
42
16
|
process.exit(0);
|
|
@@ -581,8 +581,7 @@ export class NodeBuilder {
|
|
|
581
581
|
}));
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
-
|
|
585
|
-
// Apply shadow defaults (same side-effect as buildType)
|
|
584
|
+
private applyShaddowDefaults(): void {
|
|
586
585
|
let shaddowDefaults = Object.entries(this._defaults).filter(([name, template]) => template.type && template.type.endsWith("[]"));
|
|
587
586
|
if (shaddowDefaults.length > 0) {
|
|
588
587
|
this.addIncludeEditSave(this._name + "_shaddowDefaults",
|
|
@@ -596,8 +595,10 @@ export class NodeBuilder {
|
|
|
596
595
|
`}`
|
|
597
596
|
);
|
|
598
597
|
}
|
|
598
|
+
}
|
|
599
599
|
|
|
600
|
-
|
|
600
|
+
private buildRegisterTypeBody(): string {
|
|
601
|
+
return `{
|
|
601
602
|
category: '${this._category}',
|
|
602
603
|
${(this._category !== "config" && this._icon) ? `icon: '${this._icon}',` : ""}
|
|
603
604
|
${(this._category !== "config" && this._color) ? `color: '${this._color}',` : ""}
|
|
@@ -624,6 +625,11 @@ export class NodeBuilder {
|
|
|
624
625
|
${this._onIncludeEditDelete.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
625
626
|
},
|
|
626
627
|
}`;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
public buildDeferredType(): string {
|
|
631
|
+
this.applyShaddowDefaults();
|
|
632
|
+
const registerTypeBody = this.buildRegisterTypeBody();
|
|
627
633
|
|
|
628
634
|
return getBeautify().html_beautify(`
|
|
629
635
|
<script type="text/javascript">
|
|
@@ -637,6 +643,16 @@ export class NodeBuilder {
|
|
|
637
643
|
</script>`, beautifyOptions);
|
|
638
644
|
}
|
|
639
645
|
|
|
646
|
+
public buildStandardType(): string {
|
|
647
|
+
this.applyShaddowDefaults();
|
|
648
|
+
const registerTypeBody = this.buildRegisterTypeBody();
|
|
649
|
+
|
|
650
|
+
return getBeautify().html_beautify(`
|
|
651
|
+
<script type="text/javascript">
|
|
652
|
+
RED.nodes.registerType('${this._name}', ${registerTypeBody});
|
|
653
|
+
</script>`, beautifyOptions);
|
|
654
|
+
}
|
|
655
|
+
|
|
640
656
|
private serializeProperty(value:any):string{
|
|
641
657
|
switch(typeof value){
|
|
642
658
|
case "boolean": {
|
|
@@ -710,52 +726,14 @@ export class NodeBuilder {
|
|
|
710
726
|
return script;
|
|
711
727
|
}
|
|
712
728
|
|
|
713
|
-
public buildType():string{
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
if(shaddowDefaults.length > 0){
|
|
717
|
-
this.addIncludeEditSave(this._name + "_shaddowDefaults",
|
|
718
|
-
`{ let node = this; ` +
|
|
719
|
-
shaddowDefaults
|
|
720
|
-
.map(([name, template]) => `
|
|
721
|
-
for(let i = 0; i < ${template.maxInstances}; i++){
|
|
722
|
-
node["_${name}_" + i] = (node.${name}[i] || {}).proxy || "";
|
|
723
|
-
}`)
|
|
724
|
-
.join("\n\n") +
|
|
725
|
-
`}`
|
|
726
|
-
);
|
|
727
|
-
}
|
|
729
|
+
public buildType():string{
|
|
730
|
+
this.applyShaddowDefaults();
|
|
731
|
+
const registerTypeBody = this.buildRegisterTypeBody();
|
|
728
732
|
|
|
729
733
|
return getBeautify().html_beautify(`
|
|
730
734
|
${this._onIncludeOnce.map(entry => this.serializeHTML(entry.source, entry.script)).join("")}
|
|
731
735
|
<script type="text/javascript">
|
|
732
|
-
RED.nodes.registerType('${this._name}',{
|
|
733
|
-
category: '${this._category}',
|
|
734
|
-
${(this._category !== "config" && this._icon) ? `icon: '${this._icon}',` : ""}
|
|
735
|
-
${(this._category !== "config" && this._color) ? `color: '${this._color}',` : ""}
|
|
736
|
-
${(this._category !== "config" && this._labelStyle) ? `labelStyle: '${this._labelStyle}',` : ""}
|
|
737
|
-
${(this._label) ? `label: ${this._label},` : ""}
|
|
738
|
-
${this._paletteLabel ? `paletteLabel: '${this._paletteLabel}',` : ""}
|
|
739
|
-
${(this._category !== "config") ? `inputs:${this._inputs ? "1" : "0"},` : ""}
|
|
740
|
-
${(this._category !== "config") ? `inputLabels:(i) => '${this._inputs}',` : ""}
|
|
741
|
-
${(this._category !== "config") ? `outputs:${this._outputs.length},` : ""}
|
|
742
|
-
${(this._category !== "config") ? `outputLabels:(i) => ${this.serializeProperty(this._outputs)}[i],` : ""}
|
|
743
|
-
defaults: {
|
|
744
|
-
${Object.entries(this._defaults).map(([key, value]) => this.serializeDefault(key, value)).join("\n")}
|
|
745
|
-
},
|
|
746
|
-
oneditprepare: function() {
|
|
747
|
-
${this._onIncludeEditPrepare.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
748
|
-
},
|
|
749
|
-
oneditsave: function() {
|
|
750
|
-
${this._onIncludeEditSave.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
751
|
-
},
|
|
752
|
-
oneditcancel: function() {
|
|
753
|
-
${this._onIncludeEditCancel.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
754
|
-
},
|
|
755
|
-
oneditdelete: function() {
|
|
756
|
-
${this._onIncludeEditDelete.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
757
|
-
},
|
|
758
|
-
});
|
|
736
|
+
RED.nodes.registerType('${this._name}', ${registerTypeBody});
|
|
759
737
|
</script>`, beautifyOptions);
|
|
760
738
|
};
|
|
761
739
|
|
|
@@ -58,12 +58,10 @@ class NodeGenerator {
|
|
|
58
58
|
|
|
59
59
|
public registerTemplate(template: ITemplateClass): NodeGenerator {
|
|
60
60
|
try{
|
|
61
|
-
// verify that we dont already have this template.
|
|
62
61
|
let descriptor = template.getTemplateDescriptor();
|
|
63
62
|
if(!this._templates.map(t => t.name()).includes(descriptor.name())){
|
|
64
63
|
this._templates.push(descriptor);
|
|
65
|
-
|
|
66
|
-
// descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
64
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
catch(error){
|
|
@@ -75,14 +73,14 @@ class NodeGenerator {
|
|
|
75
73
|
|
|
76
74
|
public registerNode(node:INodeClass):NodeGenerator{
|
|
77
75
|
try{
|
|
78
|
-
// verify that we have dont already have this node.
|
|
79
76
|
let descriptor = node.getNodeDescriptor();
|
|
80
77
|
if(!this._nodes[descriptor.id()]){
|
|
81
78
|
this._nodes[descriptor.id()] = {nodeClass:node, descriptor:descriptor};
|
|
82
|
-
//
|
|
83
|
-
|
|
79
|
+
// resolve templates declared in @NodeDescription
|
|
80
|
+
descriptor.templates().forEach(t => this.registerTemplate(t.template));
|
|
81
|
+
// resolve explicit dependencies (services, nodes, templates)
|
|
82
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
84
83
|
}
|
|
85
|
-
|
|
86
84
|
}
|
|
87
85
|
catch(error){
|
|
88
86
|
console.log("ERROR:", error);
|
|
@@ -90,13 +88,12 @@ class NodeGenerator {
|
|
|
90
88
|
return this;
|
|
91
89
|
}
|
|
92
90
|
|
|
93
|
-
public registerService(service: IServiceClass):NodeGenerator {
|
|
91
|
+
public registerService(service: IServiceClass):NodeGenerator {
|
|
94
92
|
try{
|
|
95
93
|
let descriptor = service.getServiceDescriptor();
|
|
96
94
|
if(!this._services.map(s => s.name()).includes(descriptor.name())){
|
|
97
95
|
this._services.push(descriptor);
|
|
98
|
-
|
|
99
|
-
//descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
96
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
catch(error){
|
|
@@ -105,19 +102,22 @@ class NodeGenerator {
|
|
|
105
102
|
return this;
|
|
106
103
|
}
|
|
107
104
|
|
|
108
|
-
public generate(nodesOutputFile:string, pluginsOutputFile:string){
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
`);
|
|
105
|
+
public generate(nodesOutputFile:string, pluginsOutputFile:string, packageName:string){
|
|
106
|
+
// Partition nodes into owned (belongs to this package) vs shared (from dependencies).
|
|
107
|
+
// Owned nodes get standard registerType + data-template-name in Nodes.html so that
|
|
108
|
+
// Node-RED's registry maps them to this module (enabling palette icons, flow library
|
|
109
|
+
// detection, etc.). Shared nodes keep the deferred pattern in Plugins.html to avoid
|
|
110
|
+
// HTML-scanning conflicts when multiple plugins bundle the same infrastructure nodes.
|
|
111
|
+
const allNodes = Object.values(this._nodes);
|
|
112
|
+
const ownedNodes = allNodes.filter(node => node.descriptor.package() === packageName);
|
|
113
|
+
const sharedNodes = allNodes.filter(node => node.descriptor.package() !== packageName);
|
|
114
|
+
|
|
115
|
+
console.log(`\nPackage: ${packageName}`);
|
|
116
|
+
console.log(` Owned nodes (→ Nodes.html): ${ownedNodes.map(n => n.descriptor.id()).join(', ') || '(none)'}`);
|
|
117
|
+
console.log(` Shared nodes (→ Plugins.html): ${sharedNodes.map(n => n.descriptor.id()).join(', ') || '(none)'}\n`);
|
|
118
|
+
|
|
119
|
+
// STEP 1. Generate Nodes.html with standard client-side definitions for owned nodes.
|
|
120
|
+
this.generateNodesHtml(nodesOutputFile + ".html", ownedNodes);
|
|
121
121
|
|
|
122
122
|
// Step 3. compose the JS structure for each of the nodes.
|
|
123
123
|
// 1. get a list of the files to import.
|
|
@@ -258,17 +258,71 @@ module.exports = function (RED) {
|
|
|
258
258
|
fs.writeFileSync(pluginsOutputFile + ".js", output);
|
|
259
259
|
console.log(`Done building ${this._services.length} services\n${this._services.map(service => " - " + service.name() + "\n").join("")}\n`);
|
|
260
260
|
|
|
261
|
-
// STEP 4. Generate Plugins.html with deferred client-side
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
261
|
+
// STEP 4. Generate Plugins.html with deferred client-side definitions for shared nodes.
|
|
262
|
+
this.generatePluginsHtml(pluginsOutputFile + ".html", sharedNodes);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
private generateNodesHtml(filePath: string, nodes: {nodeClass: INodeClass, descriptor: NodeDescriptor}[]): void {
|
|
266
|
+
if (nodes.length === 0) {
|
|
267
|
+
fs.writeFileSync(filePath, `
|
|
268
|
+
<!--
|
|
269
|
+
${NodeGenerator.warning}
|
|
270
|
+
No owned nodes in this package. Shared nodes are registered via Plugins.html.
|
|
271
|
+
-->
|
|
272
|
+
`);
|
|
273
|
+
console.log(`Nodes.html: no owned nodes\n`);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const seenOnce = new Set<string>();
|
|
278
|
+
const onceHtmlParts: string[] = [];
|
|
279
|
+
const nodeParts: string[] = [];
|
|
280
|
+
|
|
281
|
+
nodes.forEach(node => {
|
|
282
|
+
console.log(`Building Nodes.html for: ${node.descriptor.id()}`);
|
|
283
|
+
const nb = buildNodeBuilder(node.nodeClass);
|
|
284
|
+
|
|
285
|
+
nb.buildOnceHtml().forEach(({source, html}) => {
|
|
286
|
+
if (!seenOnce.has(source)) {
|
|
287
|
+
seenOnce.add(source);
|
|
288
|
+
onceHtmlParts.push(html);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
nodeParts.push([
|
|
293
|
+
nb.buildStandardType(),
|
|
294
|
+
nb.buildHtml(),
|
|
295
|
+
nb.buildDocumentation()
|
|
296
|
+
].join('\n\n'));
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
fs.writeFileSync(filePath, `
|
|
300
|
+
<!--
|
|
301
|
+
${NodeGenerator.warning}
|
|
302
|
+
-->
|
|
303
|
+
${onceHtmlParts.join('\n')}
|
|
304
|
+
${nodeParts.join('\n\n')}
|
|
305
|
+
`);
|
|
306
|
+
console.log(`Done building Nodes.html (${nodes.length} owned nodes)\n`);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
private generatePluginsHtml(filePath: string, nodes: {nodeClass: INodeClass, descriptor: NodeDescriptor}[]): void {
|
|
310
|
+
if (nodes.length === 0) {
|
|
311
|
+
fs.writeFileSync(filePath, `
|
|
312
|
+
<!--
|
|
313
|
+
${NodeGenerator.warning}
|
|
314
|
+
No shared nodes in this package. All nodes are registered via Nodes.html.
|
|
315
|
+
-->
|
|
316
|
+
`);
|
|
317
|
+
console.log(`Plugins.html: no shared nodes\n`);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
267
321
|
const seenOnce = new Set<string>();
|
|
268
322
|
const onceHtmlParts: string[] = [];
|
|
269
323
|
const nodePluginParts: string[] = [];
|
|
270
324
|
|
|
271
|
-
|
|
325
|
+
nodes.forEach(node => {
|
|
272
326
|
console.log(`Building Plugins.html for: ${node.descriptor.id()}`);
|
|
273
327
|
const nb = buildNodeBuilder(node.nodeClass);
|
|
274
328
|
|
|
@@ -286,14 +340,14 @@ module.exports = function (RED) {
|
|
|
286
340
|
].join('\n\n'));
|
|
287
341
|
});
|
|
288
342
|
|
|
289
|
-
fs.writeFileSync(
|
|
343
|
+
fs.writeFileSync(filePath, `
|
|
290
344
|
<!--
|
|
291
345
|
${NodeGenerator.warning}
|
|
292
346
|
-->
|
|
293
347
|
${onceHtmlParts.join('\n')}
|
|
294
348
|
${nodePluginParts.join('\n\n')}
|
|
295
349
|
`);
|
|
296
|
-
console.log(`Done building Plugins.html\n`);
|
|
350
|
+
console.log(`Done building Plugins.html (${nodes.length} shared nodes)\n`);
|
|
297
351
|
}
|
|
298
352
|
|
|
299
353
|
private static generateHeader(node:NodeDescriptor){
|
|
@@ -320,7 +374,7 @@ class TypeUtility {
|
|
|
320
374
|
private constructor(){}
|
|
321
375
|
|
|
322
376
|
private static getPrototypes(t:INamedType):string[] {
|
|
323
|
-
if(!t.name){
|
|
377
|
+
if(!t || !t.name){
|
|
324
378
|
return [];
|
|
325
379
|
}
|
|
326
380
|
else{
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import * as os from 'os';
|
|
2
3
|
import {BaseService, ConfigNodeConfig, ConfigNode } from "../../NodeConstructor";
|
|
3
4
|
import { ServiceDescription } from "../../tagging/ServiceDescriptionDecorator";
|
|
4
5
|
import { NodeAPI, NodeAPISettingsWithData, Node } from "node-red";
|
|
@@ -6,7 +7,18 @@ import { LoggerTemplate, LoggerTemplateConfig } from "../template/LoggerTemplate
|
|
|
6
7
|
|
|
7
8
|
// Build-time / optional runtime deps - lazy so they are never required at bundle load time.
|
|
8
9
|
function getHandlebars(): any { return require('handlebars'); }
|
|
9
|
-
|
|
10
|
+
|
|
11
|
+
function getLocalIpAddress(): string {
|
|
12
|
+
const interfaces = os.networkInterfaces();
|
|
13
|
+
for (const name of Object.keys(interfaces)) {
|
|
14
|
+
for (const iface of interfaces[name] ?? []) {
|
|
15
|
+
if (iface.family === 'IPv4' && !iface.internal) {
|
|
16
|
+
return iface.address;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return '127.0.0.1';
|
|
21
|
+
}
|
|
10
22
|
|
|
11
23
|
let _helpersRegistered = false;
|
|
12
24
|
function ensureHelpersRegistered(): void {
|
|
@@ -134,7 +146,15 @@ export abstract class AbstractLogger<BaseLoggerConfig>{
|
|
|
134
146
|
})
|
|
135
147
|
export class LoggerService extends BaseService {
|
|
136
148
|
|
|
137
|
-
|
|
149
|
+
// Backed by a global so the value is shared across separately-bundled copies
|
|
150
|
+
// of plugincore (Nodes.js and Plugins.js each inline their own copy).
|
|
151
|
+
public static get instanceID(): string {
|
|
152
|
+
return (global as any).__plugincore_instance_id__ ?? '';
|
|
153
|
+
}
|
|
154
|
+
public static set instanceID(value: string) {
|
|
155
|
+
(global as any).__plugincore_instance_id__ = value;
|
|
156
|
+
}
|
|
157
|
+
|
|
138
158
|
private red!: NodeAPI<NodeAPISettingsWithData>;
|
|
139
159
|
|
|
140
160
|
constructor(){
|
|
@@ -143,12 +163,7 @@ export class LoggerService extends BaseService {
|
|
|
143
163
|
|
|
144
164
|
public init(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void> {
|
|
145
165
|
this.red = red;
|
|
146
|
-
|
|
147
|
-
return new Promise<void>((resolve) => {
|
|
148
|
-
getNetwork().get_active_interface((_err:any, obj:any) => {
|
|
149
|
-
LoggerService.instanceID = obj.ip_address;
|
|
150
|
-
});
|
|
151
|
-
});
|
|
166
|
+
LoggerService.instanceID = getLocalIpAddress();
|
|
152
167
|
}
|
|
153
168
|
|
|
154
169
|
public deinit(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void> {}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
-
import { BaseNodeConfig, Template
|
|
2
|
+
import { BaseNodeConfig, Template } from "../../NodeConstructor"
|
|
3
|
+
import { TemplateDescription } from "../../tagging/TemplateDescriptionDecorator";
|
|
4
|
+
import { DelegatedConfigReferenceNode } from "../../other/node/DelegatedConfigReferenceNode";
|
|
5
|
+
import { LoggerService } from "../service/LoggerService";
|
|
3
6
|
|
|
4
7
|
// TODO: we need to prefix logger teplate properties with logtemplate_
|
|
5
8
|
export interface LoggerTemplateNodeConfig extends BaseNodeConfig{
|
|
@@ -18,15 +21,10 @@ export type LoggerTemplateConfig = {
|
|
|
18
21
|
level:string;
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
@TemplateDescription({
|
|
25
|
+
name: "logger",
|
|
26
|
+
templateFile: SourceUtility.getSourcePath("/build/", "/src/") + "LoggerTemplate.html",
|
|
27
|
+
dependencies: [DelegatedConfigReferenceNode, LoggerService],
|
|
28
|
+
})
|
|
21
29
|
export class LoggerTemplate extends Template {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
static getTemplateDescriptor(): TemplateDescriptor {
|
|
25
|
-
return new TemplateDescriptor(
|
|
26
|
-
"logger",
|
|
27
|
-
LoggerTemplate,
|
|
28
|
-
SourceUtility.getSourcePath("/build/", "/src/") + "LoggerTemplate.html",
|
|
29
|
-
[],
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
30
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
-
import { Template
|
|
2
|
+
import { Template } from "../../NodeConstructor"
|
|
3
|
+
import { TemplateDescription } from "../../tagging/TemplateDescriptionDecorator";
|
|
3
4
|
import { CounterMetricConfigNode } from "../node/CounterMetricConfigNode";
|
|
4
5
|
|
|
6
|
+
@TemplateDescription({
|
|
7
|
+
name: "countermetric",
|
|
8
|
+
templateFile: SourceUtility.getSourcePath("/build/", "/src/") + "CounterMetricTemplate.html",
|
|
9
|
+
dependencies: [CounterMetricConfigNode],
|
|
10
|
+
})
|
|
5
11
|
export class CounterMetricTemplate extends Template {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
9
|
-
return new TemplateDescriptor(
|
|
10
|
-
"countermetric",
|
|
11
|
-
CounterMetricTemplate,
|
|
12
|
-
SourceUtility.getSourcePath("/build/", "/src/") + "CounterMetricTemplate.html",
|
|
13
|
-
[CounterMetricConfigNode]);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
12
|
+
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
-
import { Template
|
|
2
|
+
import { Template } from "../../NodeConstructor"
|
|
3
|
+
import { TemplateDescription } from "../../tagging/TemplateDescriptionDecorator";
|
|
3
4
|
import { GaugeMetricConfigNode } from "../node/GaugeMetricConfigNode";
|
|
4
5
|
|
|
6
|
+
@TemplateDescription({
|
|
7
|
+
name: "gaugemetric",
|
|
8
|
+
templateFile: SourceUtility.getSourcePath("/build/", "/src/") + "GaugeMetricTemplate.html",
|
|
9
|
+
dependencies: [GaugeMetricConfigNode],
|
|
10
|
+
})
|
|
5
11
|
export class GaugeMetricTemplate extends Template {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
9
|
-
return new TemplateDescriptor(
|
|
10
|
-
"gaugemetric",
|
|
11
|
-
GaugeMetricTemplate,
|
|
12
|
-
SourceUtility.getSourcePath("/build/", "/src/") + "GaugeMetricTemplate.html",
|
|
13
|
-
[GaugeMetricConfigNode]);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
12
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
-
import { BaseNodeConfig, Template
|
|
2
|
+
import { BaseNodeConfig, Template } from "../../NodeConstructor"
|
|
3
|
+
import { TemplateDescription } from "../../tagging/TemplateDescriptionDecorator";
|
|
4
|
+
import { DelegatedConfigReferenceNode } from "../../other/node/DelegatedConfigReferenceNode";
|
|
5
|
+
import { MetricsService } from "../service/MetricsService";
|
|
3
6
|
import { MetricsReference } from "../service/MetricsService";
|
|
4
7
|
|
|
5
8
|
export interface MetricsTemplateConfig extends BaseNodeConfig, MetricsReference {
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
@TemplateDescription({
|
|
12
|
+
name: "metrics",
|
|
13
|
+
templateFile: SourceUtility.getSourcePath("/build/", "/src/") + "MetricsTemplate.html",
|
|
14
|
+
dependencies: [DelegatedConfigReferenceNode, MetricsService],
|
|
15
|
+
})
|
|
8
16
|
export class MetricsTemplate extends Template {
|
|
9
|
-
|
|
10
|
-
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
11
|
-
return new TemplateDescriptor(
|
|
12
|
-
"metrics",
|
|
13
|
-
MetricsTemplate,
|
|
14
|
-
SourceUtility.getSourcePath("/build/", "/src/") + "MetricsTemplate.html",
|
|
15
|
-
[]);
|
|
16
|
-
}
|
|
17
17
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
-
import { Template
|
|
2
|
+
import { Template } from "../../NodeConstructor"
|
|
3
|
+
import { TemplateDescription } from "../../tagging/TemplateDescriptionDecorator";
|
|
3
4
|
import { TimerMetricConfigNode } from "../node/TimerMetricConfigNode";
|
|
4
5
|
|
|
6
|
+
@TemplateDescription({
|
|
7
|
+
name: "timermetric",
|
|
8
|
+
templateFile: SourceUtility.getSourcePath("/build/", "/src/") + "TimerMetricTemplate.html",
|
|
9
|
+
dependencies: [TimerMetricConfigNode],
|
|
10
|
+
})
|
|
5
11
|
export class TimerMetricTemplate extends Template {
|
|
6
|
-
|
|
7
|
-
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
8
|
-
return new TemplateDescriptor(
|
|
9
|
-
"timermetric",
|
|
10
|
-
TimerMetricTemplate,
|
|
11
|
-
SourceUtility.getSourcePath("/build/", "/src/") + "TimerMetricTemplate.html",
|
|
12
|
-
[TimerMetricConfigNode]);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
12
|
+
}
|