@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
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Node, NodeAPI, NodeDef, NodeAPISettingsWithData} from "node-red";
|
|
1
|
+
import { Node, NodeAPI, NodeAPISettingsWithData} from "node-red";
|
|
3
2
|
import { INamedType, INodeClass, ITemplateClass } from "./NodeGenerator";
|
|
4
3
|
|
|
5
4
|
import "reflect-metadata";
|
|
6
|
-
import jsdom from "jsdom";
|
|
7
5
|
import fs from 'fs';
|
|
8
|
-
import beautify from 'js-beautify';
|
|
9
|
-
import markdownit from 'markdown-it'
|
|
10
|
-
import Handlebars, { template } from "handlebars";
|
|
11
|
-
import { NodeTypeService } from "./tagging/service/NodeTypeService";
|
|
12
6
|
|
|
7
|
+
import {
|
|
8
|
+
NODEMANAGER_API_VERSION,
|
|
9
|
+
POST_CONSTRUCT_KEY,
|
|
10
|
+
BaseNodeConfig,
|
|
11
|
+
runPostConstructInitializers,
|
|
12
|
+
NodeManager
|
|
13
|
+
} from "./NodeManagerRuntime";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// Re-export so existing downstream code keeps working unchanged.
|
|
16
|
+
export {
|
|
17
|
+
NODEMANAGER_API_VERSION,
|
|
18
|
+
POST_CONSTRUCT_KEY,
|
|
19
|
+
BaseNodeConfig,
|
|
20
|
+
runPostConstructInitializers,
|
|
21
|
+
NodeManager
|
|
22
|
+
};
|
|
20
23
|
|
|
21
24
|
export abstract class BaseNode<Config extends BaseNodeConfig> {
|
|
22
25
|
|
|
@@ -198,8 +201,6 @@ export abstract class Template{
|
|
|
198
201
|
|
|
199
202
|
type VoidMethod = (...args: any[]) => void | Promise<void>;
|
|
200
203
|
|
|
201
|
-
const POST_CONSTRUCT_KEY = Symbol('postConstructInitializers');
|
|
202
|
-
|
|
203
204
|
// Builder class for post-construct decorators
|
|
204
205
|
class PostConstructDecoratorBuilder<TMetadata = any> {
|
|
205
206
|
private decoratorName: string;
|
|
@@ -341,143 +342,6 @@ export function createPostConstructDecorator<TMetadata = any>(decoratorName: str
|
|
|
341
342
|
return new PostConstructDecoratorBuilder<TMetadata>(decoratorName);
|
|
342
343
|
}
|
|
343
344
|
|
|
344
|
-
// Single function to run all post-construct initializers
|
|
345
|
-
let runPostConstructInitializers = function(instance: any) {
|
|
346
|
-
const initializers = instance[POST_CONSTRUCT_KEY];
|
|
347
|
-
if (initializers && initializers.length > 0) {
|
|
348
|
-
const className = instance.constructor.name;
|
|
349
|
-
//console.log(`Running ${initializers.length} post-construct initializers for ${className}`);
|
|
350
|
-
|
|
351
|
-
initializers.forEach((init: Function, index: number) => {
|
|
352
|
-
try {
|
|
353
|
-
init(instance);
|
|
354
|
-
} catch (error) {
|
|
355
|
-
console.error(
|
|
356
|
-
`Post-construct initialization failed:\n` +
|
|
357
|
-
` Class: ${className}\n` +
|
|
358
|
-
` Initializer: ${index + 1}/${initializers.length}\n` +
|
|
359
|
-
` Error: ${error instanceof Error ? error.message : String(error)}`
|
|
360
|
-
);
|
|
361
|
-
throw error;
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
// Clear the initializers after running
|
|
366
|
-
delete instance[POST_CONSTRUCT_KEY];
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
// ************************************************
|
|
371
|
-
|
|
372
|
-
export class NodeManager{
|
|
373
|
-
private static PLUGINID = "node-red-contrib-theotherwillembotha/services-plugin";
|
|
374
|
-
private static _RED: NodeAPI<NodeAPISettingsWithData>;
|
|
375
|
-
|
|
376
|
-
private nodeTypeService:NodeTypeService;
|
|
377
|
-
private typeBacklog:INodeClass[] = []
|
|
378
|
-
|
|
379
|
-
public constructor(RED : NodeAPI<NodeAPISettingsWithData>){
|
|
380
|
-
NodeManager._RED = RED;
|
|
381
|
-
|
|
382
|
-
let nodeTypeServiceListener = async (pluginID:String) => {
|
|
383
|
-
if(pluginID === "@theotherwillembotha/nodetypeservice"){
|
|
384
|
-
// disable the listener- the plugin has been installed.
|
|
385
|
-
RED.events.off('plugin.instantiated', nodeTypeServiceListener)
|
|
386
|
-
|
|
387
|
-
// get a handle on the NodeTypeService
|
|
388
|
-
let plugin = RED.plugins.get("@theotherwillembotha/nodetypeservice") as any;
|
|
389
|
-
this.nodeTypeService = (RED.plugins.get("@theotherwillembotha/nodetypeservice") as any).instance as NodeTypeService;
|
|
390
|
-
|
|
391
|
-
// process the backlog.
|
|
392
|
-
for(let nodeType of this.typeBacklog){
|
|
393
|
-
for(let tag of nodeType.getNodeDescriptor().tags()){
|
|
394
|
-
this.nodeTypeService.registerNodeType(tag, nodeType);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// check if the reverserproxyttypesewrvice is installed yet.
|
|
401
|
-
this.nodeTypeService = (RED.plugins.get("@theotherwillembotha/nodetypeservice") as any).instance as NodeTypeService;
|
|
402
|
-
if(!this.nodeTypeService) {
|
|
403
|
-
RED.events.on('plugin.instantiated', nodeTypeServiceListener);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
public static get RED() {
|
|
408
|
-
return NodeManager._RED;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
public registerService(type:IServiceClass):NodeManager{
|
|
412
|
-
let servicePlugin:any = NodeManager.RED.plugins.get(NodeManager.PLUGINID) as PluginDefinition<any>;
|
|
413
|
-
if(servicePlugin){
|
|
414
|
-
servicePlugin.instance.install(NodeManager.RED, type);
|
|
415
|
-
}
|
|
416
|
-
else{
|
|
417
|
-
let serviceName = `${type.getServiceDescriptor().sourceFile()}.${type.getServiceDescriptor().name()}`;
|
|
418
|
-
console.log(`ERROR: plugin ${NodeManager.PLUGINID} does not seem to be loaded. Cannot start service: ${serviceName}`);
|
|
419
|
-
}
|
|
420
|
-
return this;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
public registerNodeType(typeName: string, type: INodeClass):NodeManager{
|
|
424
|
-
if(!type){
|
|
425
|
-
console.error(`Type "${typeName}" has no associated type. Make sure that it was exported and included in the index.js file!`)
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
let nodeConstructor = function(this: any, config: BaseNodeConfig | NodeDef){
|
|
429
|
-
//console.log("constructing node", typeName);
|
|
430
|
-
|
|
431
|
-
try{
|
|
432
|
-
// instantiate the node.
|
|
433
|
-
NodeManager.RED.nodes.createNode(this, config as any as NodeDef);
|
|
434
|
-
// assign an instance of it to the config.
|
|
435
|
-
//(config as any).__node = this;
|
|
436
|
-
|
|
437
|
-
// instatiate the actual node.
|
|
438
|
-
let node = new (type as any)(this, config);
|
|
439
|
-
//this.__node = node;
|
|
440
|
-
|
|
441
|
-
// run the constructor initializers.
|
|
442
|
-
runPostConstructInitializers(node);
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
// after the node has been instantiated, attempt to invole the onInit method.
|
|
446
|
-
if(node.onInit){
|
|
447
|
-
node.onInit();
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
catch(error){
|
|
451
|
-
console.log(error);
|
|
452
|
-
console.log("typeName:", typeName)
|
|
453
|
-
console.log("type:", type)
|
|
454
|
-
console.log("config:", config)
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
try{
|
|
459
|
-
NodeManager.RED.nodes.registerType(typeName, nodeConstructor, { settings: {}});
|
|
460
|
-
|
|
461
|
-
let nodeDescription = type.getNodeDescriptor();
|
|
462
|
-
|
|
463
|
-
// registger the node tags.
|
|
464
|
-
if(this.nodeTypeService){
|
|
465
|
-
for(let tag of nodeDescription.tags()){
|
|
466
|
-
this.nodeTypeService.registerNodeType(tag, type);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
else{
|
|
470
|
-
this.typeBacklog.push(type);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
catch(error){
|
|
475
|
-
console.error("registering node: " + typeName + " failed", error);
|
|
476
|
-
}
|
|
477
|
-
return this;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
345
|
export type FlowDeployment = {
|
|
482
346
|
rev:string,
|
|
483
347
|
flows:[FlowElement]
|
|
@@ -513,25 +377,27 @@ export abstract class BaseService {
|
|
|
513
377
|
}
|
|
514
378
|
}
|
|
515
379
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
}
|
|
380
|
+
// Build-time deps - lazy loaded so they are never required at runtime in production bundles.
|
|
381
|
+
// These are only invoked during `npm run build` (GenerateNodes), never in the deployed container.
|
|
382
|
+
function getJSDOM(): any { return require('jsdom').JSDOM; }
|
|
383
|
+
function getBeautify(): any { return require('js-beautify'); }
|
|
384
|
+
function getHandlebars(): any { return require('handlebars'); }
|
|
385
|
+
|
|
386
|
+
let _md: any = null;
|
|
387
|
+
function getMd(): any {
|
|
388
|
+
if (!_md) {
|
|
389
|
+
_md = require('markdown-it')({ html: true, linkify: true, typographer: true });
|
|
390
|
+
_md.renderer.rules.heading_open = (tokens: any[], idx: number) => {
|
|
391
|
+
const level = tokens[idx].tag.substring(1);
|
|
392
|
+
return `<h${level} class="custom-heading">`;
|
|
393
|
+
};
|
|
394
|
+
_md.renderer.rules.heading_close = (tokens: any[], idx: number) => {
|
|
395
|
+
const level = tokens[idx].tag.substring(1);
|
|
396
|
+
return `</h${level}>`;
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
return _md;
|
|
400
|
+
}
|
|
535
401
|
|
|
536
402
|
let beautifyOptions = {
|
|
537
403
|
"indent_size": 4,
|
|
@@ -591,7 +457,7 @@ export class NodeBuilder {
|
|
|
591
457
|
}
|
|
592
458
|
|
|
593
459
|
public addDefault(name:string, template:DefaultTemplateType):NodeBuilder{
|
|
594
|
-
// if list:true, this is an array of config references
|
|
460
|
+
// if list:true, this is an array of config references - generate shadow defaults for each slot.
|
|
595
461
|
if(template.list === true) {
|
|
596
462
|
template.maxInstances = template.maxInstances ? template.maxInstances : 10;
|
|
597
463
|
this._defaults[name] = {value:"", required:(template.required) ? template.required : false, maxInstances:template.maxInstances};
|
|
@@ -641,9 +507,10 @@ export class NodeBuilder {
|
|
|
641
507
|
|
|
642
508
|
public addTemplate(template: { template: ITemplateClass; config: TemplateConfig; }): NodeBuilder {
|
|
643
509
|
let templateDescriptor = template.template.getTemplateDescriptor();
|
|
510
|
+
let templateConfig = template.config;
|
|
644
511
|
|
|
645
512
|
// load the html source file
|
|
646
|
-
let uiDom = new
|
|
513
|
+
let uiDom = new (getJSDOM())(fs.readFileSync(templateDescriptor.templateFile()!));
|
|
647
514
|
|
|
648
515
|
// apply the onCompose section if available.
|
|
649
516
|
let onCompose = uiDom.window.document.querySelector("script[template-section='onCompose']")?.innerHTML;
|
|
@@ -655,7 +522,16 @@ export class NodeBuilder {
|
|
|
655
522
|
let sections:string[] = ['IncludeOnce', 'IncludeEditPrepare', 'IncludeEditSave', 'IncludeEditCancel', 'IncludeEditDelete', 'IncludeEditForm', 'IncludeDocumentation'];
|
|
656
523
|
Object.values(sections).forEach(section => {
|
|
657
524
|
let sectionData = uiDom.window.document.querySelector(`[template-section='on${section}']`)?.innerHTML;
|
|
525
|
+
|
|
658
526
|
if(sectionData){
|
|
527
|
+
if(section !== "IncludeOnce" && section !== "IncludeEditForm" && section !== "IncludeDocumentation") {
|
|
528
|
+
// add the packageing around the sectionData
|
|
529
|
+
sectionData = `{
|
|
530
|
+
let node = this;
|
|
531
|
+
let templateConfig = ${JSON.stringify(templateConfig)};
|
|
532
|
+
${sectionData}
|
|
533
|
+
}`;
|
|
534
|
+
}
|
|
659
535
|
(this as any)[`add${section}`](templateDescriptor.name(), sectionData);
|
|
660
536
|
}
|
|
661
537
|
});
|
|
@@ -698,6 +574,85 @@ export class NodeBuilder {
|
|
|
698
574
|
return this;
|
|
699
575
|
}
|
|
700
576
|
|
|
577
|
+
public buildOnceHtml(): {source: string, html: string}[] {
|
|
578
|
+
return this._onIncludeOnce.map(entry => ({
|
|
579
|
+
source: entry.source,
|
|
580
|
+
html: this.serializeHTML(entry.source, entry.script)
|
|
581
|
+
}));
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
private applyShaddowDefaults(): void {
|
|
585
|
+
let shaddowDefaults = Object.entries(this._defaults).filter(([name, template]) => template.type && template.type.endsWith("[]"));
|
|
586
|
+
if (shaddowDefaults.length > 0) {
|
|
587
|
+
this.addIncludeEditSave(this._name + "_shaddowDefaults",
|
|
588
|
+
`{ let node = this; ` +
|
|
589
|
+
shaddowDefaults
|
|
590
|
+
.map(([name, template]) => `
|
|
591
|
+
for(let i = 0; i < ${template.maxInstances}; i++){
|
|
592
|
+
node["_${name}_" + i] = (node.${name}[i] || {}).proxy || "";
|
|
593
|
+
}`)
|
|
594
|
+
.join("\n\n") +
|
|
595
|
+
`}`
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
private buildRegisterTypeBody(): string {
|
|
601
|
+
return `{
|
|
602
|
+
category: '${this._category}',
|
|
603
|
+
${(this._category !== "config" && this._icon) ? `icon: '${this._icon}',` : ""}
|
|
604
|
+
${(this._category !== "config" && this._color) ? `color: '${this._color}',` : ""}
|
|
605
|
+
${(this._category !== "config" && this._labelStyle) ? `labelStyle: '${this._labelStyle}',` : ""}
|
|
606
|
+
${(this._label) ? `label: ${this._label},` : ""}
|
|
607
|
+
${this._paletteLabel ? `paletteLabel: '${this._paletteLabel}',` : ""}
|
|
608
|
+
${(this._category !== "config") ? `inputs:${this._inputs ? "1" : "0"},` : ""}
|
|
609
|
+
${(this._category !== "config") ? `inputLabels:(i) => '${this._inputs}',` : ""}
|
|
610
|
+
${(this._category !== "config") ? `outputs:${this._outputs.length},` : ""}
|
|
611
|
+
${(this._category !== "config") ? `outputLabels:(i) => ${this.serializeProperty(this._outputs)}[i],` : ""}
|
|
612
|
+
defaults: {
|
|
613
|
+
${Object.entries(this._defaults).map(([key, value]) => this.serializeDefault(key, value)).join("\n")}
|
|
614
|
+
},
|
|
615
|
+
oneditprepare: function() {
|
|
616
|
+
${this._onIncludeEditPrepare.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
617
|
+
},
|
|
618
|
+
oneditsave: function() {
|
|
619
|
+
${this._onIncludeEditSave.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
620
|
+
},
|
|
621
|
+
oneditcancel: function() {
|
|
622
|
+
${this._onIncludeEditCancel.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
623
|
+
},
|
|
624
|
+
oneditdelete: function() {
|
|
625
|
+
${this._onIncludeEditDelete.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
626
|
+
},
|
|
627
|
+
}`;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
public buildDeferredType(): string {
|
|
631
|
+
this.applyShaddowDefaults();
|
|
632
|
+
const registerTypeBody = this.buildRegisterTypeBody();
|
|
633
|
+
|
|
634
|
+
return getBeautify().html_beautify(`
|
|
635
|
+
<script type="text/javascript">
|
|
636
|
+
(function () {
|
|
637
|
+
RED.events.on('registry:node-set-added', function (ns) {
|
|
638
|
+
if (ns.types && ns.types.indexOf('${this._name}') !== -1) {
|
|
639
|
+
RED.nodes.registerType('${this._name}', ${registerTypeBody});
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
}());
|
|
643
|
+
</script>`, beautifyOptions);
|
|
644
|
+
}
|
|
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
|
+
|
|
701
656
|
private serializeProperty(value:any):string{
|
|
702
657
|
switch(typeof value){
|
|
703
658
|
case "boolean": {
|
|
@@ -730,18 +685,18 @@ export class NodeBuilder {
|
|
|
730
685
|
}
|
|
731
686
|
|
|
732
687
|
return `<!-- ${source} -->
|
|
733
|
-
${
|
|
688
|
+
${getHandlebars().compile(script)(context)}
|
|
734
689
|
`
|
|
735
690
|
}
|
|
736
691
|
|
|
737
|
-
private serializeJavaScript(source:string, script:string):string{
|
|
692
|
+
private serializeJavaScript(source:string, script:string):string{
|
|
738
693
|
let context = {
|
|
739
|
-
defaults: (this._category === "config")
|
|
694
|
+
defaults: (this._category === "config")
|
|
740
695
|
? Object.fromEntries(Object.keys(this._defaults).map(k => [k, `node-config-input-${k}`]))
|
|
741
696
|
: Object.fromEntries(Object.keys(this._defaults).map(k => [k, `node-input-${k}`]))
|
|
742
697
|
}
|
|
743
698
|
|
|
744
|
-
let serialized =
|
|
699
|
+
let serialized = getHandlebars().compile(script)(context).trim();
|
|
745
700
|
if(!serialized.startsWith("{") && !serialized.endsWith("}")){
|
|
746
701
|
serialized = "{\n" + serialized + "\n}";
|
|
747
702
|
}
|
|
@@ -751,14 +706,14 @@ export class NodeBuilder {
|
|
|
751
706
|
`
|
|
752
707
|
}
|
|
753
708
|
|
|
754
|
-
private serializeFormEntry(source:string, script:string):string{
|
|
709
|
+
private serializeFormEntry(source:string, script:string):string{
|
|
755
710
|
let context = {
|
|
756
|
-
defaults: (this._category === "config")
|
|
711
|
+
defaults: (this._category === "config")
|
|
757
712
|
? Object.fromEntries(Object.keys(this._defaults).map(k => [k, `node-config-input-${k}`]))
|
|
758
713
|
: Object.fromEntries(Object.keys(this._defaults).map(k => [k, `node-input-${k}`]))
|
|
759
714
|
}
|
|
760
715
|
return `
|
|
761
|
-
<div id='section_${source}'>${
|
|
716
|
+
<div id='section_${source}'>${getHandlebars().compile(script)(context)}
|
|
762
717
|
</div>
|
|
763
718
|
`
|
|
764
719
|
}
|
|
@@ -771,57 +726,19 @@ export class NodeBuilder {
|
|
|
771
726
|
return script;
|
|
772
727
|
}
|
|
773
728
|
|
|
774
|
-
public buildType():string{
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
if(shaddowDefaults.length > 0){
|
|
778
|
-
this.addIncludeEditSave(this._name + "_shaddowDefaults",
|
|
779
|
-
`{ let node = this; ` +
|
|
780
|
-
shaddowDefaults
|
|
781
|
-
.map(([name, template]) => `
|
|
782
|
-
for(let i = 0; i < ${template.maxInstances}; i++){
|
|
783
|
-
node["_${name}_" + i] = (node.${name}[i] || {}).proxy || "";
|
|
784
|
-
}`)
|
|
785
|
-
.join("\n\n") +
|
|
786
|
-
`}`
|
|
787
|
-
);
|
|
788
|
-
}
|
|
729
|
+
public buildType():string{
|
|
730
|
+
this.applyShaddowDefaults();
|
|
731
|
+
const registerTypeBody = this.buildRegisterTypeBody();
|
|
789
732
|
|
|
790
|
-
return
|
|
733
|
+
return getBeautify().html_beautify(`
|
|
791
734
|
${this._onIncludeOnce.map(entry => this.serializeHTML(entry.source, entry.script)).join("")}
|
|
792
735
|
<script type="text/javascript">
|
|
793
|
-
RED.nodes.registerType('${this._name}',{
|
|
794
|
-
category: '${this._category}',
|
|
795
|
-
${(this._category !== "config" && this._icon) ? `icon: '${this._icon}',` : ""}
|
|
796
|
-
${(this._category !== "config" && this._color) ? `color: '${this._color}',` : ""}
|
|
797
|
-
${(this._category !== "config" && this._labelStyle) ? `labelStyle: '${this._labelStyle}',` : ""}
|
|
798
|
-
${(this._label) ? `label: ${this._label},` : ""}
|
|
799
|
-
${this._paletteLabel ? `paletteLabel: '${this._paletteLabel}',` : ""}
|
|
800
|
-
${(this._category !== "config") ? `inputs:${this._inputs ? "1" : "0"},` : ""}
|
|
801
|
-
${(this._category !== "config") ? `inputLabels:(i) => '${this._inputs}',` : ""}
|
|
802
|
-
${(this._category !== "config") ? `outputs:${this._outputs.length},` : ""}
|
|
803
|
-
${(this._category !== "config") ? `outputLabels:(i) => ${this.serializeProperty(this._outputs)}[i],` : ""}
|
|
804
|
-
defaults: {
|
|
805
|
-
${Object.entries(this._defaults).map(([key, value]) => this.serializeDefault(key, value)).join("\n")}
|
|
806
|
-
},
|
|
807
|
-
oneditprepare: function() {
|
|
808
|
-
${this._onIncludeEditPrepare.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
809
|
-
},
|
|
810
|
-
oneditsave: function() {
|
|
811
|
-
${this._onIncludeEditSave.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
812
|
-
},
|
|
813
|
-
oneditcancel: function() {
|
|
814
|
-
${this._onIncludeEditCancel.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
815
|
-
},
|
|
816
|
-
oneditdelete: function() {
|
|
817
|
-
${this._onIncludeEditDelete.map(entry => this.serializeJavaScript(entry.source, entry.script)).join("")}
|
|
818
|
-
},
|
|
819
|
-
});
|
|
736
|
+
RED.nodes.registerType('${this._name}', ${registerTypeBody});
|
|
820
737
|
</script>`, beautifyOptions);
|
|
821
738
|
};
|
|
822
739
|
|
|
823
740
|
public buildHtml():string{
|
|
824
|
-
return
|
|
741
|
+
return getBeautify().html_beautify(`
|
|
825
742
|
<script type="text/html" data-template-name='${this._name}'>
|
|
826
743
|
${this._onIncludeEditForm.map(entry => this.serializeFormEntry(entry.source, entry.script)).join("")}
|
|
827
744
|
</script>
|
|
@@ -854,13 +771,13 @@ let evalInContext = (context: any, js: string) => {
|
|
|
854
771
|
}
|
|
855
772
|
};
|
|
856
773
|
|
|
857
|
-
let
|
|
774
|
+
let buildNodeBuilder = function(node: INodeClass): NodeBuilder {
|
|
858
775
|
// get the node descriptor and create the builder.
|
|
859
776
|
let nodeDescriptor = node.getNodeDescriptor();
|
|
860
777
|
let nodeBuilder = new NodeBuilder(nodeDescriptor.id(), nodeDescriptor.group());
|
|
861
778
|
|
|
862
779
|
// load the html source file
|
|
863
|
-
let uiDom = new
|
|
780
|
+
let uiDom = new (getJSDOM())(fs.readFileSync(nodeDescriptor.sourceFile()));
|
|
864
781
|
|
|
865
782
|
// apply the onCompose section if available.
|
|
866
783
|
let onCompose = uiDom.window.document.querySelector("script[template-section='onCompose']")?.innerHTML;
|
|
@@ -880,10 +797,15 @@ let buildNode = function(node:INodeClass){
|
|
|
880
797
|
// add some of the dependencies here.
|
|
881
798
|
nodeDescriptor.templates().forEach(template => nodeBuilder.addTemplate(template));
|
|
882
799
|
|
|
883
|
-
return
|
|
800
|
+
return nodeBuilder;
|
|
801
|
+
}
|
|
884
802
|
|
|
803
|
+
let buildNode = function(node:INodeClass){
|
|
804
|
+
let nodeBuilder = buildNodeBuilder(node);
|
|
805
|
+
return [nodeBuilder.buildType(), nodeBuilder.buildHtml(), nodeBuilder.buildDocumentation()].join("\n\n");
|
|
885
806
|
}
|
|
886
807
|
|
|
887
808
|
export {
|
|
888
|
-
buildNode
|
|
809
|
+
buildNode,
|
|
810
|
+
buildNodeBuilder
|
|
889
811
|
}
|