@bonsae/nrg 0.6.1 → 0.6.2

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 (84) hide show
  1. package/README.md +5 -5
  2. package/package.json +13 -77
  3. package/{src/core/client → shims}/components.d.ts +2 -0
  4. package/{src/tsconfig → tsconfig}/client.json +3 -3
  5. package/types/client.d.ts +37 -0
  6. package/types/index.d.ts +211 -0
  7. package/types/server.d.ts +2293 -0
  8. package/types/vite.d.ts +12 -0
  9. package/build/vite/utils.js +0 -56
  10. package/src/core/client/app.vue +0 -185
  11. package/src/core/client/components/node-red-config-input.vue +0 -79
  12. package/src/core/client/components/node-red-editor-input.vue +0 -307
  13. package/src/core/client/components/node-red-input-label.vue +0 -53
  14. package/src/core/client/components/node-red-input.vue +0 -93
  15. package/src/core/client/components/node-red-json-schema-form.vue +0 -444
  16. package/src/core/client/components/node-red-select-input.vue +0 -108
  17. package/src/core/client/components/node-red-toggle.vue +0 -115
  18. package/src/core/client/components/node-red-typed-input.vue +0 -158
  19. package/src/core/client/index.ts +0 -500
  20. package/src/core/client/tsconfig.json +0 -18
  21. package/src/core/constants.ts +0 -18
  22. package/src/core/errors.ts +0 -9
  23. package/src/core/server/api/index.ts +0 -1
  24. package/src/core/server/api/serve-nrg-resources.ts +0 -54
  25. package/src/core/server/index.ts +0 -191
  26. package/src/core/server/nodes/config-node.ts +0 -67
  27. package/src/core/server/nodes/factories.ts +0 -136
  28. package/src/core/server/nodes/index.ts +0 -5
  29. package/src/core/server/nodes/io-node.ts +0 -179
  30. package/src/core/server/nodes/node.ts +0 -259
  31. package/src/core/server/nodes/types/config-node.ts +0 -28
  32. package/src/core/server/nodes/types/factories.ts +0 -130
  33. package/src/core/server/nodes/types/index.ts +0 -4
  34. package/src/core/server/nodes/types/io-node.ts +0 -40
  35. package/src/core/server/nodes/types/node.ts +0 -41
  36. package/src/core/server/nodes/utils.ts +0 -106
  37. package/src/core/server/schemas/base.ts +0 -66
  38. package/src/core/server/schemas/index.ts +0 -3
  39. package/src/core/server/schemas/type.ts +0 -95
  40. package/src/core/server/schemas/types/index.ts +0 -82
  41. package/src/core/server/tsconfig.json +0 -17
  42. package/src/core/server/types/index.ts +0 -220
  43. package/src/core/server/utils.ts +0 -56
  44. package/src/core/server/validator.ts +0 -36
  45. package/src/core/validator.ts +0 -222
  46. package/src/index.ts +0 -2
  47. package/src/types.ts +0 -189
  48. package/src/utils.ts +0 -20
  49. package/src/vite/async-utils.ts +0 -61
  50. package/src/vite/client/build.ts +0 -227
  51. package/src/vite/client/index.ts +0 -1
  52. package/src/vite/client/plugins/html-generator.ts +0 -75
  53. package/src/vite/client/plugins/index.ts +0 -5
  54. package/src/vite/client/plugins/locales-generator.ts +0 -126
  55. package/src/vite/client/plugins/minifier.ts +0 -23
  56. package/src/vite/client/plugins/node-definitions-inliner.ts +0 -275
  57. package/src/vite/client/plugins/static-copy.ts +0 -43
  58. package/src/vite/defaults.ts +0 -77
  59. package/src/vite/errors.ts +0 -37
  60. package/src/vite/index.ts +0 -2
  61. package/src/vite/logger.ts +0 -94
  62. package/src/vite/node-red-launcher.ts +0 -344
  63. package/src/vite/plugin.ts +0 -61
  64. package/src/vite/plugins/build.ts +0 -85
  65. package/src/vite/plugins/index.ts +0 -2
  66. package/src/vite/plugins/server.ts +0 -267
  67. package/src/vite/server/build.ts +0 -124
  68. package/src/vite/server/index.ts +0 -1
  69. package/src/vite/server/plugins/index.ts +0 -3
  70. package/src/vite/server/plugins/output-wrapper.ts +0 -109
  71. package/src/vite/server/plugins/package-json-generator.ts +0 -203
  72. package/src/vite/server/plugins/type-generator.ts +0 -442
  73. package/src/vite/types.ts +0 -174
  74. package/src/vite/utils.ts +0 -72
  75. /package/{build/index.js → index.js} +0 -0
  76. /package/{build/server → server}/index.cjs +0 -0
  77. /package/{build/server → server}/resources/nrg-client.js +0 -0
  78. /package/{build/server → server}/resources/vue.esm-browser.js +0 -0
  79. /package/{build/server → server}/resources/vue.esm-browser.prod.js +0 -0
  80. /package/{src/core/client → shims}/globals.d.ts +0 -0
  81. /package/{src/core/client → shims}/shims-vue.d.ts +0 -0
  82. /package/{src/tsconfig → tsconfig}/base.json +0 -0
  83. /package/{src/tsconfig → tsconfig}/server.json +0 -0
  84. /package/{build/vite → vite}/index.js +0 -0
