@theotherwillembotha/node-red-plugincore 0.0.50
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/LICENSE +15 -0
- package/README.md +190 -0
- package/build/GenerateNodes.d.ts +2 -0
- package/build/GenerateNodes.d.ts.map +1 -0
- package/build/GenerateNodes.js +36 -0
- package/build/Nodes.html +1729 -0
- package/build/Nodes.js +32 -0
- package/build/Plugins.js +74 -0
- package/build/core/NodeConstructor.d.ts +188 -0
- package/build/core/NodeConstructor.d.ts.map +1 -0
- package/build/core/NodeConstructor.js +679 -0
- package/build/core/NodeGenerator.d.ts +37 -0
- package/build/core/NodeGenerator.d.ts.map +1 -0
- package/build/core/NodeGenerator.js +300 -0
- package/build/core/Utils.d.ts +7 -0
- package/build/core/Utils.d.ts.map +1 -0
- package/build/core/Utils.js +19 -0
- package/build/core/logger/LoggerDecorator.d.ts +2 -0
- package/build/core/logger/LoggerDecorator.d.ts.map +1 -0
- package/build/core/logger/LoggerDecorator.js +93 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +16 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
- package/build/core/logger/node/ConsoleLoggerConfigNode.js +47 -0
- package/build/core/logger/node/LoggerConfigNode.d.ts +30 -0
- package/build/core/logger/node/LoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/LoggerConfigNode.html +307 -0
- package/build/core/logger/node/LoggerConfigNode.js +60 -0
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts +20 -0
- package/build/core/logger/node/LokiLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/LokiLoggerConfigNode.html +153 -0
- package/build/core/logger/node/LokiLoggerConfigNode.js +52 -0
- package/build/core/logger/node/RestLoggerConfigNode.d.ts +24 -0
- package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +1 -0
- package/build/core/logger/node/RestLoggerConfigNode.html +209 -0
- package/build/core/logger/node/RestLoggerConfigNode.js +57 -0
- package/build/core/logger/service/LoggerService.d.ts +88 -0
- package/build/core/logger/service/LoggerService.d.ts.map +1 -0
- package/build/core/logger/service/LoggerService.js +204 -0
- package/build/core/logger/service/LoggerServiceTypes.d.ts +24 -0
- package/build/core/logger/service/LoggerServiceTypes.d.ts.map +1 -0
- package/build/core/logger/service/LoggerServiceTypes.js +30 -0
- package/build/core/logger/template/LoggerTemplate.d.ts +11 -0
- package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -0
- package/build/core/logger/template/LoggerTemplate.html +328 -0
- package/build/core/logger/template/LoggerTemplate.js +12 -0
- package/build/core/metrics/MetricsDecorator.d.ts +40 -0
- package/build/core/metrics/MetricsDecorator.d.ts.map +1 -0
- package/build/core/metrics/MetricsDecorator.js +166 -0
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts +16 -0
- package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/CounterMetricConfigNode.html +48 -0
- package/build/core/metrics/node/CounterMetricConfigNode.js +61 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts +17 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.html +48 -0
- package/build/core/metrics/node/GaugeMetricConfigNode.js +61 -0
- package/build/core/metrics/node/MetricsConfigNode.d.ts +14 -0
- package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/MetricsConfigNode.html +21 -0
- package/build/core/metrics/node/MetricsConfigNode.js +56 -0
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts +28 -0
- package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -0
- package/build/core/metrics/node/TimerMetricConfigNode.html +190 -0
- package/build/core/metrics/node/TimerMetricConfigNode.js +101 -0
- package/build/core/metrics/service/MetricsService.d.ts +187 -0
- package/build/core/metrics/service/MetricsService.d.ts.map +1 -0
- package/build/core/metrics/service/MetricsService.js +385 -0
- package/build/core/metrics/template/CounterMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/CounterMetricTemplate.html +40 -0
- package/build/core/metrics/template/CounterMetricTemplate.js +12 -0
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/GaugeMetricTemplate.html +39 -0
- package/build/core/metrics/template/GaugeMetricTemplate.js +12 -0
- package/build/core/metrics/template/MetricsTemplate.d.ts +8 -0
- package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/MetricsTemplate.html +54 -0
- package/build/core/metrics/template/MetricsTemplate.js +12 -0
- package/build/core/metrics/template/TimerMetricTemplate.d.ts +5 -0
- package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -0
- package/build/core/metrics/template/TimerMetricTemplate.html +39 -0
- package/build/core/metrics/template/TimerMetricTemplate.js +12 -0
- package/build/core/other/InputDecorator.d.ts +3 -0
- package/build/core/other/InputDecorator.d.ts.map +1 -0
- package/build/core/other/InputDecorator.js +43 -0
- package/build/core/other/service/InputService.d.ts +16 -0
- package/build/core/other/service/InputService.d.ts.map +1 -0
- package/build/core/other/service/InputService.js +31 -0
- package/build/core/other/service/SettingsService.d.ts +25 -0
- package/build/core/other/service/SettingsService.d.ts.map +1 -0
- package/build/core/other/service/SettingsService.js +74 -0
- package/build/core/other/template/BasicTemplate.d.ts +5 -0
- package/build/core/other/template/BasicTemplate.d.ts.map +1 -0
- package/build/core/other/template/BasicTemplate.html +76 -0
- package/build/core/other/template/BasicTemplate.js +11 -0
- package/build/core/other/template/SettingsTemplate.d.ts +5 -0
- package/build/core/other/template/SettingsTemplate.d.ts.map +1 -0
- package/build/core/other/template/SettingsTemplate.html +128 -0
- package/build/core/other/template/SettingsTemplate.js +11 -0
- package/build/core/tagging/NodeDescriptionDecorator.d.ts +17 -0
- package/build/core/tagging/NodeDescriptionDecorator.d.ts.map +1 -0
- package/build/core/tagging/NodeDescriptionDecorator.js +25 -0
- package/build/core/tagging/service/NodeTypeService.d.ts +15 -0
- package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -0
- package/build/core/tagging/service/NodeTypeService.js +47 -0
- package/build/core/webhook/WebhookDecorator.d.ts +3 -0
- package/build/core/webhook/WebhookDecorator.d.ts.map +1 -0
- package/build/core/webhook/WebhookDecorator.js +45 -0
- package/build/core/webhook/node/WebhookServerConfigNode.d.ts +16 -0
- package/build/core/webhook/node/WebhookServerConfigNode.d.ts.map +1 -0
- package/build/core/webhook/node/WebhookServerConfigNode.html +61 -0
- package/build/core/webhook/node/WebhookServerConfigNode.js +40 -0
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts +29 -0
- package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -0
- package/build/core/webhook/service/ReverseProxyTypeService.js +24 -0
- package/build/core/webhook/service/WebhookServerService.d.ts +52 -0
- package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -0
- package/build/core/webhook/service/WebhookServerService.js +146 -0
- package/build/core/webhook/template/WebhookTemplate.d.ts +22 -0
- package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -0
- package/build/core/webhook/template/WebhookTemplate.html +434 -0
- package/build/core/webhook/template/WebhookTemplate.js +12 -0
- package/build/index.d.ts +33 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +55 -0
- package/package.json +67 -0
- package/src/GenerateNodes.ts +42 -0
- package/src/core/NodeConstructor.ts +889 -0
- package/src/core/NodeGenerator.ts +331 -0
- package/src/core/Utils.ts +19 -0
- package/src/core/logger/LoggerDecorator.ts +105 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
- package/src/core/logger/node/ConsoleLoggerConfigNode.ts +46 -0
- package/src/core/logger/node/LoggerConfigNode.html +307 -0
- package/src/core/logger/node/LoggerConfigNode.ts +95 -0
- package/src/core/logger/node/LokiLoggerConfigNode.html +153 -0
- package/src/core/logger/node/LokiLoggerConfigNode.ts +58 -0
- package/src/core/logger/node/RestLoggerConfigNode.html +209 -0
- package/src/core/logger/node/RestLoggerConfigNode.ts +67 -0
- package/src/core/logger/service/LoggerService.ts +317 -0
- package/src/core/logger/service/LoggerServiceTypes.ts +26 -0
- package/src/core/logger/template/LoggerTemplate.html +328 -0
- package/src/core/logger/template/LoggerTemplate.ts +23 -0
- package/src/core/metrics/MetricsDecorator.ts +227 -0
- package/src/core/metrics/node/CounterMetricConfigNode.html +48 -0
- package/src/core/metrics/node/CounterMetricConfigNode.ts +62 -0
- package/src/core/metrics/node/GaugeMetricConfigNode.html +48 -0
- package/src/core/metrics/node/GaugeMetricConfigNode.ts +62 -0
- package/src/core/metrics/node/MetricsConfigNode.html +21 -0
- package/src/core/metrics/node/MetricsConfigNode.ts +55 -0
- package/src/core/metrics/node/TimerMetricConfigNode.html +190 -0
- package/src/core/metrics/node/TimerMetricConfigNode.ts +118 -0
- package/src/core/metrics/service/MetricsService.ts +560 -0
- package/src/core/metrics/template/CounterMetricTemplate.html +40 -0
- package/src/core/metrics/template/CounterMetricTemplate.ts +15 -0
- package/src/core/metrics/template/GaugeMetricTemplate.html +39 -0
- package/src/core/metrics/template/GaugeMetricTemplate.ts +15 -0
- package/src/core/metrics/template/MetricsTemplate.html +54 -0
- package/src/core/metrics/template/MetricsTemplate.ts +18 -0
- package/src/core/metrics/template/TimerMetricTemplate.html +39 -0
- package/src/core/metrics/template/TimerMetricTemplate.ts +14 -0
- package/src/core/other/InputDecorator.ts +57 -0
- package/src/core/other/service/InputService.ts +36 -0
- package/src/core/other/service/SettingsService.ts +103 -0
- package/src/core/other/template/BasicTemplate.html +76 -0
- package/src/core/other/template/BasicTemplate.ts +15 -0
- package/src/core/other/template/SettingsTemplate.html +128 -0
- package/src/core/other/template/SettingsTemplate.ts +17 -0
- package/src/core/tagging/NodeDescriptionDecorator.ts +39 -0
- package/src/core/tagging/service/NodeTypeService.ts +67 -0
- package/src/core/webhook/WebhookDecorator.ts +70 -0
- package/src/core/webhook/node/WebhookServerConfigNode.html +61 -0
- package/src/core/webhook/node/WebhookServerConfigNode.ts +38 -0
- package/src/core/webhook/service/ReverseProxyTypeService.ts +46 -0
- package/src/core/webhook/service/WebhookServerService.ts +211 -0
- package/src/core/webhook/template/WebhookTemplate.html +434 -0
- package/src/core/webhook/template/WebhookTemplate.ts +36 -0
- package/src/index.ts +47 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script type="text/javascript" template-section="onCompose">
|
|
2
|
+
node
|
|
3
|
+
.addDefault("metricsEnabled", { value:false, required:true})
|
|
4
|
+
.addDefault("metricsReference", {type:"MetricsConfigNode", required:false})
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
8
|
+
let node = this;
|
|
9
|
+
|
|
10
|
+
let metricsEnabled = $("#{{defaults.metricsEnabled}}");
|
|
11
|
+
let metricsEnabledSection = $("#section_metricsEnabled");
|
|
12
|
+
|
|
13
|
+
metricsEnabled.on('change', function() {
|
|
14
|
+
if(metricsEnabled.prop("checked")){
|
|
15
|
+
metricsEnabledSection.show();
|
|
16
|
+
node._def.defaults.metricsReference.required = true;
|
|
17
|
+
}
|
|
18
|
+
else{
|
|
19
|
+
metricsEnabledSection.hide()
|
|
20
|
+
node._def.defaults.metricsReference.required = false;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
26
|
+
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<script type="text/html" template-section="onIncludeEditForm">
|
|
30
|
+
<div id="section_metricsconfig">
|
|
31
|
+
<div class="form-row editorsectionheading">
|
|
32
|
+
<i class="w-16 fa fa-eye"></i> <span>Metrics</span>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="editorgroupborder">
|
|
35
|
+
<div class="form-row nomargin metricsEnableCheck">
|
|
36
|
+
<input type="checkbox" id="{{defaults.metricsEnabled}}" value="false" style="margin:8px 0 10px 102px; width:20px;" />
|
|
37
|
+
<label style="width:auto" for="{{defaults.metricsEnabled}}"><span>Enable Metrics</span></label>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div id="section_metricsEnabled">
|
|
41
|
+
<div class="form-row nomargin">
|
|
42
|
+
<label class="towb_editorlabel" for="{{defaults.metricsReference}}">Metric Collector</label>
|
|
43
|
+
<input id="{{defaults.metricsReference}}" placeholder="metrics" />
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
51
|
+
### Metrics
|
|
52
|
+
: *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
|
|
53
|
+
: *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
+
import { BaseNodeConfig, Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
3
|
+
import { MetricsConfigNode } from "../node/MetricsConfigNode";
|
|
4
|
+
import { MetricsReference } from "../service/MetricsService";
|
|
5
|
+
|
|
6
|
+
export interface MetricsTemplateConfig extends BaseNodeConfig, MetricsReference {
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class MetricsTemplate extends Template {
|
|
10
|
+
|
|
11
|
+
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
12
|
+
return new TemplateDescriptor(
|
|
13
|
+
"metrics",
|
|
14
|
+
MetricsTemplate,
|
|
15
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "MetricsTemplate.html",
|
|
16
|
+
[MetricsConfigNode]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script type="text/javascript" template-section="onCompose">
|
|
2
|
+
node
|
|
3
|
+
.addDefault("timerConfig", { type:"TimerMetricConfigNode", required: true })
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
7
|
+
let metricsEnabled = $("#node-{{#if config.isConfigNode}}config-{{/if}}input-metricsEnabled");
|
|
8
|
+
let metricsEnabledSection = $("#section_metricsEnabled");
|
|
9
|
+
|
|
10
|
+
metricsEnabled.on('change', function() {
|
|
11
|
+
if(metricsEnabled.prop("checked")){
|
|
12
|
+
metricsEnabledSection.show();
|
|
13
|
+
node._def.defaults.metricsReference.required = true;
|
|
14
|
+
}
|
|
15
|
+
else{
|
|
16
|
+
metricsEnabledSection.hide()
|
|
17
|
+
node._def.defaults.metricsReference.required = false;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
23
|
+
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<script type="text/html" template-section="onIncludeEditForm">
|
|
27
|
+
|
|
28
|
+
<div id="section_timermetricconfig">
|
|
29
|
+
<div class="form-row">
|
|
30
|
+
<label for="node-input-timerConfig"><i class="fa fa-tag"></i> Timer</label>
|
|
31
|
+
<input type="text" id="node-input-timerConfig" />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
37
|
+
### Timer
|
|
38
|
+
: *timer* (timerconfig) : the trimer that will be incremented / decremented / observed every time the node is entered.
|
|
39
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
2
|
+
import { Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
3
|
+
import { TimerMetricConfigNode } from "../node/TimerMetricConfigNode";
|
|
4
|
+
|
|
5
|
+
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
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { BaseNode, createPostConstructDecorator } from "../NodeConstructor";
|
|
2
|
+
import { Message } from "../NodeGenerator";
|
|
3
|
+
import { InputService, InputConfig } from "./service/InputService";
|
|
4
|
+
|
|
5
|
+
class OnInputConfig{
|
|
6
|
+
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const onInput = createPostConstructDecorator<OnInputConfig>('onInput')
|
|
10
|
+
// initialize the default decorator with one parameter containing nothing.
|
|
11
|
+
.withDefaultConfig({})
|
|
12
|
+
|
|
13
|
+
// validate that we have at lease 1 parameter for this decorator.
|
|
14
|
+
.withValidator((target, propertyKey, descriptor) => {
|
|
15
|
+
const method = descriptor.value;
|
|
16
|
+
|
|
17
|
+
// Ensure at least one parameter
|
|
18
|
+
if (method.length === 0) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Method must accept at least one parameter (message: {[key:string]: any}).`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Check parameter types via metadata if available
|
|
25
|
+
const paramTypes = Reflect.getMetadata?.('design:paramtypes', target, propertyKey);
|
|
26
|
+
if (paramTypes && paramTypes[0] !== Object) {
|
|
27
|
+
console.warn(
|
|
28
|
+
`First parameter should be of type {[key:string]: any} (object), but got ${paramTypes[0]?.name || 'unknown'}.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
// business logic to initialize the function and wire it to the input service.
|
|
34
|
+
.withInitLogic((instance, propertyKey, onInputConfig:OnInputConfig) => {
|
|
35
|
+
//console.log(`Registering onInput callback`, "PROPERTYKEY", propertyKey, "WEBHOOK CONFIG", onInputConfig, "THIS", this);
|
|
36
|
+
|
|
37
|
+
let node = instance as BaseNode<InputConfig>;
|
|
38
|
+
let nodeConfig = node.config();
|
|
39
|
+
let onInputFunction = instance[propertyKey];
|
|
40
|
+
|
|
41
|
+
InputService.create(instance, nodeConfig, (message, errorHandler) => {
|
|
42
|
+
try{
|
|
43
|
+
let result = onInputFunction.apply(node, [message, errorHandler]);
|
|
44
|
+
if(result instanceof Promise){
|
|
45
|
+
result.catch((error:any) => errorHandler(error));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch(error){
|
|
49
|
+
errorHandler(error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
})
|
|
53
|
+
.build();
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
onInput
|
|
57
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BaseNode, BaseNodeConfig, Template } from "../../NodeConstructor";
|
|
2
|
+
|
|
3
|
+
export class Input{
|
|
4
|
+
constructor(node:BaseNode<BaseNodeConfig>, config:InputConfig, handler:(message:any, errorHandler:(error:any) => void) => void){
|
|
5
|
+
node.node().on("input", function(msg, send, done){
|
|
6
|
+
try{
|
|
7
|
+
handler(msg, done);
|
|
8
|
+
}
|
|
9
|
+
catch(error:any){
|
|
10
|
+
console.log(error);
|
|
11
|
+
done(error);
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class InputService {
|
|
18
|
+
private constructor(){}
|
|
19
|
+
|
|
20
|
+
static create(node:BaseNode<BaseNodeConfig>, config:InputConfig, handler:(message:any, errorHandler:Function) => void):Input{
|
|
21
|
+
return new Input(node, config, handler);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface InputConfig extends BaseNodeConfig {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export abstract class InputHandler {
|
|
30
|
+
public abstract onInput(message:any, errorHandler:Function):void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class InputTemplate extends Template {
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {BaseNode, BaseNodeConfig, BaseService, NodeManager, ServiceDescriptor} from "../../NodeConstructor"
|
|
2
|
+
import { Node, NodeAPI, NodeDef, NodeAPISettingsWithData} from "node-red";
|
|
3
|
+
|
|
4
|
+
export class SettingsService extends BaseService {
|
|
5
|
+
|
|
6
|
+
static create(node:BaseNode<BaseNodeConfig>, config:SettingsConfig): Settings{
|
|
7
|
+
// load the settings from the settings file.
|
|
8
|
+
let settings = NodeManager.RED.settings.get("NodeSettings_" + config.id);
|
|
9
|
+
//console.log("Retriving Settings for: " + "NodeSettings_" + config.id + " value: " + JSON.stringify(settings));
|
|
10
|
+
if(settings === undefined){
|
|
11
|
+
settings = {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return new Settings(settings, config);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
public constructor(){
|
|
18
|
+
super("SettingsService");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public init(red: NodeAPI<NodeAPISettingsWithData>): void {
|
|
22
|
+
|
|
23
|
+
red.httpAdmin.post("/utils/getNodeSettings", red.auth.needsPermission("inject.write"), async function(request,response) {
|
|
24
|
+
let config = request.body;
|
|
25
|
+
|
|
26
|
+
// get the settings for the node.
|
|
27
|
+
let settings = red.settings.get("NodeSettings_" + config.nodeId);
|
|
28
|
+
|
|
29
|
+
// send the response.
|
|
30
|
+
response.send({
|
|
31
|
+
status: "ok",
|
|
32
|
+
settings: settings
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public deinit(red: NodeAPI<NodeAPISettingsWithData>): void {
|
|
38
|
+
red.httpAdmin.post("/utils/getNodeSettings", red.auth.needsPermission("inject.write"), async function(request,response) {
|
|
39
|
+
response.status(404);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static override getServiceDescriptor():ServiceDescriptor {
|
|
44
|
+
return new ServiceDescriptor(
|
|
45
|
+
"@theotherwillembotha/settingsservice",
|
|
46
|
+
"SettingsService",
|
|
47
|
+
"services-plugin",
|
|
48
|
+
"@theotherwillembotha/node-red-plugincore",
|
|
49
|
+
SettingsService
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class Settings{
|
|
55
|
+
|
|
56
|
+
private _settings:any;
|
|
57
|
+
private _config:any;
|
|
58
|
+
|
|
59
|
+
constructor(settings:SettingsConfig, config:SettingsConfig){
|
|
60
|
+
this._settings = settings;
|
|
61
|
+
this._config = config;
|
|
62
|
+
|
|
63
|
+
// if config unchanged, we can update the settings version.
|
|
64
|
+
if(!this.hasChanged()){
|
|
65
|
+
Object.keys(this._settings).forEach(key => this._config[key] = this._settings[key]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
value(key:string):any{
|
|
70
|
+
return this._settings[key];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
values():any{
|
|
74
|
+
return this._settings;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
update(key:string, value:any){
|
|
78
|
+
this._settings[key] = value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
updateAll(value:any){
|
|
82
|
+
this._settings = value;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// the settings are considdered changed if the settingsTimestamp value is different;
|
|
86
|
+
hasChanged():boolean{
|
|
87
|
+
return (this._settings.settingsTimestamp !== this._config.settingsTimestamp);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
persist() {
|
|
91
|
+
NodeManager.RED.settings.set("NodeSettings_" + this._config.id, this._settings);
|
|
92
|
+
//console.log("Persisted Settings for: " + "NodeSettings_" + this._config.id + " value: " + JSON.stringify(this._settings));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
delete(){
|
|
96
|
+
NodeManager.RED.settings.delete("NodeSettings_" + this._config.id);
|
|
97
|
+
//console.log("Deleted Settings for: " + "NodeSettings_" + this._config.id + " value: " + JSON.stringify(this._settings));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface SettingsConfig extends BaseNodeConfig {
|
|
102
|
+
settingsTimestamp:number
|
|
103
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
|
|
2
|
+
<div template-section="onIncludeOnce">
|
|
3
|
+
<!-- BasicTemplate:includeOnce -->
|
|
4
|
+
<style>
|
|
5
|
+
.editorgroupborder {
|
|
6
|
+
border-width:1px;
|
|
7
|
+
border-style:solid;
|
|
8
|
+
border-color:lightgray;
|
|
9
|
+
padding: 3px;
|
|
10
|
+
margin-top: 2px;
|
|
11
|
+
margin-bottom: 2px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.editorsectionheading {
|
|
15
|
+
font-weight: 600;
|
|
16
|
+
margin-bottom:1px !important;
|
|
17
|
+
margin-top:6px !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.nomargin {
|
|
21
|
+
margin-bottom:1px !important;
|
|
22
|
+
margin-top:1px !important;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.slidecontainer {
|
|
26
|
+
width: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.slider {
|
|
30
|
+
-webkit-appearance: none;
|
|
31
|
+
appearance: none;
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 25px;
|
|
34
|
+
background: #d3d3d3;
|
|
35
|
+
outline: none;
|
|
36
|
+
opacity: 0.7;
|
|
37
|
+
-webkit-transition: .2s;
|
|
38
|
+
transition: opacity .2s;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.slider:hover {
|
|
42
|
+
opacity: 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.slider::-webkit-slider-thumb {
|
|
46
|
+
-webkit-appearance: none;
|
|
47
|
+
appearance: none;
|
|
48
|
+
width: 25px;
|
|
49
|
+
height: 25px;
|
|
50
|
+
background: #04AA6D;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.slider::-moz-range-thumb {
|
|
55
|
+
width: 25px;
|
|
56
|
+
height: 25px;
|
|
57
|
+
background: #04AA6D;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
.towb_editorlabel {
|
|
64
|
+
width: 120px !important;
|
|
65
|
+
}
|
|
66
|
+
.towb_editorfield {
|
|
67
|
+
width: 70% !important;
|
|
68
|
+
}
|
|
69
|
+
.towb_editorfield_short {
|
|
70
|
+
width: 30% !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
</style>
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NodeAPI, NodeAPISettingsWithData } from "node-red"
|
|
2
|
+
import { Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
3
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
4
|
+
|
|
5
|
+
export class BasicTemplate extends Template {
|
|
6
|
+
|
|
7
|
+
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
8
|
+
return new TemplateDescriptor(
|
|
9
|
+
"basic",
|
|
10
|
+
BasicTemplate,
|
|
11
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "BasicTemplate.html",
|
|
12
|
+
[]
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
|
|
2
|
+
<script type="text/javascript" template-section="onCompose">
|
|
3
|
+
node
|
|
4
|
+
.addDefault("settingsTimestamp", { value:0})
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div template-section="onIncludeOnce">
|
|
8
|
+
<script type="text/javascript">
|
|
9
|
+
getNodeSettings = function(nodeId, callback){
|
|
10
|
+
console.log("Rerieving settings for node id: " + nodeId);
|
|
11
|
+
|
|
12
|
+
$.ajax({
|
|
13
|
+
url: "utils/getNodeSettings" ,
|
|
14
|
+
type: "POST",
|
|
15
|
+
data: JSON.stringify({nodeId:nodeId}),
|
|
16
|
+
contentType: "application/json; charset=utf-8",
|
|
17
|
+
success: function (response) {
|
|
18
|
+
callback(response.settings);
|
|
19
|
+
},
|
|
20
|
+
error: function (jqXHR, textStatus, errorThrown) {
|
|
21
|
+
console.log(jqXHR);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
handleNodeSettings = function(node){
|
|
27
|
+
|
|
28
|
+
// if "settingsTimestamp" is "0" then there shouldnt be any settings to retrieve.
|
|
29
|
+
if(node.settingsTimestamp === undefined || node.settingsTimestamp === 0){
|
|
30
|
+
console.log("settingstimestamp = 0. No settings to retrieve");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// if "settingsTimestamp" is not "0", retieve the settings.
|
|
35
|
+
console.log("settingstimestamp != 0. Load settings");
|
|
36
|
+
getNodeSettings(node.id, settings => {
|
|
37
|
+
//console.log("settings retrieved: " + JSON.stringify(settings, null, 2));
|
|
38
|
+
// if the settings is undefined, it means that the node has not been persisted yet.
|
|
39
|
+
if(settings === undefined){
|
|
40
|
+
console.log("no settings retrieved");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log("Settings timestamp: " + settings.settingsTimestamp);
|
|
45
|
+
console.log("Node timestamp: " + node.settingsTimestamp);
|
|
46
|
+
|
|
47
|
+
if(settings.settingsTimestamp !== node.settingsTimestamp){
|
|
48
|
+
// if "settingsTimestamp" is different than the one that was returned by getSettings(),
|
|
49
|
+
// then dont replace the current values with settings.
|
|
50
|
+
console.log("config timestamp different than settings timestamp. no update")
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// TODO:
|
|
55
|
+
// if "settingsTimestamp" is the same as the one returned by getSettings(), then replace the config values with those from settings.
|
|
56
|
+
console.log("Replacing Settings");
|
|
57
|
+
|
|
58
|
+
// go through the defaults and find the elements and their types that are assigned to them.
|
|
59
|
+
let inputValueSetters = {
|
|
60
|
+
"text" : (input, value) => { input.val(value) },
|
|
61
|
+
"number" : (input, value) => { input.val(value) },
|
|
62
|
+
"select-one" : (input, value) => { input.val(value) },
|
|
63
|
+
"hidden" : (input, value) => { input.val(value) },
|
|
64
|
+
"checkbox" : (input, value) => { input.val(value).prop("checked", value).trigger('change') },
|
|
65
|
+
// todo: add the other types of inputs here.
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
let prefix = (node._def.category === "config") ? "#node-config-input-" : "#node-input-";
|
|
69
|
+
Object.keys(node._def.defaults)
|
|
70
|
+
.filter(entry => settings.hasOwnProperty(entry))
|
|
71
|
+
.forEach(entry => {
|
|
72
|
+
try{
|
|
73
|
+
// get the field.
|
|
74
|
+
let field = $(prefix + entry);
|
|
75
|
+
|
|
76
|
+
if(!field[0]){
|
|
77
|
+
console.log("field " + (prefix + entry) + "[0] not found");
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// get the setter for the field.
|
|
82
|
+
let setValue = inputValueSetters[field[0].type];
|
|
83
|
+
if(setValue){
|
|
84
|
+
try{
|
|
85
|
+
//console.log("setting " + prefix + entry + " to " + settings[entry]);
|
|
86
|
+
setValue(field, settings[entry]);
|
|
87
|
+
}
|
|
88
|
+
catch(error){
|
|
89
|
+
console.log(error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else{
|
|
93
|
+
console.log("no setter for type: " + field[0].type + " (" + entry + ")")
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch(error){
|
|
97
|
+
console.log(error);
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
return;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
</script>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<script type="text/javascript" template-section="onIncludeEditPrepare">
|
|
107
|
+
handleNodeSettings(node);
|
|
108
|
+
</script>
|
|
109
|
+
|
|
110
|
+
<script type="text/javascript" template-section="onIncludeEditSave">
|
|
111
|
+
// set the value for "settingsTimestamp" to now() - this will ensure that values are not overwritten if the editor is opened again before a deploy.
|
|
112
|
+
|
|
113
|
+
// NOTE on ONDEPLOY on the server side:
|
|
114
|
+
// when the deployment is being done and there are no settings, then this is a first deployment. Do the intialization and persist to settings (remember to include 'settingsTimestamp')
|
|
115
|
+
// when the deployment is being done and 'settingsTimestamp' from config is the same as 'settingsTimestamp' from settings, then nothing actually changed. its a redeployment
|
|
116
|
+
// when the deployment is being done and 'settingsTimestamp' from config is different from 'settingsTimestamp' from settings then its an update. (save to settings + include settingsTimestap)
|
|
117
|
+
$("#node-config-input-settingsTimestamp").val(new Date().getTime());
|
|
118
|
+
$("#node-input-settingsTimestamp").val(new Date().getTime());
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<script type="text/html" template-section="onIncludeEditForm">
|
|
122
|
+
<input type="hidden" id="node-config-input-settingsTimestamp" />
|
|
123
|
+
<input type="hidden" id="node-input-settingsTimestamp" />
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<script type="text/markdown" template-section="onIncludeDocumentation">
|
|
127
|
+
|
|
128
|
+
</script>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NodeAPI, NodeAPISettingsWithData } from "node-red"
|
|
2
|
+
import { BaseNode, BaseNodeConfig, NodeManager, Template, TemplateDescriptor } from "../../NodeConstructor"
|
|
3
|
+
import { SourceUtility } from "../../NodeGenerator";
|
|
4
|
+
|
|
5
|
+
export class SettingsTemplate extends Template {
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
public static getTemplateDescriptor(): TemplateDescriptor {
|
|
10
|
+
return new TemplateDescriptor(
|
|
11
|
+
"settings",
|
|
12
|
+
SettingsTemplate,
|
|
13
|
+
SourceUtility.getSourcePath("/build/", "/src/") + "SettingsTemplate.html",
|
|
14
|
+
[]
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { NodeDependencyType, NodeDescriptor, TemplateConfig } from "../NodeConstructor";
|
|
2
|
+
import { ITemplateClass } from "../NodeGenerator";
|
|
3
|
+
|
|
4
|
+
export type NodeDescriptionConfig = {
|
|
5
|
+
id: string;
|
|
6
|
+
name:string,
|
|
7
|
+
group: string;
|
|
8
|
+
sourceFile: string;
|
|
9
|
+
package: string;
|
|
10
|
+
templates?: {template:ITemplateClass, config:TemplateConfig}[];
|
|
11
|
+
dependencies?: NodeDependencyType[];
|
|
12
|
+
tags?:string[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function NodeDescription(config:NodeDescriptionConfig) {
|
|
16
|
+
return function(target: any) {
|
|
17
|
+
let descriptor:NodeDescriptor = new NodeDescriptor(config.group, config.id, config.sourceFile, config.package);
|
|
18
|
+
|
|
19
|
+
if(config.templates){
|
|
20
|
+
for(let template of config.templates){
|
|
21
|
+
descriptor.addTemplate(template.template, template.config);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if(config.tags){
|
|
26
|
+
for(let tag of config.tags){
|
|
27
|
+
descriptor.addTag(tag);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if(config.dependencies){
|
|
32
|
+
for(let dependency of config.dependencies){
|
|
33
|
+
descriptor.addDependency(dependency);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
target.getNodeDescriptor = (): NodeDescriptor => descriptor;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { INodeClass } from "../../NodeGenerator";
|
|
2
|
+
import { BaseService, ConfigNode, FlowDeployment, ServiceDescriptor } from "../../NodeConstructor";
|
|
3
|
+
import { NodeAPI, NodeAPISettingsWithData } from "node-red";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class NodeTypeService extends BaseService {
|
|
7
|
+
private red!: NodeAPI<NodeAPISettingsWithData>;
|
|
8
|
+
private nodeTypes:{[key:string]:INodeClass[]} = {};
|
|
9
|
+
|
|
10
|
+
constructor(){
|
|
11
|
+
super("nodetypes")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public init(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void> {
|
|
15
|
+
this.red = red;
|
|
16
|
+
|
|
17
|
+
// update the config/
|
|
18
|
+
this.red.httpAdmin.get("/nodetypeservice/find", this.red.auth.needsPermission("inject.write"), (request,response) => {
|
|
19
|
+
let tag = request.query.tag as string;
|
|
20
|
+
|
|
21
|
+
// serialize the types to a javascript friendly format
|
|
22
|
+
let types = this.getNodeTypesForTag(tag).map( type => {
|
|
23
|
+
let description = type.getNodeDescriptor();
|
|
24
|
+
return {
|
|
25
|
+
"id": description.name(),
|
|
26
|
+
"name": description.name(),
|
|
27
|
+
};
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
response.send(types);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public deinit(red: NodeAPI<NodeAPISettingsWithData>): void | Promise<void> {
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public onDeploy(flowDeployment: FlowDeployment): void | Promise<void> {
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public registerNodeType(tag:string, resource: INodeClass): Promise<void> {
|
|
45
|
+
let nodes = this.nodeTypes[tag];
|
|
46
|
+
if(!nodes){
|
|
47
|
+
this.nodeTypes[tag] = nodes = [];
|
|
48
|
+
}
|
|
49
|
+
nodes.push(resource);
|
|
50
|
+
return Promise.resolve();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public getNodeTypesForTag(tag:string):INodeClass[] {
|
|
54
|
+
return this.nodeTypes[tag] ? this.nodeTypes[tag] : [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static override getServiceDescriptor():ServiceDescriptor {
|
|
58
|
+
return new ServiceDescriptor(
|
|
59
|
+
"@theotherwillembotha/nodetypeservice",
|
|
60
|
+
"NodeTypeService",
|
|
61
|
+
"services-plugin",
|
|
62
|
+
"@theotherwillembotha/node-red-plugincore",
|
|
63
|
+
NodeTypeService,
|
|
64
|
+
[]
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|