@plitzi/sdk-schema 0.36.0 → 0.36.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.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @plitzi/sdk-schema
|
|
2
2
|
|
|
3
|
+
## 0.36.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- v0.36.2
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @plitzi/sdk-shared@0.36.2
|
|
10
|
+
- @plitzi/sdk-style@0.36.2
|
|
11
|
+
|
|
12
|
+
## 0.36.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- v0.36.1
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @plitzi/sdk-shared@0.36.1
|
|
19
|
+
- @plitzi/sdk-style@0.36.1
|
|
20
|
+
|
|
3
21
|
## 0.36.0
|
|
4
22
|
|
|
5
23
|
### Minor Changes
|
|
@@ -74,7 +74,12 @@ declare class FlatMap {
|
|
|
74
74
|
updateVariable: (variable: SchemaVariable) => boolean;
|
|
75
75
|
removeVariables: (variables: string[]) => boolean;
|
|
76
76
|
removeVariable: (variable: string) => boolean;
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Everything an element is rendered inside, nearest first — its ancestors, and past a root the shell that root is
|
|
79
|
+
* shown in. A layout names its own shell the way a page does, so the walk continues through as many as are nested;
|
|
80
|
+
* `visited` keeps a document whose shells name each other from walking forever.
|
|
81
|
+
*/
|
|
82
|
+
parentTree: (elementId: Element["id"], visited?: Set<Element["id"]>) => string[];
|
|
78
83
|
childTree: (elementId: Element["id"]) => string[];
|
|
79
84
|
isValidElement: (element?: Partial<Element>) => boolean;
|
|
80
85
|
flatAsTemplate: (style: Style, elementId: Element["id"], excludeRoot?: boolean) => {
|
package/dist/helpers/FlatMap.mjs
CHANGED
|
@@ -151,17 +151,19 @@ var p = class {
|
|
|
151
151
|
return this.variables = this.variables.filter((t) => e.includes(t.name)), t !== this.variables.length;
|
|
152
152
|
};
|
|
153
153
|
removeVariable = (e) => this.removeVariables([e]);
|
|
154
|
-
parentTree = (e) => {
|
|
155
|
-
let
|
|
156
|
-
if (!
|
|
154
|
+
parentTree = (e, t = /* @__PURE__ */ new Set()) => {
|
|
155
|
+
let n = this.flat[e], r = [];
|
|
156
|
+
if (!n) return r;
|
|
157
157
|
do {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
let i = s(n, "definition.type");
|
|
159
|
+
if ((i === "page" || i === "layoutContainer") && !t.has(n.id)) {
|
|
160
|
+
t.add(n.id);
|
|
161
|
+
let e = s(n, "attributes.layout"), i = s(n, "attributes.layoutContainer");
|
|
162
|
+
e && i && r.push(i, ...this.parentTree(i, t));
|
|
161
163
|
}
|
|
162
|
-
e !==
|
|
163
|
-
} while (
|
|
164
|
-
return
|
|
164
|
+
e !== n.id && r.push(n.id), n = s(this.flat, s(n, "definition.parentId"), void 0);
|
|
165
|
+
} while (n);
|
|
166
|
+
return r;
|
|
165
167
|
};
|
|
166
168
|
childTree = (e) => {
|
|
167
169
|
let t = this.flat[e];
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { isValidElementId as e } from "./elementId.mjs";
|
|
2
|
+
import { findLayoutCycle as t } from "@plitzi/sdk-shared/schema/layoutChain";
|
|
2
3
|
//#region src/helpers/schemaValidator.ts
|
|
3
|
-
var
|
|
4
|
-
let
|
|
4
|
+
var n = (n) => {
|
|
5
|
+
let r = [], i = [], { flat: a, pages: o, pageFolders: s, variables: c } = n, l = (e) => !!a[e], u = (e) => a[e], d = () => Object.values(a).filter((e) => e?.definition?.type === "layoutContainer" && !e.definition.parentId).map((e) => e.id), f = () => [...o, ...d()], p = () => !a || typeof a != "object" ? (r.push({
|
|
5
6
|
code: "INVALID_FLAT",
|
|
6
7
|
message: "Schema.flat must be a valid Record<string, Element>"
|
|
7
|
-
}), !1) : Array.isArray(
|
|
8
|
+
}), !1) : Array.isArray(o) ? Array.isArray(s) ? Array.isArray(c) ? !0 : (r.push({
|
|
8
9
|
code: "INVALID_VARIABLES",
|
|
9
10
|
message: "Schema.variables must be an array"
|
|
10
|
-
}), !1) : (
|
|
11
|
+
}), !1) : (r.push({
|
|
11
12
|
code: "INVALID_PAGE_FOLDERS",
|
|
12
13
|
message: "Schema.pageFolders must be an array"
|
|
13
|
-
}), !1) : (
|
|
14
|
+
}), !1) : (r.push({
|
|
14
15
|
code: "INVALID_PAGES",
|
|
15
16
|
message: "Schema.pages must be an array of element IDs"
|
|
16
|
-
}), !1),
|
|
17
|
-
Object.entries(
|
|
17
|
+
}), !1), m = () => {
|
|
18
|
+
Object.entries(a).forEach(([e, t]) => {
|
|
18
19
|
if (!t) {
|
|
19
|
-
|
|
20
|
+
r.push({
|
|
20
21
|
code: "NULL_ELEMENT",
|
|
21
22
|
message: `Element with id "${e}" is null or undefined`,
|
|
22
23
|
elementId: e
|
|
@@ -24,163 +25,163 @@ var t = (t) => {
|
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
if (!t.id) {
|
|
27
|
-
|
|
28
|
+
r.push({
|
|
28
29
|
code: "MISSING_ID",
|
|
29
30
|
message: `Element at key "${e}" has no id property`
|
|
30
31
|
});
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
if (t.id !== e &&
|
|
34
|
+
if (t.id !== e && r.push({
|
|
34
35
|
code: "ID_MISMATCH",
|
|
35
36
|
message: `Element id "${t.id}" doesn't match flat key "${e}"`,
|
|
36
37
|
elementId: e
|
|
37
38
|
}), !t.definition) {
|
|
38
|
-
|
|
39
|
+
r.push({
|
|
39
40
|
code: "MISSING_DEFINITION",
|
|
40
41
|
message: "Element missing definition",
|
|
41
42
|
elementId: e
|
|
42
43
|
});
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
|
-
let { definition:
|
|
46
|
-
|
|
46
|
+
let { definition: n, attributes: a } = t;
|
|
47
|
+
n.type || r.push({
|
|
47
48
|
code: "MISSING_TYPE",
|
|
48
49
|
message: "Element missing definition.type",
|
|
49
50
|
elementId: e
|
|
50
|
-
}),
|
|
51
|
+
}), n.label === void 0 && r.push({
|
|
51
52
|
code: "MISSING_LABEL",
|
|
52
53
|
message: "Element missing definition.label",
|
|
53
54
|
elementId: e
|
|
54
|
-
}),
|
|
55
|
+
}), n.rootId || r.push({
|
|
55
56
|
code: "MISSING_ROOT_ID",
|
|
56
57
|
message: "Element missing definition.rootId",
|
|
57
58
|
elementId: e
|
|
58
|
-
}), (!
|
|
59
|
+
}), (!n.styleSelectors || typeof n.styleSelectors != "object") && r.push({
|
|
59
60
|
code: "MISSING_STYLE_SELECTORS",
|
|
60
61
|
message: "Element missing or invalid definition.styleSelectors",
|
|
61
62
|
elementId: e
|
|
62
|
-
}), a ||
|
|
63
|
+
}), a || i.push({
|
|
63
64
|
code: "MISSING_ATTRIBUTES",
|
|
64
65
|
message: "Element has no attributes",
|
|
65
66
|
elementId: e
|
|
66
|
-
}),
|
|
67
|
-
|
|
67
|
+
}), n.items && (Array.isArray(n.items) ? n.items.forEach((t, n) => {
|
|
68
|
+
l(t) || r.push({
|
|
68
69
|
code: "ORPHANED_ITEM_REFERENCE",
|
|
69
|
-
message: `Element "${e}" references non-existent child "${t}" at items[${
|
|
70
|
+
message: `Element "${e}" references non-existent child "${t}" at items[${n}]`,
|
|
70
71
|
elementId: e,
|
|
71
72
|
details: {
|
|
72
73
|
childId: t,
|
|
73
|
-
index:
|
|
74
|
+
index: n
|
|
74
75
|
}
|
|
75
76
|
});
|
|
76
|
-
}) :
|
|
77
|
+
}) : r.push({
|
|
77
78
|
code: "INVALID_ITEMS",
|
|
78
79
|
message: "Element.definition.items must be an array",
|
|
79
80
|
elementId: e
|
|
80
|
-
})),
|
|
81
|
+
})), n.parentId && !l(n.parentId) && r.push({
|
|
81
82
|
code: "ORPHANED_PARENT_REFERENCE",
|
|
82
|
-
message: `Element "${e}" has parentId "${
|
|
83
|
+
message: `Element "${e}" has parentId "${n.parentId}" but parent doesn't exist in flat`,
|
|
83
84
|
elementId: e,
|
|
84
|
-
details: { parentId:
|
|
85
|
+
details: { parentId: n.parentId }
|
|
85
86
|
});
|
|
86
87
|
});
|
|
87
|
-
},
|
|
88
|
-
Object.values(
|
|
88
|
+
}, h = () => {
|
|
89
|
+
Object.values(a).forEach((e) => {
|
|
89
90
|
if (!e?.definition) return;
|
|
90
|
-
let { id: t, definition:
|
|
91
|
-
if (
|
|
92
|
-
let
|
|
93
|
-
|
|
91
|
+
let { id: t, definition: n } = e;
|
|
92
|
+
if (n.items && n.items.forEach((e) => {
|
|
93
|
+
let n = u(e);
|
|
94
|
+
n?.definition && n.definition.parentId !== t && r.push({
|
|
94
95
|
code: "PARENT_CHILD_MISMATCH",
|
|
95
|
-
message: `Element "${e}" is in "${t}".items but has parentId "${
|
|
96
|
+
message: `Element "${e}" is in "${t}".items but has parentId "${n.definition.parentId}"`,
|
|
96
97
|
elementId: e,
|
|
97
98
|
details: {
|
|
98
99
|
expectedParent: t,
|
|
99
|
-
actualParent:
|
|
100
|
+
actualParent: n.definition.parentId
|
|
100
101
|
}
|
|
101
102
|
});
|
|
102
|
-
}),
|
|
103
|
-
let e =
|
|
103
|
+
}), n.parentId) {
|
|
104
|
+
let e = u(n.parentId);
|
|
104
105
|
if (!e?.definition) return;
|
|
105
106
|
let i = e.definition.items || [];
|
|
106
|
-
i.includes(t) ||
|
|
107
|
+
i.includes(t) || r.push({
|
|
107
108
|
code: "PARENT_CHILD_MISMATCH",
|
|
108
|
-
message: `Element "${t}" has parentId "${
|
|
109
|
+
message: `Element "${t}" has parentId "${n.parentId}" but parent doesn't have it in items`,
|
|
109
110
|
elementId: t,
|
|
110
111
|
details: {
|
|
111
|
-
parentId:
|
|
112
|
+
parentId: n.parentId,
|
|
112
113
|
parentItems: i
|
|
113
114
|
}
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
});
|
|
117
|
-
},
|
|
118
|
-
let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(),
|
|
119
|
-
if (t.has(i)) return
|
|
118
|
+
}, g = () => {
|
|
119
|
+
let e = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), n = (i) => {
|
|
120
|
+
if (t.has(i)) return r.push({
|
|
120
121
|
code: "CIRCULAR_REFERENCE",
|
|
121
122
|
message: `Circular reference detected involving element "${i}"`,
|
|
122
123
|
elementId: i
|
|
123
124
|
}), !0;
|
|
124
125
|
if (e.has(i)) return !1;
|
|
125
126
|
e.add(i), t.add(i);
|
|
126
|
-
let a =
|
|
127
|
+
let a = u(i);
|
|
127
128
|
if (a?.definition?.items) {
|
|
128
|
-
for (let e of a.definition.items) if (
|
|
129
|
+
for (let e of a.definition.items) if (n(e)) return t.delete(i), !0;
|
|
129
130
|
}
|
|
130
131
|
let o = /* @__PURE__ */ new Set(), s = a;
|
|
131
132
|
for (; s?.definition?.parentId;) {
|
|
132
|
-
if (o.has(s.id)) return
|
|
133
|
+
if (o.has(s.id)) return r.push({
|
|
133
134
|
code: "CIRCULAR_PARENT_REFERENCE",
|
|
134
135
|
message: `Circular parent reference detected involving element "${s.id}"`,
|
|
135
136
|
elementId: s.id
|
|
136
137
|
}), !0;
|
|
137
|
-
o.add(s.id), s =
|
|
138
|
+
o.add(s.id), s = u(s.definition.parentId);
|
|
138
139
|
}
|
|
139
140
|
return t.delete(i), !1;
|
|
140
141
|
};
|
|
141
|
-
Object.keys(
|
|
142
|
-
e.has(t) ||
|
|
142
|
+
Object.keys(a).forEach((t) => {
|
|
143
|
+
e.has(t) || n(t);
|
|
143
144
|
});
|
|
144
|
-
},
|
|
145
|
+
}, _ = () => {
|
|
145
146
|
let e = /* @__PURE__ */ new Set(), t = 0;
|
|
146
|
-
|
|
147
|
-
e.has(
|
|
147
|
+
o.forEach((n, i) => {
|
|
148
|
+
e.has(n) && r.push({
|
|
148
149
|
code: "DUPLICATE_PAGE",
|
|
149
|
-
message: `Duplicate page ID "${
|
|
150
|
-
elementId:
|
|
151
|
-
}), e.add(
|
|
152
|
-
let a =
|
|
150
|
+
message: `Duplicate page ID "${n}" in pages array at index ${i}`,
|
|
151
|
+
elementId: n
|
|
152
|
+
}), e.add(n);
|
|
153
|
+
let a = u(n);
|
|
153
154
|
if (!a) {
|
|
154
|
-
|
|
155
|
+
r.push({
|
|
155
156
|
code: "INVALID_PAGE_REFERENCE",
|
|
156
|
-
message: `Page ID "${
|
|
157
|
-
elementId:
|
|
157
|
+
message: `Page ID "${n}" in pages array doesn't exist in flat`,
|
|
158
|
+
elementId: n
|
|
158
159
|
});
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
161
|
-
a.definition.type !== "page" &&
|
|
162
|
+
a.definition.type !== "page" && r.push({
|
|
162
163
|
code: "INVALID_PAGE_TYPE",
|
|
163
|
-
message: `Element "${
|
|
164
|
-
elementId:
|
|
165
|
-
}), a.definition.rootId !==
|
|
164
|
+
message: `Element "${n}" in pages array has type "${a.definition.type}" instead of "page"`,
|
|
165
|
+
elementId: n
|
|
166
|
+
}), a.definition.rootId !== n && r.push({
|
|
166
167
|
code: "PAGE_ROOT_ID_MISMATCH",
|
|
167
|
-
message: `Page "${
|
|
168
|
-
elementId:
|
|
168
|
+
message: `Page "${n}" has rootId "${a.definition.rootId}" instead of its own ID`,
|
|
169
|
+
elementId: n
|
|
169
170
|
}), a.attributes?.default && t++;
|
|
170
|
-
}), t === 0 &&
|
|
171
|
+
}), t === 0 && o.length > 0 ? i.push({
|
|
171
172
|
code: "NO_DEFAULT_PAGE",
|
|
172
173
|
message: "No default page found in schema"
|
|
173
|
-
}) : t > 1 &&
|
|
174
|
+
}) : t > 1 && i.push({
|
|
174
175
|
code: "MULTIPLE_DEFAULT_PAGES",
|
|
175
176
|
message: `Found ${t} default pages, expected 1`
|
|
176
177
|
});
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
let t =
|
|
178
|
+
}, v = () => {
|
|
179
|
+
f().forEach((e) => {
|
|
180
|
+
let t = u(e);
|
|
180
181
|
if (!t) return;
|
|
181
|
-
let
|
|
182
|
-
let i =
|
|
183
|
-
i?.definition && (i.definition.rootId !== e &&
|
|
182
|
+
let n = (t) => {
|
|
183
|
+
let i = u(t);
|
|
184
|
+
i?.definition && (i.definition.rootId !== e && r.push({
|
|
184
185
|
code: "ROOT_ID_MISMATCH",
|
|
185
186
|
message: `Element "${t}" has rootId "${i.definition.rootId}" but should be "${e}" (its root's ID)`,
|
|
186
187
|
elementId: t,
|
|
@@ -188,98 +189,110 @@ var t = (t) => {
|
|
|
188
189
|
expectedRootId: e,
|
|
189
190
|
actualRootId: i.definition.rootId
|
|
190
191
|
}
|
|
191
|
-
}), i.definition.items && i.definition.items.forEach((e) =>
|
|
192
|
+
}), i.definition.items && i.definition.items.forEach((e) => n(e)));
|
|
192
193
|
};
|
|
193
|
-
t.definition.items && t.definition.items.forEach((e) =>
|
|
194
|
+
t.definition.items && t.definition.items.forEach((e) => n(e));
|
|
194
195
|
});
|
|
195
|
-
},
|
|
196
|
+
}, y = () => {
|
|
196
197
|
let e = /* @__PURE__ */ new Set();
|
|
197
|
-
|
|
198
|
+
s.forEach((t, n) => {
|
|
198
199
|
if (!t.id) {
|
|
199
|
-
|
|
200
|
+
r.push({
|
|
200
201
|
code: "INVALID_FOLDER",
|
|
201
|
-
message: `Page folder at index ${
|
|
202
|
+
message: `Page folder at index ${n} has no id`
|
|
202
203
|
});
|
|
203
204
|
return;
|
|
204
205
|
}
|
|
205
|
-
e.has(t.id) &&
|
|
206
|
+
e.has(t.id) && r.push({
|
|
206
207
|
code: "DUPLICATE_FOLDER",
|
|
207
208
|
message: `Duplicate folder ID "${t.id}"`,
|
|
208
209
|
elementId: t.id
|
|
209
|
-
}), e.add(t.id), t.parentId && (e.has(t.parentId) ||
|
|
210
|
+
}), e.add(t.id), t.parentId && (e.has(t.parentId) || r.push({
|
|
210
211
|
code: "ORPHANED_FOLDER_PARENT",
|
|
211
212
|
message: `Folder "${t.id}" has non-existent parent "${t.parentId}"`,
|
|
212
213
|
elementId: t.id,
|
|
213
214
|
details: { parentId: t.parentId }
|
|
214
215
|
}));
|
|
215
216
|
});
|
|
216
|
-
},
|
|
217
|
+
}, b = () => {
|
|
218
|
+
let e = /* @__PURE__ */ new Set();
|
|
219
|
+
d().forEach((n) => {
|
|
220
|
+
let i = t(u, n);
|
|
221
|
+
i.length === 0 || e.has(i[0]) || (i.forEach((t) => e.add(t)), r.push({
|
|
222
|
+
code: "LAYOUT_CYCLE",
|
|
223
|
+
message: `Layouts sit inside each other in a circle: ${i.join(" → ")}`,
|
|
224
|
+
elementId: n,
|
|
225
|
+
details: { cycle: i }
|
|
226
|
+
}));
|
|
227
|
+
});
|
|
228
|
+
}, x = (e) => {
|
|
217
229
|
let t = /* @__PURE__ */ new Set(), n = (e) => {
|
|
218
230
|
if (t.has(e)) return;
|
|
219
231
|
t.add(e);
|
|
220
|
-
let r =
|
|
232
|
+
let r = u(e);
|
|
221
233
|
r?.definition?.items && r.definition.items.forEach((e) => n(e));
|
|
222
|
-
},
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
t
|
|
234
|
+
}, r = /* @__PURE__ */ new Set(), o = (e) => {
|
|
235
|
+
if (r.has(e)) return;
|
|
236
|
+
r.add(e), n(e);
|
|
237
|
+
let t = u(e)?.attributes;
|
|
238
|
+
t?.layout && o(t.layout), t?.layoutContainer && n(t.layoutContainer);
|
|
226
239
|
};
|
|
227
|
-
e ?
|
|
228
|
-
let
|
|
229
|
-
Object.keys(
|
|
230
|
-
let n =
|
|
231
|
-
n && !t.has(e) && n.definition.type !== "page" && !
|
|
240
|
+
e ? o(e) : f().forEach(o);
|
|
241
|
+
let s = new Set(f());
|
|
242
|
+
Object.keys(a).forEach((e) => {
|
|
243
|
+
let n = u(e);
|
|
244
|
+
n && !t.has(e) && n.definition.type !== "page" && !s.has(e) && i.push({
|
|
232
245
|
code: "ORPHANED_ELEMENT",
|
|
233
246
|
message: `Element "${e}" is not reachable from any page or layout`,
|
|
234
247
|
elementId: e
|
|
235
248
|
});
|
|
236
249
|
});
|
|
237
|
-
},
|
|
250
|
+
}, S = () => {
|
|
238
251
|
let e = /* @__PURE__ */ new Set();
|
|
239
|
-
|
|
252
|
+
c.forEach((t, n) => {
|
|
240
253
|
if (!t.name) {
|
|
241
|
-
|
|
254
|
+
r.push({
|
|
242
255
|
code: "INVALID_VARIABLE",
|
|
243
|
-
message: `Variable at index ${
|
|
256
|
+
message: `Variable at index ${n} has no name`
|
|
244
257
|
});
|
|
245
258
|
return;
|
|
246
259
|
}
|
|
247
|
-
e.has(t.name) &&
|
|
260
|
+
e.has(t.name) && r.push({
|
|
248
261
|
code: "DUPLICATE_VARIABLE",
|
|
249
262
|
message: `Duplicate variable name "${t.name}"`,
|
|
250
263
|
details: { variableName: t.name }
|
|
251
|
-
}), e.add(t.name), t.type ||
|
|
264
|
+
}), e.add(t.name), t.type || i.push({
|
|
252
265
|
code: "MISSING_VARIABLE_TYPE",
|
|
253
266
|
message: `Variable "${t.name}" has no type`,
|
|
254
267
|
details: { variableName: t.name }
|
|
255
268
|
});
|
|
256
269
|
});
|
|
257
|
-
},
|
|
258
|
-
Object.values(
|
|
259
|
-
t && (e(t.id) ||
|
|
270
|
+
}, C = () => {
|
|
271
|
+
Object.values(a).forEach((t) => {
|
|
272
|
+
t && (e(t.id) || r.push({
|
|
260
273
|
code: "INVALID_ELEMENT_ID",
|
|
261
274
|
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)`,
|
|
262
275
|
elementId: t.id
|
|
263
276
|
}));
|
|
264
277
|
});
|
|
265
|
-
},
|
|
266
|
-
let t = /* @__PURE__ */ new Set(),
|
|
267
|
-
Object.values(
|
|
268
|
-
if (!
|
|
269
|
-
t.add(
|
|
270
|
-
let
|
|
271
|
-
|
|
272
|
-
}), Object.values(
|
|
273
|
-
|
|
278
|
+
}, w = (e) => {
|
|
279
|
+
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map();
|
|
280
|
+
Object.values(a).forEach((r) => {
|
|
281
|
+
if (!r) return;
|
|
282
|
+
t.add(r.id);
|
|
283
|
+
let a = e?.[r.definition.type];
|
|
284
|
+
a && i.set(r.id, a), n.add(r.definition.type);
|
|
285
|
+
}), Object.values(a).forEach((a) => {
|
|
286
|
+
a && a.definition.bindings && Object.entries(a.definition.bindings).forEach(([o, s]) => {
|
|
274
287
|
(s ?? []).forEach((s) => {
|
|
275
288
|
let c = s.source.split(".")[0], l = c.indexOf("_");
|
|
276
289
|
if (l === -1) return;
|
|
277
|
-
let u = c.slice(0, l), d = c.slice(l + 1), f = `Element "${
|
|
290
|
+
let u = c.slice(0, l), d = c.slice(l + 1), f = `Element "${a.id}" binds ${o}.${s.to} to "${s.source}"`;
|
|
278
291
|
if (!t.has(d)) {
|
|
279
|
-
(e ||
|
|
292
|
+
(e || n.has(u)) && r.push({
|
|
280
293
|
code: "UNRESOLVED_BINDING_SOURCE",
|
|
281
294
|
message: `${f}, but no element answers to the name "${d}"`,
|
|
282
|
-
elementId:
|
|
295
|
+
elementId: a.id,
|
|
283
296
|
details: {
|
|
284
297
|
source: s.source,
|
|
285
298
|
elementId: d
|
|
@@ -287,11 +300,11 @@ var t = (t) => {
|
|
|
287
300
|
});
|
|
288
301
|
return;
|
|
289
302
|
}
|
|
290
|
-
let p =
|
|
291
|
-
p && p !== u &&
|
|
303
|
+
let p = i.get(d);
|
|
304
|
+
p && p !== u && r.push({
|
|
292
305
|
code: "MISMATCHED_BINDING_SOURCE",
|
|
293
306
|
message: `${f}, but "${d}" publishes its source as "${p}_${d}"`,
|
|
294
|
-
elementId:
|
|
307
|
+
elementId: a.id,
|
|
295
308
|
details: {
|
|
296
309
|
source: s.source,
|
|
297
310
|
elementId: d,
|
|
@@ -301,54 +314,54 @@ var t = (t) => {
|
|
|
301
314
|
});
|
|
302
315
|
});
|
|
303
316
|
});
|
|
304
|
-
},
|
|
305
|
-
let t = new Set(Object.keys(
|
|
306
|
-
Object.values(
|
|
307
|
-
let i =
|
|
317
|
+
}, T = () => {
|
|
318
|
+
let t = new Set(Object.keys(a));
|
|
319
|
+
Object.values(a).forEach((n) => {
|
|
320
|
+
let i = n?.definition.interactions;
|
|
308
321
|
if (!i) return;
|
|
309
322
|
let a = Object.keys(i);
|
|
310
323
|
Object.entries(i).forEach(([i, o]) => {
|
|
311
|
-
e(i) ||
|
|
324
|
+
e(i) || r.push({
|
|
312
325
|
code: "INVALID_INTERACTION_ID",
|
|
313
|
-
message: `Interaction "${i}" on element "${
|
|
314
|
-
elementId:
|
|
315
|
-
}), o.id !== i &&
|
|
326
|
+
message: `Interaction "${i}" 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 {{ ${i}.field }}`,
|
|
327
|
+
elementId: n.id
|
|
328
|
+
}), o.id !== i && r.push({
|
|
316
329
|
code: "INTERACTION_ID_MISMATCH",
|
|
317
|
-
message: `Interaction id "${o.id}" on element "${
|
|
318
|
-
elementId:
|
|
330
|
+
message: `Interaction id "${o.id}" on element "${n.id}" doesn't match its key "${i}"`,
|
|
331
|
+
elementId: n.id
|
|
319
332
|
}), ["beforeNode", "afterNode"].forEach((e) => {
|
|
320
333
|
let t = o[e];
|
|
321
|
-
t && !a.includes(t) &&
|
|
334
|
+
t && !a.includes(t) && r.push({
|
|
322
335
|
code: "BROKEN_FLOW_LINK",
|
|
323
|
-
message: `Interaction "${o.id}" on element "${
|
|
324
|
-
elementId:
|
|
336
|
+
message: `Interaction "${o.id}" on element "${n.id}" names ${e} "${t}", which is not a node of this flow`,
|
|
337
|
+
elementId: n.id
|
|
325
338
|
});
|
|
326
|
-
}), o.flowId && !a.includes(o.flowId) &&
|
|
339
|
+
}), o.flowId && !a.includes(o.flowId) && r.push({
|
|
327
340
|
code: "BROKEN_FLOW_ID",
|
|
328
|
-
message: `Interaction "${o.id}" on element "${
|
|
329
|
-
elementId:
|
|
330
|
-
}), o.type === "callback" && o.elementId && !t.has(o.elementId) &&
|
|
341
|
+
message: `Interaction "${o.id}" on element "${n.id}" belongs to flow "${o.flowId}", which is not a node of this flow`,
|
|
342
|
+
elementId: n.id
|
|
343
|
+
}), o.type === "callback" && o.elementId && !t.has(o.elementId) && r.push({
|
|
331
344
|
code: "UNRESOLVED_INTERACTION_TARGET",
|
|
332
|
-
message: `Interaction "${o.id}" on element "${
|
|
333
|
-
elementId:
|
|
345
|
+
message: `Interaction "${o.id}" on element "${n.id}" runs against "${o.elementId}", but no element answers to that name`,
|
|
346
|
+
elementId: n.id
|
|
334
347
|
});
|
|
335
348
|
});
|
|
336
349
|
});
|
|
337
|
-
},
|
|
338
|
-
Object.values(
|
|
350
|
+
}, E = () => {
|
|
351
|
+
Object.values(a).forEach((e) => {
|
|
339
352
|
if (!e || !e.definition.bindings) return;
|
|
340
353
|
let t = /* @__PURE__ */ new Set();
|
|
341
|
-
Object.entries(e.definition.bindings).forEach(([
|
|
354
|
+
Object.entries(e.definition.bindings).forEach(([n, i]) => {
|
|
342
355
|
(i ?? []).forEach((i) => {
|
|
343
356
|
if (!i.id) {
|
|
344
|
-
|
|
357
|
+
r.push({
|
|
345
358
|
code: "MISSING_BINDING_ID",
|
|
346
|
-
message: `Element "${e.id}" has a ${
|
|
359
|
+
message: `Element "${e.id}" has a ${n} binding to "${i.to}" with no id`,
|
|
347
360
|
elementId: e.id
|
|
348
361
|
});
|
|
349
362
|
return;
|
|
350
363
|
}
|
|
351
|
-
t.has(i.id) &&
|
|
364
|
+
t.has(i.id) && r.push({
|
|
352
365
|
code: "DUPLICATE_BINDING_ID",
|
|
353
366
|
message: `Element "${e.id}" has two bindings called "${i.id}"`,
|
|
354
367
|
elementId: e.id,
|
|
@@ -360,22 +373,22 @@ var t = (t) => {
|
|
|
360
373
|
};
|
|
361
374
|
return { validate: (e) => {
|
|
362
375
|
let { baseElementId: t } = e ?? {};
|
|
363
|
-
return
|
|
364
|
-
valid:
|
|
365
|
-
errors:
|
|
366
|
-
warnings:
|
|
376
|
+
return p() ? (m(), h(), g(), _(), v(), y(), b(), x(t), S(), C(), w(e?.sourceTypes), E(), T(), {
|
|
377
|
+
valid: r.length === 0,
|
|
378
|
+
errors: r,
|
|
379
|
+
warnings: i
|
|
367
380
|
}) : {
|
|
368
381
|
valid: !1,
|
|
369
|
-
errors:
|
|
370
|
-
warnings:
|
|
382
|
+
errors: r,
|
|
383
|
+
warnings: i
|
|
371
384
|
};
|
|
372
385
|
} };
|
|
373
|
-
},
|
|
374
|
-
let i =
|
|
386
|
+
}, r = (e, t) => n(e).validate(t), i = (e, t, n) => {
|
|
387
|
+
let i = r(e, t);
|
|
375
388
|
if (!i.valid) {
|
|
376
|
-
let e = `Invalid schema${
|
|
389
|
+
let e = `Invalid schema${n ? ` (${n})` : ""}: ${i.errors.map((e) => e.message).join("; ")}`;
|
|
377
390
|
throw Error(e);
|
|
378
391
|
}
|
|
379
|
-
},
|
|
392
|
+
}, a = (e, t) => r(e, t).valid;
|
|
380
393
|
//#endregion
|
|
381
|
-
export {
|
|
394
|
+
export { i as assertSchemaValid, a as isSchemaValid, r as validateSchema };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Element, Style } from '@plitzi/sdk-shared';
|
|
2
|
+
/**
|
|
3
|
+
* Why an element's style applies to nothing, if it does not.
|
|
4
|
+
*
|
|
5
|
+
* An `apiContainer` whose `subType` is empty — its default, the builder's "Container Tag: None" — renders its
|
|
6
|
+
* children and no element of its own, so a class with rules, a variant or a style binding on it styles nothing: its
|
|
7
|
+
* children sit straight in the parent's layout, and the gap or padding written on the provider is not there. Found on
|
|
8
|
+
* real spaces as a counter card with no card, a sticky sidebar that did not stick, and page sections that lost the
|
|
9
|
+
* gap between them.
|
|
10
|
+
*
|
|
11
|
+
* Needs the style document: the builder and the authoring package both give every element a class of its own, rules
|
|
12
|
+
* or not, so a class name on its own says nothing. A provider with no tag is legal and often right.
|
|
13
|
+
*/
|
|
14
|
+
export declare const styleWithoutTag: (element: Element, style: Pick<Style, "platform">) => string | undefined;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/helpers/styleWithoutTag.ts
|
|
2
|
+
var e = (e) => Object.keys(e ?? {}).length > 0, t = (t) => Object.values(t ?? {}).some(e), n = (n) => e(n.default) || t(n.states) || Object.values(n.variants ?? {}).some((n) => e(n.default) || t(n.states)), r = (e, t) => Object.values(e.platform).some((e) => Object.hasOwn(e, t) && Object.values(e[t].attributes).some(n)), i = (e, t) => {
|
|
3
|
+
if (e.definition.type !== "apiContainer") return;
|
|
4
|
+
let n = e.attributes.subType;
|
|
5
|
+
if (typeof n == "string" && n !== "") return;
|
|
6
|
+
let { styleSelectors: i, initialState: a, bindings: o } = e.definition, s = Object.values(i).some((e) => e.split(" ").some((e) => e && r(t, e))), c = Object.keys(a?.styleVariant ?? {}).length > 0, l = (o?.style?.length ?? 0) > 0;
|
|
7
|
+
if (s || c || l) return "has style but no `subType` (container tag), so it renders no element of its own and the style applies to nothing — its children lay out in its parent. Give it a tag (a `subType` of `div`, `section`, …) or move the style onto its parent or a child.";
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { i as styleWithoutTag };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-schema",
|
|
3
|
-
"version": "0.36.
|
|
3
|
+
"version": "0.36.2",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./dist/helpers/schemaValidator.d.ts",
|
|
27
27
|
"import": "./dist/helpers/schemaValidator.mjs"
|
|
28
28
|
},
|
|
29
|
+
"./helpers/styleWithoutTag": {
|
|
30
|
+
"types": "./dist/helpers/styleWithoutTag.d.ts",
|
|
31
|
+
"import": "./dist/helpers/styleWithoutTag.mjs"
|
|
32
|
+
},
|
|
29
33
|
"./index": {
|
|
30
34
|
"types": "./dist/index.d.ts",
|
|
31
35
|
"import": "./dist/index.mjs"
|
|
@@ -45,14 +49,14 @@
|
|
|
45
49
|
},
|
|
46
50
|
"dependencies": {
|
|
47
51
|
"@plitzi/plitzi-ui": "^1.6.21",
|
|
48
|
-
"@plitzi/sdk-shared": "0.36.
|
|
49
|
-
"@plitzi/sdk-style": "0.36.
|
|
52
|
+
"@plitzi/sdk-shared": "0.36.2",
|
|
53
|
+
"@plitzi/sdk-style": "0.36.2",
|
|
50
54
|
"prop-types": "^15.8.1"
|
|
51
55
|
},
|
|
52
56
|
"devDependencies": {
|
|
53
57
|
"eslint": "^9.39.5",
|
|
54
58
|
"typescript": "^6.0.3",
|
|
55
59
|
"vite": "^8.3.0",
|
|
56
|
-
"vitest": "^5.0.
|
|
60
|
+
"vitest": "^5.0.1"
|
|
57
61
|
}
|
|
58
62
|
}
|