@bonsae/nrg 0.21.1 → 0.22.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/LICENSE +21 -0
- package/README.md +2 -3
- package/package.json +14 -9
- package/schemas/labels.schema.json +15 -5
- package/server/index.cjs +2 -1346
- package/test/client/component/index.js +41 -224
- package/test/client/component/setup.js +201 -1475
- package/test/client/e2e/config.js +12 -0
- package/test/client/e2e/index.js +422 -199
- package/test/client/unit/index.js +19 -32
- package/test/client/unit/setup.js +28 -21
- package/test/server/integration/index.js +2 -26
- package/test/server/unit/index.js +2 -184
- package/types/client.d.ts +1 -259
- package/types/server.d.ts +1 -892
- package/types/test-client-component.d.ts +7 -143
- package/types/test-client-e2e.d.ts +0 -6
- package/types/test-client-unit.d.ts +11 -105
- package/types/test-server-integration.d.ts +73 -49
- package/types/test-server-unit.d.ts +26 -2
- package/types/vite.d.ts +2 -0
- package/vite/index.js +381 -150
- package/server/resources/nrg-client.js +0 -7495
- package/test/client/component/nrg.css +0 -1
- package/types/shims/brands.d.ts +0 -32
- package/types/shims/client/form/components/node-red-config-input.vue.d.ts +0 -125
- package/types/shims/client/form/components/node-red-editor-input.vue.d.ts +0 -124
- package/types/shims/client/form/components/node-red-input-label.vue.d.ts +0 -34
- package/types/shims/client/form/components/node-red-input.vue.d.ts +0 -123
- package/types/shims/client/form/components/node-red-json-schema-form.vue.d.ts +0 -772
- package/types/shims/client/form/components/node-red-select-input.vue.d.ts +0 -132
- package/types/shims/client/form/components/node-red-toggle.vue.d.ts +0 -36
- package/types/shims/client/form/components/node-red-typed-input.vue.d.ts +0 -151
- package/types/shims/client/globals.d.ts +0 -320
- package/types/shims/client/types.d.ts +0 -220
- package/types/shims/components.d.ts +0 -23
- package/types/shims/constants.d.ts +0 -4
- package/types/shims/schema-options.d.ts +0 -24
- package/types/shims/shims-vue.d.ts +0 -5
- package/types/shims/typebox.d.ts +0 -10
|
@@ -1,242 +1,59 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import F from "ajv-errors";
|
|
10
|
-
class b {
|
|
11
|
-
constructor(e) {
|
|
12
|
-
u(this, "ajv");
|
|
13
|
-
const { customKeywords: t, customFormats: o, ...s } = e || {};
|
|
14
|
-
this.ajv = new j({
|
|
15
|
-
allErrors: !0,
|
|
16
|
-
code: {
|
|
17
|
-
source: !1
|
|
18
|
-
},
|
|
19
|
-
coerceTypes: !0,
|
|
20
|
-
removeAdditional: !1,
|
|
21
|
-
strict: !1,
|
|
22
|
-
strictSchema: !1,
|
|
23
|
-
useDefaults: !0,
|
|
24
|
-
validateFormats: !0,
|
|
25
|
-
// NOTE: typebox handles validation via typescript
|
|
26
|
-
// NOTE: if true, types that are not serializable JSON, like Function, would not work
|
|
27
|
-
validateSchema: !1,
|
|
28
|
-
verbose: !0,
|
|
29
|
-
...s
|
|
30
|
-
}), $(this.ajv), F(this.ajv), this.addCustomKeywords(t || []), this.addCustomFormats(o || {});
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Add custom keywords to the validator
|
|
34
|
-
*/
|
|
35
|
-
addCustomKeywords(e) {
|
|
36
|
-
e && e.forEach((t) => {
|
|
37
|
-
this.ajv.addKeyword(t);
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Add custom formats to the validator
|
|
42
|
-
*/
|
|
43
|
-
addCustomFormats(e) {
|
|
44
|
-
e && Object.entries(e).forEach(([t, o]) => {
|
|
45
|
-
o instanceof RegExp ? this.ajv.addFormat(t, o) : this.ajv.addFormat(t, { validate: o });
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Create a validator function with caching
|
|
50
|
-
* @param schema - JSON Schema to validate against
|
|
51
|
-
* @param cacheKey - Optional cache key for reusing validators
|
|
52
|
-
*/
|
|
53
|
-
createValidator(e, t) {
|
|
54
|
-
if (t && !e.$id && (e.$id = t), e.$id) {
|
|
55
|
-
const s = this.ajv.getSchema(e.$id);
|
|
56
|
-
if (s) return s;
|
|
57
|
-
}
|
|
58
|
-
return this.ajv.compile(e);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Validate data against a schema and return a structured result
|
|
62
|
-
*/
|
|
63
|
-
validate(e, t, o) {
|
|
64
|
-
const s = this.createValidator(t, o == null ? void 0 : o.cacheKey);
|
|
65
|
-
if (!s(e)) {
|
|
66
|
-
const n = this.formatErrors(s.errors);
|
|
67
|
-
if (o != null && o.throwOnError)
|
|
68
|
-
throw new f(n, s.errors || []);
|
|
69
|
-
return {
|
|
70
|
-
valid: !1,
|
|
71
|
-
errors: s.errors || void 0,
|
|
72
|
-
errorMessage: n
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
valid: !0,
|
|
77
|
-
data: e
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Format errors into a human-readable string
|
|
82
|
-
*/
|
|
83
|
-
formatErrors(e, t) {
|
|
84
|
-
return !e || e.length === 0 ? "No errors" : this.ajv.errorsText(e, {
|
|
85
|
-
separator: "; ",
|
|
86
|
-
dataVar: "data",
|
|
87
|
-
...t
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Get detailed error information
|
|
92
|
-
*/
|
|
93
|
-
getDetailedErrors(e) {
|
|
94
|
-
return !e || e.length === 0 ? [] : e.map((t) => ({
|
|
95
|
-
field: t.instancePath || "/",
|
|
96
|
-
message: t.message || "Validation failed",
|
|
97
|
-
keyword: t.keyword,
|
|
98
|
-
params: t.params,
|
|
99
|
-
schemaPath: t.schemaPath
|
|
100
|
-
}));
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Add a schema to the validator for reference
|
|
104
|
-
*/
|
|
105
|
-
addSchema(e, t) {
|
|
106
|
-
return this.ajv.addSchema(e, t), this;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Remove a schema from the validator
|
|
110
|
-
*/
|
|
111
|
-
removeSchema(e) {
|
|
112
|
-
return this.ajv.removeSchema(e), this;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
class f extends Error {
|
|
116
|
-
constructor(e, t) {
|
|
117
|
-
super(e), this.errors = t, this.name = "ValidationError", Object.setPrototypeOf(this, f.prototype);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const k = new b({
|
|
121
|
-
customKeywords: [
|
|
122
|
-
{
|
|
123
|
-
keyword: "x-nrg-skip-validation",
|
|
124
|
-
schemaType: "boolean",
|
|
125
|
-
valid: !0
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
keyword: "x-nrg-node-type",
|
|
129
|
-
type: "string",
|
|
130
|
-
validate: (r, e) => {
|
|
131
|
-
if (!e) return !0;
|
|
132
|
-
const t = RED.nodes.node(e);
|
|
133
|
-
return !!t && t.type === r;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
],
|
|
137
|
-
customFormats: {
|
|
138
|
-
"node-id": /^[a-zA-Z0-9-_]+$/,
|
|
139
|
-
"flow-id": /^[a-f0-9]{16}$/,
|
|
140
|
-
"topic-path": (r) => /^[a-zA-Z0-9/_-]+$/.test(r)
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
function O(r, e) {
|
|
144
|
-
return r && (e != null && e.properties) ? {
|
|
145
|
-
...r,
|
|
146
|
-
properties: {
|
|
147
|
-
...r.properties,
|
|
148
|
-
credentials: {
|
|
149
|
-
type: "object",
|
|
150
|
-
properties: e.properties
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
} : r;
|
|
154
|
-
}
|
|
155
|
-
function P(r, e) {
|
|
156
|
-
const t = k.validate(r, e, {
|
|
157
|
-
cacheKey: `node-schema-${r.type}`
|
|
158
|
-
});
|
|
159
|
-
return t.valid ? [] : t.errors ?? [];
|
|
160
|
-
}
|
|
161
|
-
function v(r, e) {
|
|
162
|
-
return P(r, e).filter((t) => {
|
|
163
|
-
var s;
|
|
164
|
-
return ((s = t.parentSchema) == null ? void 0 : s.format) !== "password" ? !0 : w.get(r, t.instancePath) !== "__PWD__";
|
|
165
|
-
}).reduce(
|
|
166
|
-
(t, o) => {
|
|
167
|
-
var n;
|
|
168
|
-
let s = o.instancePath;
|
|
169
|
-
o.keyword === "required" && ((n = o.params) != null && n.missingProperty) && (s = `${s}/${o.params.missingProperty}`);
|
|
170
|
-
const i = `node${s.replaceAll("/", ".")}`;
|
|
171
|
-
return t[i] = o.message ?? "Invalid", t;
|
|
172
|
-
},
|
|
173
|
-
{}
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
function I() {
|
|
177
|
-
const r = m("__nrg_form_node"), e = m("__nrg_form_schema"), t = m("__nrg_form_errors");
|
|
178
|
-
if (!r)
|
|
179
|
-
throw new Error(
|
|
180
|
-
"useFormNode() must be called inside a form component mounted by NRG."
|
|
181
|
-
);
|
|
182
|
-
return {
|
|
183
|
-
node: r,
|
|
184
|
-
schema: e,
|
|
185
|
-
errors: t
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
let h = 0;
|
|
189
|
-
function Z(r = {}) {
|
|
190
|
-
const e = "configs" in r || "configSchema" in r || "credentialsSchema" in r || "nodes" in r ? r : { configs: r }, t = p({
|
|
191
|
-
id: `test-${h}`,
|
|
1
|
+
import { vi as f } from "vitest";
|
|
2
|
+
import { reactive as m, watch as _ } from "vue";
|
|
3
|
+
import { composeValidationSchema as g, validateForm as p } from "@bonsae/nrg-runtime/internal/client";
|
|
4
|
+
import { useFormNode as O } from "@bonsae/nrg-runtime/internal/client";
|
|
5
|
+
let l = 0;
|
|
6
|
+
function w(e = {}) {
|
|
7
|
+
const n = "configs" in e || "configSchema" in e || "credentialsSchema" in e || "nodes" in e ? e : { configs: e }, s = m({
|
|
8
|
+
id: `test-${l}`,
|
|
192
9
|
// Unique type per node: validateForm caches compiled schemas by
|
|
193
10
|
// `node-schema-${subject.type}`, so a shared type would silently reuse
|
|
194
11
|
// the first schema for every later createNode call in the same file.
|
|
195
|
-
type: `test-node-${
|
|
12
|
+
type: `test-node-${l++}`,
|
|
196
13
|
changed: !1,
|
|
197
14
|
_def: { outputs: 1 },
|
|
198
|
-
_: (
|
|
199
|
-
...
|
|
200
|
-
credentials: { ...
|
|
201
|
-
}),
|
|
202
|
-
|
|
203
|
-
|
|
15
|
+
_: (t) => t,
|
|
16
|
+
...n.configs,
|
|
17
|
+
credentials: { ...n.credentials }
|
|
18
|
+
}), a = g(
|
|
19
|
+
n.configSchema,
|
|
20
|
+
n.credentialsSchema
|
|
204
21
|
);
|
|
205
|
-
let
|
|
206
|
-
if (
|
|
207
|
-
const { $id:
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
for (const
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
22
|
+
let r;
|
|
23
|
+
if (a) {
|
|
24
|
+
const { $id: t, ...i } = a;
|
|
25
|
+
r = i;
|
|
26
|
+
}
|
|
27
|
+
const d = v();
|
|
28
|
+
u(d), d.nodes.clear();
|
|
29
|
+
for (const t of n.nodes ?? [])
|
|
30
|
+
d.nodes.add(t);
|
|
31
|
+
const c = m(
|
|
32
|
+
r ? p(s, r) : {}
|
|
216
33
|
);
|
|
217
|
-
return
|
|
218
|
-
|
|
34
|
+
return r && _(
|
|
35
|
+
s,
|
|
219
36
|
() => {
|
|
220
|
-
const
|
|
221
|
-
Object.keys(
|
|
37
|
+
const t = p(s, r);
|
|
38
|
+
Object.keys(c).forEach((i) => delete c[i]), Object.assign(c, t);
|
|
222
39
|
},
|
|
223
40
|
{ deep: !0 }
|
|
224
|
-
), { node:
|
|
225
|
-
__nrg_form_node:
|
|
226
|
-
__nrg_form_schema:
|
|
227
|
-
__nrg_form_errors:
|
|
41
|
+
), { node: s, errors: c, RED: d, provide: {
|
|
42
|
+
__nrg_form_node: s,
|
|
43
|
+
__nrg_form_schema: r ?? {},
|
|
44
|
+
__nrg_form_errors: c
|
|
228
45
|
} };
|
|
229
46
|
}
|
|
230
|
-
function
|
|
231
|
-
|
|
47
|
+
function o(e, n) {
|
|
48
|
+
f.isMockFunction(e[n]) || f.spyOn(e, n);
|
|
232
49
|
}
|
|
233
|
-
function
|
|
234
|
-
|
|
50
|
+
function u(e) {
|
|
51
|
+
o(e, "_"), o(e, "notify"), o(e.editor, "createEditor"), o(e.editor, "prepareConfigNodeSelect"), o(e.editor, "validateNode"), o(e.tray, "show"), o(e.tray, "close"), o(e.popover, "tooltip"), o(e.popover, "create"), o(e.nodes, "registerType"), o(e.nodes, "node"), o(e.nodes, "add"), o(e.nodes, "remove"), o(e.nodes, "getType"), o(e.nodes, "dirty"), o(e.events, "on"), o(e.events, "off"), o(e.events, "emit"), o(e.comms, "subscribe"), o(e.comms, "unsubscribe");
|
|
235
52
|
}
|
|
236
|
-
function
|
|
53
|
+
function v() {
|
|
237
54
|
return window.RED;
|
|
238
55
|
}
|
|
239
56
|
export {
|
|
240
|
-
|
|
241
|
-
|
|
57
|
+
w as createNode,
|
|
58
|
+
O as useFormNode
|
|
242
59
|
};
|