@plitzi/sdk-schema 0.37.8 → 0.37.10
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/CHANGELOG.md +825 -0
- package/dist/SchemaReducer.d.ts +34 -4
- package/dist/SchemaReducer.mjs +143 -96
- package/dist/helpers/FlatMap.d.ts +9 -3
- package/dist/helpers/FlatMap.mjs +11 -10
- package/dist/helpers/components.d.ts +68 -0
- package/dist/helpers/components.mjs +130 -0
- package/dist/helpers/elementId.d.ts +4 -4
- package/dist/helpers/elementId.mjs +2 -0
- package/dist/helpers/fitSnippet.d.ts +32 -0
- package/dist/helpers/fitSnippet.mjs +71 -0
- package/dist/helpers/schemaValidator.d.ts +3 -0
- package/dist/helpers/schemaValidator.mjs +289 -176
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +4 -3
- package/package.json +12 -4
|
@@ -1,27 +1,37 @@
|
|
|
1
1
|
import { isValidElementId as e } from "./elementId.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { isInstance as t, propNameProblem as n } from "./components.mjs";
|
|
3
|
+
import { findLayoutCycle as r } from "@plitzi/sdk-shared/schema/layoutChain";
|
|
3
4
|
//#region src/helpers/schemaValidator.ts
|
|
4
|
-
var
|
|
5
|
+
var i = /* @__PURE__ */ new Set([
|
|
5
6
|
"UNRESOLVED_BINDING_SOURCE",
|
|
6
7
|
"MISMATCHED_BINDING_SOURCE",
|
|
7
|
-
"UNRESOLVED_INTERACTION_TARGET"
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
"UNRESOLVED_INTERACTION_TARGET",
|
|
9
|
+
"UNRESOLVED_COMPONENT",
|
|
10
|
+
"UNKNOWN_COMPONENT_SLOT"
|
|
11
|
+
]), a = (e) => !i.has(e.code), o = (i, a) => {
|
|
12
|
+
let s = [], c = [], { flat: l, pages: u, pageFolders: d, variables: f, components: p } = i, m = a?.baseElementId, h = (e) => !!l[e], g = (e) => l[e], _ = () => Object.values(l).filter((e) => e?.definition?.type === "layoutContainer" && !e.definition.parentId).map((e) => e.id), v = () => [.../* @__PURE__ */ new Set([
|
|
13
|
+
...u,
|
|
14
|
+
..._(),
|
|
15
|
+
...m ? [m] : []
|
|
16
|
+
])], y = () => !l || typeof l != "object" ? (s.push({
|
|
10
17
|
code: "INVALID_FLAT",
|
|
11
18
|
message: "Schema.flat must be a valid Record<string, Element>"
|
|
12
|
-
}), !1) : Array.isArray(
|
|
19
|
+
}), !1) : Array.isArray(u) ? Array.isArray(d) ? Array.isArray(f) ? !p || typeof p != "object" ? (s.push({
|
|
20
|
+
code: "INVALID_COMPONENTS",
|
|
21
|
+
message: "Schema.components must be a Record<string, SpaceComponent>"
|
|
22
|
+
}), !1) : !0 : (s.push({
|
|
13
23
|
code: "INVALID_VARIABLES",
|
|
14
24
|
message: "Schema.variables must be an array"
|
|
15
|
-
}), !1) : (
|
|
25
|
+
}), !1) : (s.push({
|
|
16
26
|
code: "INVALID_PAGE_FOLDERS",
|
|
17
27
|
message: "Schema.pageFolders must be an array"
|
|
18
|
-
}), !1) : (
|
|
28
|
+
}), !1) : (s.push({
|
|
19
29
|
code: "INVALID_PAGES",
|
|
20
30
|
message: "Schema.pages must be an array of element IDs"
|
|
21
|
-
}), !1),
|
|
22
|
-
Object.entries(
|
|
31
|
+
}), !1), b = () => {
|
|
32
|
+
Object.entries(l).forEach(([e, t]) => {
|
|
23
33
|
if (!t) {
|
|
24
|
-
|
|
34
|
+
s.push({
|
|
25
35
|
code: "NULL_ELEMENT",
|
|
26
36
|
message: `Element with id "${e}" is null or undefined`,
|
|
27
37
|
elementId: e
|
|
@@ -29,47 +39,47 @@ var n = /* @__PURE__ */ new Set([
|
|
|
29
39
|
return;
|
|
30
40
|
}
|
|
31
41
|
if (!t.id) {
|
|
32
|
-
|
|
42
|
+
s.push({
|
|
33
43
|
code: "MISSING_ID",
|
|
34
44
|
message: `Element at key "${e}" has no id property`
|
|
35
45
|
});
|
|
36
46
|
return;
|
|
37
47
|
}
|
|
38
|
-
if (t.id !== e &&
|
|
48
|
+
if (t.id !== e && s.push({
|
|
39
49
|
code: "ID_MISMATCH",
|
|
40
50
|
message: `Element id "${t.id}" doesn't match flat key "${e}"`,
|
|
41
51
|
elementId: e
|
|
42
52
|
}), !t.definition) {
|
|
43
|
-
|
|
53
|
+
s.push({
|
|
44
54
|
code: "MISSING_DEFINITION",
|
|
45
55
|
message: "Element missing definition",
|
|
46
56
|
elementId: e
|
|
47
57
|
});
|
|
48
58
|
return;
|
|
49
59
|
}
|
|
50
|
-
let { definition: n, attributes:
|
|
51
|
-
n.type ||
|
|
60
|
+
let { definition: n, attributes: r } = t;
|
|
61
|
+
n.type || s.push({
|
|
52
62
|
code: "MISSING_TYPE",
|
|
53
63
|
message: "Element missing definition.type",
|
|
54
64
|
elementId: e
|
|
55
|
-
}), n.label === void 0 &&
|
|
65
|
+
}), n.label === void 0 && s.push({
|
|
56
66
|
code: "MISSING_LABEL",
|
|
57
67
|
message: "Element missing definition.label",
|
|
58
68
|
elementId: e
|
|
59
|
-
}), n.rootId ||
|
|
69
|
+
}), n.rootId || s.push({
|
|
60
70
|
code: "MISSING_ROOT_ID",
|
|
61
71
|
message: "Element missing definition.rootId",
|
|
62
72
|
elementId: e
|
|
63
|
-
}), (!n.styleSelectors || typeof n.styleSelectors != "object") &&
|
|
73
|
+
}), (!n.styleSelectors || typeof n.styleSelectors != "object") && s.push({
|
|
64
74
|
code: "MISSING_STYLE_SELECTORS",
|
|
65
75
|
message: "Element missing or invalid definition.styleSelectors",
|
|
66
76
|
elementId: e
|
|
67
|
-
}),
|
|
77
|
+
}), r || c.push({
|
|
68
78
|
code: "MISSING_ATTRIBUTES",
|
|
69
79
|
message: "Element has no attributes",
|
|
70
80
|
elementId: e
|
|
71
81
|
}), n.items && (Array.isArray(n.items) ? n.items.forEach((t, n) => {
|
|
72
|
-
|
|
82
|
+
h(t) || s.push({
|
|
73
83
|
code: "ORPHANED_ITEM_REFERENCE",
|
|
74
84
|
message: `Element "${e}" references non-existent child "${t}" at items[${n}]`,
|
|
75
85
|
elementId: e,
|
|
@@ -78,24 +88,24 @@ var n = /* @__PURE__ */ new Set([
|
|
|
78
88
|
index: n
|
|
79
89
|
}
|
|
80
90
|
});
|
|
81
|
-
}) :
|
|
91
|
+
}) : s.push({
|
|
82
92
|
code: "INVALID_ITEMS",
|
|
83
93
|
message: "Element.definition.items must be an array",
|
|
84
94
|
elementId: e
|
|
85
|
-
})), n.parentId && !
|
|
95
|
+
})), n.parentId && !h(n.parentId) && s.push({
|
|
86
96
|
code: "ORPHANED_PARENT_REFERENCE",
|
|
87
97
|
message: `Element "${e}" has parentId "${n.parentId}" but parent doesn't exist in flat`,
|
|
88
98
|
elementId: e,
|
|
89
99
|
details: { parentId: n.parentId }
|
|
90
100
|
});
|
|
91
101
|
});
|
|
92
|
-
},
|
|
93
|
-
Object.values(
|
|
102
|
+
}, x = () => {
|
|
103
|
+
Object.values(l).forEach((e) => {
|
|
94
104
|
if (!e?.definition) return;
|
|
95
105
|
let { id: t, definition: n } = e;
|
|
96
106
|
if (n.items && n.items.forEach((e) => {
|
|
97
|
-
let n =
|
|
98
|
-
n?.definition && n.definition.parentId !== t &&
|
|
107
|
+
let n = g(e);
|
|
108
|
+
n?.definition && n.definition.parentId !== t && s.push({
|
|
99
109
|
code: "PARENT_CHILD_MISMATCH",
|
|
100
110
|
message: `Element "${e}" is in "${t}".items but has parentId "${n.definition.parentId}"`,
|
|
101
111
|
elementId: e,
|
|
@@ -105,87 +115,87 @@ var n = /* @__PURE__ */ new Set([
|
|
|
105
115
|
}
|
|
106
116
|
});
|
|
107
117
|
}), n.parentId) {
|
|
108
|
-
let e =
|
|
118
|
+
let e = g(n.parentId);
|
|
109
119
|
if (!e?.definition) return;
|
|
110
|
-
let
|
|
111
|
-
|
|
120
|
+
let r = e.definition.items || [];
|
|
121
|
+
r.includes(t) || s.push({
|
|
112
122
|
code: "PARENT_CHILD_MISMATCH",
|
|
113
123
|
message: `Element "${t}" has parentId "${n.parentId}" but parent doesn't have it in items`,
|
|
114
124
|
elementId: t,
|
|
115
125
|
details: {
|
|
116
126
|
parentId: n.parentId,
|
|
117
|
-
parentItems:
|
|
127
|
+
parentItems: r
|
|
118
128
|
}
|
|
119
129
|
});
|
|
120
130
|
}
|
|
121
131
|
});
|
|
122
|
-
},
|
|
123
|
-
let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = (
|
|
124
|
-
if (t.has(
|
|
132
|
+
}, S = () => {
|
|
133
|
+
let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = (r) => {
|
|
134
|
+
if (t.has(r)) return s.push({
|
|
125
135
|
code: "CIRCULAR_REFERENCE",
|
|
126
|
-
message: `Circular reference detected involving element "${
|
|
127
|
-
elementId:
|
|
136
|
+
message: `Circular reference detected involving element "${r}"`,
|
|
137
|
+
elementId: r
|
|
128
138
|
}), !0;
|
|
129
|
-
if (e.has(
|
|
130
|
-
e.add(
|
|
131
|
-
let
|
|
132
|
-
if (
|
|
133
|
-
for (let e of
|
|
139
|
+
if (e.has(r)) return !1;
|
|
140
|
+
e.add(r), t.add(r);
|
|
141
|
+
let i = g(r);
|
|
142
|
+
if (i?.definition?.items) {
|
|
143
|
+
for (let e of i.definition.items) if (n(e)) return t.delete(r), !0;
|
|
134
144
|
}
|
|
135
|
-
let
|
|
136
|
-
for (;
|
|
137
|
-
if (
|
|
145
|
+
let a = /* @__PURE__ */ new Set(), o = i;
|
|
146
|
+
for (; o?.definition?.parentId;) {
|
|
147
|
+
if (a.has(o.id)) return s.push({
|
|
138
148
|
code: "CIRCULAR_PARENT_REFERENCE",
|
|
139
|
-
message: `Circular parent reference detected involving element "${
|
|
140
|
-
elementId:
|
|
149
|
+
message: `Circular parent reference detected involving element "${o.id}"`,
|
|
150
|
+
elementId: o.id
|
|
141
151
|
}), !0;
|
|
142
|
-
|
|
152
|
+
a.add(o.id), o = g(o.definition.parentId);
|
|
143
153
|
}
|
|
144
|
-
return t.delete(
|
|
154
|
+
return t.delete(r), !1;
|
|
145
155
|
};
|
|
146
|
-
Object.keys(
|
|
156
|
+
Object.keys(l).forEach((t) => {
|
|
147
157
|
e.has(t) || n(t);
|
|
148
158
|
});
|
|
149
|
-
},
|
|
159
|
+
}, C = () => {
|
|
150
160
|
let e = /* @__PURE__ */ new Set(), t = 0;
|
|
151
|
-
|
|
152
|
-
e.has(n) &&
|
|
161
|
+
u.forEach((n, r) => {
|
|
162
|
+
e.has(n) && s.push({
|
|
153
163
|
code: "DUPLICATE_PAGE",
|
|
154
|
-
message: `Duplicate page ID "${n}" in pages array at index ${
|
|
164
|
+
message: `Duplicate page ID "${n}" in pages array at index ${r}`,
|
|
155
165
|
elementId: n
|
|
156
166
|
}), e.add(n);
|
|
157
|
-
let
|
|
158
|
-
if (!
|
|
159
|
-
|
|
167
|
+
let i = g(n);
|
|
168
|
+
if (!i) {
|
|
169
|
+
s.push({
|
|
160
170
|
code: "INVALID_PAGE_REFERENCE",
|
|
161
171
|
message: `Page ID "${n}" in pages array doesn't exist in flat`,
|
|
162
172
|
elementId: n
|
|
163
173
|
});
|
|
164
174
|
return;
|
|
165
175
|
}
|
|
166
|
-
|
|
176
|
+
i.definition.type !== "page" && s.push({
|
|
167
177
|
code: "INVALID_PAGE_TYPE",
|
|
168
|
-
message: `Element "${n}" in pages array has type "${
|
|
178
|
+
message: `Element "${n}" in pages array has type "${i.definition.type}" instead of "page"`,
|
|
169
179
|
elementId: n
|
|
170
|
-
}),
|
|
180
|
+
}), i.definition.rootId !== n && s.push({
|
|
171
181
|
code: "PAGE_ROOT_ID_MISMATCH",
|
|
172
|
-
message: `Page "${n}" has rootId "${
|
|
182
|
+
message: `Page "${n}" has rootId "${i.definition.rootId}" instead of its own ID`,
|
|
173
183
|
elementId: n
|
|
174
|
-
}),
|
|
175
|
-
}), t === 0 &&
|
|
184
|
+
}), i.attributes?.default && t++;
|
|
185
|
+
}), t === 0 && u.length > 0 ? c.push({
|
|
176
186
|
code: "NO_DEFAULT_PAGE",
|
|
177
187
|
message: "No default page found in schema"
|
|
178
|
-
}) : t > 1 &&
|
|
188
|
+
}) : t > 1 && c.push({
|
|
179
189
|
code: "MULTIPLE_DEFAULT_PAGES",
|
|
180
190
|
message: `Found ${t} default pages, expected 1`
|
|
181
191
|
});
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
let t =
|
|
192
|
+
}, w = () => {
|
|
193
|
+
v().forEach((e) => {
|
|
194
|
+
let t = g(e);
|
|
185
195
|
if (!t) return;
|
|
186
|
-
let n = (t) => {
|
|
187
|
-
let i =
|
|
188
|
-
i?.definition && (i.definition.rootId !== e &&
|
|
196
|
+
let n = /* @__PURE__ */ new Set([e]), r = (t) => {
|
|
197
|
+
let i = g(t);
|
|
198
|
+
i?.definition && !n.has(t) && (n.add(t), i.definition.rootId !== e && s.push({
|
|
189
199
|
code: "ROOT_ID_MISMATCH",
|
|
190
200
|
message: `Element "${t}" has rootId "${i.definition.rootId}" but should be "${e}" (its root's ID)`,
|
|
191
201
|
elementId: t,
|
|
@@ -193,124 +203,124 @@ var n = /* @__PURE__ */ new Set([
|
|
|
193
203
|
expectedRootId: e,
|
|
194
204
|
actualRootId: i.definition.rootId
|
|
195
205
|
}
|
|
196
|
-
}), i.definition.items && i.definition.items.forEach((e) =>
|
|
206
|
+
}), i.definition.items && i.definition.items.forEach((e) => r(e)));
|
|
197
207
|
};
|
|
198
|
-
t.definition.items && t.definition.items.forEach((e) =>
|
|
208
|
+
t.definition.items && t.definition.items.forEach((e) => r(e));
|
|
199
209
|
});
|
|
200
|
-
},
|
|
210
|
+
}, T = () => {
|
|
201
211
|
let e = /* @__PURE__ */ new Set();
|
|
202
|
-
|
|
212
|
+
d.forEach((t, n) => {
|
|
203
213
|
if (!t.id) {
|
|
204
|
-
|
|
214
|
+
s.push({
|
|
205
215
|
code: "INVALID_FOLDER",
|
|
206
216
|
message: `Page folder at index ${n} has no id`
|
|
207
217
|
});
|
|
208
218
|
return;
|
|
209
219
|
}
|
|
210
|
-
e.has(t.id) &&
|
|
220
|
+
e.has(t.id) && s.push({
|
|
211
221
|
code: "DUPLICATE_FOLDER",
|
|
212
222
|
message: `Duplicate folder ID "${t.id}"`,
|
|
213
223
|
elementId: t.id
|
|
214
|
-
}), e.add(t.id), t.parentId && (e.has(t.parentId) ||
|
|
224
|
+
}), e.add(t.id), t.parentId && (e.has(t.parentId) || s.push({
|
|
215
225
|
code: "ORPHANED_FOLDER_PARENT",
|
|
216
226
|
message: `Folder "${t.id}" has non-existent parent "${t.parentId}"`,
|
|
217
227
|
elementId: t.id,
|
|
218
228
|
details: { parentId: t.parentId }
|
|
219
229
|
}));
|
|
220
230
|
});
|
|
221
|
-
},
|
|
231
|
+
}, E = () => {
|
|
222
232
|
let e = /* @__PURE__ */ new Set();
|
|
223
|
-
|
|
224
|
-
let
|
|
225
|
-
|
|
233
|
+
_().forEach((t) => {
|
|
234
|
+
let n = r(g, t);
|
|
235
|
+
n.length === 0 || e.has(n[0]) || (n.forEach((t) => e.add(t)), s.push({
|
|
226
236
|
code: "LAYOUT_CYCLE",
|
|
227
|
-
message: `Layouts sit inside each other in a circle: ${
|
|
228
|
-
elementId:
|
|
229
|
-
details: { cycle:
|
|
237
|
+
message: `Layouts sit inside each other in a circle: ${n.join(" → ")}`,
|
|
238
|
+
elementId: t,
|
|
239
|
+
details: { cycle: n }
|
|
230
240
|
}));
|
|
231
241
|
});
|
|
232
|
-
},
|
|
233
|
-
let
|
|
234
|
-
if (
|
|
235
|
-
|
|
236
|
-
let r =
|
|
237
|
-
r?.definition?.items && r.definition.items.forEach((e) =>
|
|
238
|
-
},
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
let
|
|
242
|
-
|
|
242
|
+
}, D = () => {
|
|
243
|
+
let e = /* @__PURE__ */ new Set(), t = (n) => {
|
|
244
|
+
if (e.has(n)) return;
|
|
245
|
+
e.add(n);
|
|
246
|
+
let r = g(n);
|
|
247
|
+
r?.definition?.items && r.definition.items.forEach((e) => t(e));
|
|
248
|
+
}, n = /* @__PURE__ */ new Set(), r = (e) => {
|
|
249
|
+
if (n.has(e)) return;
|
|
250
|
+
n.add(e), t(e);
|
|
251
|
+
let i = g(e)?.attributes;
|
|
252
|
+
i?.layout && r(i.layout), i?.layoutContainer && t(i.layoutContainer);
|
|
243
253
|
};
|
|
244
|
-
|
|
245
|
-
let
|
|
246
|
-
Object.keys(
|
|
247
|
-
let n =
|
|
248
|
-
n && !
|
|
254
|
+
m ? r(m) : v().forEach(r);
|
|
255
|
+
let i = new Set(v());
|
|
256
|
+
Object.keys(l).forEach((t) => {
|
|
257
|
+
let n = g(t);
|
|
258
|
+
n && !e.has(t) && n.definition.type !== "page" && !i.has(t) && c.push({
|
|
249
259
|
code: "ORPHANED_ELEMENT",
|
|
250
|
-
message: `Element "${
|
|
251
|
-
elementId:
|
|
260
|
+
message: `Element "${t}" is not reachable from any page or layout`,
|
|
261
|
+
elementId: t
|
|
252
262
|
});
|
|
253
263
|
});
|
|
254
|
-
},
|
|
264
|
+
}, O = () => {
|
|
255
265
|
let e = /* @__PURE__ */ new Set();
|
|
256
|
-
|
|
266
|
+
f.forEach((t, n) => {
|
|
257
267
|
if (!t.name) {
|
|
258
|
-
|
|
268
|
+
s.push({
|
|
259
269
|
code: "INVALID_VARIABLE",
|
|
260
270
|
message: `Variable at index ${n} has no name`
|
|
261
271
|
});
|
|
262
272
|
return;
|
|
263
273
|
}
|
|
264
|
-
e.has(t.name) &&
|
|
274
|
+
e.has(t.name) && s.push({
|
|
265
275
|
code: "DUPLICATE_VARIABLE",
|
|
266
276
|
message: `Duplicate variable name "${t.name}"`,
|
|
267
277
|
details: { variableName: t.name }
|
|
268
|
-
}), e.add(t.name), t.type ||
|
|
278
|
+
}), e.add(t.name), t.type || c.push({
|
|
269
279
|
code: "MISSING_VARIABLE_TYPE",
|
|
270
280
|
message: `Variable "${t.name}" has no type`,
|
|
271
281
|
details: { variableName: t.name }
|
|
272
282
|
});
|
|
273
283
|
});
|
|
274
|
-
},
|
|
275
|
-
Object.values(
|
|
276
|
-
t && (e(t.id) ||
|
|
284
|
+
}, k = () => {
|
|
285
|
+
Object.values(l).forEach((t) => {
|
|
286
|
+
t && (e(t.id) || s.push({
|
|
277
287
|
code: "INVALID_ELEMENT_ID",
|
|
278
288
|
message: `Element "${t.id}" has a name that must start with a letter, then letters, numbers, hyphens and underscores (no hyphen or underscore at the start, and no hyphen at the end)`,
|
|
279
289
|
elementId: t.id
|
|
280
290
|
}));
|
|
281
291
|
});
|
|
282
|
-
},
|
|
283
|
-
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(),
|
|
284
|
-
Object.values(
|
|
285
|
-
if (!
|
|
286
|
-
t.add(
|
|
287
|
-
let a = e?.[
|
|
288
|
-
a &&
|
|
289
|
-
}), Object.values(
|
|
290
|
-
|
|
291
|
-
(
|
|
292
|
-
let c =
|
|
292
|
+
}, A = (e) => {
|
|
293
|
+
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Map();
|
|
294
|
+
Object.values(l).forEach((i) => {
|
|
295
|
+
if (!i) return;
|
|
296
|
+
t.add(i.id);
|
|
297
|
+
let a = e?.[i.definition.type];
|
|
298
|
+
a && r.set(i.id, a), n.add(i.definition.type);
|
|
299
|
+
}), Object.values(l).forEach((i) => {
|
|
300
|
+
i && i.definition.bindings && Object.entries(i.definition.bindings).forEach(([a, o]) => {
|
|
301
|
+
(o ?? []).forEach((o) => {
|
|
302
|
+
let c = o.source.split(".")[0], l = c.indexOf("_");
|
|
293
303
|
if (l === -1) return;
|
|
294
|
-
let u = c.slice(0, l), d = c.slice(l + 1), f = `Element "${
|
|
304
|
+
let u = c.slice(0, l), d = c.slice(l + 1), f = `Element "${i.id}" binds ${a}.${o.to} to "${o.source}"`;
|
|
295
305
|
if (!t.has(d)) {
|
|
296
|
-
(e || n.has(u)) &&
|
|
306
|
+
(e || n.has(u)) && s.push({
|
|
297
307
|
code: "UNRESOLVED_BINDING_SOURCE",
|
|
298
308
|
message: `${f}, but no element answers to the name "${d}"`,
|
|
299
|
-
elementId:
|
|
309
|
+
elementId: i.id,
|
|
300
310
|
details: {
|
|
301
|
-
source:
|
|
311
|
+
source: o.source,
|
|
302
312
|
elementId: d
|
|
303
313
|
}
|
|
304
314
|
});
|
|
305
315
|
return;
|
|
306
316
|
}
|
|
307
|
-
let p =
|
|
308
|
-
p && p !== u &&
|
|
317
|
+
let p = r.get(d);
|
|
318
|
+
p && p !== u && s.push({
|
|
309
319
|
code: "MISMATCHED_BINDING_SOURCE",
|
|
310
320
|
message: `${f}, but "${d}" publishes its source as "${p}_${d}"`,
|
|
311
|
-
elementId:
|
|
321
|
+
elementId: i.id,
|
|
312
322
|
details: {
|
|
313
|
-
source:
|
|
323
|
+
source: o.source,
|
|
314
324
|
elementId: d,
|
|
315
325
|
expected: `${p}_${d}`
|
|
316
326
|
}
|
|
@@ -318,87 +328,190 @@ var n = /* @__PURE__ */ new Set([
|
|
|
318
328
|
});
|
|
319
329
|
});
|
|
320
330
|
});
|
|
321
|
-
},
|
|
322
|
-
let t = new Set(Object.keys(
|
|
323
|
-
Object.values(
|
|
324
|
-
let
|
|
325
|
-
if (!
|
|
326
|
-
let
|
|
327
|
-
Object.entries(
|
|
328
|
-
e(
|
|
331
|
+
}, j = () => {
|
|
332
|
+
let t = new Set(Object.keys(l));
|
|
333
|
+
Object.values(l).forEach((n) => {
|
|
334
|
+
let r = n?.definition.interactions;
|
|
335
|
+
if (!r) return;
|
|
336
|
+
let i = Object.keys(r);
|
|
337
|
+
Object.entries(r).forEach(([r, a]) => {
|
|
338
|
+
e(r) || s.push({
|
|
329
339
|
code: "INVALID_INTERACTION_ID",
|
|
330
|
-
message: `Interaction "${
|
|
340
|
+
message: `Interaction "${r}" on element "${n.id}" has a name that must start with a letter, then letters, numbers, hyphens and underscores — a later step reads it as {{ ${r}.field }}`,
|
|
331
341
|
elementId: n.id
|
|
332
|
-
}),
|
|
342
|
+
}), a.id !== r && s.push({
|
|
333
343
|
code: "INTERACTION_ID_MISMATCH",
|
|
334
|
-
message: `Interaction id "${
|
|
344
|
+
message: `Interaction id "${a.id}" on element "${n.id}" doesn't match its key "${r}"`,
|
|
335
345
|
elementId: n.id
|
|
336
346
|
}), ["beforeNode", "afterNode"].forEach((e) => {
|
|
337
|
-
let t =
|
|
338
|
-
t && !
|
|
347
|
+
let t = a[e];
|
|
348
|
+
t && !i.includes(t) && s.push({
|
|
339
349
|
code: "BROKEN_FLOW_LINK",
|
|
340
|
-
message: `Interaction "${
|
|
350
|
+
message: `Interaction "${a.id}" on element "${n.id}" names ${e} "${t}", which is not a node of this flow`,
|
|
341
351
|
elementId: n.id
|
|
342
352
|
});
|
|
343
|
-
}),
|
|
353
|
+
}), a.flowId && !i.includes(a.flowId) && s.push({
|
|
344
354
|
code: "BROKEN_FLOW_ID",
|
|
345
|
-
message: `Interaction "${
|
|
355
|
+
message: `Interaction "${a.id}" on element "${n.id}" belongs to flow "${a.flowId}", which is not a node of this flow`,
|
|
346
356
|
elementId: n.id
|
|
347
|
-
}),
|
|
357
|
+
}), a.type === "callback" && a.elementId && !t.has(a.elementId) && s.push({
|
|
348
358
|
code: "UNRESOLVED_INTERACTION_TARGET",
|
|
349
|
-
message: `Interaction "${
|
|
359
|
+
message: `Interaction "${a.id}" on element "${n.id}" runs against "${a.elementId}", but no element answers to that name`,
|
|
350
360
|
elementId: n.id
|
|
351
361
|
});
|
|
352
|
-
let
|
|
353
|
-
|
|
362
|
+
let o = a.type === "trigger" && a.action === "onSubmit" && a.enabled ? g(a.elementId ?? n.id) : void 0;
|
|
363
|
+
o?.definition.type === "form" && o.attributes.managedByInteractions !== !0 && c.push({
|
|
354
364
|
code: "FORM_SUBMIT_UNMANAGED",
|
|
355
|
-
message: `Form "${
|
|
356
|
-
elementId:
|
|
365
|
+
message: `Form "${o.id}" has an onSubmit flow but is not managedByInteractions, so the browser submits it natively and the flow never runs — set managedByInteractions: true`,
|
|
366
|
+
elementId: o.id
|
|
357
367
|
});
|
|
358
368
|
});
|
|
359
369
|
});
|
|
360
|
-
},
|
|
361
|
-
Object.values(
|
|
370
|
+
}, M = () => {
|
|
371
|
+
Object.values(l).forEach((e) => {
|
|
362
372
|
if (!e || !e.definition.bindings) return;
|
|
363
373
|
let t = /* @__PURE__ */ new Set();
|
|
364
|
-
Object.entries(e.definition.bindings).forEach(([n,
|
|
365
|
-
(
|
|
366
|
-
if (!
|
|
367
|
-
|
|
374
|
+
Object.entries(e.definition.bindings).forEach(([n, r]) => {
|
|
375
|
+
(r ?? []).forEach((r) => {
|
|
376
|
+
if (!r.id) {
|
|
377
|
+
s.push({
|
|
368
378
|
code: "MISSING_BINDING_ID",
|
|
369
|
-
message: `Element "${e.id}" has a ${n} binding to "${
|
|
379
|
+
message: `Element "${e.id}" has a ${n} binding to "${r.to}" with no id`,
|
|
370
380
|
elementId: e.id
|
|
371
381
|
});
|
|
372
382
|
return;
|
|
373
383
|
}
|
|
374
|
-
t.has(
|
|
384
|
+
t.has(r.id) && s.push({
|
|
375
385
|
code: "DUPLICATE_BINDING_ID",
|
|
376
|
-
message: `Element "${e.id}" has two bindings called "${
|
|
386
|
+
message: `Element "${e.id}" has two bindings called "${r.id}"`,
|
|
377
387
|
elementId: e.id,
|
|
378
|
-
details: { bindingId:
|
|
379
|
-
}), t.add(
|
|
388
|
+
details: { bindingId: r.id }
|
|
389
|
+
}), t.add(r.id);
|
|
380
390
|
});
|
|
381
391
|
});
|
|
382
392
|
});
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
393
|
+
}, N = () => {
|
|
394
|
+
let r = new Map(Object.keys(l).map((e) => [e, ""])), u = (e) => e ? `component "${e}"` : "the pages", d = /* @__PURE__ */ new Map();
|
|
395
|
+
Object.entries(p).forEach(([t, l]) => {
|
|
396
|
+
let d = `Component "${t}"`;
|
|
397
|
+
l.id !== t && s.push({
|
|
398
|
+
code: "COMPONENT_ID_MISMATCH",
|
|
399
|
+
message: `${d} has id "${l.id}"`,
|
|
400
|
+
componentId: t
|
|
401
|
+
}), e(t) || s.push({
|
|
402
|
+
code: "INVALID_COMPONENT_ID",
|
|
403
|
+
message: `${d} has a name that must start with a letter, then letters, numbers, hyphens and underscores`,
|
|
404
|
+
componentId: t
|
|
405
|
+
});
|
|
406
|
+
let f = l.flat[l.rootId];
|
|
407
|
+
if (!f) {
|
|
408
|
+
s.push({
|
|
409
|
+
code: "COMPONENT_ROOT_MISSING",
|
|
410
|
+
message: `${d} is rooted at "${l.rootId}", which is not an element of its tree`,
|
|
411
|
+
componentId: t
|
|
412
|
+
});
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
f.definition.parentId && s.push({
|
|
416
|
+
code: "COMPONENT_ROOT_HAS_PARENT",
|
|
417
|
+
message: `${d} is rooted at "${l.rootId}", which names a parent — a component's root has none`,
|
|
418
|
+
elementId: l.rootId,
|
|
419
|
+
componentId: t
|
|
420
|
+
}), Object.keys(l.flat).forEach((e) => {
|
|
421
|
+
let n = r.get(e);
|
|
422
|
+
n === void 0 ? r.set(e, t) : s.push({
|
|
423
|
+
code: "DUPLICATE_ELEMENT_ID",
|
|
424
|
+
message: `"${e}" names an element of ${u(n)} and one of ${u(t)} — an id is one element in the whole space`,
|
|
425
|
+
elementId: e,
|
|
426
|
+
componentId: t
|
|
427
|
+
});
|
|
428
|
+
}), Object.keys(l.props ?? {}).forEach((e) => {
|
|
429
|
+
let r = n(e);
|
|
430
|
+
r && s.push({
|
|
431
|
+
code: "INVALID_COMPONENT_PROP",
|
|
432
|
+
message: `${d}: ${r}`,
|
|
433
|
+
componentId: t
|
|
434
|
+
});
|
|
435
|
+
}), (l.slots ?? []).forEach((e) => {
|
|
436
|
+
Object.hasOwn(l.flat, e) || s.push({
|
|
437
|
+
code: "MISSING_COMPONENT_SLOT",
|
|
438
|
+
message: `${d} declares slot "${e}", which is not an element of its tree`,
|
|
439
|
+
componentId: t
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
let p = o({
|
|
443
|
+
...i,
|
|
444
|
+
flat: l.flat,
|
|
445
|
+
pages: [],
|
|
446
|
+
pageFolders: [],
|
|
447
|
+
components: {}
|
|
448
|
+
}, {
|
|
449
|
+
baseElementId: l.rootId,
|
|
450
|
+
sourceTypes: a?.sourceTypes
|
|
451
|
+
}).validate();
|
|
452
|
+
p.errors.forEach((e) => s.push({
|
|
453
|
+
...e,
|
|
454
|
+
message: `${d}: ${e.message}`,
|
|
455
|
+
componentId: t
|
|
456
|
+
})), p.warnings.forEach((e) => c.push({
|
|
457
|
+
...e,
|
|
458
|
+
message: `${d}: ${e.message}`,
|
|
459
|
+
componentId: t
|
|
460
|
+
}));
|
|
461
|
+
}), [["", l], ...Object.entries(p).map(([e, t]) => [e, t.flat])].forEach(([e, n]) => {
|
|
462
|
+
Object.values(n).forEach((r) => {
|
|
463
|
+
if (!r || !t(r)) return;
|
|
464
|
+
let i = r.attributes.referenceId, a = typeof i == "string" ? p[i] : void 0;
|
|
465
|
+
if (!a || typeof i != "string") {
|
|
466
|
+
s.push({
|
|
467
|
+
code: "UNRESOLVED_COMPONENT",
|
|
468
|
+
message: `Instance "${r.id}" places component "${String(i)}", which this space does not declare`,
|
|
469
|
+
elementId: r.id,
|
|
470
|
+
...e ? { componentId: e } : {}
|
|
471
|
+
});
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
e && d.set(e, (d.get(e) ?? /* @__PURE__ */ new Set()).add(i)), (r.definition.items ?? []).forEach((t) => {
|
|
475
|
+
let o = n[t]?.attributes.slot ?? a.slots?.[0];
|
|
476
|
+
(typeof o != "string" || !a.slots?.includes(o)) && s.push({
|
|
477
|
+
code: "UNKNOWN_COMPONENT_SLOT",
|
|
478
|
+
message: `"${t}" fills ${typeof o == "string" ? `slot "${o}"` : "a slot"} of instance "${r.id}", but component "${i}" declares ${a.slots?.length ? `only ${a.slots.map((e) => `"${e}"`).join(", ")}` : "no slots"}`,
|
|
479
|
+
elementId: t,
|
|
480
|
+
...e ? { componentId: e } : {}
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
let f = /* @__PURE__ */ new Set(), m = (e, t) => {
|
|
486
|
+
if (t.includes(e)) {
|
|
487
|
+
let n = [...t.slice(t.indexOf(e)), e];
|
|
488
|
+
n.some((e) => f.has(e)) || (n.forEach((e) => f.add(e)), s.push({
|
|
489
|
+
code: "COMPONENT_CYCLE",
|
|
490
|
+
message: `Components place each other in a circle: ${n.join(" → ")}`,
|
|
491
|
+
componentId: e,
|
|
492
|
+
details: { cycle: n }
|
|
493
|
+
}));
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
d.get(e)?.forEach((n) => m(n, [...t, e]));
|
|
394
497
|
};
|
|
498
|
+
Object.keys(p).forEach((e) => m(e, []));
|
|
499
|
+
};
|
|
500
|
+
return { validate: () => y() ? (b(), x(), S(), C(), w(), T(), E(), D(), O(), k(), A(a?.sourceTypes), M(), j(), m || N(), {
|
|
501
|
+
valid: s.length === 0,
|
|
502
|
+
errors: s,
|
|
503
|
+
warnings: c
|
|
504
|
+
}) : {
|
|
505
|
+
valid: !1,
|
|
506
|
+
errors: s,
|
|
507
|
+
warnings: c
|
|
395
508
|
} };
|
|
396
|
-
},
|
|
397
|
-
let r =
|
|
509
|
+
}, s = (e, t) => o(e, t).validate(), c = (e, t, n) => {
|
|
510
|
+
let r = s(e, t);
|
|
398
511
|
if (!r.valid) {
|
|
399
512
|
let e = `Invalid schema${n ? ` (${n})` : ""}: ${r.errors.map((e) => e.message).join("; ")}`;
|
|
400
513
|
throw Error(e);
|
|
401
514
|
}
|
|
402
|
-
},
|
|
515
|
+
}, l = (e, t) => s(e, t).valid;
|
|
403
516
|
//#endregion
|
|
404
|
-
export {
|
|
517
|
+
export { i as REFERENCE_ERROR_CODES, c as assertSchemaValid, a as isIntegrityError, l as isSchemaValid, s as validateSchema };
|