@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.
Files changed (180) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +190 -0
  3. package/build/GenerateNodes.d.ts +2 -0
  4. package/build/GenerateNodes.d.ts.map +1 -0
  5. package/build/GenerateNodes.js +36 -0
  6. package/build/Nodes.html +1729 -0
  7. package/build/Nodes.js +32 -0
  8. package/build/Plugins.js +74 -0
  9. package/build/core/NodeConstructor.d.ts +188 -0
  10. package/build/core/NodeConstructor.d.ts.map +1 -0
  11. package/build/core/NodeConstructor.js +679 -0
  12. package/build/core/NodeGenerator.d.ts +37 -0
  13. package/build/core/NodeGenerator.d.ts.map +1 -0
  14. package/build/core/NodeGenerator.js +300 -0
  15. package/build/core/Utils.d.ts +7 -0
  16. package/build/core/Utils.d.ts.map +1 -0
  17. package/build/core/Utils.js +19 -0
  18. package/build/core/logger/LoggerDecorator.d.ts +2 -0
  19. package/build/core/logger/LoggerDecorator.d.ts.map +1 -0
  20. package/build/core/logger/LoggerDecorator.js +93 -0
  21. package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts +16 -0
  22. package/build/core/logger/node/ConsoleLoggerConfigNode.d.ts.map +1 -0
  23. package/build/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
  24. package/build/core/logger/node/ConsoleLoggerConfigNode.js +47 -0
  25. package/build/core/logger/node/LoggerConfigNode.d.ts +30 -0
  26. package/build/core/logger/node/LoggerConfigNode.d.ts.map +1 -0
  27. package/build/core/logger/node/LoggerConfigNode.html +307 -0
  28. package/build/core/logger/node/LoggerConfigNode.js +60 -0
  29. package/build/core/logger/node/LokiLoggerConfigNode.d.ts +20 -0
  30. package/build/core/logger/node/LokiLoggerConfigNode.d.ts.map +1 -0
  31. package/build/core/logger/node/LokiLoggerConfigNode.html +153 -0
  32. package/build/core/logger/node/LokiLoggerConfigNode.js +52 -0
  33. package/build/core/logger/node/RestLoggerConfigNode.d.ts +24 -0
  34. package/build/core/logger/node/RestLoggerConfigNode.d.ts.map +1 -0
  35. package/build/core/logger/node/RestLoggerConfigNode.html +209 -0
  36. package/build/core/logger/node/RestLoggerConfigNode.js +57 -0
  37. package/build/core/logger/service/LoggerService.d.ts +88 -0
  38. package/build/core/logger/service/LoggerService.d.ts.map +1 -0
  39. package/build/core/logger/service/LoggerService.js +204 -0
  40. package/build/core/logger/service/LoggerServiceTypes.d.ts +24 -0
  41. package/build/core/logger/service/LoggerServiceTypes.d.ts.map +1 -0
  42. package/build/core/logger/service/LoggerServiceTypes.js +30 -0
  43. package/build/core/logger/template/LoggerTemplate.d.ts +11 -0
  44. package/build/core/logger/template/LoggerTemplate.d.ts.map +1 -0
  45. package/build/core/logger/template/LoggerTemplate.html +328 -0
  46. package/build/core/logger/template/LoggerTemplate.js +12 -0
  47. package/build/core/metrics/MetricsDecorator.d.ts +40 -0
  48. package/build/core/metrics/MetricsDecorator.d.ts.map +1 -0
  49. package/build/core/metrics/MetricsDecorator.js +166 -0
  50. package/build/core/metrics/node/CounterMetricConfigNode.d.ts +16 -0
  51. package/build/core/metrics/node/CounterMetricConfigNode.d.ts.map +1 -0
  52. package/build/core/metrics/node/CounterMetricConfigNode.html +48 -0
  53. package/build/core/metrics/node/CounterMetricConfigNode.js +61 -0
  54. package/build/core/metrics/node/GaugeMetricConfigNode.d.ts +17 -0
  55. package/build/core/metrics/node/GaugeMetricConfigNode.d.ts.map +1 -0
  56. package/build/core/metrics/node/GaugeMetricConfigNode.html +48 -0
  57. package/build/core/metrics/node/GaugeMetricConfigNode.js +61 -0
  58. package/build/core/metrics/node/MetricsConfigNode.d.ts +14 -0
  59. package/build/core/metrics/node/MetricsConfigNode.d.ts.map +1 -0
  60. package/build/core/metrics/node/MetricsConfigNode.html +21 -0
  61. package/build/core/metrics/node/MetricsConfigNode.js +56 -0
  62. package/build/core/metrics/node/TimerMetricConfigNode.d.ts +28 -0
  63. package/build/core/metrics/node/TimerMetricConfigNode.d.ts.map +1 -0
  64. package/build/core/metrics/node/TimerMetricConfigNode.html +190 -0
  65. package/build/core/metrics/node/TimerMetricConfigNode.js +101 -0
  66. package/build/core/metrics/service/MetricsService.d.ts +187 -0
  67. package/build/core/metrics/service/MetricsService.d.ts.map +1 -0
  68. package/build/core/metrics/service/MetricsService.js +385 -0
  69. package/build/core/metrics/template/CounterMetricTemplate.d.ts +5 -0
  70. package/build/core/metrics/template/CounterMetricTemplate.d.ts.map +1 -0
  71. package/build/core/metrics/template/CounterMetricTemplate.html +40 -0
  72. package/build/core/metrics/template/CounterMetricTemplate.js +12 -0
  73. package/build/core/metrics/template/GaugeMetricTemplate.d.ts +5 -0
  74. package/build/core/metrics/template/GaugeMetricTemplate.d.ts.map +1 -0
  75. package/build/core/metrics/template/GaugeMetricTemplate.html +39 -0
  76. package/build/core/metrics/template/GaugeMetricTemplate.js +12 -0
  77. package/build/core/metrics/template/MetricsTemplate.d.ts +8 -0
  78. package/build/core/metrics/template/MetricsTemplate.d.ts.map +1 -0
  79. package/build/core/metrics/template/MetricsTemplate.html +54 -0
  80. package/build/core/metrics/template/MetricsTemplate.js +12 -0
  81. package/build/core/metrics/template/TimerMetricTemplate.d.ts +5 -0
  82. package/build/core/metrics/template/TimerMetricTemplate.d.ts.map +1 -0
  83. package/build/core/metrics/template/TimerMetricTemplate.html +39 -0
  84. package/build/core/metrics/template/TimerMetricTemplate.js +12 -0
  85. package/build/core/other/InputDecorator.d.ts +3 -0
  86. package/build/core/other/InputDecorator.d.ts.map +1 -0
  87. package/build/core/other/InputDecorator.js +43 -0
  88. package/build/core/other/service/InputService.d.ts +16 -0
  89. package/build/core/other/service/InputService.d.ts.map +1 -0
  90. package/build/core/other/service/InputService.js +31 -0
  91. package/build/core/other/service/SettingsService.d.ts +25 -0
  92. package/build/core/other/service/SettingsService.d.ts.map +1 -0
  93. package/build/core/other/service/SettingsService.js +74 -0
  94. package/build/core/other/template/BasicTemplate.d.ts +5 -0
  95. package/build/core/other/template/BasicTemplate.d.ts.map +1 -0
  96. package/build/core/other/template/BasicTemplate.html +76 -0
  97. package/build/core/other/template/BasicTemplate.js +11 -0
  98. package/build/core/other/template/SettingsTemplate.d.ts +5 -0
  99. package/build/core/other/template/SettingsTemplate.d.ts.map +1 -0
  100. package/build/core/other/template/SettingsTemplate.html +128 -0
  101. package/build/core/other/template/SettingsTemplate.js +11 -0
  102. package/build/core/tagging/NodeDescriptionDecorator.d.ts +17 -0
  103. package/build/core/tagging/NodeDescriptionDecorator.d.ts.map +1 -0
  104. package/build/core/tagging/NodeDescriptionDecorator.js +25 -0
  105. package/build/core/tagging/service/NodeTypeService.d.ts +15 -0
  106. package/build/core/tagging/service/NodeTypeService.d.ts.map +1 -0
  107. package/build/core/tagging/service/NodeTypeService.js +47 -0
  108. package/build/core/webhook/WebhookDecorator.d.ts +3 -0
  109. package/build/core/webhook/WebhookDecorator.d.ts.map +1 -0
  110. package/build/core/webhook/WebhookDecorator.js +45 -0
  111. package/build/core/webhook/node/WebhookServerConfigNode.d.ts +16 -0
  112. package/build/core/webhook/node/WebhookServerConfigNode.d.ts.map +1 -0
  113. package/build/core/webhook/node/WebhookServerConfigNode.html +61 -0
  114. package/build/core/webhook/node/WebhookServerConfigNode.js +40 -0
  115. package/build/core/webhook/service/ReverseProxyTypeService.d.ts +29 -0
  116. package/build/core/webhook/service/ReverseProxyTypeService.d.ts.map +1 -0
  117. package/build/core/webhook/service/ReverseProxyTypeService.js +24 -0
  118. package/build/core/webhook/service/WebhookServerService.d.ts +52 -0
  119. package/build/core/webhook/service/WebhookServerService.d.ts.map +1 -0
  120. package/build/core/webhook/service/WebhookServerService.js +146 -0
  121. package/build/core/webhook/template/WebhookTemplate.d.ts +22 -0
  122. package/build/core/webhook/template/WebhookTemplate.d.ts.map +1 -0
  123. package/build/core/webhook/template/WebhookTemplate.html +434 -0
  124. package/build/core/webhook/template/WebhookTemplate.js +12 -0
  125. package/build/index.d.ts +33 -0
  126. package/build/index.d.ts.map +1 -0
  127. package/build/index.js +55 -0
  128. package/package.json +67 -0
  129. package/src/GenerateNodes.ts +42 -0
  130. package/src/core/NodeConstructor.ts +889 -0
  131. package/src/core/NodeGenerator.ts +331 -0
  132. package/src/core/Utils.ts +19 -0
  133. package/src/core/logger/LoggerDecorator.ts +105 -0
  134. package/src/core/logger/node/ConsoleLoggerConfigNode.html +131 -0
  135. package/src/core/logger/node/ConsoleLoggerConfigNode.ts +46 -0
  136. package/src/core/logger/node/LoggerConfigNode.html +307 -0
  137. package/src/core/logger/node/LoggerConfigNode.ts +95 -0
  138. package/src/core/logger/node/LokiLoggerConfigNode.html +153 -0
  139. package/src/core/logger/node/LokiLoggerConfigNode.ts +58 -0
  140. package/src/core/logger/node/RestLoggerConfigNode.html +209 -0
  141. package/src/core/logger/node/RestLoggerConfigNode.ts +67 -0
  142. package/src/core/logger/service/LoggerService.ts +317 -0
  143. package/src/core/logger/service/LoggerServiceTypes.ts +26 -0
  144. package/src/core/logger/template/LoggerTemplate.html +328 -0
  145. package/src/core/logger/template/LoggerTemplate.ts +23 -0
  146. package/src/core/metrics/MetricsDecorator.ts +227 -0
  147. package/src/core/metrics/node/CounterMetricConfigNode.html +48 -0
  148. package/src/core/metrics/node/CounterMetricConfigNode.ts +62 -0
  149. package/src/core/metrics/node/GaugeMetricConfigNode.html +48 -0
  150. package/src/core/metrics/node/GaugeMetricConfigNode.ts +62 -0
  151. package/src/core/metrics/node/MetricsConfigNode.html +21 -0
  152. package/src/core/metrics/node/MetricsConfigNode.ts +55 -0
  153. package/src/core/metrics/node/TimerMetricConfigNode.html +190 -0
  154. package/src/core/metrics/node/TimerMetricConfigNode.ts +118 -0
  155. package/src/core/metrics/service/MetricsService.ts +560 -0
  156. package/src/core/metrics/template/CounterMetricTemplate.html +40 -0
  157. package/src/core/metrics/template/CounterMetricTemplate.ts +15 -0
  158. package/src/core/metrics/template/GaugeMetricTemplate.html +39 -0
  159. package/src/core/metrics/template/GaugeMetricTemplate.ts +15 -0
  160. package/src/core/metrics/template/MetricsTemplate.html +54 -0
  161. package/src/core/metrics/template/MetricsTemplate.ts +18 -0
  162. package/src/core/metrics/template/TimerMetricTemplate.html +39 -0
  163. package/src/core/metrics/template/TimerMetricTemplate.ts +14 -0
  164. package/src/core/other/InputDecorator.ts +57 -0
  165. package/src/core/other/service/InputService.ts +36 -0
  166. package/src/core/other/service/SettingsService.ts +103 -0
  167. package/src/core/other/template/BasicTemplate.html +76 -0
  168. package/src/core/other/template/BasicTemplate.ts +15 -0
  169. package/src/core/other/template/SettingsTemplate.html +128 -0
  170. package/src/core/other/template/SettingsTemplate.ts +17 -0
  171. package/src/core/tagging/NodeDescriptionDecorator.ts +39 -0
  172. package/src/core/tagging/service/NodeTypeService.ts +67 -0
  173. package/src/core/webhook/WebhookDecorator.ts +70 -0
  174. package/src/core/webhook/node/WebhookServerConfigNode.html +61 -0
  175. package/src/core/webhook/node/WebhookServerConfigNode.ts +38 -0
  176. package/src/core/webhook/service/ReverseProxyTypeService.ts +46 -0
  177. package/src/core/webhook/service/WebhookServerService.ts +211 -0
  178. package/src/core/webhook/template/WebhookTemplate.html +434 -0
  179. package/src/core/webhook/template/WebhookTemplate.ts +36 -0
  180. package/src/index.ts +47 -0
