@theotherwillembotha/node-red-plugincore 0.1.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/README.md +616 -220
- package/build/GenerateNodes.js +9 -33
- package/build/Nodes.html +2 -1505
- package/build/Nodes.js +5 -19
- package/build/Plugins.html +11 -0
- package/build/Plugins.js +17 -12
- package/build/core/NodeConstructor.d.ts +12 -16
- package/build/core/NodeConstructor.d.ts.map +1 -1
- package/build/core/NodeConstructor.js +125 -185
- package/build/core/NodeGenerator.d.ts +3 -1
- package/build/core/NodeGenerator.d.ts.map +1 -1
- package/build/core/NodeGenerator.js +139 -43
- package/build/core/NodeManagerRuntime.d.ts +44 -0
- package/build/core/NodeManagerRuntime.d.ts.map +1 -0
- package/build/core/NodeManagerRuntime.js +140 -0
- package/build/core/Utils.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.d.ts +8 -6
- package/build/core/logger/service/LoggerService.d.ts.map +1 -1
- package/build/core/logger/service/LoggerService.js +101 -23
- 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/MetricsDecorator.d.ts +1 -2
- package/build/core/metrics/MetricsDecorator.d.ts.map +1 -1
- package/build/core/metrics/MetricsDecorator.js +89 -116
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/CounterMetricConfigNode.js +4 -5
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/GaugeMetricConfigNode.js +5 -6
- package/build/core/metrics/node/MetricsConfigNode.d.ts +19 -9
- package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/MetricsConfigNode.js +14 -45
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -1
- package/build/core/metrics/node/TimerMetricConfigNode.js +11 -17
- package/build/core/metrics/service/MetricsService.d.ts +110 -114
- package/build/core/metrics/service/MetricsService.d.ts.map +1 -1
- package/build/core/metrics/service/MetricsService.js +122 -339
- 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 -6
- 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/node/DelegatedConfigReferenceNode.d.ts +1 -1
- package/build/core/other/node/DelegatedConfigReferenceNode.d.ts.map +1 -1
- package/build/core/other/node/DelegatedConfigReferenceNode.js +1 -1
- package/build/core/other/service/InputService.d.ts.map +1 -1
- package/build/core/other/service/SettingsService.d.ts +1 -2
- package/build/core/other/service/SettingsService.d.ts.map +1 -1
- package/build/core/other/service/SettingsService.js +19 -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/node/InternalStateConfigNode.d.ts +16 -0
- package/build/core/state/node/InternalStateConfigNode.d.ts.map +1 -0
- package/build/core/state/node/InternalStateConfigNode.js +89 -0
- package/build/core/state/node/StateConfigNode.d.ts +24 -0
- package/build/core/state/node/StateConfigNode.d.ts.map +1 -0
- package/build/core/state/node/StateConfigNode.js +22 -0
- package/build/core/state/service/StateService.d.ts +34 -0
- package/build/core/state/service/StateService.d.ts.map +1 -0
- package/build/core/state/service/StateService.js +201 -0
- package/build/core/state/template/StateTemplate.d.ts +7 -0
- package/build/core/state/template/StateTemplate.d.ts.map +1 -0
- package/build/core/state/template/StateTemplate.js +25 -0
- package/build/core/tagging/ServiceDescriptionDecorator.d.ts +10 -0
- package/build/core/tagging/ServiceDescriptionDecorator.d.ts.map +1 -0
- package/build/core/tagging/ServiceDescriptionDecorator.js +10 -0
- 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/tagging/service/NodeTypeService.d.ts +1 -2
- package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -1
- package/build/core/tagging/service/NodeTypeService.js +19 -5
- 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/node/WebhookServerConfigNode.d.ts.map +1 -1
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.d.ts +3 -4
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -1
- package/build/core/webhook/service/WebhookServerService.js +48 -18
- 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 +6 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -2
- package/build/runtime/NodeManagerRuntime.js +140 -0
- package/documentation/CounterMetricConfigNode.png +0 -0
- package/documentation/GaugeMetricConfigNode.png +0 -0
- package/documentation/LoggerTemplate.png +0 -0
- package/documentation/MetricsTemplate.png +0 -0
- package/documentation/StateTemplate.png +0 -0
- package/documentation/TimerMetricConfigNode_histogram.png +0 -0
- package/documentation/TimerMetricConfigNode_summary.png +0 -0
- package/documentation/WebhookServerConfigNode.png +0 -0
- package/documentation/WebhookTemplate.png +0 -0
- package/package.json +4 -11
- package/src/GenerateNodes.ts +10 -40
- package/src/core/NodeConstructor.ts +150 -228
- package/src/core/NodeGenerator.ts +156 -47
- package/src/core/NodeManagerRuntime.ts +179 -0
- package/src/core/logger/service/LoggerService.ts +60 -32
- package/src/core/logger/template/LoggerTemplate.html +11 -6
- package/src/core/logger/template/LoggerTemplate.ts +9 -11
- package/src/core/metrics/MetricsDecorator.ts +140 -168
- package/src/core/metrics/node/CounterMetricConfigNode.ts +20 -20
- package/src/core/metrics/node/GaugeMetricConfigNode.ts +24 -25
- package/src/core/metrics/node/MetricsConfigNode.ts +29 -48
- package/src/core/metrics/node/TimerMetricConfigNode.ts +50 -59
- package/src/core/metrics/service/MetricsService.ts +214 -489
- package/src/core/metrics/template/CounterMetricTemplate.html +0 -1
- package/src/core/metrics/template/CounterMetricTemplate.ts +8 -11
- package/src/core/metrics/template/GaugeMetricTemplate.html +1 -1
- package/src/core/metrics/template/GaugeMetricTemplate.ts +8 -11
- package/src/core/metrics/template/MetricsTemplate.html +132 -13
- package/src/core/metrics/template/MetricsTemplate.ts +9 -10
- package/src/core/metrics/template/TimerMetricTemplate.ts +8 -10
- package/src/core/other/node/DelegatedConfigReferenceNode.ts +1 -1
- package/src/core/other/service/SettingsService.ts +6 -10
- package/src/core/other/template/BasicTemplate.html +1 -1
- package/src/core/other/template/BasicTemplate.ts +6 -11
- package/src/core/other/template/SettingsTemplate.ts +8 -13
- package/src/core/state/node/InternalStateConfigNode.html +77 -0
- package/src/core/state/node/InternalStateConfigNode.ts +102 -0
- package/src/core/state/node/StateConfigNode.ts +29 -0
- package/src/core/state/service/StateService.ts +180 -0
- package/src/core/state/template/StateTemplate.html +244 -0
- package/src/core/state/template/StateTemplate.ts +18 -0
- package/src/core/tagging/ServiceDescriptionDecorator.ts +23 -0
- package/src/core/tagging/TemplateDescriptionDecorator.ts +19 -0
- package/src/core/tagging/service/NodeTypeService.ts +6 -11
- package/src/core/ui/template/ScriptEditorTemplate.ts +6 -10
- package/src/core/ui/template/UIHelperTemplate.html +41 -26
- package/src/core/ui/template/UIHelperTemplate.ts +6 -10
- package/src/core/webhook/service/WebhookServerService.ts +39 -23
- package/src/core/webhook/template/WebhookTemplate.html +28 -35
- package/src/core/webhook/template/WebhookTemplate.ts +10 -12
- package/src/index.ts +8 -2
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +0 -20
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +0 -1
- package/build/core/logger/node/ConsoleLoggerConfigNode.js +0 -62
- package/build/core/logger/node/RestLoggerConfigNode.d.ts +0 -40
- package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +0 -1
- package/build/core/logger/node/RestLoggerConfigNode.js +0 -128
- package/documentation/ConsoleLoggerConfigNode.png +0 -0
- package/documentation/MetricsConfigNode.png +0 -0
- package/documentation/RestLoggerConfigNode.png +0 -0
- package/documentation/TimerMetricConfigNode.png +0 -0
- package/documentation/WebhookNode.png +0 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.html +0 -90
- package/src/core/logger/node/ConsoleLoggerConfigNode.ts +0 -71
- package/src/core/logger/node/RestLoggerConfigNode.html +0 -183
- package/src/core/logger/node/RestLoggerConfigNode.ts +0 -170
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.SourceUtility = exports.NodeGenerator = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
38
39
|
const NodeConstructor_1 = require("./NodeConstructor");
|
|
39
40
|
const templatePropertyKeys = ["onIncludeOnce", "onIncludeDefaults", "onIncludeEditPrepare", "onIncludeEditPrepare", "onIncludeEditSave", "onIncludeEditForm"];
|
|
40
41
|
class NodeGenerator {
|
|
@@ -68,12 +69,10 @@ class NodeGenerator {
|
|
|
68
69
|
}
|
|
69
70
|
registerTemplate(template) {
|
|
70
71
|
try {
|
|
71
|
-
// verify that we dont already have this template.
|
|
72
72
|
let descriptor = template.getTemplateDescriptor();
|
|
73
73
|
if (!this._templates.map(t => t.name()).includes(descriptor.name())) {
|
|
74
74
|
this._templates.push(descriptor);
|
|
75
|
-
|
|
76
|
-
// descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
75
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
77
76
|
}
|
|
78
77
|
}
|
|
79
78
|
catch (error) {
|
|
@@ -83,12 +82,13 @@ class NodeGenerator {
|
|
|
83
82
|
}
|
|
84
83
|
registerNode(node) {
|
|
85
84
|
try {
|
|
86
|
-
// verify that we have dont already have this node.
|
|
87
85
|
let descriptor = node.getNodeDescriptor();
|
|
88
86
|
if (!this._nodes[descriptor.id()]) {
|
|
89
87
|
this._nodes[descriptor.id()] = { nodeClass: node, descriptor: descriptor };
|
|
90
|
-
//
|
|
91
|
-
|
|
88
|
+
// resolve templates declared in @NodeDescription
|
|
89
|
+
descriptor.templates().forEach(t => this.registerTemplate(t.template));
|
|
90
|
+
// resolve explicit dependencies (services, nodes, templates)
|
|
91
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
catch (error) {
|
|
@@ -101,8 +101,7 @@ class NodeGenerator {
|
|
|
101
101
|
let descriptor = service.getServiceDescriptor();
|
|
102
102
|
if (!this._services.map(s => s.name()).includes(descriptor.name())) {
|
|
103
103
|
this._services.push(descriptor);
|
|
104
|
-
|
|
105
|
-
//descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
104
|
+
descriptor.dependencies().forEach(dependency => this.addDependency(dependency));
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
catch (error) {
|
|
@@ -110,30 +109,20 @@ class NodeGenerator {
|
|
|
110
109
|
}
|
|
111
110
|
return this;
|
|
112
111
|
}
|
|
113
|
-
generate(nodesOutputFile, pluginsOutputFile) {
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
})
|
|
128
|
-
.join("\n");
|
|
129
|
-
fs.writeFileSync(nodesOutputFile + ".html", `
|
|
130
|
-
<!--
|
|
131
|
-
${NodeGenerator.warning}
|
|
132
|
-
-->
|
|
133
|
-
${templateInclude}
|
|
134
|
-
${nodeHTMLOutut}
|
|
135
|
-
|
|
136
|
-
`);
|
|
112
|
+
generate(nodesOutputFile, pluginsOutputFile, packageName) {
|
|
113
|
+
// Partition nodes into owned (belongs to this package) vs shared (from dependencies).
|
|
114
|
+
// Owned nodes get standard registerType + data-template-name in Nodes.html so that
|
|
115
|
+
// Node-RED's registry maps them to this module (enabling palette icons, flow library
|
|
116
|
+
// detection, etc.). Shared nodes keep the deferred pattern in Plugins.html to avoid
|
|
117
|
+
// HTML-scanning conflicts when multiple plugins bundle the same infrastructure nodes.
|
|
118
|
+
const allNodes = Object.values(this._nodes);
|
|
119
|
+
const ownedNodes = allNodes.filter(node => node.descriptor.package() === packageName);
|
|
120
|
+
const sharedNodes = allNodes.filter(node => node.descriptor.package() !== packageName);
|
|
121
|
+
console.log(`\nPackage: ${packageName}`);
|
|
122
|
+
console.log(` Owned nodes (→ Nodes.html): ${ownedNodes.map(n => n.descriptor.id()).join(', ') || '(none)'}`);
|
|
123
|
+
console.log(` Shared nodes (→ Plugins.html): ${sharedNodes.map(n => n.descriptor.id()).join(', ') || '(none)'}\n`);
|
|
124
|
+
// STEP 1. Generate Nodes.html with standard client-side definitions for owned nodes.
|
|
125
|
+
this.generateNodesHtml(nodesOutputFile + ".html", ownedNodes);
|
|
137
126
|
// Step 3. compose the JS structure for each of the nodes.
|
|
138
127
|
// 1. get a list of the files to import.
|
|
139
128
|
let importList = [
|
|
@@ -153,14 +142,34 @@ ${nodeHTMLOutut}
|
|
|
153
142
|
${NodeGenerator.warning}
|
|
154
143
|
*/
|
|
155
144
|
"use strict";
|
|
156
|
-
const NodeManager = require("
|
|
145
|
+
const { NodeManager } = require("./runtime/NodeManagerRuntime");
|
|
157
146
|
${importList}
|
|
158
147
|
module.exports = (RED) => {
|
|
159
148
|
let manager = new NodeManager(RED);
|
|
160
149
|
${moduleExports}
|
|
161
|
-
}
|
|
162
|
-
|
|
150
|
+
}
|
|
151
|
+
|
|
163
152
|
`);
|
|
153
|
+
// Copy NodeManagerRuntime.js into the plugin's build/runtime/ folder so that
|
|
154
|
+
// the generated Nodes.js require("./runtime/NodeManagerRuntime") resolves locally
|
|
155
|
+
// with no dependency on plugincore being installed in the user's environment.
|
|
156
|
+
const outputDir = path.dirname(nodesOutputFile);
|
|
157
|
+
const runtimeDestDir = path.join(outputDir, 'runtime');
|
|
158
|
+
const runtimeDestPath = path.join(runtimeDestDir, 'NodeManagerRuntime.js');
|
|
159
|
+
let runtimeSrcPath;
|
|
160
|
+
try {
|
|
161
|
+
// Resolves when this is a consumer plugin - plugincore is in node_modules.
|
|
162
|
+
runtimeSrcPath = require.resolve('@theotherwillembotha/node-red-plugincore/build/runtime/NodeManagerRuntime');
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// We ARE plugincore - NodeManagerRuntime.js is compiled alongside us in build/core/.
|
|
166
|
+
runtimeSrcPath = path.join(__dirname, 'NodeManagerRuntime.js');
|
|
167
|
+
}
|
|
168
|
+
if (path.resolve(runtimeSrcPath) !== path.resolve(runtimeDestPath)) {
|
|
169
|
+
fs.mkdirSync(runtimeDestDir, { recursive: true });
|
|
170
|
+
fs.copyFileSync(runtimeSrcPath, runtimeDestPath);
|
|
171
|
+
}
|
|
172
|
+
console.log(`NodeManagerRuntime.js → ${runtimeDestPath}`);
|
|
164
173
|
console.log(`Done building ${Object.keys(this._nodes).length} nodes\n${Object.values(this._nodes).map(node => " - " + node.descriptor.id() + "\n").join("")}\n`);
|
|
165
174
|
let serviceExports = this._services.map(service => {
|
|
166
175
|
return ` manager.registerService(${service.name()}.${service.name()});`;
|
|
@@ -192,29 +201,38 @@ module.exports = function (RED) {
|
|
|
192
201
|
|
|
193
202
|
if(addedPlugin && plugin.instantiate && !plugin.instance){
|
|
194
203
|
plugin.instance = new plugin.class();
|
|
195
|
-
|
|
204
|
+
|
|
196
205
|
// instantiate the plugin.
|
|
197
206
|
await plugin.instance.init(RED);
|
|
198
207
|
|
|
208
|
+
// Eagerly call onDeploy with any pre-existing saved flows so that
|
|
209
|
+
// service registries (MetricsService, WebhookServerService, etc.) are
|
|
210
|
+
// populated before config nodes are constructed during flow startup.
|
|
211
|
+
// Without this, MetricsConfigNode._metrics is undefined on first boot.
|
|
212
|
+
const existingFlows = await runtime.flows.getFlows({});
|
|
213
|
+
const hasExistingFlows = existingFlows && existingFlows.flows && existingFlows.flows.length > 0;
|
|
214
|
+
if (hasExistingFlows) {
|
|
215
|
+
await plugin.instance.onDeploy(existingFlows);
|
|
216
|
+
}
|
|
217
|
+
|
|
199
218
|
// publish an event that it has ben deployed.
|
|
200
219
|
RED.events.emit("plugin.instantiated", pluginID);
|
|
201
|
-
|
|
220
|
+
|
|
202
221
|
pluginList.splice(pluginList.findIndex(current => current.id() === addedPlugin.id()), 1);
|
|
203
222
|
|
|
204
223
|
// register a flow deployment listener.
|
|
205
|
-
|
|
224
|
+
// startupDeployment is only needed for a truly fresh Node-RED with no saved flows.
|
|
225
|
+
let startupDeployment = !hasExistingFlows;
|
|
206
226
|
RED.events.on('runtime-event', async (event) => {
|
|
207
|
-
// startup deployment.
|
|
227
|
+
// startup deployment (fresh Node-RED with no pre-existing flows).
|
|
208
228
|
if ("runtime-deploy" === event?.id && startupDeployment) {
|
|
209
|
-
//console.log("STARTUP DEPLOYMENT");
|
|
210
229
|
startupDeployment = false;
|
|
211
230
|
const flows = await runtime.flows.getFlows({});
|
|
212
231
|
await plugin.instance.onDeploy(flows);
|
|
213
232
|
}
|
|
214
|
-
|
|
233
|
+
|
|
215
234
|
// stopping flows on redeployment.
|
|
216
235
|
if ("runtime-state" === event?.id && event?.payload?.state === "stop" && event?.payload?.deploy) {
|
|
217
|
-
//console.log("REDEPLOY!");
|
|
218
236
|
const flows = await runtime.flows.getFlows({});
|
|
219
237
|
await plugin.instance.onDeploy(flows);
|
|
220
238
|
}
|
|
@@ -235,6 +253,84 @@ module.exports = function (RED) {
|
|
|
235
253
|
`;
|
|
236
254
|
fs.writeFileSync(pluginsOutputFile + ".js", output);
|
|
237
255
|
console.log(`Done building ${this._services.length} services\n${this._services.map(service => " - " + service.name() + "\n").join("")}\n`);
|
|
256
|
+
// STEP 4. Generate Plugins.html with deferred client-side definitions for shared nodes.
|
|
257
|
+
this.generatePluginsHtml(pluginsOutputFile + ".html", sharedNodes);
|
|
258
|
+
}
|
|
259
|
+
generateNodesHtml(filePath, nodes) {
|
|
260
|
+
if (nodes.length === 0) {
|
|
261
|
+
fs.writeFileSync(filePath, `
|
|
262
|
+
<!--
|
|
263
|
+
${NodeGenerator.warning}
|
|
264
|
+
No owned nodes in this package. Shared nodes are registered via Plugins.html.
|
|
265
|
+
-->
|
|
266
|
+
`);
|
|
267
|
+
console.log(`Nodes.html: no owned nodes\n`);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const seenOnce = new Set();
|
|
271
|
+
const onceHtmlParts = [];
|
|
272
|
+
const nodeParts = [];
|
|
273
|
+
nodes.forEach(node => {
|
|
274
|
+
console.log(`Building Nodes.html for: ${node.descriptor.id()}`);
|
|
275
|
+
const nb = (0, NodeConstructor_1.buildNodeBuilder)(node.nodeClass);
|
|
276
|
+
nb.buildOnceHtml().forEach(({ source, html }) => {
|
|
277
|
+
if (!seenOnce.has(source)) {
|
|
278
|
+
seenOnce.add(source);
|
|
279
|
+
onceHtmlParts.push(html);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
nodeParts.push([
|
|
283
|
+
nb.buildStandardType(),
|
|
284
|
+
nb.buildHtml(),
|
|
285
|
+
nb.buildDocumentation()
|
|
286
|
+
].join('\n\n'));
|
|
287
|
+
});
|
|
288
|
+
fs.writeFileSync(filePath, `
|
|
289
|
+
<!--
|
|
290
|
+
${NodeGenerator.warning}
|
|
291
|
+
-->
|
|
292
|
+
${onceHtmlParts.join('\n')}
|
|
293
|
+
${nodeParts.join('\n\n')}
|
|
294
|
+
`);
|
|
295
|
+
console.log(`Done building Nodes.html (${nodes.length} owned nodes)\n`);
|
|
296
|
+
}
|
|
297
|
+
generatePluginsHtml(filePath, nodes) {
|
|
298
|
+
if (nodes.length === 0) {
|
|
299
|
+
fs.writeFileSync(filePath, `
|
|
300
|
+
<!--
|
|
301
|
+
${NodeGenerator.warning}
|
|
302
|
+
No shared nodes in this package. All nodes are registered via Nodes.html.
|
|
303
|
+
-->
|
|
304
|
+
`);
|
|
305
|
+
console.log(`Plugins.html: no shared nodes\n`);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
const seenOnce = new Set();
|
|
309
|
+
const onceHtmlParts = [];
|
|
310
|
+
const nodePluginParts = [];
|
|
311
|
+
nodes.forEach(node => {
|
|
312
|
+
console.log(`Building Plugins.html for: ${node.descriptor.id()}`);
|
|
313
|
+
const nb = (0, NodeConstructor_1.buildNodeBuilder)(node.nodeClass);
|
|
314
|
+
nb.buildOnceHtml().forEach(({ source, html }) => {
|
|
315
|
+
if (!seenOnce.has(source)) {
|
|
316
|
+
seenOnce.add(source);
|
|
317
|
+
onceHtmlParts.push(html);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
nodePluginParts.push([
|
|
321
|
+
nb.buildDeferredType(),
|
|
322
|
+
nb.buildHtml(),
|
|
323
|
+
nb.buildDocumentation()
|
|
324
|
+
].join('\n\n'));
|
|
325
|
+
});
|
|
326
|
+
fs.writeFileSync(filePath, `
|
|
327
|
+
<!--
|
|
328
|
+
${NodeGenerator.warning}
|
|
329
|
+
-->
|
|
330
|
+
${onceHtmlParts.join('\n')}
|
|
331
|
+
${nodePluginParts.join('\n\n')}
|
|
332
|
+
`);
|
|
333
|
+
console.log(`Done building Plugins.html (${nodes.length} shared nodes)\n`);
|
|
238
334
|
}
|
|
239
335
|
static generateHeader(node) {
|
|
240
336
|
let padding = ' '.repeat(Math.max(0, Math.floor(NodeGenerator.headerWidth - node.id().length) / 2));
|
|
@@ -249,7 +345,7 @@ exports.NodeGenerator = NodeGenerator;
|
|
|
249
345
|
class TypeUtility {
|
|
250
346
|
constructor() { }
|
|
251
347
|
static getPrototypes(t) {
|
|
252
|
-
if (!t.name) {
|
|
348
|
+
if (!t || !t.name) {
|
|
253
349
|
return [];
|
|
254
350
|
}
|
|
255
351
|
else {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeManagerRuntime.ts
|
|
3
|
+
*
|
|
4
|
+
* STANDALONE - zero imports from the rest of plugincore.
|
|
5
|
+
*
|
|
6
|
+
* This file is compiled and copied into every plugin's build output so that
|
|
7
|
+
* plugins are self-contained and do not require plugincore to be separately
|
|
8
|
+
* installed in the user's Node-RED environment.
|
|
9
|
+
*
|
|
10
|
+
* When multiple plugins are deployed, each ships its own copy of this file.
|
|
11
|
+
* The first plugin to load registers its NodeManager and nodes; subsequent
|
|
12
|
+
* copies operate independently on their own node types with no conflict.
|
|
13
|
+
*
|
|
14
|
+
* POST_CONSTRUCT_KEY is intentionally a plain string (not a Symbol) so that
|
|
15
|
+
* the decorators (from plugincore's NodeConstructor, loaded via the plugin's
|
|
16
|
+
* dependency on plugincore) and this runtime file (a separate module instance)
|
|
17
|
+
* resolve to the same property key on node instances.
|
|
18
|
+
*/
|
|
19
|
+
import type { NodeAPI, NodeAPISettingsWithData } from "node-red";
|
|
20
|
+
export declare const NODEMANAGER_API_VERSION = "1.0.0";
|
|
21
|
+
export declare const POST_CONSTRUCT_KEY = "__plugincore_postConstructInitializers__";
|
|
22
|
+
export interface BaseNodeConfig {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
type: string;
|
|
26
|
+
}
|
|
27
|
+
interface INodeDescriptor {
|
|
28
|
+
id(): string;
|
|
29
|
+
tags(): string[];
|
|
30
|
+
}
|
|
31
|
+
interface INodeClass {
|
|
32
|
+
new (node: any, config: any): any;
|
|
33
|
+
getNodeDescriptor(): INodeDescriptor;
|
|
34
|
+
}
|
|
35
|
+
export declare function runPostConstructInitializers(instance: any): void;
|
|
36
|
+
export declare class NodeManager {
|
|
37
|
+
private nodeTypeService;
|
|
38
|
+
private typeBacklog;
|
|
39
|
+
constructor(RED: NodeAPI<NodeAPISettingsWithData>);
|
|
40
|
+
static get RED(): NodeAPI<NodeAPISettingsWithData>;
|
|
41
|
+
registerNodeType(typeName: string, type: INodeClass): NodeManager;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=NodeManagerRuntime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeManagerRuntime.d.ts","sourceRoot":"","sources":["../../src/core/NodeManagerRuntime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAMjE,eAAO,MAAM,uBAAuB,UAAU,CAAC;AAI/C,eAAO,MAAM,kBAAkB,6CAA6C,CAAC;AAI7E,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAe;IACrB,EAAE,IAAI,MAAM,CAAC;IACb,IAAI,IAAI,MAAM,EAAE,CAAC;CACpB;AAED,UAAU,UAAU;IAChB,KAAI,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IACjC,iBAAiB,IAAI,eAAe,CAAC;CACxC;AAID,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAoBhE;AA0BD,qBAAa,WAAW;IAGpB,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,WAAW,CAAoB;IAEvC,YAAmB,GAAG,EAAE,OAAO,CAAC,uBAAuB,CAAC,EAuBvD;IAED,WAAkB,GAAG,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAExD;IAEM,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,WAAW,CA6CvE;CACJ"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* NodeManagerRuntime.ts
|
|
4
|
+
*
|
|
5
|
+
* STANDALONE - zero imports from the rest of plugincore.
|
|
6
|
+
*
|
|
7
|
+
* This file is compiled and copied into every plugin's build output so that
|
|
8
|
+
* plugins are self-contained and do not require plugincore to be separately
|
|
9
|
+
* installed in the user's Node-RED environment.
|
|
10
|
+
*
|
|
11
|
+
* When multiple plugins are deployed, each ships its own copy of this file.
|
|
12
|
+
* The first plugin to load registers its NodeManager and nodes; subsequent
|
|
13
|
+
* copies operate independently on their own node types with no conflict.
|
|
14
|
+
*
|
|
15
|
+
* POST_CONSTRUCT_KEY is intentionally a plain string (not a Symbol) so that
|
|
16
|
+
* the decorators (from plugincore's NodeConstructor, loaded via the plugin's
|
|
17
|
+
* dependency on plugincore) and this runtime file (a separate module instance)
|
|
18
|
+
* resolve to the same property key on node instances.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.NodeManager = exports.POST_CONSTRUCT_KEY = exports.NODEMANAGER_API_VERSION = void 0;
|
|
22
|
+
exports.runPostConstructInitializers = runPostConstructInitializers;
|
|
23
|
+
// ─── API version ────────────────────────────────────────────────────────────
|
|
24
|
+
// Semver of the NodeManager API contract - independent of plugincore's package
|
|
25
|
+
// version. Bump when the contract changes; plugins can read this to warn users
|
|
26
|
+
// that they were built against a different NodeManager version.
|
|
27
|
+
exports.NODEMANAGER_API_VERSION = "1.0.0";
|
|
28
|
+
// ─── Shared key for post-construct initializer lists ────────────────────────
|
|
29
|
+
// Must be a plain string so it resolves identically across module instances.
|
|
30
|
+
exports.POST_CONSTRUCT_KEY = '__plugincore_postConstructInitializers__';
|
|
31
|
+
// ─── Post-construct initializer runner ───────────────────────────────────────
|
|
32
|
+
function runPostConstructInitializers(instance) {
|
|
33
|
+
const initializers = instance[exports.POST_CONSTRUCT_KEY];
|
|
34
|
+
if (!initializers || initializers.length === 0)
|
|
35
|
+
return;
|
|
36
|
+
const className = instance.constructor.name;
|
|
37
|
+
initializers.forEach((init, index) => {
|
|
38
|
+
try {
|
|
39
|
+
init(instance);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(`Post-construct initialization failed:\n` +
|
|
43
|
+
` Class: ${className}\n` +
|
|
44
|
+
` Initializer: ${index + 1}/${initializers.length}\n` +
|
|
45
|
+
` Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
delete instance[exports.POST_CONSTRUCT_KEY];
|
|
50
|
+
}
|
|
51
|
+
// ─── NodeManager ─────────────────────────────────────────────────────────────
|
|
52
|
+
// RED is stored on `global` rather than as a static class field so that all
|
|
53
|
+
// module instances of NodeManagerRuntime (the local copy bundled into Nodes.js
|
|
54
|
+
// and the copy bundled via plugincore's NodeConstructor) share the same value.
|
|
55
|
+
// Without this, esbuild's two separate inline copies would have independent
|
|
56
|
+
// static fields and the one used by decorators would never see RED being set.
|
|
57
|
+
const _GLOBAL_RED_KEY = '__plugincore_NodeManager_RED__';
|
|
58
|
+
// ─── Global node-type registration guard ─────────────────────────────────────
|
|
59
|
+
// When multiple self-contained plugins are installed they each bundle plugincore
|
|
60
|
+
// inline and each try to call RED.nodes.registerType for the same shared
|
|
61
|
+
// infrastructure node types (ConsoleLoggerConfigNode, RestLoggerConfigNode, etc.).
|
|
62
|
+
// Node-RED rejects duplicate registrations with a warning and the second
|
|
63
|
+
// plugin's Nodes.js fails to load. This global set tracks which types have
|
|
64
|
+
// already been registered so subsequent plugins silently skip them.
|
|
65
|
+
const _GLOBAL_REGISTERED_NODES_KEY = '__plugincore_registered_nodes__';
|
|
66
|
+
function getRegisteredNodes() {
|
|
67
|
+
if (!global[_GLOBAL_REGISTERED_NODES_KEY]) {
|
|
68
|
+
global[_GLOBAL_REGISTERED_NODES_KEY] = new Set();
|
|
69
|
+
}
|
|
70
|
+
return global[_GLOBAL_REGISTERED_NODES_KEY];
|
|
71
|
+
}
|
|
72
|
+
class NodeManager {
|
|
73
|
+
constructor(RED) {
|
|
74
|
+
this.typeBacklog = [];
|
|
75
|
+
global[_GLOBAL_RED_KEY] = RED;
|
|
76
|
+
const nodeTypeServiceId = "@theotherwillembotha/nodetypeservice";
|
|
77
|
+
const nodeTypeServiceListener = (pluginID) => {
|
|
78
|
+
if (pluginID === nodeTypeServiceId) {
|
|
79
|
+
RED.events.off('plugin.instantiated', nodeTypeServiceListener);
|
|
80
|
+
this.nodeTypeService = RED.plugins.get(nodeTypeServiceId).instance;
|
|
81
|
+
for (const nodeType of this.typeBacklog) {
|
|
82
|
+
for (const tag of nodeType.getNodeDescriptor().tags()) {
|
|
83
|
+
this.nodeTypeService.registerNodeType(tag, nodeType);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this.typeBacklog = [];
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
this.nodeTypeService = RED.plugins.get(nodeTypeServiceId)?.instance;
|
|
90
|
+
if (!this.nodeTypeService) {
|
|
91
|
+
RED.events.on('plugin.instantiated', nodeTypeServiceListener);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
static get RED() {
|
|
95
|
+
return global[_GLOBAL_RED_KEY];
|
|
96
|
+
}
|
|
97
|
+
registerNodeType(typeName, type) {
|
|
98
|
+
if (!type) {
|
|
99
|
+
console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Type "${typeName}" is undefined. ` +
|
|
100
|
+
`Ensure it is exported and included in GenerateNodes.`);
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
const registeredNodes = getRegisteredNodes();
|
|
104
|
+
if (registeredNodes.has(typeName)) {
|
|
105
|
+
// Already registered by another plugin - skip to avoid Node-RED duplicate-registration error.
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
registeredNodes.add(typeName);
|
|
109
|
+
const nodeConstructor = function (config) {
|
|
110
|
+
try {
|
|
111
|
+
NodeManager.RED.nodes.createNode(this, config);
|
|
112
|
+
const node = new type(this, config);
|
|
113
|
+
runPostConstructInitializers(node);
|
|
114
|
+
if (node.onInit) {
|
|
115
|
+
node.onInit();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Failed to construct node "${typeName}":`, error);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
try {
|
|
123
|
+
NodeManager.RED.nodes.registerType(typeName, nodeConstructor, { settings: {} });
|
|
124
|
+
const nodeDescription = type.getNodeDescriptor();
|
|
125
|
+
if (this.nodeTypeService) {
|
|
126
|
+
for (const tag of nodeDescription.tags()) {
|
|
127
|
+
this.nodeTypeService.registerNodeType(tag, type);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.typeBacklog.push(type);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error(`[NodeManager v${exports.NODEMANAGER_API_VERSION}] Failed to register node type "${typeName}":`, error);
|
|
136
|
+
}
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.NodeManager = NodeManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../../src/core/Utils.ts"],"names":[],"mappings":"AAAA,cAAM,QAAQ;
|
|
1
|
+
{"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../../src/core/Utils.ts"],"names":[],"mappings":"AAAA,cAAM,QAAQ;IACV,OAAc,UAAU,CAAC,MAAM,EAAC;QAAC,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAA;KAAC,EAAE,QAAQ,EAAC,MAAM,EAAE,QAAQ,EAAC,GAAG,GAAE,GAAG,CAYrF;CACJ;AAED,OAAO,EACH,QAAQ,EACX,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseService,
|
|
1
|
+
import { BaseService, ConfigNodeConfig, ConfigNode } from "../../NodeConstructor";
|
|
2
2
|
import { NodeAPI, NodeAPISettingsWithData, Node } from "node-red";
|
|
3
3
|
import { LoggerTemplateConfig } from "../template/LoggerTemplate";
|
|
4
4
|
export declare enum Level {
|
|
@@ -26,9 +26,11 @@ export type TagMap = {
|
|
|
26
26
|
};
|
|
27
27
|
export declare abstract class Log {
|
|
28
28
|
private _config;
|
|
29
|
-
private
|
|
29
|
+
private _templateStr;
|
|
30
|
+
private _compiledTemplate;
|
|
30
31
|
private tags;
|
|
31
32
|
protected constructor(config: LoggerTemplateConfig);
|
|
33
|
+
private getTemplate;
|
|
32
34
|
protected config(): LoggerTemplateConfig;
|
|
33
35
|
log(payload: {
|
|
34
36
|
[key: string]: any;
|
|
@@ -52,12 +54,12 @@ export declare abstract class AbstractLogger<BaseLoggerConfig> {
|
|
|
52
54
|
protected abstract createLogger(config: LoggerTemplateConfig): Log;
|
|
53
55
|
}
|
|
54
56
|
export declare class LoggerService extends BaseService {
|
|
55
|
-
static instanceID: string;
|
|
57
|
+
static get instanceID(): string;
|
|
58
|
+
static set instanceID(value: string);
|
|
56
59
|
private red;
|
|
57
60
|
constructor();
|
|
58
61
|
init(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void>;
|
|
59
62
|
deinit(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void>;
|
|
60
|
-
static getServiceDescriptor(): ServiceDescriptor;
|
|
61
63
|
}
|
|
62
64
|
export type LoggerConfigNodeConfig = ConfigNodeConfig & BaseLoggerConfig & {};
|
|
63
65
|
export declare abstract class LoggerConfigNode<CNC extends LoggerConfigNodeConfig, LoggerType extends AbstractLogger<BaseLoggerConfig>> extends ConfigNode<CNC> {
|
|
@@ -66,8 +68,8 @@ export declare abstract class LoggerConfigNode<CNC extends LoggerConfigNodeConfi
|
|
|
66
68
|
registerTemplate(config: LoggerTemplateConfig): Log;
|
|
67
69
|
}
|
|
68
70
|
export declare class DoNothingAppender extends Log {
|
|
69
|
-
private static
|
|
70
|
-
static get():
|
|
71
|
+
private static _instance;
|
|
72
|
+
static get(): DoNothingAppender;
|
|
71
73
|
private constructor();
|
|
72
74
|
log(payload: {
|
|
73
75
|
[key: string]: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoggerService.d.ts","sourceRoot":"","sources":["../../../../src/core/logger/service/LoggerService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LoggerService.d.ts","sourceRoot":"","sources":["../../../../src/core/logger/service/LoggerService.ts"],"names":[],"mappings":"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"}
|