@bonsae/nrg 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -40
- package/package.json +3 -2
- package/server/index.cjs +248 -237
- package/server/resources/nrg-client.js +514 -500
- package/test/index.js +131 -67
- package/types/server.d.ts +290 -1847
- package/types/shims/components.d.ts +13 -10
- package/types/shims/form/components/node-red-config-input.vue.d.ts +112 -0
- package/types/shims/form/components/node-red-editor-input.vue.d.ts +105 -0
- package/types/shims/form/components/node-red-input-label.vue.d.ts +34 -0
- package/types/shims/form/components/node-red-input.vue.d.ts +111 -0
- package/types/shims/form/components/node-red-json-schema-form.vue.d.ts +651 -0
- package/types/shims/form/components/node-red-select-input.vue.d.ts +117 -0
- package/types/shims/form/components/node-red-toggle.vue.d.ts +36 -0
- package/types/shims/form/components/node-red-typed-input.vue.d.ts +106 -0
- package/types/shims/globals.d.ts +1 -1
- package/types/shims/schema-options.d.ts +11 -0
- package/types/shims/typebox.d.ts +10 -0
- package/types/test.d.ts +391 -21
- package/types/vite.d.ts +164 -7
- package/vite/index.js +223 -31
- package/server/resources/vue.esm-browser.js +0 -18708
- package/server/resources/vue.esm-browser.prod.js +0 -13
package/test/index.js
CHANGED
|
@@ -3,19 +3,44 @@ import { vi as vi2 } from "vitest";
|
|
|
3
3
|
|
|
4
4
|
// src/test/mocks.ts
|
|
5
5
|
import { vi } from "vitest";
|
|
6
|
-
function
|
|
7
|
-
const {
|
|
8
|
-
|
|
6
|
+
function createNodeRedRuntime(options = {}) {
|
|
7
|
+
const { settings = {} } = options;
|
|
8
|
+
const nodes = {};
|
|
9
|
+
const red = {
|
|
9
10
|
log: {
|
|
10
11
|
info: vi.fn(),
|
|
11
12
|
warn: vi.fn(),
|
|
12
13
|
error: vi.fn(),
|
|
13
|
-
debug: vi.fn()
|
|
14
|
+
debug: vi.fn(),
|
|
15
|
+
trace: vi.fn(),
|
|
16
|
+
log: vi.fn(),
|
|
17
|
+
metric: vi.fn(() => false),
|
|
18
|
+
audit: vi.fn(),
|
|
19
|
+
addHandler: vi.fn(),
|
|
20
|
+
removeHandler: vi.fn(),
|
|
21
|
+
FATAL: 10,
|
|
22
|
+
ERROR: 20,
|
|
23
|
+
WARN: 30,
|
|
24
|
+
INFO: 40,
|
|
25
|
+
DEBUG: 50,
|
|
26
|
+
TRACE: 60,
|
|
27
|
+
AUDIT: 98,
|
|
28
|
+
METRIC: 99
|
|
14
29
|
},
|
|
15
30
|
nodes: {
|
|
16
31
|
getNode: vi.fn((id) => nodes[id]),
|
|
17
32
|
registerType: vi.fn(),
|
|
18
|
-
createNode: vi.fn()
|
|
33
|
+
createNode: vi.fn(),
|
|
34
|
+
getCredentials: vi.fn(),
|
|
35
|
+
eachNode: vi.fn(),
|
|
36
|
+
getType: vi.fn(),
|
|
37
|
+
getNodeInfo: vi.fn(),
|
|
38
|
+
getNodeList: vi.fn(() => []),
|
|
39
|
+
getModuleInfo: vi.fn(),
|
|
40
|
+
installModule: vi.fn(),
|
|
41
|
+
uninstallModule: vi.fn(),
|
|
42
|
+
enableNode: vi.fn(),
|
|
43
|
+
disableNode: vi.fn()
|
|
19
44
|
},
|
|
20
45
|
httpAdmin: {
|
|
21
46
|
get: vi.fn(),
|
|
@@ -24,6 +49,25 @@ function createMockRED(options = {}) {
|
|
|
24
49
|
delete: vi.fn(),
|
|
25
50
|
use: vi.fn()
|
|
26
51
|
},
|
|
52
|
+
httpNode: {
|
|
53
|
+
get: vi.fn(),
|
|
54
|
+
post: vi.fn(),
|
|
55
|
+
put: vi.fn(),
|
|
56
|
+
delete: vi.fn(),
|
|
57
|
+
use: vi.fn()
|
|
58
|
+
},
|
|
59
|
+
hooks: {
|
|
60
|
+
add: vi.fn(),
|
|
61
|
+
remove: vi.fn(),
|
|
62
|
+
trigger: vi.fn(),
|
|
63
|
+
has: vi.fn(() => false),
|
|
64
|
+
clear: vi.fn()
|
|
65
|
+
},
|
|
66
|
+
events: {
|
|
67
|
+
on: vi.fn(),
|
|
68
|
+
emit: vi.fn(),
|
|
69
|
+
removeListener: vi.fn()
|
|
70
|
+
},
|
|
27
71
|
settings: { ...settings },
|
|
28
72
|
_: vi.fn((key, subs) => {
|
|
29
73
|
if (!subs) return key;
|
|
@@ -80,18 +124,34 @@ function createMockRED(options = {}) {
|
|
|
80
124
|
callback(err, void 0);
|
|
81
125
|
}
|
|
82
126
|
}
|
|
83
|
-
)
|
|
127
|
+
),
|
|
128
|
+
generateId: vi.fn(() => "mock-id"),
|
|
129
|
+
cloneMessage: vi.fn((msg) => ({ ...msg })),
|
|
130
|
+
ensureString: vi.fn((o) => String(o)),
|
|
131
|
+
ensureBuffer: vi.fn(),
|
|
132
|
+
compareObjects: vi.fn(),
|
|
133
|
+
getMessageProperty: vi.fn(),
|
|
134
|
+
setMessageProperty: vi.fn(),
|
|
135
|
+
getObjectProperty: vi.fn(),
|
|
136
|
+
setObjectProperty: vi.fn(),
|
|
137
|
+
normalisePropertyExpression: vi.fn(),
|
|
138
|
+
normaliseNodeTypeName: vi.fn(),
|
|
139
|
+
prepareJSONataExpression: vi.fn(),
|
|
140
|
+
evaluateJSONataExpression: vi.fn(),
|
|
141
|
+
parseContextStore: vi.fn(),
|
|
142
|
+
getSetting: vi.fn(),
|
|
143
|
+
encodeObject: vi.fn()
|
|
84
144
|
},
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
145
|
+
version: vi.fn(() => "0.0.0-test"),
|
|
146
|
+
validator: void 0,
|
|
147
|
+
registerNode(id, nodeRedNode) {
|
|
148
|
+
nodes[id] = nodeRedNode;
|
|
88
149
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
},
|
|
93
|
-
version: vi.fn(() => "0.0.0-test")
|
|
150
|
+
registerNrgNode(id, nrgInstance) {
|
|
151
|
+
nodes[id] = createNodeRedNode({ id, _node: nrgInstance });
|
|
152
|
+
}
|
|
94
153
|
};
|
|
154
|
+
return red;
|
|
95
155
|
}
|
|
96
156
|
function getProperty(obj, path) {
|
|
97
157
|
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
|
@@ -113,7 +173,7 @@ function createContextStore() {
|
|
|
113
173
|
)
|
|
114
174
|
};
|
|
115
175
|
}
|
|
116
|
-
function
|
|
176
|
+
function createNodeRedNode(options = {}) {
|
|
117
177
|
const nodeCtx = createContextStore();
|
|
118
178
|
const flowCtx = createContextStore();
|
|
119
179
|
const globalCtx = createContextStore();
|
|
@@ -123,14 +183,14 @@ function createMockNodeRedNode(options = {}) {
|
|
|
123
183
|
global: globalCtx
|
|
124
184
|
};
|
|
125
185
|
return {
|
|
126
|
-
id: options.id ?? `
|
|
186
|
+
id: options.id ?? `node-${Math.random().toString(36).slice(2, 10)}`,
|
|
127
187
|
type: options.type ?? "test-node",
|
|
128
|
-
name: options.name ?? "",
|
|
188
|
+
name: options.name ?? "test-node",
|
|
129
189
|
z: options.z ?? "flow-1",
|
|
130
190
|
x: 100,
|
|
131
191
|
y: 200,
|
|
132
|
-
g:
|
|
133
|
-
wires: options.wires ?? [[]],
|
|
192
|
+
g: "group-1",
|
|
193
|
+
wires: options.wires ?? [["node-2"]],
|
|
134
194
|
credentials: options.credentials ?? {},
|
|
135
195
|
log: vi.fn(),
|
|
136
196
|
warn: vi.fn(),
|
|
@@ -189,11 +249,11 @@ var Validator = class {
|
|
|
189
249
|
*/
|
|
190
250
|
addCustomFormats(formats) {
|
|
191
251
|
if (!formats) return;
|
|
192
|
-
Object.entries(formats).forEach(([name,
|
|
193
|
-
if (
|
|
194
|
-
this.ajv.addFormat(name,
|
|
252
|
+
Object.entries(formats).forEach(([name, validator]) => {
|
|
253
|
+
if (validator instanceof RegExp) {
|
|
254
|
+
this.ajv.addFormat(name, validator);
|
|
195
255
|
} else {
|
|
196
|
-
this.ajv.addFormat(name, { validate:
|
|
256
|
+
this.ajv.addFormat(name, { validate: validator });
|
|
197
257
|
}
|
|
198
258
|
});
|
|
199
259
|
}
|
|
@@ -210,23 +270,23 @@ var Validator = class {
|
|
|
210
270
|
const cached = this.ajv.getSchema(schema.$id);
|
|
211
271
|
if (cached) return cached;
|
|
212
272
|
}
|
|
213
|
-
const
|
|
214
|
-
return
|
|
273
|
+
const validator = this.ajv.compile(schema);
|
|
274
|
+
return validator;
|
|
215
275
|
}
|
|
216
276
|
/**
|
|
217
277
|
* Validate data against a schema and return a structured result
|
|
218
278
|
*/
|
|
219
279
|
validate(data, schema, options) {
|
|
220
|
-
const
|
|
221
|
-
const valid =
|
|
280
|
+
const validator = this.createValidator(schema, options?.cacheKey);
|
|
281
|
+
const valid = validator(data);
|
|
222
282
|
if (!valid) {
|
|
223
|
-
const errorMessage = this.formatErrors(
|
|
283
|
+
const errorMessage = this.formatErrors(validator.errors);
|
|
224
284
|
if (options?.throwOnError) {
|
|
225
|
-
throw new ValidationError(errorMessage,
|
|
285
|
+
throw new ValidationError(errorMessage, validator.errors || []);
|
|
226
286
|
}
|
|
227
287
|
return {
|
|
228
288
|
valid: false,
|
|
229
|
-
errors:
|
|
289
|
+
errors: validator.errors || void 0,
|
|
230
290
|
errorMessage
|
|
231
291
|
};
|
|
232
292
|
}
|
|
@@ -286,30 +346,42 @@ var ValidationError = class _ValidationError extends Error {
|
|
|
286
346
|
};
|
|
287
347
|
|
|
288
348
|
// src/core/server/validation.ts
|
|
289
|
-
var validator = void 0;
|
|
290
349
|
function initValidator(RED) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
350
|
+
const nrg = {
|
|
351
|
+
validator: new Validator({
|
|
352
|
+
customKeywords: [
|
|
353
|
+
{
|
|
354
|
+
keyword: "x-nrg-skip-validation",
|
|
355
|
+
schemaType: "boolean",
|
|
356
|
+
valid: true
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
keyword: "x-nrg-node-type",
|
|
360
|
+
type: "string",
|
|
361
|
+
validate: (schemaValue, dataValue) => {
|
|
362
|
+
if (!dataValue) return true;
|
|
363
|
+
const node = RED.nodes.getNode(dataValue);
|
|
364
|
+
return node?.type === schemaValue;
|
|
365
|
+
}
|
|
305
366
|
}
|
|
367
|
+
],
|
|
368
|
+
customFormats: {
|
|
369
|
+
"node-id": /^[a-zA-Z0-9-_]+$/,
|
|
370
|
+
"flow-id": /^[a-f0-9]{16}$/,
|
|
371
|
+
"topic-path": (data) => /^[a-zA-Z0-9/_-]+$/.test(data)
|
|
306
372
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
373
|
+
})
|
|
374
|
+
};
|
|
375
|
+
Object.defineProperty(RED, "_nrg", {
|
|
376
|
+
value: nrg,
|
|
377
|
+
writable: false,
|
|
378
|
+
enumerable: false,
|
|
379
|
+
configurable: false
|
|
380
|
+
});
|
|
381
|
+
Object.defineProperty(RED, "validator", {
|
|
382
|
+
get: () => nrg.validator,
|
|
383
|
+
enumerable: false,
|
|
384
|
+
configurable: false
|
|
313
385
|
});
|
|
314
386
|
}
|
|
315
387
|
|
|
@@ -320,24 +392,14 @@ function buildConfig(NodeClass, userConfig = {}) {
|
|
|
320
392
|
for (const [key, prop] of Object.entries(
|
|
321
393
|
NodeClass.configSchema.properties
|
|
322
394
|
)) {
|
|
323
|
-
|
|
324
|
-
|
|
395
|
+
const schemaProp = prop;
|
|
396
|
+
if (schemaProp.default !== void 0) {
|
|
397
|
+
defaults[key] = schemaProp.default;
|
|
325
398
|
}
|
|
326
399
|
}
|
|
327
400
|
}
|
|
328
401
|
return { ...defaults, ...userConfig };
|
|
329
402
|
}
|
|
330
|
-
function buildNodeRedNodes(configNodes) {
|
|
331
|
-
const nodes = {};
|
|
332
|
-
for (const [id, value] of Object.entries(configNodes)) {
|
|
333
|
-
if (value && typeof value === "object" && "id" in value) {
|
|
334
|
-
nodes[id] = { _node: value };
|
|
335
|
-
} else {
|
|
336
|
-
nodes[id] = value;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
return nodes;
|
|
340
|
-
}
|
|
341
403
|
function attachHelpers(node, nodeRedNode) {
|
|
342
404
|
const sentMessages = [];
|
|
343
405
|
const statusCalls = [];
|
|
@@ -415,9 +477,11 @@ async function createNode(NodeClass, options = {}) {
|
|
|
415
477
|
resolvedConfig[key] = value;
|
|
416
478
|
}
|
|
417
479
|
}
|
|
418
|
-
const
|
|
419
|
-
const RED = createMockRED({ nodes: redNodes, settings });
|
|
480
|
+
const RED = createNodeRedRuntime({ settings });
|
|
420
481
|
initValidator(RED);
|
|
482
|
+
for (const [id, value] of Object.entries(configNodes)) {
|
|
483
|
+
RED.registerNrgNode(id, value);
|
|
484
|
+
}
|
|
421
485
|
const configDefaults = {
|
|
422
486
|
id: overrideOpts.id ?? `test-${Math.random().toString(36).slice(2, 10)}`,
|
|
423
487
|
type: NodeClass.type
|
|
@@ -429,7 +493,7 @@ async function createNode(NodeClass, options = {}) {
|
|
|
429
493
|
...configDefaults,
|
|
430
494
|
...resolvedConfig
|
|
431
495
|
});
|
|
432
|
-
const nodeRedNode =
|
|
496
|
+
const nodeRedNode = createNodeRedNode({
|
|
433
497
|
id: config.id,
|
|
434
498
|
type: NodeClass.type,
|
|
435
499
|
name: config.name ?? "",
|