@@ -0,0 +1,1729 @@
1
+
2
+ <!--
3
+
4
+ This file was automatically generated using the NODERED Core utility.
5
+ Any modifications to his file will be overwritten the next time the code is regenerated.
6
+
7
+ You have been warned.
8
+
9
+ -->
10
+
11
+ <script type="text/javascript">
12
+ RED.nodes.registerType('ConsoleLoggerConfigNode', {
13
+ category: 'config',
14
+ label: function() {
15
+ return this.name
16
+ },
17
+ paletteLabel: 'Console Logger Config Node',
18
+ defaults: {
19
+ name: {
20
+ value: 'Logger Example',
21
+ required: true
22
+ },
23
+ platform: {
24
+ value: 'rest',
25
+ required: true
26
+ },
27
+ template: {
28
+ value: 'message:{{msg}}',
29
+ required: true
30
+ },
31
+ level: {
32
+ value: 'info',
33
+ required: true
34
+ },
35
+ },
36
+ oneditprepare: function() {
37
+ // **** ConsoleLoggerConfigNode **** //
38
+ {
39
+ let node = this;
40
+ let levelSelection = $("#node-config-input-level");
41
+ levelSelection.typedInput({
42
+ type: "level",
43
+ types: [{
44
+ value: "level",
45
+ options: [{
46
+ value: "DEBUG",
47
+ label: "debug"
48
+ }, {
49
+ value: "INFO",
50
+ label: "info"
51
+ }, {
52
+ value: "WARNING",
53
+ label: "warning"
54
+ }, {
55
+ value: "ERROR",
56
+ label: "error"
57
+ }, ]
58
+ }]
59
+ });
60
+ this.editor = RED.editor.createEditor({
61
+ id: 'node-config-input-templateEditor',
62
+ mode: 'ace/mode/handlebars',
63
+ value: this.template
64
+ });
65
+ }
66
+ },
67
+ oneditsave: function() {
68
+ // **** ConsoleLoggerConfigNode **** //
69
+ {
70
+ let node = this;
71
+ this.template = this.editor.getValue();
72
+ this.editor.destroy();
73
+ delete this.editor;
74
+ }
75
+ },
76
+ oneditcancel: function() {},
77
+ oneditdelete: function() {},
78
+ });
79
+
80
+ </script>
81
+
82
+
83
+ <script type="text/html" data-template-name='ConsoleLoggerConfigNode'>
84
+ <div id='section_ConsoleLoggerConfigNode'>
85
+ <div id="LoggerConfig">
86
+ <div class="form-row">
87
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
88
+ <input type="text" id="node-config-input-name" />
89
+ </div>
90
+
91
+ <div class="form-row">
92
+ <label for="node-config-input-level"><i class="fa fa-tag"></i> Level</label>
93
+ <input type="text" id="node-config-input-level" />
94
+ </div>
95
+
96
+ <div class="form-row">
97
+ <label for="node-config-input-templateEditor"><i class="fa fa-tag"></i> Template</label>
98
+ <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
99
+ </div>
100
+ </div>
101
+
102
+ </div>
103
+ </script>
104
+
105
+ <script type="text/markdown" data-help-name='ConsoleLoggerConfigNode'>
106
+ Configuration node for the Logger Integration
107
+
108
+ ## Inputs
109
+ : *name* (string) : The common name for the logger Configuration
110
+ : *level* (level) : The logging level - debug, info, warning, error
111
+ : *platform*(string) : The common name for the logger Configuration
112
+ : *template*(mustache) : A template for the log messages.
113
+
114
+ ## Logger platform
115
+ Currently supported logging platforms
116
+
117
+ ### Console
118
+ The log message will be printed out to stdio
119
+
120
+ ### Http / Https
121
+ Publish the message to an http endpoint using a http / https POST command.
122
+
123
+ : *url* (url) : The endpoint for the url where requests are to be posted to.
124
+ : *ignore ssl errors* (boolean) : If enabled, the invalid ssl certificates will be ignored.
125
+ : *authentication* (auth method) : what auth method should be used for the http request. (none, basic, api key)
126
+
127
+ #### Authentication
128
+ ##### Basic
129
+ Provides basic authentication using the Authorization header
130
+
131
+ : *username* (string) : the username used for basic authentication
132
+ : *password* (string) : the password used for basic authentication
133
+
134
+ ##### APIKey
135
+ Provides authentication using a matrix parameter, header or query parameter and an apikey
136
+
137
+ : *mechanism* (mechanism) : the mechanism that will be used for transmitting the key (header, queryparam, matrixparam)
138
+ : *apikey name* (string) : the name of the key used for api authentication. (path variable or query param name)
139
+ : *apikey value*(string) : the value of the api key that will be transmitted. (beware of special characters)
140
+
141
+ ### Loki
142
+ Publish the message to a loki endpoint.
143
+
144
+ : *host* (string) : the host and port\ of the loki instance that it being logged to
145
+ : *tenant* (string) : the tenant id that will be used to log to
146
+ : *username* (string) : the username for the loki instance.
147
+ : *authtoken* (string) : the authtoken for the loki instance.
148
+
149
+ # Mustache Templating
150
+ Mustache / Handlebars are used for building up the logged message payloads that are sent to the logging backend.
151
+ The resultant message will be interpreted as a string, meaning care should be taken in the event that a string representation of a json object is built.
152
+
153
+ ### Provided Properties
154
+ A couple of values are provided to the logging context by default.
155
+
156
+ : *msg* (object) : an object containing the payload or message that should be parsed through the template.
157
+ : *currentTime* (object) : a string containing the current time in ISO8601 format
158
+
159
+ ### Mustache Helpers
160
+ In addition to the provided properties, some "helpers" have also been provided to assist in serialization.
161
+
162
+ : *json* (helper) : converts a json object to a string using the JSON.stringify method.
163
+
164
+ ## Examples
165
+ - {{{json msg}}} - serializes the the msg object to json format.
166
+
167
+ # References
168
+ - [Mustache - Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
169
+ - [Mustache - Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
170
+ </script>
171
+ <script type="text/javascript">
172
+ RED.nodes.registerType('RestLoggerConfigNode', {
173
+ category: 'config',
174
+ label: function() {
175
+ return this.name
176
+ },
177
+ paletteLabel: 'Rest Logger Config Node',
178
+ defaults: {
179
+ name: {
180
+ value: 'Logger Example',
181
+ required: true
182
+ },
183
+ template: {
184
+ value: 'message:{{msg}}',
185
+ required: true
186
+ },
187
+ level: {
188
+ value: 'info',
189
+ required: true
190
+ },
191
+ est_url: {},
192
+ est_ignoresslerror: {},
193
+ rest_auth_type: {},
194
+ rest_auth_basic_username: {},
195
+ rest_auth_basic_password: {},
196
+ rest_auth_apikey_mechanism: {},
197
+ rest_auth_apikey_name: {},
198
+ rest_auth_apikey_value: {},
199
+ },
200
+ oneditprepare: function() {
201
+ // **** RestLoggerConfigNode **** //
202
+ {
203
+ let node = this;
204
+ let showSelectedRestAuthMethod = (value) => {
205
+ $("#LoggerConfig").find(".platform.platform-rest").first().find(".platform-rest-auth").each((i, t) => {
206
+ t = $(t);
207
+ if (t.hasClass(`auth-${value}`)) {
208
+ t.show();
209
+ } else {
210
+ t.hide();
211
+ }
212
+ });
213
+ }
214
+ let levelSelection = $("#node-config-input-level");
215
+ levelSelection.typedInput({
216
+ type: "level",
217
+ types: [{
218
+ value: "level",
219
+ options: [{
220
+ value: "DEBUG",
221
+ label: "debug"
222
+ }, {
223
+ value: "INFO",
224
+ label: "info"
225
+ }, {
226
+ value: "WARNING",
227
+ label: "warning"
228
+ }, {
229
+ value: "ERROR",
230
+ label: "error"
231
+ }, ]
232
+ }]
233
+ });
234
+ let platformRestAuthType = $("#node-config-input-rest_auth_type");
235
+ platformRestAuthType.typedInput({
236
+ type: "authtype",
237
+ types: [{
238
+ value: "authtype",
239
+ options: [{
240
+ value: "none",
241
+ label: "None"
242
+ }, {
243
+ value: "basic",
244
+ label: "Basic"
245
+ }, {
246
+ value: "apikey",
247
+ label: "ApiKey"
248
+ }]
249
+ }]
250
+ });
251
+ platformRestAuthType.on("change", () => showSelectedRestAuthMethod(platformRestAuthType.val()));
252
+ let apiKeyMechanism = $("#node-config-input-rest_auth_apikey_mechanism");
253
+ apiKeyMechanism.typedInput({
254
+ type: "apikeymechansim",
255
+ types: [{
256
+ value: "apikeymechansim",
257
+ options: [{
258
+ value: "header",
259
+ label: "Header"
260
+ }, {
261
+ value: "queryparam",
262
+ label: "Query Param"
263
+ }, {
264
+ value: "matrixparam",
265
+ label: "Matrix Param"
266
+ }]
267
+ }]
268
+ });
269
+ this.editor = RED.editor.createEditor({
270
+ id: 'node-config-input-templateEditor',
271
+ mode: 'ace/mode/handlebars',
272
+ value: this.template
273
+ });
274
+ }
275
+ },
276
+ oneditsave: function() {
277
+ // **** RestLoggerConfigNode **** //
278
+ {
279
+ let node = this;
280
+ this.template = this.editor.getValue();
281
+ this.editor.destroy();
282
+ delete this.editor;
283
+ }
284
+ },
285
+ oneditcancel: function() {},
286
+ oneditdelete: function() {},
287
+ });
288
+
289
+ </script>
290
+
291
+
292
+ <script type="text/html" data-template-name='RestLoggerConfigNode'>
293
+ <div id='section_RestLoggerConfigNode'>
294
+ <div id="LoggerConfig">
295
+ <div class="form-row">
296
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
297
+ <input type="text" id="node-config-input-name" />
298
+ </div>
299
+
300
+ <div class="form-row">
301
+ <label for="node-config-input-level"><i class="fa fa-tag"></i> Level</label>
302
+ <input type="text" id="node-config-input-level" />
303
+ </div>
304
+
305
+ <div class="platform platform-rest">
306
+ <div class="form-row">
307
+ <label for="node-config-input-rest_url"><i class="fa fa-tag"></i> URL</label>
308
+ <input class="platform-rest-input required" type="text" id="node-config-input-rest_url" />
309
+ </div>
310
+ <div class="form-row">
311
+ <label></label>
312
+ <input type="checkbox" id="node-config-input-rest_ignoresslerror" style="width:20px; margin-right:5px;" />
313
+ <label style="width:auto" for="node-config-input-rest_ignoresslerror"><span>Ignore Invalid SSL certificates</span></label>
314
+ </div>
315
+ <div class="form-row">
316
+ <label for="node-config-input-rest_auth_type"><i class="fa fa-tag"></i> Authentication</label>
317
+ <input class="platform-rest-input required" type="text" id="node-config-input-rest_auth_type" />
318
+ </div>
319
+ <div class="form-row platform-rest-auth auth-basic">
320
+ <label for="node-config-input-rest_auth_basic_username"><i class="fa fa-tag"></i> Username</label>
321
+ <input class="platform-rest-input" type="text" id="node-config-input-rest_auth_basic_username" />
322
+ </div>
323
+ <div class="form-row platform-rest-auth auth-basic">
324
+ <label for="node-config-input-rest_auth_basic_password"><i class="fa fa-tag"></i> Password</label>
325
+ <input class="platform-rest-input" type="password" id="node-config-input-rest_auth_basic_password" />
326
+ </div>
327
+ <div class="form-row platform-rest-auth auth-apikey">
328
+ <label for="node-config-input-rest_auth_apikey_mechanism"><i class="fa fa-tag"></i> Mechanism</label>
329
+ <input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_mechanism" />
330
+ </div>
331
+ <div class="form-row platform-rest-auth auth-apikey">
332
+ <label for="node-config-input-rest_auth_apikey_name"><i class="fa fa-tag"></i> APIKey name</label>
333
+ <input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_name" />
334
+ </div>
335
+ <div class="form-row platform-rest-auth auth-apikey">
336
+ <label for="node-config-input-rest_auth_apikey_value"><i class="fa fa-tag"></i> APIKey value</label>
337
+ <input class="platform-rest-input" type="text" id="node-config-input-rest_auth_apikey_value" />
338
+ </div>
339
+ </div>
340
+
341
+ <div class="form-row">
342
+ <label for="node-config-input-templateEditor"><i class="fa fa-tag"></i> Template</label>
343
+ <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
344
+ </div>
345
+ </div>
346
+
347
+ </div>
348
+ </script>
349
+
350
+ <script type="text/markdown" data-help-name='RestLoggerConfigNode'>
351
+ Configuration node for the Logger Integration
352
+
353
+ ## Inputs
354
+ : *name* (string) : The common name for the logger Configuration
355
+ : *level* (level) : The logging level - debug, info, warning, error
356
+ : *platform*(string) : The common name for the logger Configuration
357
+ : *template*(mustache) : A template for the log messages.
358
+
359
+ ## Logger platform
360
+ Currently supported logging platforms
361
+
362
+ ### Console
363
+ The log message will be printed out to stdio
364
+
365
+ ### Http / Https
366
+ Publish the message to an http endpoint using a http / https POST command.
367
+
368
+ : *url* (url) : The endpoint for the url where requests are to be posted to.
369
+ : *ignore ssl errors* (boolean) : If enabled, the invalid ssl certificates will be ignored.
370
+ : *authentication* (auth method) : what auth method should be used for the http request. (none, basic, api key)
371
+
372
+ #### Authentication
373
+ ##### Basic
374
+ Provides basic authentication using the Authorization header
375
+
376
+ : *username* (string) : the username used for basic authentication
377
+ : *password* (string) : the password used for basic authentication
378
+
379
+ ##### APIKey
380
+ Provides authentication using a matrix parameter, header or query parameter and an apikey
381
+
382
+ : *mechanism* (mechanism) : the mechanism that will be used for transmitting the key (header, queryparam, matrixparam)
383
+ : *apikey name* (string) : the name of the key used for api authentication. (path variable or query param name)
384
+ : *apikey value*(string) : the value of the api key that will be transmitted. (beware of special characters)
385
+
386
+ ### Loki
387
+ Publish the message to a loki endpoint.
388
+
389
+ : *host* (string) : the host and port\ of the loki instance that it being logged to
390
+ : *tenant* (string) : the tenant id that will be used to log to
391
+ : *username* (string) : the username for the loki instance.
392
+ : *authtoken* (string) : the authtoken for the loki instance.
393
+
394
+ # Mustache Templating
395
+ Mustache / Handlebars are used for building up the logged message payloads that are sent to the logging backend.
396
+ The resultant message will be interpreted as a string, meaning care should be taken in the event that a string representation of a json object is built.
397
+
398
+ ### Provided Properties
399
+ A couple of values are provided to the logging context by default.
400
+
401
+ : *msg* (object) : an object containing the payload or message that should be parsed through the template.
402
+ : *currentTime* (object) : a string containing the current time in ISO8601 format
403
+
404
+ ### Mustache Helpers
405
+ In addition to the provided properties, some "helpers" have also been provided to assist in serialization.
406
+
407
+ : *json* (helper) : converts a json object to a string using the JSON.stringify method.
408
+
409
+ ## Examples
410
+ - {{{json msg}}} - serializes the the msg object to json format.
411
+
412
+ # References
413
+ - [Mustache - Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
414
+ - [Mustache - Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
415
+ </script>
416
+ <script type="text/javascript">
417
+ RED.nodes.registerType('LokiLoggerConfigNode', {
418
+ category: 'config',
419
+ label: function() {
420
+ return this.name
421
+ },
422
+ paletteLabel: 'Loki Logger Config Node',
423
+ defaults: {
424
+ name: {
425
+ value: 'Logger Example',
426
+ required: true
427
+ },
428
+ template: {
429
+ value: 'message:{{msg}}',
430
+ required: true
431
+ },
432
+ level: {
433
+ value: 'info',
434
+ required: true
435
+ },
436
+ loki_host: {},
437
+ loki_tenantID: {},
438
+ loki_userid: {},
439
+ loki_authtoken: {},
440
+ },
441
+ oneditprepare: function() {
442
+ // **** LokiLoggerConfigNode **** //
443
+ {
444
+ let node = this;
445
+ let levelSelection = $("#node-config-input-level");
446
+ levelSelection.typedInput({
447
+ type: "level",
448
+ types: [{
449
+ value: "level",
450
+ options: [{
451
+ value: "DEBUG",
452
+ label: "debug"
453
+ }, {
454
+ value: "INFO",
455
+ label: "info"
456
+ }, {
457
+ value: "WARNING",
458
+ label: "warning"
459
+ }, {
460
+ value: "ERROR",
461
+ label: "error"
462
+ }, ]
463
+ }]
464
+ });
465
+ this.editor = RED.editor.createEditor({
466
+ id: 'node-config-input-templateEditor',
467
+ mode: 'ace/mode/handlebars',
468
+ value: this.template
469
+ });
470
+ }
471
+ },
472
+ oneditsave: function() {
473
+ // **** LokiLoggerConfigNode **** //
474
+ {
475
+ let node = this;
476
+ this.template = this.editor.getValue();
477
+ this.editor.destroy();
478
+ delete this.editor;
479
+ }
480
+ },
481
+ oneditcancel: function() {},
482
+ oneditdelete: function() {},
483
+ });
484
+
485
+ </script>
486
+
487
+
488
+ <script type="text/html" data-template-name='LokiLoggerConfigNode'>
489
+ <div id='section_LokiLoggerConfigNode'>
490
+ <div id="LoggerConfig">
491
+ <div class="form-row">
492
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
493
+ <input type="text" id="node-config-input-name" />
494
+ </div>
495
+
496
+ <div class="form-row">
497
+ <label for="node-config-input-level"><i class="fa fa-tag"></i> Level</label>
498
+ <input type="text" id="node-config-input-level" />
499
+ </div>
500
+
501
+ <div class="form-row">
502
+ <label for="node-config-input-loki_host"><i class="fa fa-tag"></i> Host</label>
503
+ <input class="required" type="text" id="node-config-input-loki_host" />
504
+ </div>
505
+ <div class="form-row">
506
+ <label for="node-config-input-loki_tenantID"><i class="fa fa-tag"></i> TenantID</label>
507
+ <input class="" type="text" id="node-config-input-loki_tenantID" />
508
+ </div>
509
+ <div class="form-row">
510
+ <label for="node-config-input-loki_userid"><i class="fa fa-tag"></i> Username</label>
511
+ <input class="" type="text" id="node-config-input-loki_userid" />
512
+ </div>
513
+ <div class="form-row">
514
+ <label for="node-config-input-loki_authtoken"><i class="fa fa-tag"></i> AuthToken</label>
515
+ <input class="" type="password" id="node-config-input-loki_authtoken" />
516
+ </div>
517
+
518
+ <div class="form-row">
519
+ <label for="node-config-input-templateEditor"><i class="fa fa-tag"></i> Template</label>
520
+ <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-config-input-templateEditor"></div>
521
+ </div>
522
+ </div>
523
+
524
+ </div>
525
+ </script>
526
+
527
+ <script type="text/markdown" data-help-name='LokiLoggerConfigNode'>
528
+ Configuration node for the Logger Integration
529
+
530
+ ## Inputs
531
+ : *name* (string) : The common name for the logger Configuration
532
+ : *level* (level) : The logging level - debug, info, warning, error
533
+ : *platform*(string) : The common name for the logger Configuration
534
+ : *template*(mustache) : A template for the log messages.
535
+
536
+ ## Logger platform
537
+ Currently supported logging platforms
538
+
539
+ ### Console
540
+ The log message will be printed out to stdio
541
+
542
+ ### Http / Https
543
+ Publish the message to an http endpoint using a http / https POST command.
544
+
545
+ : *url* (url) : The endpoint for the url where requests are to be posted to.
546
+ : *ignore ssl errors* (boolean) : If enabled, the invalid ssl certificates will be ignored.
547
+ : *authentication* (auth method) : what auth method should be used for the http request. (none, basic, api key)
548
+
549
+ #### Authentication
550
+ ##### Basic
551
+ Provides basic authentication using the Authorization header
552
+
553
+ : *username* (string) : the username used for basic authentication
554
+ : *password* (string) : the password used for basic authentication
555
+
556
+ ##### APIKey
557
+ Provides authentication using a matrix parameter, header or query parameter and an apikey
558
+
559
+ : *mechanism* (mechanism) : the mechanism that will be used for transmitting the key (header, queryparam, matrixparam)
560
+ : *apikey name* (string) : the name of the key used for api authentication. (path variable or query param name)
561
+ : *apikey value*(string) : the value of the api key that will be transmitted. (beware of special characters)
562
+
563
+ ### Loki
564
+ Publish the message to a loki endpoint.
565
+
566
+ : *host* (string) : the host and port\ of the loki instance that it being logged to
567
+ : *tenant* (string) : the tenant id that will be used to log to
568
+ : *username* (string) : the username for the loki instance.
569
+ : *authtoken* (string) : the authtoken for the loki instance.
570
+
571
+ # Mustache Templating
572
+ Mustache / Handlebars are used for building up the logged message payloads that are sent to the logging backend.
573
+ The resultant message will be interpreted as a string, meaning care should be taken in the event that a string representation of a json object is built.
574
+
575
+ ### Provided Properties
576
+ A couple of values are provided to the logging context by default.
577
+
578
+ : *msg* (object) : an object containing the payload or message that should be parsed through the template.
579
+ : *currentTime* (object) : a string containing the current time in ISO8601 format
580
+
581
+ ### Mustache Helpers
582
+ In addition to the provided properties, some "helpers" have also been provided to assist in serialization.
583
+
584
+ : *json* (helper) : converts a json object to a string using the JSON.stringify method.
585
+
586
+ ## Examples
587
+ - {{{json msg}}} - serializes the the msg object to json format.
588
+
589
+ # References
590
+ - [Mustache - Wikipedia](https://en.wikipedia.org/wiki/Mustache_(template_system))
591
+ - [Mustache - Playground](https://jgonggrijp.gitlab.io/wontache/playground.html)
592
+ </script>
593
+ <!-- webhook -->
594
+ <script type="text/javascript">
595
+ // CSS
596
+ dropdownStyles = `
597
+ .proxy-dropdown {
598
+ position: absolute;
599
+ background: white;
600
+ border: 1px solid #ccc;
601
+ border-radius: 4px;
602
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
603
+ max-height: 150px;
604
+ overflow-y: auto;
605
+ z-index: 1000;
606
+ min-width: 150px;
607
+ }
608
+ .proxy-dropdown .dropdown-item {
609
+ padding: 6px 12px;
610
+ cursor: pointer;
611
+ }
612
+ .proxy-dropdown .dropdown-item:hover {
613
+ background: #f0f0f0;
614
+ }
615
+ `;
616
+ $('<style>').text(dropdownStyles).appendTo('head');
617
+
618
+ </script>
619
+ <script type="text/javascript">
620
+ RED.nodes.registerType('MetricsConfigNode', {
621
+ category: 'config',
622
+ label: function() {
623
+ return this.name
624
+ },
625
+ paletteLabel: 'Metrics Config',
626
+ defaults: {
627
+ name: {
628
+ value: 'Metrics Example',
629
+ required: true
630
+ },
631
+ webhook: {
632
+ type: 'WebhookServerConfigNode',
633
+ required: true
634
+ },
635
+ webhookPath: {
636
+ value: '/example',
637
+ required: true
638
+ },
639
+ webhookAuth: {
640
+ value: 'none',
641
+ required: true
642
+ },
643
+ webhookAuth_basic_username: {
644
+ value: 'user',
645
+ required: false
646
+ },
647
+ webhookAuth_basic_password: {
648
+ value: 'pass',
649
+ required: false
650
+ },
651
+ webhookAuth_apikey_mechanism: {
652
+ value: 'header',
653
+ required: false
654
+ },
655
+ webhookAuth_apikey_key: {
656
+ value: 'x-api-key',
657
+ required: false
658
+ },
659
+ webhookAuth_apikey_value: {
660
+ value: 'testkey',
661
+ required: false
662
+ },
663
+ reverseProxies_enabled: {
664
+ required: false
665
+ },
666
+ reverseProxies_connections: {
667
+ type: 'ReverseProxyType[]',
668
+ value: '',
669
+ required: true,
670
+ maxInstances: 10
671
+ },
672
+ _reverseProxies_connections_0: {
673
+ value: '',
674
+ required: false
675
+ },
676
+ _reverseProxies_connections_1: {
677
+ value: '',
678
+ required: false
679
+ },
680
+ _reverseProxies_connections_2: {
681
+ value: '',
682
+ required: false
683
+ },
684
+ _reverseProxies_connections_3: {
685
+ value: '',
686
+ required: false
687
+ },
688
+ _reverseProxies_connections_4: {
689
+ value: '',
690
+ required: false
691
+ },
692
+ _reverseProxies_connections_5: {
693
+ value: '',
694
+ required: false
695
+ },
696
+ _reverseProxies_connections_6: {
697
+ value: '',
698
+ required: false
699
+ },
700
+ _reverseProxies_connections_7: {
701
+ value: '',
702
+ required: false
703
+ },
704
+ _reverseProxies_connections_8: {
705
+ value: '',
706
+ required: false
707
+ },
708
+ _reverseProxies_connections_9: {
709
+ value: '',
710
+ required: false
711
+ },
712
+ },
713
+ oneditprepare: function() {
714
+ // **** webhook **** //
715
+ {
716
+ let node = this;
717
+ let showSelectedAutnetication = function(value) {
718
+ let webhookConfig = $("#section_webhookconfig");
719
+ webhookConfig.find(".webhookauth").each((i, t) => {
720
+ t = $(t);
721
+ if (t.hasClass(`webhookauth-${value}`)) {
722
+ t.show();
723
+ } else {
724
+ t.hide();
725
+ }
726
+ });
727
+ webhookConfig.find(`.webhookauth-${value}`).find(`.webhookauth-${value}-input.required`).each((i, entry) => {
728
+ let id = entry.id.replace("node-input-", "");
729
+ if (node._def.defaults[id]) {
730
+ node._def.defaults[id].required = true;
731
+ } else {
732
+ console.log(`you forgot to define ${id} in the defaults for WebhookTemplate`);
733
+ }
734
+ });
735
+ Object.entries(node._def.defaults).filter(([k, v]) => k.startsWith(`webhookAuth_`)).filter(([k, v]) => !k.startsWith(`webhookAuth_${value}_`)).forEach(([k, v]) => v.required = false);
736
+ node.webhookAuth = value;
737
+ }
738
+ let webhookAuthSelection = $("#node-config-input-webhookAuth");
739
+ webhookAuthSelection.typedInput({
740
+ type: "authentication",
741
+ types: [{
742
+ value: "authentication",
743
+ options: [{
744
+ value: "none",
745
+ label: "None"
746
+ }, {
747
+ value: "basic",
748
+ label: "BasicAuth"
749
+ }, {
750
+ value: "apikey",
751
+ label: "APIKey"
752
+ }]
753
+ }]
754
+ });
755
+ webhookAuthSelection.on("change", () => showSelectedAutnetication(webhookAuthSelection.val()));
756
+ showSelectedAutnetication(webhookAuthSelection.val());
757
+ let webhookAPIKeyMechanism = $("#node-config-input-webhookAuth_apikey_mechanism");
758
+ webhookAPIKeyMechanism.typedInput({
759
+ type: "apikeymechanism",
760
+ types: [{
761
+ value: "apikeymechansim",
762
+ options: [{
763
+ value: "header",
764
+ label: "Header"
765
+ }, {
766
+ value: "queryparam",
767
+ label: "Query Param"
768
+ }, {
769
+ value: "matrixparam",
770
+ label: "Matrix Param"
771
+ }]
772
+ }]
773
+ });
774
+ webhookAuthSelection.on("change", () => showSelectedAutnetication(webhookAuthSelection.val()));
775
+ showSelectedAutnetication(webhookAuthSelection.val());
776
+ let enableReverseProxy = $("#node-config-input-reverseProxies_enabled");
777
+ let reverseProxySection = $("#section_webhookconfig_reverseproxy");
778
+ enableReverseProxy.on("change", () => {
779
+ console.log("show / hide reverse proxy table");
780
+ if (enableReverseProxy.prop("checked")) {
781
+ reverseProxySection.show();
782
+ } else {
783
+ reverseProxySection.hide();
784
+ }
785
+ });
786
+ if (this.reverseProxies_enabled) {
787
+ reverseProxySection.show();
788
+ } else {
789
+ reverseProxySection.hide();
790
+ }
791
+ let getProxyTypes = async () => {
792
+ let types = [];
793
+ await $.ajax({
794
+ url: "nodetypeservice/find?tag=ReverseProxyType",
795
+ type: "GET",
796
+ contentType: "application/json; charset=utf-8",
797
+ data: JSON.stringify({
798
+ id: node.id
799
+ }),
800
+ success: (response) => {
801
+ types = response;
802
+ },
803
+ error: (jqXHR, textStatus, errorThrown) => {
804
+ console.log(jqXHR, textStatus, errorThrown);
805
+ },
806
+ });
807
+ return types;
808
+ }
809
+ let getProxies = async () => {
810
+ let proxies = [];
811
+ // get the list of types again.
812
+ let proxyTypes = (await getProxyTypes()).map(type => type.id);
813
+ // add all of the known proxies.
814
+ RED.nodes.eachConfig(cfg => {
815
+ if (proxyTypes.includes(cfg.type)) {
816
+ proxies.push({
817
+ id: cfg.id,
818
+ name: cfg.label(),
819
+ type: cfg.type
820
+ });
821
+ }
822
+ });
823
+ return proxies;
824
+ };
825
+ let reverseProxyList = $("#reverseproxylist_table");
826
+ reverseProxyList.editableList({
827
+ sortable: true,
828
+ removable: true,
829
+ height: 'auto',
830
+ scrollOnAdd: true,
831
+ addButton: 'Add ProxyHost',
832
+ header: $('<div>').append($.parseHTML(`
833
+ <div style='width:30%; margin-left:5%; display:inline-grid;'>Proxy</div>
834
+ <div style='width:auto; margin-right:5%; display:inline-grid;'>Domain Name</div>
835
+ `)),
836
+ buttons: [{
837
+ label: "Add Reverse Proxy",
838
+ icon: "fa fa-star",
839
+ title: "Add a reverse proxy configuration",
840
+ click: () => {
841
+ event.stopPropagation();
842
+ let $btn = $(event.target);
843
+ // Remove any existing dropdown
844
+ $('.proxy-dropdown').remove();
845
+ // Fetch the list of reverseproxy types.
846
+ getProxyTypes().then(proxyTypes => {
847
+ let $dropdown = $('<div class="proxy-dropdown red-ui-editor"></div>');
848
+ proxyTypes.forEach(proxyType => {
849
+ $('<div class="dropdown-item"></div>').text(proxyType.name).data('value', proxyType.id).css({
850
+ padding: '4px 8px',
851
+ cursor: 'pointer'
852
+ }).appendTo($dropdown);
853
+ });
854
+ // Position it near the button
855
+ $dropdown.css({
856
+ top: $btn.offset().top + $btn.height(),
857
+ left: $btn.offset().left
858
+ });
859
+ $('body').append($dropdown);
860
+ // Handle item selection
861
+ $dropdown.on('click', '.dropdown-item', function(e) {
862
+ e.stopPropagation();
863
+ const selectedValue = $(this).data('value');
864
+ const selectedText = $(this).text();
865
+ // Do whatever you need with the selection
866
+ $dropdown.remove();
867
+ RED.editor.editConfig("reverseproxy", selectedValue, "_ADD_");
868
+ });
869
+ })
870
+ },
871
+ }, {
872
+ label: "Edit Reverse Proxy",
873
+ icon: "fa fa-edit",
874
+ title: "Edit a reverse proxy configuration",
875
+ click: async (event) => {
876
+ event.stopPropagation();
877
+ // Remove any existing dropdown
878
+ $('.proxy-dropdown').remove();
879
+ // Build the dropdown from the select's options
880
+ const $dropdown = $('<div class="proxy-dropdown red-ui-editor"></div>');
881
+ (await getProxies()).forEach(proxy => {
882
+ $('<div class="dropdown-item"></div>').text(proxy.name).data('value', proxy.id).data('type', proxy.type).css({
883
+ padding: '4px 8px',
884
+ cursor: 'pointer'
885
+ }).appendTo($dropdown);
886
+ });
887
+ // Position it near the button
888
+ let $btn = $(event.target);
889
+ $dropdown.css({
890
+ top: $btn.offset().top + $btn.height(),
891
+ left: $btn.offset().left
892
+ });
893
+ $('body').append($dropdown);
894
+ // Handle item selection
895
+ $dropdown.on('click', '.dropdown-item', function(e) {
896
+ e.stopPropagation();
897
+ const selectedType = $(this).data('type');
898
+ const selectedValue = $(this).data('value');
899
+ const selectedText = $(this).text();
900
+ // Do whatever you need with the selection
901
+ $dropdown.remove();
902
+ RED.editor.editConfig("reverseproxy", selectedType, selectedValue);
903
+ });
904
+ }
905
+ }],
906
+ addItem: async function(container, i, proxy) {
907
+ let row = $('<div/>', {
908
+ class: 'form-row',
909
+ style: 'display: flex; margin-bottom: 0;'
910
+ }).appendTo(container);
911
+ let proxyColumn = $('<select/>', {
912
+ type: 'text',
913
+ name: i,
914
+ required: true,
915
+ style: 'margin-left: 5px; margin-bottom: 0;',
916
+ class: 'proxy-proxy'
917
+ }).appendTo(row);
918
+ (await getProxies()).forEach(proxy => {
919
+ $('<option value="' + proxy.id + '">' + proxy.name + '</option>').appendTo(proxyColumn);
920
+ });
921
+ proxyColumn.on("focus", async () => {
922
+ proxyColumn.empty();
923
+ (await getProxies()).forEach(proxy => {
924
+ $('<option value="' + proxy.id + '">' + proxy.name + '</option>').appendTo(proxyColumn);
925
+ })
926
+ });
927
+ proxyColumn.val(proxy.proxy);
928
+ // Add the Domain Name column
929
+ let domainnameColumn = $('<input/>', {
930
+ type: 'text',
931
+ name: i,
932
+ required: true,
933
+ style: 'margin-left: 5px; margin-bottom: 0;',
934
+ class: 'proxy-domainname'
935
+ }).appendTo(row)
936
+ domainnameColumn.val(proxy.domainname);
937
+ },
938
+ removeItem: function(data) {
939
+ // nothing to do here.
940
+ },
941
+ });
942
+ // Close dropdown when clicking anywhere else
943
+ $(document).on('click', function() {
944
+ $('.proxy-dropdown').remove();
945
+ });
946
+ this.reverseProxies_connections = (this.reverseProxies_connections) ? this.reverseProxies_connections : [];
947
+ reverseProxyList.editableList('addItems', this.reverseProxies_connections);
948
+ }
949
+ },
950
+ oneditsave: function() {
951
+ // **** webhook **** //
952
+ {
953
+ let node = this;
954
+ // pulling the values from the reverseproxy table.
955
+ let connectionList = $("#reverseproxylist_table").editableList('items');
956
+ node.reverseProxies_connections = [];
957
+ connectionList.each(function(i) {
958
+ node.reverseProxies_connections.push({
959
+ proxy: $(this).find('.proxy-proxy').val(),
960
+ domainname: $(this).find('.proxy-domainname').val(),
961
+ });
962
+ });
963
+ console.log(node.reverseProxies_connections);
964
+ }
965
+ // **** MetricsConfigNode_shaddowDefaults **** //
966
+ {
967
+ let node = this;
968
+ for (let i = 0; i < 10; i++) {
969
+ node["_reverseProxies_connections_" + i] = (node.reverseProxies_connections[i] || {}).proxy || "";
970
+ }
971
+ }
972
+ },
973
+ oneditcancel: function() {},
974
+ oneditdelete: function() {},
975
+ });
976
+
977
+ </script>
978
+
979
+
980
+ <script type="text/html" data-template-name='MetricsConfigNode'>
981
+ <div id='section_MetricsConfigNode'>
982
+ <div id="MetricsConfig">
983
+ <div class="form-row">
984
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
985
+ <input type="text" id="node-config-input-name" />
986
+ </div>
987
+ </div>
988
+
989
+ </div>
990
+
991
+ <div id='section_webhook'>
992
+ <div id="section_webhookconfig">
993
+ <div class="form-row editorsectionheading">
994
+ <i class="w-16 fa fa-eye"></i> <span>Webhook</span>
995
+ </div>
996
+
997
+ <div class="editorgroupborder">
998
+ <div class="form-row nomargin">
999
+ <label for="node-config-input-webhook">Server</label>
1000
+ <input id="node-config-input-webhook" placeholder="webhook" />
1001
+ </div>
1002
+
1003
+ <div class="form-row">
1004
+ <label for="node-config-input-webhookPath">Path</label>
1005
+ <input type="text" id="node-config-input-webhookPath" placeholder="/example" />
1006
+ </div>
1007
+
1008
+ <div class="form-row">
1009
+ <label for="node-config-input-webhookAuth">Authentication</label>
1010
+ <input type="text" id="node-config-input-webhookAuth" placeholder="none" />
1011
+ </div>
1012
+
1013
+ <div class="webhookauth webhookauth-none">
1014
+ </div>
1015
+
1016
+ <div class="webhookauth webhookauth-basic">
1017
+ <div class="form-row">
1018
+ <label for="node-config-input-webhookAuth_basic_username">Auth Username:</label>
1019
+ <input type="text" id="node-config-input-webhookAuth_basic_username" placeholder="testUser" />
1020
+ </div>
1021
+
1022
+ <div class="form-row">
1023
+ <label for="node-config-input-webhookAuth_basic_password">Auth Password:</label>
1024
+ <input type="password" id="node-config-input-webhookAuth_basic_password" placeholder="password" />
1025
+ </div>
1026
+ </div>
1027
+
1028
+ <div class="webhookauth webhookauth-apikey">
1029
+ <div class="form-row">
1030
+ <label for="node-config-input-webhookAuth_apikey_mechanism">APIKey Mechanism:</label>
1031
+ <input type="text" id="node-config-input-webhookAuth_apikey_mechanism" />
1032
+ </div>
1033
+
1034
+ <div class="form-row">
1035
+ <label for="node-config-input-webhookAuth_apikey_key">APIKey Key:</label>
1036
+ <input type="text" id="node-config-input-webhookAuth_apikey_key" placeholder="x-api-key" />
1037
+ </div>
1038
+
1039
+ <div class="form-row">
1040
+ <label for="node-config-input-webhookAuth_apikey_value">APIKey Value</label>
1041
+ <input type="text" id="node-config-input-webhookAuth_apikey_value" placeholder="testvalue" />
1042
+ </div>
1043
+ </div>
1044
+
1045
+ <div class="form-row">
1046
+ <label>Reverse Proxy</label>
1047
+ <input type="checkbox" id="node-config-input-reverseProxies_enabled" style="width:20px; margin-right:5px;" />
1048
+ <label style="width:auto" for="node-config-input-reverseProxies_enabled"><span>Enable Reverse Proxy</span></label>
1049
+ </div>
1050
+ <div id="section_webhookconfig_reverseproxy" style="display:none">
1051
+ <div class="form-row">
1052
+ <label></label>
1053
+ <ol id="reverseproxylist_table" class="theotherwillembotha-compact-table"></ol>
1054
+ </div>
1055
+ </div>
1056
+
1057
+
1058
+ </div>
1059
+ </div>
1060
+
1061
+ </div>
1062
+ </script>
1063
+
1064
+ <script type="text/markdown" data-help-name='MetricsConfigNode'>
1065
+ ### Inputs
1066
+ : *name* (string) : The common name for the metrics integration.
1067
+
1068
+ ### Webhook
1069
+ : *server* (webhookserverconfig) : the web server that this webhook will be bound to.
1070
+ : *path* (string) : the url path eg '/service' that should be regeistered on the webserver for this webhook callback
1071
+ : *authentication* (auth) : the authentication mechanism that should be used on this endpoint
1072
+ : *enable reverse proxy* (boolean) : whether this webhook will be exposed using a reverse proxy or not.
1073
+ : *reverse proxies* (reverse proxies) : the list of reverse proxies thie endpoint will be exposed on.
1074
+
1075
+ ### Webhook Authentication
1076
+ Three strategies are available for securing the webhook endpoint.
1077
+
1078
+ - None:
1079
+ The endpoint accepts all incoming requests without any credential check.
1080
+
1081
+ - Basic Auth:
1082
+ Validates the `Authorization` header on each incoming request against a username and password pair using HTTP Basic Authentication (RFC 7617).
1083
+ : *username* (string) : the username expected in the `Authorization` header
1084
+ : *password* (string) : the password expected in the `Authorization` header
1085
+
1086
+ - API Key:
1087
+ Validates a key/value pair carried in the request. Only the `Header` mechanism is currently supported — the key is read from a named request header and compared against the configured value. Requests that do not supply the correct key receive a `401` response.
1088
+ : *mechanism* (mechanism) : the transport mechanism for the key. Currently supported: `Header`
1089
+ : *key name* (string) : the name of the request header carrying the key (e.g. `x-api-key`)
1090
+ : *key value* (string) : the expected value — requests not matching this value are rejected
1091
+
1092
+ ### Reverse Proxy
1093
+ When *enable reverse proxy* is checked, the webhook endpoint is registered with one or more reverse proxy services installed in Node-RED. Reverse proxy types are discovered automatically from any plugin that registers a service tagged `ReverseProxyType` (e.g. an Nginx Proxy Manager integration). Each row in the list maps the internal webhook server to a public-facing domain.
1094
+
1095
+ : *proxy* (ReverseProxyType) : the reverse proxy service to register the endpoint with
1096
+ : *domain name* (string) : the public domain name to expose the endpoint on
1097
+
1098
+ The *external host* and *external port* fields on the linked **Webhook Server** config node must be set correctly for the proxy registration to resolve to the right internal address.
1099
+ </script>
1100
+ <script type="text/javascript">
1101
+ RED.nodes.registerType('CounterMetricConfigNode', {
1102
+ category: 'config',
1103
+ label: function() {
1104
+ return this.name
1105
+ },
1106
+ paletteLabel: 'Counter Metric Config',
1107
+ defaults: {
1108
+ name: {
1109
+ value: 'Counter Example',
1110
+ required: true
1111
+ },
1112
+ description: {
1113
+ value: 'an example couter',
1114
+ required: false
1115
+ },
1116
+ reset: {
1117
+ value: false,
1118
+ required: false
1119
+ },
1120
+ metricsEnabled: {
1121
+ value: false,
1122
+ required: true
1123
+ },
1124
+ metricsReference: {
1125
+ type: 'MetricsConfigNode',
1126
+ required: false
1127
+ },
1128
+ },
1129
+ oneditprepare: function() {
1130
+ // **** CounterMetricConfigNode **** //
1131
+ {
1132
+ // enable the metrics by default and hide the Enable metrics button.
1133
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1134
+ metricsEnabled.prop('checked', true);
1135
+ metricsEnabled.trigger("change");
1136
+ $("#section_metricsconfig").find(".metricsEnableCheck").hide();
1137
+ }
1138
+ // **** metrics **** //
1139
+ {
1140
+ let node = this;
1141
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1142
+ let metricsEnabledSection = $("#section_metricsEnabled");
1143
+ metricsEnabled.on('change', function() {
1144
+ if (metricsEnabled.prop("checked")) {
1145
+ metricsEnabledSection.show();
1146
+ node._def.defaults.metricsReference.required = true;
1147
+ } else {
1148
+ metricsEnabledSection.hide()
1149
+ node._def.defaults.metricsReference.required = false;
1150
+ }
1151
+ });
1152
+ }
1153
+ },
1154
+ oneditsave: function() {
1155
+ // **** metrics **** //
1156
+ {}
1157
+ },
1158
+ oneditcancel: function() {},
1159
+ oneditdelete: function() {},
1160
+ });
1161
+
1162
+ </script>
1163
+
1164
+
1165
+ <script type="text/html" data-template-name='CounterMetricConfigNode'>
1166
+ <div id='section_CounterMetricConfigNode'>
1167
+ <div id="MetricsConfig">
1168
+ <div class="form-row">
1169
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
1170
+ <input type="text" id="node-config-input-name" />
1171
+ </div>
1172
+
1173
+ <div class="form-row">
1174
+ <label for="node-config-input-description"><i class="fa fa-tag"></i> Description</label>
1175
+ <input type="text" id="node-config-input-description" />
1176
+ </div>
1177
+
1178
+ <div class="form-row">
1179
+ <label></label>
1180
+ <input type="checkbox" id="node-config-input-reset" style="width:20px; margin-right:5px;" />
1181
+ <label style="width:auto" for="node-config-input-reset"><span>Reset on Deploy</span></label>
1182
+ </div>
1183
+ </div>
1184
+
1185
+ </div>
1186
+
1187
+ <div id='section_metrics'>
1188
+ <div id="section_metricsconfig">
1189
+ <div class="form-row editorsectionheading">
1190
+ <i class="w-16 fa fa-eye"></i> <span>Metrics</span>
1191
+ </div>
1192
+ <div class="editorgroupborder">
1193
+ <div class="form-row nomargin metricsEnableCheck">
1194
+ <input type="checkbox" id="node-config-input-metricsEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;" />
1195
+ <label style="width:auto" for="node-config-input-metricsEnabled"><span>Enable Metrics</span></label>
1196
+ </div>
1197
+
1198
+ <div id="section_metricsEnabled">
1199
+ <div class="form-row nomargin">
1200
+ <label class="towb_editorlabel" for="node-config-input-metricsReference">Metric Collector</label>
1201
+ <input id="node-config-input-metricsReference" placeholder="metrics" />
1202
+ </div>
1203
+ </div>
1204
+ </div>
1205
+ </div>
1206
+
1207
+ </div>
1208
+ </script>
1209
+
1210
+ <script type="text/markdown" data-help-name='CounterMetricConfigNode'>
1211
+ Configuration node for the Counter Metrics
1212
+
1213
+ ### Inputs
1214
+ : *name* (string) : The common name for the counter.
1215
+ : *description* (string) : A description for the given counter
1216
+
1217
+
1218
+ ### Metrics
1219
+ : *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
1220
+ : *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
1221
+ </script>
1222
+ <script type="text/javascript">
1223
+ RED.nodes.registerType('GaugeMetricConfigNode', {
1224
+ category: 'config',
1225
+ label: function() {
1226
+ return this.name
1227
+ },
1228
+ paletteLabel: 'Gauge Metric Config',
1229
+ defaults: {
1230
+ name: {
1231
+ value: 'Metrics Example',
1232
+ required: true
1233
+ },
1234
+ description: {
1235
+ value: 'an example gauge',
1236
+ required: false
1237
+ },
1238
+ reset: {
1239
+ value: false,
1240
+ required: false
1241
+ },
1242
+ metricsEnabled: {
1243
+ value: false,
1244
+ required: true
1245
+ },
1246
+ metricsReference: {
1247
+ type: 'MetricsConfigNode',
1248
+ required: false
1249
+ },
1250
+ },
1251
+ oneditprepare: function() {
1252
+ // **** GaugeMetricConfigNode **** //
1253
+ {
1254
+ // enable the metrics by default and hide the Enable metrics button.
1255
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1256
+ metricsEnabled.prop('checked', true);
1257
+ metricsEnabled.trigger("change");
1258
+ $("#section_metricsconfig").find(".metricsEnableCheck").hide();
1259
+ }
1260
+ // **** metrics **** //
1261
+ {
1262
+ let node = this;
1263
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1264
+ let metricsEnabledSection = $("#section_metricsEnabled");
1265
+ metricsEnabled.on('change', function() {
1266
+ if (metricsEnabled.prop("checked")) {
1267
+ metricsEnabledSection.show();
1268
+ node._def.defaults.metricsReference.required = true;
1269
+ } else {
1270
+ metricsEnabledSection.hide()
1271
+ node._def.defaults.metricsReference.required = false;
1272
+ }
1273
+ });
1274
+ }
1275
+ },
1276
+ oneditsave: function() {
1277
+ // **** metrics **** //
1278
+ {}
1279
+ },
1280
+ oneditcancel: function() {},
1281
+ oneditdelete: function() {},
1282
+ });
1283
+
1284
+ </script>
1285
+
1286
+
1287
+ <script type="text/html" data-template-name='GaugeMetricConfigNode'>
1288
+ <div id='section_GaugeMetricConfigNode'>
1289
+ <div id="MetricsConfig">
1290
+ <div class="form-row">
1291
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
1292
+ <input type="text" id="node-config-input-name">
1293
+ </div>
1294
+
1295
+ <div class="form-row">
1296
+ <label for="node-config-input-description"><i class="fa fa-tag"></i> Description</label>
1297
+ <input type="text" id="node-config-input-description">
1298
+ </div>
1299
+
1300
+ <div class="form-row">
1301
+ <label></label>
1302
+ <input type="checkbox" id="node-config-input-reset" style="width:20px; margin-right:5px;">
1303
+ <label style="width:auto" for="node-config-input-reset"><span>Reset on Deploy</span></label>
1304
+ </div>
1305
+ </div>
1306
+
1307
+ </div>
1308
+
1309
+ <div id='section_metrics'>
1310
+ <div id="section_metricsconfig">
1311
+ <div class="form-row editorsectionheading">
1312
+ <i class="w-16 fa fa-eye"></i> <span>Metrics</span>
1313
+ </div>
1314
+ <div class="editorgroupborder">
1315
+ <div class="form-row nomargin metricsEnableCheck">
1316
+ <input type="checkbox" id="node-config-input-metricsEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;" />
1317
+ <label style="width:auto" for="node-config-input-metricsEnabled"><span>Enable Metrics</span></label>
1318
+ </div>
1319
+
1320
+ <div id="section_metricsEnabled">
1321
+ <div class="form-row nomargin">
1322
+ <label class="towb_editorlabel" for="node-config-input-metricsReference">Metric Collector</label>
1323
+ <input id="node-config-input-metricsReference" placeholder="metrics" />
1324
+ </div>
1325
+ </div>
1326
+ </div>
1327
+ </div>
1328
+
1329
+ </div>
1330
+ </script>
1331
+
1332
+ <script type="text/markdown" data-help-name='GaugeMetricConfigNode'>
1333
+ Configuration node for the Gauge Metrics
1334
+
1335
+ ### Inputs
1336
+ : *name* (string) : The common name for the gauge.
1337
+ : *description* (string) : A description for the given gauge.
1338
+
1339
+
1340
+ ### Metrics
1341
+ : *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
1342
+ : *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
1343
+ </script>
1344
+ <script type="text/javascript">
1345
+ RED.nodes.registerType('TimerMetricConfigNode', {
1346
+ category: 'config',
1347
+ label: function() {
1348
+ return this.name
1349
+ },
1350
+ paletteLabel: 'Timer Metric Config',
1351
+ defaults: {
1352
+ name: {
1353
+ value: 'Timer Example',
1354
+ required: true
1355
+ },
1356
+ description: {
1357
+ value: 'an example gauge',
1358
+ required: false
1359
+ },
1360
+ metricType: {
1361
+ required: true
1362
+ },
1363
+ buckettype: {
1364
+ value: 'Default',
1365
+ required: false
1366
+ },
1367
+ buckettype_manual_intervals: {
1368
+ value: '0.001, 0.01, 0.1, 1, 2, 5',
1369
+ required: false
1370
+ },
1371
+ buckettype_linear_start: {
1372
+ value: '0',
1373
+ required: false
1374
+ },
1375
+ buckettype_linear_interval: {
1376
+ value: '5',
1377
+ required: false
1378
+ },
1379
+ buckettype_linear_count: {
1380
+ value: '10',
1381
+ required: false
1382
+ },
1383
+ buckettype_exponential_start: {
1384
+ value: '1',
1385
+ required: false
1386
+ },
1387
+ buckettype_exponential_factor: {
1388
+ value: '2',
1389
+ required: false
1390
+ },
1391
+ buckettype_exponential_count: {
1392
+ value: '10',
1393
+ required: false
1394
+ },
1395
+ percentiletype: {
1396
+ value: 'Default',
1397
+ required: false
1398
+ },
1399
+ percentiletype_manual_intervals: {
1400
+ value: '0.01, 0.1, 0.9, 0.99',
1401
+ required: false
1402
+ },
1403
+ metricsEnabled: {
1404
+ value: false,
1405
+ required: true
1406
+ },
1407
+ metricsReference: {
1408
+ type: 'MetricsConfigNode',
1409
+ required: false
1410
+ },
1411
+ },
1412
+ oneditprepare: function() {
1413
+ // **** TimerMetricConfigNode **** //
1414
+ {
1415
+ let node = this;
1416
+ // bucket generator selection
1417
+ let selectBucketType = function(value) {
1418
+ $("#TimerMetricConfig").find(".metricsconfig_buckets").hide();
1419
+ $("#TimerMetricConfig").find(`.metricsconfig_buckets_${value}`).show();
1420
+ };
1421
+ let bucketTypeSelection = $("#node-config-input-buckettype");
1422
+ bucketTypeSelection.typedInput({
1423
+ type: "buckettype",
1424
+ types: [{
1425
+ value: "buckettype",
1426
+ options: [{
1427
+ value: "default",
1428
+ label: "Default"
1429
+ }, {
1430
+ value: "manual",
1431
+ label: "Manual"
1432
+ }, {
1433
+ value: "linear",
1434
+ label: "Linear"
1435
+ }, {
1436
+ value: "exponential",
1437
+ label: "Exponential"
1438
+ }, ]
1439
+ }]
1440
+ });
1441
+ bucketTypeSelection.on("change", () => selectBucketType(bucketTypeSelection.val()));
1442
+ selectBucketType(bucketTypeSelection.val());
1443
+ // percentile type selection.
1444
+ let selectPercentileType = function(value) {
1445
+ $("#TimerMetricConfig").find(".metricsconfig_percentiles").hide();
1446
+ $("#TimerMetricConfig").find(`.metricsconfig_percentiles_${value}`).show();
1447
+ }
1448
+ let percentileTypeSelection = $("#node-config-input-percentiletype");
1449
+ percentileTypeSelection.typedInput({
1450
+ type: "percentiletype",
1451
+ types: [{
1452
+ value: "percentiletype",
1453
+ options: [{
1454
+ value: "default",
1455
+ label: "Default"
1456
+ }, {
1457
+ value: "manual",
1458
+ label: "Manual"
1459
+ }, ]
1460
+ }]
1461
+ });
1462
+ percentileTypeSelection.on("change", () => selectPercentileType(percentileTypeSelection.val()));
1463
+ selectPercentileType(percentileTypeSelection.val());
1464
+ // metric type selection.
1465
+ let selectMetricType = function(value) {
1466
+ // show/hide the relevant metric type section.
1467
+ $("#TimerMetricConfig").find(`.metrictype`).hide();
1468
+ $("#TimerMetricConfig").find(`.metrictype_${value}`).show();
1469
+ bucketTypeSelection.trigger("change");
1470
+ percentileTypeSelection.trigger("change");
1471
+ }
1472
+ let metricTypeSelection = $("#node-config-input-metricType");
1473
+ metricTypeSelection.typedInput({
1474
+ type: "metricType",
1475
+ types: [{
1476
+ value: "metricType",
1477
+ options: [{
1478
+ value: "histogram",
1479
+ label: "Histogram"
1480
+ }, {
1481
+ value: "summary",
1482
+ label: "Summary"
1483
+ }, ]
1484
+ }]
1485
+ });
1486
+ metricTypeSelection.on("change", () => selectMetricType(metricTypeSelection.val()));
1487
+ selectMetricType(metricTypeSelection.val());
1488
+ // enable the metrics by default and hide the Enable metrics button.
1489
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1490
+ metricsEnabled.prop('checked', true);
1491
+ metricsEnabled.trigger("change");
1492
+ $("#section_metricsconfig").find(".metricsEnableCheck").hide();
1493
+ }
1494
+ // **** metrics **** //
1495
+ {
1496
+ let node = this;
1497
+ let metricsEnabled = $("#node-config-input-metricsEnabled");
1498
+ let metricsEnabledSection = $("#section_metricsEnabled");
1499
+ metricsEnabled.on('change', function() {
1500
+ if (metricsEnabled.prop("checked")) {
1501
+ metricsEnabledSection.show();
1502
+ node._def.defaults.metricsReference.required = true;
1503
+ } else {
1504
+ metricsEnabledSection.hide()
1505
+ node._def.defaults.metricsReference.required = false;
1506
+ }
1507
+ });
1508
+ }
1509
+ },
1510
+ oneditsave: function() {
1511
+ // **** metrics **** //
1512
+ {}
1513
+ },
1514
+ oneditcancel: function() {},
1515
+ oneditdelete: function() {},
1516
+ });
1517
+
1518
+ </script>
1519
+
1520
+
1521
+ <script type="text/html" data-template-name='TimerMetricConfigNode'>
1522
+ <div id='section_TimerMetricConfigNode'>
1523
+ <div id="TimerMetricConfig">
1524
+ <div class="form-row">
1525
+ <label class="towb_editorlabel" for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
1526
+ <input type="text" id="node-config-input-name" />
1527
+ </div>
1528
+
1529
+ <div class="form-row">
1530
+ <label class="towb_editorlabel" for="node-config-input-description"><i class="fa fa-tag"></i> Description</label>
1531
+ <input type="text" id="node-config-input-description" />
1532
+ </div>
1533
+
1534
+ <div class="form-row">
1535
+ <label class="towb_editorlabel" for="node-config-input-metricType"><i class="fa fa-tag"></i> Type</label>
1536
+ <input class="towb_editorfield" type="text" id="node-config-input-metricType" />
1537
+ </div>
1538
+
1539
+ <div class="metrictype metrictype_histogram">
1540
+ <div class="form-row">
1541
+ <label class="towb_editorlabel" for="node-config-input-buckettype"><i class="fa fa-tag"></i> Bucket Type</label>
1542
+ <input class="towb_editorfield" type="text" id="node-config-input-buckettype" />
1543
+ </div>
1544
+
1545
+ <div class="metricsconfig_buckets metricsconfig_buckets_default">
1546
+ <span>Default bucket sizes configured as 0.001, 0.01, 0.1, 1, 2, 5 seconds</span>
1547
+ </div>
1548
+
1549
+ <div class="metricsconfig_buckets metricsconfig_buckets_manual">
1550
+ <div class="form-row">
1551
+ <label class="towb_editorlabel" for="node-config-input-buckettype_manual_intervals"><i class="fa fa-tag"></i> Buckets</label>
1552
+ <input type="text" id="node-config-input-buckettype_manual_intervals" placeholder="0.001, 0.01, 0.1, 1, 2, 5" , value="0.001, 0.01, 0.1, 1, 2, 5" />
1553
+ </div>
1554
+ </div>
1555
+
1556
+ <div class="metricsconfig_buckets metricsconfig_buckets_linear">
1557
+ <div class="form-row">
1558
+ <label class="towb_editorlabel" for="node-config-input-buckettype_linear_start"><i class="fa fa-tag"></i> Start</label>
1559
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_linear_start" placeholder="0.000" , value="0.000" />
1560
+ </div>
1561
+ <div class="form-row">
1562
+ <label class="towb_editorlabel" for="node-config-input-buckettype_linear_inteval"><i class="fa fa-tag"></i> Interval</label>
1563
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_linear_interval" placeholder="10" , value="10" />
1564
+ </div>
1565
+ <div class="form-row">
1566
+ <label class="towb_editorlabel" for="node-config-input-buckettype_linear_count"><i class="fa fa-tag"></i> Count</label>
1567
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_linear_count" placeholder="10" , value="10" />
1568
+ </div>
1569
+ </div>
1570
+
1571
+ <div class="metricsconfig_buckets metricsconfig_buckets_exponential">
1572
+ <div class="form-row">
1573
+ <label class="towb_editorlabel" for="node-config-input-buckettype_exponential_start"><i class="fa fa-tag"></i> Start</label>
1574
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_exponential_start" placeholder="1" , value="1" />
1575
+ </div>
1576
+ <div class="form-row">
1577
+ <label class="towb_editorlabel" for="node-config-input-buckettype_exponential_factor"><i class="fa fa-tag"></i> Factor</label>
1578
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_exponential_factor" placeholder="2" , value="2" />
1579
+ </div>
1580
+ <div class="form-row">
1581
+ <label class="towb_editorlabel" for="node-config-input-buckettype_exponential_count"><i class="fa fa-tag"></i> Count</label>
1582
+ <input class="towb_editorfield_short" type="text" id="node-config-input-buckettype_exponential_count" placeholder="10" , value="10" />
1583
+ </div>
1584
+ </div>
1585
+ </div>
1586
+
1587
+ <div class="metrictype metrictype_summary">
1588
+ <div class="form-row">
1589
+ <label class="towb_editorlabel" for="node-config-input-percentiletype"><i class="fa fa-tag"></i> Percentile Type</label>
1590
+ <input type="text" id="node-config-input-percentiletype" />
1591
+ </div>
1592
+
1593
+ <div class="metricsconfig_percentiles metricsconfig_percentiles_default">
1594
+ <span>Default percentille sizes configured as [0.01, 0.1, 0.9, 0.99]</span>
1595
+ </div>
1596
+
1597
+ <div class="metricsconfig_percentiles metricsconfig_percentiles_manual">
1598
+ <div class="form-row">
1599
+ <label class="towb_editorlabel" for="node-config-input-percentiletype_manual_intervals"><i class="fa fa-tag"></i> Percentiles</label>
1600
+ <input class="towb_editorfield" type="text" id="node-config-input-percentiletype_manual_intervals" placeholder="0.01, 0.1, 0.9, 0.99" , value="0.01, 0.1, 0.9, 0.99" />
1601
+ </div>
1602
+ </div>
1603
+ </div>
1604
+ </div>
1605
+
1606
+ </div>
1607
+
1608
+ <div id='section_metrics'>
1609
+ <div id="section_metricsconfig">
1610
+ <div class="form-row editorsectionheading">
1611
+ <i class="w-16 fa fa-eye"></i> <span>Metrics</span>
1612
+ </div>
1613
+ <div class="editorgroupborder">
1614
+ <div class="form-row nomargin metricsEnableCheck">
1615
+ <input type="checkbox" id="node-config-input-metricsEnabled" value="false" style="margin:8px 0 10px 102px; width:20px;" />
1616
+ <label style="width:auto" for="node-config-input-metricsEnabled"><span>Enable Metrics</span></label>
1617
+ </div>
1618
+
1619
+ <div id="section_metricsEnabled">
1620
+ <div class="form-row nomargin">
1621
+ <label class="towb_editorlabel" for="node-config-input-metricsReference">Metric Collector</label>
1622
+ <input id="node-config-input-metricsReference" placeholder="metrics" />
1623
+ </div>
1624
+ </div>
1625
+ </div>
1626
+ </div>
1627
+
1628
+ </div>
1629
+ </script>
1630
+
1631
+ <script type="text/markdown" data-help-name='TimerMetricConfigNode'>
1632
+ Configuration node for the Timer Metrics
1633
+
1634
+ ### Inputs
1635
+ : *name* (string) : The common name for the timer.
1636
+ : *description* (string) : A description for the timer
1637
+ : *type* (string) : the type of timer metric ie. Histogram or Summary
1638
+
1639
+ #### Histogram
1640
+ : *type* (string) : the type of timer metric ie. Histogram or Summary
1641
+
1642
+ #### Summary
1643
+ : *percentile type* (string) : the type of percentile strategy. currently supported are default and manual
1644
+ : *percentiles* (string) : a comma separated list of percentiles to group observations into. note that the scale goes from 0 to 1.
1645
+
1646
+
1647
+ ### Metrics
1648
+ : *enable metrics* (boolean) : if checked, then the node will produce metrics output to the specified metrics provider.
1649
+ : *metric collector* (metricconfig) : the collection point or grouping where this particular metric will be attached.
1650
+ </script>
1651
+ <!-- WebhookServerConfigNode -->
1652
+ <script type="text/javascript">
1653
+ RED.nodes.registerType('WebhookServerConfigNode', {
1654
+ category: 'config',
1655
+ label: function() {
1656
+ return this.name
1657
+ },
1658
+ paletteLabel: 'Webhook',
1659
+ defaults: {
1660
+ name: {
1661
+ value: 'Example Test Node',
1662
+ required: true
1663
+ },
1664
+ port: {
1665
+ value: 6644,
1666
+ required: true
1667
+ },
1668
+ externalHost: {
1669
+ value: 'localhost',
1670
+ required: true
1671
+ },
1672
+ externalPort: {
1673
+ value: 6644,
1674
+ required: true
1675
+ },
1676
+ },
1677
+ oneditprepare: function() {},
1678
+ oneditsave: function() {},
1679
+ oneditcancel: function() {},
1680
+ oneditdelete: function() {},
1681
+ });
1682
+
1683
+ </script>
1684
+
1685
+
1686
+ <script type="text/html" data-template-name='WebhookServerConfigNode'>
1687
+ <div id='section_WebhookServerConfigNode'>\
1688
+ <div id="WebhookServerConfig">
1689
+ <div class="form-row">
1690
+ <label for="node-config-input-name"><i class="fa fa-tag"></i> Name</label>
1691
+ <input type="text" id="node-config-input-name" />
1692
+ </div>
1693
+
1694
+ <div class="form-row">
1695
+ <label for="node-config-input-port"><i class="fa fa-tag"></i> Port</label>
1696
+ <input type="number" id="node-config-input-port" />
1697
+ </div>
1698
+
1699
+ <div class="form-row">
1700
+ <label for="node-config-input-externalHost"><i class="fa fa-tag"></i> External Host</label>
1701
+ <input type="text" id="node-config-input-externalHost" />
1702
+ </div>
1703
+
1704
+ <div class="form-row">
1705
+ <label for="node-config-input-externalPort"><i class="fa fa-tag"></i> External Port</label>
1706
+ <input type="number" id="node-config-input-externalPort" />
1707
+ </div>
1708
+ <!-- add a button here to autmatically find an open port -->
1709
+ </div>
1710
+
1711
+
1712
+ </div>
1713
+ </script>
1714
+
1715
+ <script type="text/markdown" data-help-name='WebhookServerConfigNode'>
1716
+ Configuration node for an Express HTTP server that webhook nodes attach to. A single server instance is shared by all webhook nodes that reference it. The server is started when the flow is first deployed and stopped when it is torn down.
1717
+
1718
+ ### Inputs
1719
+ : *name* (string) : A descriptive name for this webhook server.
1720
+ : *port* (number) : The local port the HTTP server will listen on. Defaults to `6644`. Each server instance must use a unique port.
1721
+
1722
+ ### Reverse Proxy
1723
+ When this server sits behind a reverse proxy, configure the following fields so that webhook nodes know the externally-visible address. This is used when registering endpoints with a reverse proxy service.
1724
+
1725
+ : *external host* (string) : The public hostname or IP of the reverse proxy (e.g. `myserver.example.com`).
1726
+ : *external port* (number) : The public port exposed by the reverse proxy.
1727
+ </script>
1728
+
1729
+