@@ -1,500 +0,0 @@
1
- import type { Component, App } from "vue";
2
- import { createApp } from "vue";
3
- import { cloneDeep, isEqual } from "es-toolkit";
4
- import type { JSONSchemaType } from "ajv";
5
- import NodeRedVueApp from "./app.vue";
6
- import NodeRedInput from "./components/node-red-input.vue";
7
- import NodeRedTypedInput from "./components/node-red-typed-input.vue";
8
- import NodeRedConfigInput from "./components/node-red-config-input.vue";
9
- import NodeRedSelectInput from "./components/node-red-select-input.vue";
10
- import NodeRedEditorInput from "./components/node-red-editor-input.vue";
11
- import NodeRedInputLabel from "./components/node-red-input-label.vue";
12
- import NodeRedToggle from "./components/node-red-toggle.vue";
13
- import NodeRedJsonSchemaForm from "./components/node-red-json-schema-form.vue";
14
-
15
- const _schemas: Record<string, any> = {};
16
- const _forms: Record<string, Component> = {};
17
-
18
- function __setSchemas(schemas: Record<string, any>): void {
19
- Object.assign(_schemas, schemas);
20
- }
21
-
22
- function __setForms(forms: Record<string, Component>): void {
23
- Object.assign(_forms, forms);
24
- }
25
-
26
- interface NodeStateCredentials {
27
- [key: string]: any;
28
- }
29
-
30
- interface NodeState {
31
- credentials: NodeStateCredentials;
32
- [key: string]: any;
33
- }
34
-
35
- interface Node {
36
- id: string;
37
- type: string;
38
- name: string;
39
- category: string;
40
- x: string;
41
- y: string;
42
- g: string;
43
- z: string;
44
- credentials: Record<string, any>;
45
- _def: {
46
- defaults: Record<
47
- string,
48
- { value: string; type?: string; label?: string; required?: boolean }
49
- >;
50
- credentials: Record<
51
- string,
52
- {
53
- value: string;
54
- type?: "password" | "text";
55
- label?: string;
56
- required?: boolean;
57
- }
58
- >;
59
- category: string;
60
- color?: string;
61
- icon?: string;
62
- label?: ((this: Node) => string) | string;
63
- inputs?: number;
64
- outputs?: number;
65
- paletteLabel?: ((this: Node) => string) | string;
66
- labelStyle?: ((this: Node) => string) | string;
67
- inputLabels?: ((this: Node) => string) | string;
68
- outputLabels?: ((this: Node) => string) | string;
69
- align?: "left" | "right";
70
- button?: NodeButtonDefinition;
71
- onPaletteAdd?: (this: Node) => void;
72
- onPaletteRemove?: (this: Node) => void;
73
- form: NodeFormDefinition;
74
- };
75
- _newState?: Node;
76
- _app?: App | null;
77
- _: (str: string) => string;
78
- [key: string]: any;
79
- }
80
-
81
- /**
82
- * Interface representing the button configuration for a Node.
83
- *
84
- * @interface NodeButtonDefinition
85
- * @property {string} toggle - Text to display when toggling the button.
86
- * @property {function(): void} onclick - Function to execute when the button is clicked.
87
- * @property {function(): boolean} [enabled] - Function that determines whether the button should be
88
- * enabled. Returns true if the button should be enabled, false otherwise.
89
- * @property {function(): boolean} [visible] - Function that determines whether the button should be
90
- * visible. Returns true if the button should be visible, false otherwise.
91
- */
92
- interface NodeButtonDefinition {
93
- toggle: string;
94
- onclick: () => void;
95
- enabled?: () => boolean;
96
- visible?: () => boolean;
97
- }
98
-
99
- /**
100
- * Interface representing the form configuration for a Node.
101
- *
102
- * @interface NodeFormDefinition
103
- * @property {Component} [component] - Vue 3 component.
104
- */
105
- interface NodeFormDefinition {
106
- component?: Component;
107
- }
108
-
109
- /**
110
- * Interface representing the Node options used during registration
111
- *
112
- * @type NodeDefinition
113
- * @property {string} type - The unique identifier for this node type.
114
- * @property {string} category - The category this node belongs to in the palette.
115
- * @property {string} [color] - The color associated with this node, in hex format.
116
- * @property {string} [icon] - The icon to display for this node.
117
- * @property {(function(): string)|string} [label] - The label to display on the node. Can be a static string or a function returning a string.
118
- * @property {number} [inputs] - Number of input ports the node should have.
119
- * @property {number} [outputs] - Number of output ports the node should have.
120
- * @property {(function(): string)|string} [paletteLabel] - The label to show in the palette. Can be a static string or a function returning a string.
121
- * @property {(function(): string)|string} [labelStyle] - CSS style to apply to the node label. Can be a static string or a function returning a string.
122
- * @property {(function(): string)|string} [inputLabels] - Labels for the input ports. Can be a static string or a function returning a string.
123
- * @property {(function(): string)|string} [outputLabels] - Labels for the output ports. Can be a static string or a function returning a string.
124
- * @property {"left"|"right"} [align] - Alignment of the node content.
125
- * @property {NodeButtonDefinition} [button] - Configuration for a button on the node.
126
- * @property {function(): void} [onPaletteAdd] - Function called when the node is added to the palette.
127
- * @property {function(): void} [onPaletteRemove] - Function called when the node is removed from the palette.
128
- * @property {NodeFormDefinition} form - The form component to use for configuring the node.
129
- * @property {JSONSchemaType} [schema] - Schema definition for validation.
130
- */
131
- interface NodeDefinition {
132
- type: string;
133
- category?: string;
134
- color?: string;
135
- icon?: ((this: Node) => string) | string;
136
- label?: ((this: Node) => string) | string;
137
- inputs?: number;
138
- outputs?: number;
139
- paletteLabel?: ((this: Node) => string) | string;
140
- labelStyle?: ((this: Node) => string) | string;
141
- inputLabels?: ((this: Node) => string) | string;
142
- outputLabels?: ((this: Node) => string) | string;
143
- align?: "left" | "right";
144
- button?: NodeButtonDefinition;
145
- onEditResize?: (this: Node, size: { width: number; height: number }) => void;
146
- onPaletteAdd?: (this: Node) => void;
147
- onPaletteRemove?: (this: Node) => void;
148
- form?: NodeFormDefinition;
149
- }
150
-
151
- interface NodeFeatures {
152
- hasInputSchema: boolean;
153
- hasOutputSchema: boolean;
154
- }
155
-
156
- function createNodeRedVueApp(
157
- node: Node,
158
- form: NodeFormDefinition | undefined,
159
- schema: JSONSchemaType<any>,
160
- features: NodeFeatures,
161
- ): App<Element> {
162
- const app = createApp(NodeRedVueApp, {
163
- node,
164
- schema,
165
- features,
166
- });
167
-
168
- app.component("NodeRedInputLabel", NodeRedInputLabel);
169
- app.component("NodeRedToggle", NodeRedToggle);
170
- app.component("NodeRedInput", NodeRedInput);
171
- app.component("NodeRedTypedInput", NodeRedTypedInput);
172
- app.component("NodeRedConfigInput", NodeRedConfigInput);
173
- app.component("NodeRedSelectInput", NodeRedSelectInput);
174
- app.component("NodeRedEditorInput", NodeRedEditorInput);
175
- app.component("NodeRedJsonSchemaForm", NodeRedJsonSchemaForm);
176
- app.component("NodeRedNodeForm", form?.component ?? NodeRedJsonSchemaForm);
177
-
178
- // NOTE: now every form can use $i18n to access Node-RED built in i18n features
179
- app.config.globalProperties.$i18n = (label: string) =>
180
- node._(`${node.type}.${label}`);
181
- return app;
182
- }
183
-
184
- function mountApp(
185
- node: Node,
186
- form: NodeFormDefinition | undefined,
187
- schema: JSONSchemaType<any>,
188
- features: NodeFeatures,
189
- containerId: string,
190
- ) {
191
- $(`#${containerId}`).empty();
192
- node._newState = cloneDeep(node);
193
- node._app = createNodeRedVueApp(node._newState, form, schema, features);
194
- node._app.mount(`#${containerId}`);
195
- }
196
-
197
- function unmountApp(node: Node) {
198
- if (node._app) {
199
- node._app.unmount();
200
- node._app = null;
201
- }
202
- }
203
-
204
- function getNodeState(node: Node): NodeState {
205
- const state: NodeState = {
206
- credentials: {},
207
- };
208
- Object.keys(node._def.defaults ?? {}).forEach((prop) => {
209
- state[prop] = node[prop];
210
- });
211
- if (node._def.credentials) {
212
- Object.keys(node._def.credentials).forEach((prop) => {
213
- state.credentials[prop] = node.credentials?.[prop];
214
-
215
- if (node._def.credentials[prop].type === "password") {
216
- state.credentials[`has_${prop}`] =
217
- node.credentials?.[`has_${prop}`] || false;
218
- }
219
- });
220
- }
221
-
222
- return state;
223
- }
224
-
225
- function getChanges(
226
- o: Record<any, any>,
227
- n: Record<any, any>,
228
- ): Record<string, any> {
229
- const changes: Record<string, any> = {};
230
-
231
- const allKeys = new Set([...Object.keys(o), ...Object.keys(n ?? {})]);
232
- allKeys.forEach((prop) => {
233
- const _o = o[prop];
234
- const _n = (n ?? {})[prop];
235
-
236
- if (!Array.isArray(_o) && typeof _o === "object" && _o !== null) {
237
- const _changes = getChanges(_o, _n);
238
- if (Object.keys(_changes).length) {
239
- changes[prop] = _changes;
240
- }
241
- } else if (!isEqual(_o, _n)) {
242
- changes[prop] = _o;
243
- }
244
- });
245
-
246
- return changes;
247
- }
248
-
249
- // Deep-merge source into target, but replace arrays wholesale instead of
250
- // merging them element-by-element (es-toolkit merge keeps old array items
251
- // when the source is shorter, e.g. going from ["a","b"] to [] keeps ["a","b"]).
252
- function applyState(target: any, source: any): void {
253
- for (const key of Object.keys(source)) {
254
- const srcVal = source[key];
255
- if (Array.isArray(srcVal)) {
256
- target[key] = [...srcVal];
257
- } else if (srcVal !== null && typeof srcVal === "object") {
258
- if (
259
- !target[key] ||
260
- typeof target[key] !== "object" ||
261
- Array.isArray(target[key])
262
- ) {
263
- target[key] = {};
264
- }
265
- applyState(target[key], srcVal);
266
- } else {
267
- target[key] = srcVal;
268
- }
269
- }
270
- }
271
-
272
- function defineNode<T extends NodeDefinition>(options: T): T {
273
- return options;
274
- }
275
-
276
- /**
277
- * Prepares a node registration function using the provided base configuration.
278
- *
279
- * This is a higher-order function that returns a function which can be used
280
- * to register the node with a specific type at runtime.
281
- *
282
- * @param {Object} options - The static configuration shared by all nodes of this kind
283
- * @param {string} [options.category="undefined"] - The category this node belongs to in the palette
284
- * @param {string} [options.color="#FFFFFF"] - The color associated with this node, in hex format
285
- * @param {string} [options.icon] - The icon to display for this node
286
- * @param {(function(): string)|string} [options.label] - The label to display on the node
287
- * @param {number} [options.inputs=0] - Number of input ports the node should have
288
- * @param {number} [options.outputs=0] - Number of output ports the node should have
289
- * @param {(function(): string)|string} [options.paletteLabel] - The label to show in the palette
290
- * @param {(function(): string)|string} [options.labelStyle] - CSS style to apply to the node label
291
- * @param {(function(): string)|string} [options.inputLabels] - Labels for the input ports
292
- * @param {(function(): string)|string} [options.outputLabels] - Labels for the output ports
293
- * @param {"left"|"right"} [options.align="left"] - Alignment of the node content
294
- * @param {NodeButtonDefinition} [options.button] - Configuration for a button on the node
295
- * @param {function(): void} [options.onPaletteAdd] - Function called when the node is added to the palette
296
- * @param {function(): void} [options.onPaletteRemove] - Function called when the node is removed from the palette
297
- * @param {Component} options.form - The form component to use for configuring the node
298
- * @param {JSONSchemaType} [options.schema] - Schema definition for validation
299
- *
300
- * @returns A function that registers the node with the specified type
301
- */
302
- async function registerType(definition: NodeDefinition): Promise<void> {
303
- const { type } = definition;
304
- try {
305
- const nodeDefinition = {
306
- ...(_schemas[type] ?? {}),
307
- ...definition,
308
- };
309
-
310
- // defaults and credentials are pre-computed at build time by the inliner
311
- const defaults = nodeDefinition.defaults ?? undefined;
312
- const credentials = nodeDefinition.credentials ?? undefined;
313
-
314
- const appContainerId = `nrg-app-${type}`;
315
-
316
- $("<script>", {
317
- type: "text/html",
318
- "data-template-name": type,
319
- html: `<div id="${appContainerId}"></div>`,
320
- }).appendTo("body");
321
-
322
- function oneditprepare(this: Node) {
323
- const validationSchema =
324
- nodeDefinition.configSchema &&
325
- nodeDefinition.credentialsSchema?.properties
326
- ? {
327
- ...nodeDefinition.configSchema,
328
- properties: {
329
- ...nodeDefinition.configSchema.properties,
330
- credentials: {
331
- type: "object",
332
- properties: nodeDefinition.credentialsSchema.properties,
333
- },
334
- },
335
- }
336
- : nodeDefinition.configSchema;
337
-
338
- const form =
339
- definition.form ??
340
- (_forms[type] ? { component: _forms[type] } : undefined);
341
- const features: NodeFeatures = {
342
- hasInputSchema: !!nodeDefinition.inputSchema,
343
- hasOutputSchema: !!nodeDefinition.outputsSchema,
344
- };
345
- mountApp(this, form, validationSchema, features, appContainerId);
346
- }
347
-
348
- function oneditsave(this: Node) {
349
- // eslint-disable-next-line @typescript-eslint/no-this-alias
350
- const node = this;
351
- unmountApp(node);
352
-
353
- const newState = getNodeState(node._newState!);
354
- const oldState = getNodeState(node);
355
- const changes = getChanges(oldState, newState);
356
- const changed = !!Object.keys(changes)?.length;
357
- if (!changed) return false;
358
-
359
- Object.keys(node._def.defaults ?? {}).forEach((prop) => {
360
- if (!node._def.defaults?.[prop]?.type) return;
361
- const oldConfigNodeId: string = node[prop] as string;
362
- const newConfigNodeId: string = node._newState![prop] as string;
363
- if (oldConfigNodeId === newConfigNodeId) return;
364
- const oldConfigNode = RED.nodes.node(oldConfigNodeId);
365
- if (oldConfigNode && oldConfigNode._def.category === "config") {
366
- const idx = oldConfigNode.users.findIndex(
367
- (_node) => _node.id === node.id,
368
- );
369
- if (idx !== -1) {
370
- oldConfigNode.users.splice(idx, 1);
371
- }
372
- }
373
- });
374
-
375
- Object.keys(node._def.defaults ?? {}).forEach((prop) => {
376
- if (!node._def.defaults?.[prop]?.type) return;
377
- const newConfigNodeId: string = node._newState![prop] as string;
378
- if (!newConfigNodeId) return;
379
- const newConfigNode = RED.nodes.node(newConfigNodeId);
380
- if (newConfigNode && newConfigNode._def.category === "config") {
381
- const idx = newConfigNode.users.findIndex(
382
- (_node) => _node.id === node.id,
383
- );
384
- if (idx === -1) {
385
- newConfigNode.users.push(node);
386
- }
387
- }
388
- });
389
-
390
- applyState(node, newState);
391
-
392
- // For config nodes, populate the standard Node-RED input elements so
393
- // pane.apply() can read the new values after oneditsave returns.
394
- // Regular nodes must NOT have hidden inputs created here: pane.apply()
395
- // reads them back via input.val() which coerces arrays/objects to strings,
396
- // overwriting the correctly-typed values already set by merge() above.
397
- const isConfigNode = definition.category === "config";
398
- if (isConfigNode) {
399
- Object.keys(node._def.defaults ?? {}).forEach((prop) => {
400
- if (node._def.defaults[prop].type) return; // config-node refs handled separately
401
- const inputId = `node-config-input-${prop}`;
402
- let input = $(`#${inputId}`);
403
- if (!input.length) {
404
- input = $("<input>", { type: "hidden", id: inputId });
405
- $(`#${appContainerId}`).append(input);
406
- }
407
- input.val(newState[prop] ?? "");
408
- });
409
- return undefined;
410
- }
411
-
412
- return {
413
- changed,
414
- history: [
415
- {
416
- t: "edit",
417
- node,
418
- changes,
419
- links: [],
420
- dirty: RED.nodes.dirty(),
421
- changed,
422
- },
423
- ],
424
- };
425
- }
426
-
427
- function oneditcancel(this: Node) {
428
- unmountApp(this);
429
- }
430
-
431
- function oneditdelete(this: Node) {
432
- unmountApp(this);
433
- }
434
-
435
- RED.nodes.registerType(type, {
436
- type,
437
- defaults,
438
- credentials,
439
- category: nodeDefinition.category,
440
- color: nodeDefinition.color || "#FFFFFF",
441
- icon: nodeDefinition.icon,
442
- inputs: nodeDefinition.inputs || 0,
443
- outputs: nodeDefinition.outputs || 0,
444
- label:
445
- nodeDefinition.label ||
446
- function (this: Node) {
447
- return this.name || this._(`${type}.label`);
448
- },
449
- paletteLabel: nodeDefinition.paletteLabel || type,
450
- labelStyle: nodeDefinition.labelStyle,
451
- inputLabels: nodeDefinition.inputLabels,
452
- outputLabels: nodeDefinition.outputLabels,
453
- align: nodeDefinition.align || "left",
454
- button: nodeDefinition.button,
455
- oneditprepare,
456
- oneditsave,
457
- oneditcancel,
458
- oneditdelete,
459
- oneditresize: nodeDefinition.onEditResize,
460
- onpaletteadd: nodeDefinition.onPaletteAdd,
461
- onpaletteremove: nodeDefinition.onPaletteRemove,
462
- });
463
- } catch (error) {
464
- console.error(`Error while registering node type ${type}:`, error);
465
- throw error;
466
- }
467
- }
468
-
469
- /**
470
- * Registers multiple nodes with Node-RED in parallel.
471
- *
472
- * @param {Array<[string, NodeDefinition]>} nodes - Array of tuples containing node type and definition
473
- * @returns Resolves when all nodes are registered
474
- *
475
- * @example
476
- * await registerTypes([
477
- * ["remote-server", remoteServer],
478
- * ["your-node", yourNode],
479
- * ]);
480
- */
481
- async function registerTypes(nodes: NodeDefinition[]): Promise<void> {
482
- try {
483
- await Promise.all(nodes.map((definition) => registerType(definition)));
484
- } catch (error) {
485
- console.error("Error registering node types:", error);
486
- throw error;
487
- }
488
- }
489
-
490
- export {
491
- __setSchemas,
492
- __setForms,
493
- defineNode,
494
- registerType,
495
- registerTypes,
496
- NodeDefinition,
497
- NodeButtonDefinition,
498
- NodeFormDefinition,
499
- Node,
500
- };
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "noEmit": true,
11
- "noImplicitAny": false,
12
- "noImplicitOverride": true,
13
- "resolveJsonModule": true
14
- },
15
- "files": ["shims-vue.d.ts", "components.d.ts", "globals.d.ts"],
16
- "include": ["**/*.ts", "**/*.vue", "../constants.ts", "../validator.ts"],
17
- "exclude": ["node_modules"]
18
- }
@@ -1,18 +0,0 @@
1
- const TYPED_INPUT_TYPES = [
2
- "msg",
3
- "flow",
4
- "global",
5
- "str",
6
- "num",
7
- "bool",
8
- "json",
9
- "bin",
10
- "re",
11
- "jsonata",
12
- "date",
13
- "env",
14
- "node",
15
- "cred",
16
- ] as const;
17
-
18
- export { TYPED_INPUT_TYPES };
@@ -1,9 +0,0 @@
1
- class NrgError extends Error {
2
- constructor(message: string) {
3
- super(message);
4
- this.name = "NrgError";
5
- Object.setPrototypeOf(this, NrgError.prototype);
6
- }
7
- }
8
-
9
- export { NrgError };
@@ -1 +0,0 @@
1
- export { serveNrgResources } from "./serve-nrg-resources";
@@ -1,54 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import type { RED } from "../types";
4
-
5
- const MIME: Record<string, string> = {
6
- ".js": "application/javascript",
7
- ".mjs": "application/javascript",
8
- ".css": "text/css",
9
- ".json": "application/json",
10
- ".map": "application/json",
11
- ".png": "image/png",
12
- ".svg": "image/svg+xml",
13
- };
14
-
15
- let _registered = false;
16
-
17
- function serveNrgResources(RED: RED): void {
18
- if (_registered) return;
19
- _registered = true;
20
-
21
- const clientDir = path.resolve(__dirname, "./resources");
22
- if (!fs.existsSync(clientDir)) return;
23
-
24
- const httpAdmin = (RED as any).httpAdmin;
25
- if (!httpAdmin) return;
26
-
27
- // /nrg/assets/ is not handled by Node-RED's editorApp, so our handler
28
- // appended via use() is reached normally without any stack manipulation.
29
- httpAdmin.use(function (req: any, res: any, next: any) {
30
- const prefix = "/nrg/assets/";
31
- if (!(req.path as string).startsWith(prefix)) return next();
32
- let reqPath = (req.path as string).slice(prefix.length);
33
- // Serve the Vue dev build in development for devtools support
34
- if (
35
- reqPath === "vue.esm-browser.prod.js" &&
36
- process.env.NODE_ENV !== "production"
37
- ) {
38
- const devPath = path.resolve(clientDir, "vue.esm-browser.js");
39
- if (fs.existsSync(devPath)) {
40
- reqPath = "vue.esm-browser.js";
41
- }
42
- }
43
- const filePath = path.resolve(clientDir, reqPath);
44
- const rel = path.relative(clientDir, filePath);
45
- if (rel.startsWith("..") || path.isAbsolute(rel)) return next();
46
- if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile())
47
- return next();
48
- const ext = path.extname(filePath);
49
- res.setHeader("Content-Type", MIME[ext] ?? "application/octet-stream");
50
- fs.createReadStream(filePath).pipe(res);
51
- });
52
- }
53
-
54
- export { serveNrgResources };