@constela/core 0.16.2 → 0.17.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/dist/index.d.ts +284 -4
- package/dist/index.js +435 -121
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
// src/types/theme.ts
|
|
2
|
+
var COLOR_SCHEMES = ["light", "dark", "system"];
|
|
3
|
+
function isObject(value) {
|
|
4
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function isColorScheme(value) {
|
|
7
|
+
return typeof value === "string" && COLOR_SCHEMES.includes(value);
|
|
8
|
+
}
|
|
9
|
+
function isThemeColors(value) {
|
|
10
|
+
if (!isObject(value)) return false;
|
|
11
|
+
for (const val of Object.values(value)) {
|
|
12
|
+
if (val !== void 0 && typeof val !== "string") {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function isThemeFonts(value) {
|
|
19
|
+
if (!isObject(value)) return false;
|
|
20
|
+
for (const val of Object.values(value)) {
|
|
21
|
+
if (val !== void 0 && typeof val !== "string") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
function isThemeConfig(value) {
|
|
28
|
+
if (!isObject(value)) return false;
|
|
29
|
+
if ("mode" in value && value["mode"] !== void 0) {
|
|
30
|
+
if (!isColorScheme(value["mode"])) return false;
|
|
31
|
+
}
|
|
32
|
+
if ("colors" in value && value["colors"] !== void 0) {
|
|
33
|
+
if (!isThemeColors(value["colors"])) return false;
|
|
34
|
+
}
|
|
35
|
+
if ("darkColors" in value && value["darkColors"] !== void 0) {
|
|
36
|
+
if (!isThemeColors(value["darkColors"])) return false;
|
|
37
|
+
}
|
|
38
|
+
if ("fonts" in value && value["fonts"] !== void 0) {
|
|
39
|
+
if (!isThemeFonts(value["fonts"])) return false;
|
|
40
|
+
}
|
|
41
|
+
if ("cssPrefix" in value && value["cssPrefix"] !== void 0) {
|
|
42
|
+
if (typeof value["cssPrefix"] !== "string") return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
1
47
|
// src/types/ast.ts
|
|
2
48
|
var BINARY_OPERATORS = [
|
|
3
49
|
"+",
|
|
@@ -43,6 +89,7 @@ var VALIDITY_PROPERTIES = [
|
|
|
43
89
|
"message"
|
|
44
90
|
];
|
|
45
91
|
var NAVIGATE_TARGETS = ["_self", "_blank"];
|
|
92
|
+
var ISLAND_STRATEGIES = ["load", "idle", "visible", "interaction", "media", "never"];
|
|
46
93
|
var PARAM_TYPES = ["string", "number", "boolean", "json"];
|
|
47
94
|
var DATA_TRANSFORMS = ["mdx", "yaml", "csv"];
|
|
48
95
|
var DATA_SOURCE_TYPES = ["glob", "file", "api", "ai"];
|
|
@@ -50,41 +97,41 @@ var AI_PROVIDER_TYPES = ["anthropic", "openai"];
|
|
|
50
97
|
var AI_OUTPUT_TYPES = ["component", "view"];
|
|
51
98
|
|
|
52
99
|
// src/types/guards.ts
|
|
53
|
-
function
|
|
100
|
+
function isObject2(value) {
|
|
54
101
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
55
102
|
}
|
|
56
103
|
function isLitExpr(value) {
|
|
57
|
-
if (!
|
|
104
|
+
if (!isObject2(value)) return false;
|
|
58
105
|
if (value["expr"] !== "lit") return false;
|
|
59
106
|
return "value" in value;
|
|
60
107
|
}
|
|
61
108
|
function isStateExpr(value) {
|
|
62
|
-
if (!
|
|
109
|
+
if (!isObject2(value)) return false;
|
|
63
110
|
if (value["expr"] !== "state") return false;
|
|
64
111
|
return typeof value["name"] === "string";
|
|
65
112
|
}
|
|
66
113
|
function isVarExpr(value) {
|
|
67
|
-
if (!
|
|
114
|
+
if (!isObject2(value)) return false;
|
|
68
115
|
if (value["expr"] !== "var") return false;
|
|
69
116
|
return typeof value["name"] === "string";
|
|
70
117
|
}
|
|
71
118
|
function isBinExpr(value) {
|
|
72
|
-
if (!
|
|
119
|
+
if (!isObject2(value)) return false;
|
|
73
120
|
if (value["expr"] !== "bin") return false;
|
|
74
121
|
if (!BINARY_OPERATORS.includes(value["op"])) {
|
|
75
122
|
return false;
|
|
76
123
|
}
|
|
77
|
-
if (!
|
|
124
|
+
if (!isObject2(value["left"]) || !isObject2(value["right"])) return false;
|
|
78
125
|
return true;
|
|
79
126
|
}
|
|
80
127
|
function isNotExpr(value) {
|
|
81
|
-
if (!
|
|
128
|
+
if (!isObject2(value)) return false;
|
|
82
129
|
if (value["expr"] !== "not") return false;
|
|
83
|
-
if (!
|
|
130
|
+
if (!isObject2(value["operand"])) return false;
|
|
84
131
|
return true;
|
|
85
132
|
}
|
|
86
133
|
function isParamExpr(value) {
|
|
87
|
-
if (!
|
|
134
|
+
if (!isObject2(value)) return false;
|
|
88
135
|
if (value["expr"] !== "param") return false;
|
|
89
136
|
if (typeof value["name"] !== "string") return false;
|
|
90
137
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -93,20 +140,20 @@ function isParamExpr(value) {
|
|
|
93
140
|
return true;
|
|
94
141
|
}
|
|
95
142
|
function isCondExpr(value) {
|
|
96
|
-
if (!
|
|
143
|
+
if (!isObject2(value)) return false;
|
|
97
144
|
if (value["expr"] !== "cond") return false;
|
|
98
|
-
if (!
|
|
145
|
+
if (!isObject2(value["if"]) || !isObject2(value["then"]) || !isObject2(value["else"])) return false;
|
|
99
146
|
return true;
|
|
100
147
|
}
|
|
101
148
|
function isGetExpr(value) {
|
|
102
|
-
if (!
|
|
149
|
+
if (!isObject2(value)) return false;
|
|
103
150
|
if (value["expr"] !== "get") return false;
|
|
104
|
-
if (!
|
|
151
|
+
if (!isObject2(value["base"])) return false;
|
|
105
152
|
if (typeof value["path"] !== "string") return false;
|
|
106
153
|
return true;
|
|
107
154
|
}
|
|
108
155
|
function isRouteExpr(value) {
|
|
109
|
-
if (!
|
|
156
|
+
if (!isObject2(value)) return false;
|
|
110
157
|
if (value["expr"] !== "route") return false;
|
|
111
158
|
if (typeof value["name"] !== "string") return false;
|
|
112
159
|
if ("source" in value && value["source"] !== void 0) {
|
|
@@ -116,7 +163,7 @@ function isRouteExpr(value) {
|
|
|
116
163
|
return true;
|
|
117
164
|
}
|
|
118
165
|
function isImportExpr(value) {
|
|
119
|
-
if (!
|
|
166
|
+
if (!isObject2(value)) return false;
|
|
120
167
|
if (value["expr"] !== "import") return false;
|
|
121
168
|
if (typeof value["name"] !== "string") return false;
|
|
122
169
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -125,7 +172,7 @@ function isImportExpr(value) {
|
|
|
125
172
|
return true;
|
|
126
173
|
}
|
|
127
174
|
function isDataExpr(value) {
|
|
128
|
-
if (!
|
|
175
|
+
if (!isObject2(value)) return false;
|
|
129
176
|
if (value["expr"] !== "data") return false;
|
|
130
177
|
if (typeof value["name"] !== "string") return false;
|
|
131
178
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -134,23 +181,23 @@ function isDataExpr(value) {
|
|
|
134
181
|
return true;
|
|
135
182
|
}
|
|
136
183
|
function isRefExpr(value) {
|
|
137
|
-
if (!
|
|
184
|
+
if (!isObject2(value)) return false;
|
|
138
185
|
if (value["expr"] !== "ref") return false;
|
|
139
186
|
return typeof value["name"] === "string";
|
|
140
187
|
}
|
|
141
188
|
function isIndexExpr(value) {
|
|
142
|
-
if (!
|
|
189
|
+
if (!isObject2(value)) return false;
|
|
143
190
|
if (value["expr"] !== "index") return false;
|
|
144
191
|
if (!("base" in value)) return false;
|
|
145
192
|
if (!("key" in value)) return false;
|
|
146
193
|
return true;
|
|
147
194
|
}
|
|
148
195
|
function isStyleExpr(value) {
|
|
149
|
-
if (!
|
|
196
|
+
if (!isObject2(value)) return false;
|
|
150
197
|
if (value["expr"] !== "style") return false;
|
|
151
198
|
if (typeof value["name"] !== "string") return false;
|
|
152
199
|
if ("variants" in value && value["variants"] !== void 0) {
|
|
153
|
-
if (!
|
|
200
|
+
if (!isObject2(value["variants"])) return false;
|
|
154
201
|
}
|
|
155
202
|
return true;
|
|
156
203
|
}
|
|
@@ -161,7 +208,7 @@ function isArrayExpr(value) {
|
|
|
161
208
|
return typeof value === "object" && value !== null && value.expr === "array" && Array.isArray(value.elements);
|
|
162
209
|
}
|
|
163
210
|
function isValidityExpr(value) {
|
|
164
|
-
if (!
|
|
211
|
+
if (!isObject2(value)) return false;
|
|
165
212
|
if (value["expr"] !== "validity") return false;
|
|
166
213
|
if (typeof value["ref"] !== "string") return false;
|
|
167
214
|
if ("property" in value && value["property"] !== void 0) {
|
|
@@ -172,7 +219,7 @@ function isValidityExpr(value) {
|
|
|
172
219
|
return true;
|
|
173
220
|
}
|
|
174
221
|
function isDataSource(value) {
|
|
175
|
-
if (!
|
|
222
|
+
if (!isObject2(value)) return false;
|
|
176
223
|
const type = value["type"];
|
|
177
224
|
if (!DATA_SOURCE_TYPES.includes(type)) {
|
|
178
225
|
return false;
|
|
@@ -198,7 +245,7 @@ function isDataSource(value) {
|
|
|
198
245
|
return true;
|
|
199
246
|
}
|
|
200
247
|
function isAiDataSource(value) {
|
|
201
|
-
if (!
|
|
248
|
+
if (!isObject2(value)) return false;
|
|
202
249
|
if (value["type"] !== "ai") return false;
|
|
203
250
|
if (!AI_PROVIDER_TYPES.includes(value["provider"])) return false;
|
|
204
251
|
if (typeof value["prompt"] !== "string") return false;
|
|
@@ -206,7 +253,7 @@ function isAiDataSource(value) {
|
|
|
206
253
|
return true;
|
|
207
254
|
}
|
|
208
255
|
function isGenerateStep(value) {
|
|
209
|
-
if (!
|
|
256
|
+
if (!isObject2(value)) return false;
|
|
210
257
|
if (value["do"] !== "generate") return false;
|
|
211
258
|
if (!AI_PROVIDER_TYPES.includes(value["provider"])) return false;
|
|
212
259
|
if (!("prompt" in value)) return false;
|
|
@@ -215,13 +262,13 @@ function isGenerateStep(value) {
|
|
|
215
262
|
return true;
|
|
216
263
|
}
|
|
217
264
|
function isStaticPathsDefinition(value) {
|
|
218
|
-
if (!
|
|
265
|
+
if (!isObject2(value)) return false;
|
|
219
266
|
if (typeof value["source"] !== "string") return false;
|
|
220
|
-
if (!("params" in value) || !
|
|
267
|
+
if (!("params" in value) || !isObject2(value["params"])) return false;
|
|
221
268
|
return true;
|
|
222
269
|
}
|
|
223
270
|
function isRouteDefinition(value) {
|
|
224
|
-
if (!
|
|
271
|
+
if (!isObject2(value)) return false;
|
|
225
272
|
if (typeof value["path"] !== "string") return false;
|
|
226
273
|
return true;
|
|
227
274
|
}
|
|
@@ -229,36 +276,36 @@ function isExpression(value) {
|
|
|
229
276
|
return isLitExpr(value) || isStateExpr(value) || isVarExpr(value) || isBinExpr(value) || isNotExpr(value) || isParamExpr(value) || isCondExpr(value) || isGetExpr(value) || isRouteExpr(value) || isImportExpr(value) || isDataExpr(value) || isRefExpr(value) || isIndexExpr(value) || isStyleExpr(value) || isConcatExpr(value) || isValidityExpr(value) || isArrayExpr(value);
|
|
230
277
|
}
|
|
231
278
|
function isElementNode(value) {
|
|
232
|
-
if (!
|
|
279
|
+
if (!isObject2(value)) return false;
|
|
233
280
|
if (value["kind"] !== "element") return false;
|
|
234
281
|
return typeof value["tag"] === "string";
|
|
235
282
|
}
|
|
236
283
|
function isTextNode(value) {
|
|
237
|
-
if (!
|
|
284
|
+
if (!isObject2(value)) return false;
|
|
238
285
|
if (value["kind"] !== "text") return false;
|
|
239
|
-
return
|
|
286
|
+
return isObject2(value["value"]);
|
|
240
287
|
}
|
|
241
288
|
function isIfNode(value) {
|
|
242
|
-
if (!
|
|
289
|
+
if (!isObject2(value)) return false;
|
|
243
290
|
if (value["kind"] !== "if") return false;
|
|
244
|
-
if (!
|
|
245
|
-
if (!
|
|
291
|
+
if (!isObject2(value["condition"])) return false;
|
|
292
|
+
if (!isObject2(value["then"])) return false;
|
|
246
293
|
return true;
|
|
247
294
|
}
|
|
248
295
|
function isEachNode(value) {
|
|
249
|
-
if (!
|
|
296
|
+
if (!isObject2(value)) return false;
|
|
250
297
|
if (value["kind"] !== "each") return false;
|
|
251
|
-
if (!
|
|
298
|
+
if (!isObject2(value["items"])) return false;
|
|
252
299
|
if (typeof value["as"] !== "string") return false;
|
|
253
|
-
if (!
|
|
300
|
+
if (!isObject2(value["body"])) return false;
|
|
254
301
|
return true;
|
|
255
302
|
}
|
|
256
303
|
function isComponentNode(value) {
|
|
257
|
-
if (!
|
|
304
|
+
if (!isObject2(value)) return false;
|
|
258
305
|
if (value["kind"] !== "component") return false;
|
|
259
306
|
if (typeof value["name"] !== "string") return false;
|
|
260
307
|
if ("props" in value && value["props"] !== void 0) {
|
|
261
|
-
if (!
|
|
308
|
+
if (!isObject2(value["props"])) return false;
|
|
262
309
|
}
|
|
263
310
|
if ("children" in value && value["children"] !== void 0) {
|
|
264
311
|
if (!Array.isArray(value["children"])) return false;
|
|
@@ -266,40 +313,107 @@ function isComponentNode(value) {
|
|
|
266
313
|
return true;
|
|
267
314
|
}
|
|
268
315
|
function isSlotNode(value) {
|
|
269
|
-
if (!
|
|
316
|
+
if (!isObject2(value)) return false;
|
|
270
317
|
return value["kind"] === "slot";
|
|
271
318
|
}
|
|
272
319
|
function isMarkdownNode(value) {
|
|
273
|
-
if (!
|
|
320
|
+
if (!isObject2(value)) return false;
|
|
274
321
|
if (value["kind"] !== "markdown") return false;
|
|
275
|
-
return "content" in value &&
|
|
322
|
+
return "content" in value && isObject2(value["content"]);
|
|
276
323
|
}
|
|
277
324
|
function isCodeNode(value) {
|
|
278
|
-
if (!
|
|
325
|
+
if (!isObject2(value)) return false;
|
|
279
326
|
if (value["kind"] !== "code") return false;
|
|
280
|
-
if (!("language" in value) || !
|
|
281
|
-
if (!("content" in value) || !
|
|
327
|
+
if (!("language" in value) || !isObject2(value["language"])) return false;
|
|
328
|
+
if (!("content" in value) || !isObject2(value["content"])) return false;
|
|
282
329
|
return true;
|
|
283
330
|
}
|
|
284
331
|
function isPortalNode(value) {
|
|
285
|
-
if (!
|
|
332
|
+
if (!isObject2(value)) return false;
|
|
286
333
|
if (value["kind"] !== "portal") return false;
|
|
287
334
|
if (typeof value["target"] !== "string") return false;
|
|
288
335
|
if (!Array.isArray(value["children"])) return false;
|
|
289
336
|
return true;
|
|
290
337
|
}
|
|
338
|
+
function isIslandStrategy(value) {
|
|
339
|
+
return typeof value === "string" && ISLAND_STRATEGIES.includes(value);
|
|
340
|
+
}
|
|
341
|
+
function isIslandStrategyOptions(value) {
|
|
342
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
const obj = value;
|
|
346
|
+
if (obj["threshold"] !== void 0) {
|
|
347
|
+
if (typeof obj["threshold"] !== "number" || obj["threshold"] < 0 || obj["threshold"] > 1) {
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (obj["rootMargin"] !== void 0 && typeof obj["rootMargin"] !== "string") {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
if (obj["media"] !== void 0 && typeof obj["media"] !== "string") {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
if (obj["timeout"] !== void 0) {
|
|
358
|
+
if (typeof obj["timeout"] !== "number" || obj["timeout"] < 0) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
function isIslandNode(value) {
|
|
365
|
+
if (!isObject2(value)) return false;
|
|
366
|
+
if (value["kind"] !== "island") return false;
|
|
367
|
+
if (typeof value["id"] !== "string") return false;
|
|
368
|
+
if (!isIslandStrategy(value["strategy"])) return false;
|
|
369
|
+
if ("strategyOptions" in value && value["strategyOptions"] !== void 0) {
|
|
370
|
+
if (!isIslandStrategyOptions(value["strategyOptions"])) return false;
|
|
371
|
+
}
|
|
372
|
+
if (!("content" in value) || !isObject2(value["content"])) return false;
|
|
373
|
+
const content = value["content"];
|
|
374
|
+
const validKinds = ["element", "text", "if", "each", "component", "slot", "markdown", "code", "portal", "island"];
|
|
375
|
+
if (!validKinds.includes(content["kind"])) {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
return true;
|
|
379
|
+
}
|
|
380
|
+
function isSuspenseNode(value) {
|
|
381
|
+
if (!isObject2(value)) return false;
|
|
382
|
+
if (value["kind"] !== "suspense") return false;
|
|
383
|
+
if (typeof value["id"] !== "string") return false;
|
|
384
|
+
if (!("fallback" in value) || !isObject2(value["fallback"])) return false;
|
|
385
|
+
if (!("content" in value) || !isObject2(value["content"])) return false;
|
|
386
|
+
const validKinds = ["element", "text", "if", "each", "component", "slot", "markdown", "code", "portal", "island", "suspense", "errorBoundary"];
|
|
387
|
+
const fallback = value["fallback"];
|
|
388
|
+
const content = value["content"];
|
|
389
|
+
if (!validKinds.includes(fallback["kind"])) return false;
|
|
390
|
+
if (!validKinds.includes(content["kind"])) return false;
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
function isErrorBoundaryNode(value) {
|
|
394
|
+
if (!isObject2(value)) return false;
|
|
395
|
+
if (value["kind"] !== "errorBoundary") return false;
|
|
396
|
+
if (!("fallback" in value) || !isObject2(value["fallback"])) return false;
|
|
397
|
+
if (!("content" in value) || !isObject2(value["content"])) return false;
|
|
398
|
+
const validKinds = ["element", "text", "if", "each", "component", "slot", "markdown", "code", "portal", "island", "suspense", "errorBoundary"];
|
|
399
|
+
const fallback = value["fallback"];
|
|
400
|
+
const content = value["content"];
|
|
401
|
+
if (!validKinds.includes(fallback["kind"])) return false;
|
|
402
|
+
if (!validKinds.includes(content["kind"])) return false;
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
291
405
|
function isViewNode(value) {
|
|
292
|
-
return isElementNode(value) || isTextNode(value) || isIfNode(value) || isEachNode(value) || isComponentNode(value) || isSlotNode(value) || isMarkdownNode(value) || isCodeNode(value) || isPortalNode(value);
|
|
406
|
+
return isElementNode(value) || isTextNode(value) || isIfNode(value) || isEachNode(value) || isComponentNode(value) || isSlotNode(value) || isMarkdownNode(value) || isCodeNode(value) || isPortalNode(value) || isIslandNode(value) || isSuspenseNode(value) || isErrorBoundaryNode(value);
|
|
293
407
|
}
|
|
294
408
|
function isSetStep(value) {
|
|
295
|
-
if (!
|
|
409
|
+
if (!isObject2(value)) return false;
|
|
296
410
|
if (value["do"] !== "set") return false;
|
|
297
411
|
if (typeof value["target"] !== "string") return false;
|
|
298
|
-
if (!
|
|
412
|
+
if (!isObject2(value["value"])) return false;
|
|
299
413
|
return true;
|
|
300
414
|
}
|
|
301
415
|
function isUpdateStep(value) {
|
|
302
|
-
if (!
|
|
416
|
+
if (!isObject2(value)) return false;
|
|
303
417
|
if (value["do"] !== "update") return false;
|
|
304
418
|
if (typeof value["target"] !== "string") return false;
|
|
305
419
|
if (!UPDATE_OPERATIONS.includes(value["operation"])) {
|
|
@@ -308,17 +422,17 @@ function isUpdateStep(value) {
|
|
|
308
422
|
return true;
|
|
309
423
|
}
|
|
310
424
|
function isSetPathStep(value) {
|
|
311
|
-
if (!
|
|
425
|
+
if (!isObject2(value)) return false;
|
|
312
426
|
if (value["do"] !== "setPath") return false;
|
|
313
427
|
if (typeof value["target"] !== "string") return false;
|
|
314
|
-
if (!
|
|
315
|
-
if (!
|
|
428
|
+
if (!isObject2(value["path"])) return false;
|
|
429
|
+
if (!isObject2(value["value"])) return false;
|
|
316
430
|
return true;
|
|
317
431
|
}
|
|
318
432
|
function isFetchStep(value) {
|
|
319
|
-
if (!
|
|
433
|
+
if (!isObject2(value)) return false;
|
|
320
434
|
if (value["do"] !== "fetch") return false;
|
|
321
|
-
if (!
|
|
435
|
+
if (!isObject2(value["url"])) return false;
|
|
322
436
|
if ("method" in value && value["method"] !== void 0) {
|
|
323
437
|
if (!HTTP_METHODS.includes(value["method"])) {
|
|
324
438
|
return false;
|
|
@@ -327,7 +441,7 @@ function isFetchStep(value) {
|
|
|
327
441
|
return true;
|
|
328
442
|
}
|
|
329
443
|
function isStorageStep(value) {
|
|
330
|
-
if (!
|
|
444
|
+
if (!isObject2(value)) return false;
|
|
331
445
|
if (value["do"] !== "storage") return false;
|
|
332
446
|
if (!STORAGE_OPERATIONS.includes(value["operation"])) {
|
|
333
447
|
return false;
|
|
@@ -339,7 +453,7 @@ function isStorageStep(value) {
|
|
|
339
453
|
return true;
|
|
340
454
|
}
|
|
341
455
|
function isClipboardStep(value) {
|
|
342
|
-
if (!
|
|
456
|
+
if (!isObject2(value)) return false;
|
|
343
457
|
if (value["do"] !== "clipboard") return false;
|
|
344
458
|
if (!CLIPBOARD_OPERATIONS.includes(value["operation"])) {
|
|
345
459
|
return false;
|
|
@@ -347,7 +461,7 @@ function isClipboardStep(value) {
|
|
|
347
461
|
return true;
|
|
348
462
|
}
|
|
349
463
|
function isNavigateStep(value) {
|
|
350
|
-
if (!
|
|
464
|
+
if (!isObject2(value)) return false;
|
|
351
465
|
if (value["do"] !== "navigate") return false;
|
|
352
466
|
if (!("url" in value)) return false;
|
|
353
467
|
if ("target" in value && value["target"] !== void 0) {
|
|
@@ -358,56 +472,56 @@ function isNavigateStep(value) {
|
|
|
358
472
|
return true;
|
|
359
473
|
}
|
|
360
474
|
function isImportStep(value) {
|
|
361
|
-
if (!
|
|
475
|
+
if (!isObject2(value)) return false;
|
|
362
476
|
if (value["do"] !== "import") return false;
|
|
363
477
|
if (typeof value["module"] !== "string") return false;
|
|
364
478
|
if (typeof value["result"] !== "string") return false;
|
|
365
479
|
return true;
|
|
366
480
|
}
|
|
367
481
|
function isCallStep(value) {
|
|
368
|
-
if (!
|
|
482
|
+
if (!isObject2(value)) return false;
|
|
369
483
|
if (value["do"] !== "call") return false;
|
|
370
|
-
if (!
|
|
484
|
+
if (!isObject2(value["target"])) return false;
|
|
371
485
|
return true;
|
|
372
486
|
}
|
|
373
487
|
function isSubscribeStep(value) {
|
|
374
|
-
if (!
|
|
488
|
+
if (!isObject2(value)) return false;
|
|
375
489
|
if (value["do"] !== "subscribe") return false;
|
|
376
|
-
if (!
|
|
490
|
+
if (!isObject2(value["target"])) return false;
|
|
377
491
|
if (typeof value["event"] !== "string") return false;
|
|
378
492
|
if (typeof value["action"] !== "string") return false;
|
|
379
493
|
return true;
|
|
380
494
|
}
|
|
381
495
|
function isDisposeStep(value) {
|
|
382
|
-
if (!
|
|
496
|
+
if (!isObject2(value)) return false;
|
|
383
497
|
if (value["do"] !== "dispose") return false;
|
|
384
|
-
if (!
|
|
498
|
+
if (!isObject2(value["target"])) return false;
|
|
385
499
|
return true;
|
|
386
500
|
}
|
|
387
501
|
function isDelayStep(value) {
|
|
388
|
-
if (!
|
|
502
|
+
if (!isObject2(value)) return false;
|
|
389
503
|
if (value["do"] !== "delay") return false;
|
|
390
|
-
if (!
|
|
504
|
+
if (!isObject2(value["ms"])) return false;
|
|
391
505
|
if (!Array.isArray(value["then"])) return false;
|
|
392
506
|
return true;
|
|
393
507
|
}
|
|
394
508
|
function isIntervalStep(value) {
|
|
395
|
-
if (!
|
|
509
|
+
if (!isObject2(value)) return false;
|
|
396
510
|
if (value["do"] !== "interval") return false;
|
|
397
|
-
if (!
|
|
511
|
+
if (!isObject2(value["ms"])) return false;
|
|
398
512
|
if (typeof value["action"] !== "string") return false;
|
|
399
513
|
return true;
|
|
400
514
|
}
|
|
401
515
|
function isClearTimerStep(value) {
|
|
402
|
-
if (!
|
|
516
|
+
if (!isObject2(value)) return false;
|
|
403
517
|
if (value["do"] !== "clearTimer") return false;
|
|
404
|
-
if (!
|
|
518
|
+
if (!isObject2(value["target"])) return false;
|
|
405
519
|
return true;
|
|
406
520
|
}
|
|
407
521
|
function isFocusStep(value) {
|
|
408
|
-
if (!
|
|
522
|
+
if (!isObject2(value)) return false;
|
|
409
523
|
if (value["do"] !== "focus") return false;
|
|
410
|
-
if (!
|
|
524
|
+
if (!isObject2(value["target"])) return false;
|
|
411
525
|
if (!FOCUS_OPERATIONS.includes(value["operation"])) {
|
|
412
526
|
return false;
|
|
413
527
|
}
|
|
@@ -420,7 +534,7 @@ function isLocalActionStep(value) {
|
|
|
420
534
|
return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value);
|
|
421
535
|
}
|
|
422
536
|
function isLocalActionDefinition(value) {
|
|
423
|
-
if (!
|
|
537
|
+
if (!isObject2(value)) return false;
|
|
424
538
|
if (typeof value["name"] !== "string") return false;
|
|
425
539
|
if (!Array.isArray(value["steps"])) return false;
|
|
426
540
|
for (const step of value["steps"]) {
|
|
@@ -429,7 +543,7 @@ function isLocalActionDefinition(value) {
|
|
|
429
543
|
return true;
|
|
430
544
|
}
|
|
431
545
|
function isNumberField(value) {
|
|
432
|
-
if (!
|
|
546
|
+
if (!isObject2(value)) return false;
|
|
433
547
|
if (value["type"] !== "number") return false;
|
|
434
548
|
return typeof value["initial"] === "number";
|
|
435
549
|
}
|
|
@@ -437,22 +551,22 @@ function isCookieInitialExpr(value) {
|
|
|
437
551
|
return typeof value === "object" && value !== null && "expr" in value && value.expr === "cookie" && "key" in value && typeof value.key === "string" && "default" in value && typeof value.default === "string";
|
|
438
552
|
}
|
|
439
553
|
function isStringField(value) {
|
|
440
|
-
if (!
|
|
554
|
+
if (!isObject2(value)) return false;
|
|
441
555
|
if (value["type"] !== "string") return false;
|
|
442
556
|
return typeof value["initial"] === "string" || isCookieInitialExpr(value["initial"]);
|
|
443
557
|
}
|
|
444
558
|
function isListField(value) {
|
|
445
|
-
if (!
|
|
559
|
+
if (!isObject2(value)) return false;
|
|
446
560
|
if (value["type"] !== "list") return false;
|
|
447
561
|
return Array.isArray(value["initial"]);
|
|
448
562
|
}
|
|
449
563
|
function isBooleanField(value) {
|
|
450
|
-
if (!
|
|
564
|
+
if (!isObject2(value)) return false;
|
|
451
565
|
if (value["type"] !== "boolean") return false;
|
|
452
566
|
return typeof value["initial"] === "boolean";
|
|
453
567
|
}
|
|
454
568
|
function isObjectField(value) {
|
|
455
|
-
if (!
|
|
569
|
+
if (!isObject2(value)) return false;
|
|
456
570
|
if (value["type"] !== "object") return false;
|
|
457
571
|
return typeof value["initial"] === "object" && value["initial"] !== null;
|
|
458
572
|
}
|
|
@@ -460,20 +574,20 @@ function isStateField(value) {
|
|
|
460
574
|
return isNumberField(value) || isStringField(value) || isListField(value) || isBooleanField(value) || isObjectField(value);
|
|
461
575
|
}
|
|
462
576
|
function isEventHandler(value) {
|
|
463
|
-
if (!
|
|
577
|
+
if (!isObject2(value)) return false;
|
|
464
578
|
if (!("event" in value) || typeof value["event"] !== "string") return false;
|
|
465
579
|
if (!("action" in value) || typeof value["action"] !== "string") return false;
|
|
466
580
|
return true;
|
|
467
581
|
}
|
|
468
582
|
function isLayoutProgram(value) {
|
|
469
|
-
if (!
|
|
583
|
+
if (!isObject2(value)) return false;
|
|
470
584
|
if (value["version"] !== "1.0") return false;
|
|
471
585
|
if (value["type"] !== "layout") return false;
|
|
472
586
|
if (!("view" in value)) return false;
|
|
473
587
|
return true;
|
|
474
588
|
}
|
|
475
589
|
function isNamedSlotNode(value) {
|
|
476
|
-
if (!
|
|
590
|
+
if (!isObject2(value)) return false;
|
|
477
591
|
if (value["kind"] !== "slot") return false;
|
|
478
592
|
if (typeof value["name"] !== "string") return false;
|
|
479
593
|
return true;
|
|
@@ -819,6 +933,16 @@ function createLocalActionInvalidStepError(stepType, path) {
|
|
|
819
933
|
path
|
|
820
934
|
);
|
|
821
935
|
}
|
|
936
|
+
function createDuplicateIslandIdError(id, path, suggestions) {
|
|
937
|
+
return new ConstelaError(
|
|
938
|
+
"DUPLICATE_ISLAND_ID",
|
|
939
|
+
`Duplicate island ID: "${id}"`,
|
|
940
|
+
path,
|
|
941
|
+
{
|
|
942
|
+
suggestion: suggestions?.[0] ?? "Use a unique ID for each island"
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
}
|
|
822
946
|
function levenshteinDistance(a, b) {
|
|
823
947
|
const aLen = a.length;
|
|
824
948
|
const bLen = b.length;
|
|
@@ -860,10 +984,10 @@ function findSimilarNames(target, candidates, maxDistance = 2) {
|
|
|
860
984
|
}
|
|
861
985
|
|
|
862
986
|
// src/schema/validator.ts
|
|
863
|
-
function
|
|
987
|
+
function isObject3(value) {
|
|
864
988
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
865
989
|
}
|
|
866
|
-
var VALID_VIEW_KINDS = ["element", "text", "if", "each", "component", "slot", "markdown", "code", "portal"];
|
|
990
|
+
var VALID_VIEW_KINDS = ["element", "text", "if", "each", "component", "slot", "markdown", "code", "portal", "island"];
|
|
867
991
|
var VALID_EXPR_TYPES = ["lit", "state", "var", "bin", "not", "param", "cond", "get", "style", "validity", "index", "call", "lambda", "array"];
|
|
868
992
|
var VALID_PARAM_TYPES = ["string", "number", "boolean", "json"];
|
|
869
993
|
var VALID_ACTION_TYPES = ["set", "update", "setPath", "fetch", "delay", "interval", "clearTimer", "focus", "if"];
|
|
@@ -872,7 +996,7 @@ var VALID_BIN_OPS = BINARY_OPERATORS;
|
|
|
872
996
|
var VALID_UPDATE_OPS = UPDATE_OPERATIONS;
|
|
873
997
|
var VALID_HTTP_METHODS = HTTP_METHODS;
|
|
874
998
|
function validateViewNode(node, path) {
|
|
875
|
-
if (!
|
|
999
|
+
if (!isObject3(node)) {
|
|
876
1000
|
return { path, message: "must be an object" };
|
|
877
1001
|
}
|
|
878
1002
|
const kind = node["kind"];
|
|
@@ -887,9 +1011,9 @@ function validateViewNode(node, path) {
|
|
|
887
1011
|
if (typeof node["tag"] !== "string") {
|
|
888
1012
|
return { path: path + "/tag", message: "tag is required" };
|
|
889
1013
|
}
|
|
890
|
-
if (node["props"] !== void 0 &&
|
|
1014
|
+
if (node["props"] !== void 0 && isObject3(node["props"])) {
|
|
891
1015
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
892
|
-
if (
|
|
1016
|
+
if (isObject3(propValue) && "event" in propValue) {
|
|
893
1017
|
} else {
|
|
894
1018
|
const error = validateExpression(propValue, path + "/props/" + propName);
|
|
895
1019
|
if (error) return error;
|
|
@@ -947,7 +1071,7 @@ function validateViewNode(node, path) {
|
|
|
947
1071
|
if (typeof node["name"] !== "string") {
|
|
948
1072
|
return { path: path + "/name", message: "name is required" };
|
|
949
1073
|
}
|
|
950
|
-
if (node["props"] !== void 0 &&
|
|
1074
|
+
if (node["props"] !== void 0 && isObject3(node["props"])) {
|
|
951
1075
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
952
1076
|
const error = validateExpression(propValue, path + "/props/" + propName);
|
|
953
1077
|
if (error) return error;
|
|
@@ -990,11 +1114,90 @@ function validateViewNode(node, path) {
|
|
|
990
1114
|
}
|
|
991
1115
|
}
|
|
992
1116
|
break;
|
|
1117
|
+
case "island":
|
|
1118
|
+
if (typeof node["id"] !== "string" || node["id"] === "") {
|
|
1119
|
+
return { path: path + "/id", message: "id is required and must be a non-empty string" };
|
|
1120
|
+
}
|
|
1121
|
+
if (typeof node["strategy"] !== "string") {
|
|
1122
|
+
return { path: path + "/strategy", message: "strategy is required" };
|
|
1123
|
+
}
|
|
1124
|
+
if (!ISLAND_STRATEGIES.includes(node["strategy"])) {
|
|
1125
|
+
return { path: path + "/strategy", message: `must be one of: ${ISLAND_STRATEGIES.join(", ")}` };
|
|
1126
|
+
}
|
|
1127
|
+
if (!("content" in node)) {
|
|
1128
|
+
return { path: path + "/content", message: "content is required" };
|
|
1129
|
+
}
|
|
1130
|
+
{
|
|
1131
|
+
const contentError = validateViewNode(node["content"], path + "/content");
|
|
1132
|
+
if (contentError) return contentError;
|
|
1133
|
+
}
|
|
1134
|
+
if ("strategyOptions" in node && node["strategyOptions"] !== void 0) {
|
|
1135
|
+
if (!isObject3(node["strategyOptions"])) {
|
|
1136
|
+
return { path: path + "/strategyOptions", message: "strategyOptions must be an object" };
|
|
1137
|
+
}
|
|
1138
|
+
const opts = node["strategyOptions"];
|
|
1139
|
+
if ("threshold" in opts && opts["threshold"] !== void 0) {
|
|
1140
|
+
if (typeof opts["threshold"] !== "number" || opts["threshold"] < 0 || opts["threshold"] > 1) {
|
|
1141
|
+
return { path: path + "/strategyOptions/threshold", message: "threshold must be a number between 0 and 1" };
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
if ("rootMargin" in opts && opts["rootMargin"] !== void 0) {
|
|
1145
|
+
if (typeof opts["rootMargin"] !== "string") {
|
|
1146
|
+
return { path: path + "/strategyOptions/rootMargin", message: "rootMargin must be a string" };
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
if ("event" in opts && opts["event"] !== void 0) {
|
|
1150
|
+
if (typeof opts["event"] !== "string") {
|
|
1151
|
+
return { path: path + "/strategyOptions/event", message: "event must be a string" };
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
if ("media" in opts && opts["media"] !== void 0) {
|
|
1155
|
+
if (typeof opts["media"] !== "string") {
|
|
1156
|
+
return { path: path + "/strategyOptions/media", message: "media must be a string" };
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
if ("timeout" in opts && opts["timeout"] !== void 0) {
|
|
1160
|
+
if (typeof opts["timeout"] !== "number" || opts["timeout"] < 0) {
|
|
1161
|
+
return { path: path + "/strategyOptions/timeout", message: "timeout must be a non-negative number" };
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
if ("state" in node && node["state"] !== void 0) {
|
|
1166
|
+
if (!isObject3(node["state"])) {
|
|
1167
|
+
return { path: path + "/state", message: "state must be an object" };
|
|
1168
|
+
}
|
|
1169
|
+
for (const [name, field] of Object.entries(node["state"])) {
|
|
1170
|
+
const error = validateStateField(field, path + "/state/" + name);
|
|
1171
|
+
if (error) return error;
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if ("actions" in node && node["actions"] !== void 0) {
|
|
1175
|
+
if (!Array.isArray(node["actions"])) {
|
|
1176
|
+
return { path: path + "/actions", message: "actions must be an array" };
|
|
1177
|
+
}
|
|
1178
|
+
for (let i = 0; i < node["actions"].length; i++) {
|
|
1179
|
+
const action = node["actions"][i];
|
|
1180
|
+
if (!isObject3(action)) {
|
|
1181
|
+
return { path: path + "/actions/" + i, message: "action must be an object" };
|
|
1182
|
+
}
|
|
1183
|
+
if (typeof action["name"] !== "string") {
|
|
1184
|
+
return { path: path + "/actions/" + i + "/name", message: "name is required" };
|
|
1185
|
+
}
|
|
1186
|
+
if (!Array.isArray(action["steps"])) {
|
|
1187
|
+
return { path: path + "/actions/" + i + "/steps", message: "steps is required" };
|
|
1188
|
+
}
|
|
1189
|
+
for (let j = 0; j < action["steps"].length; j++) {
|
|
1190
|
+
const error = validateActionStep(action["steps"][j], path + "/actions/" + i + "/steps/" + j);
|
|
1191
|
+
if (error) return error;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
break;
|
|
993
1196
|
}
|
|
994
1197
|
return null;
|
|
995
1198
|
}
|
|
996
1199
|
function validateExpression(expr, path) {
|
|
997
|
-
if (!
|
|
1200
|
+
if (!isObject3(expr)) {
|
|
998
1201
|
return { path, message: "must be an object" };
|
|
999
1202
|
}
|
|
1000
1203
|
const exprType = expr["expr"];
|
|
@@ -1081,7 +1284,7 @@ function validateExpression(expr, path) {
|
|
|
1081
1284
|
return { path: path + "/name", message: "name is required" };
|
|
1082
1285
|
}
|
|
1083
1286
|
if ("variants" in expr && expr["variants"] !== void 0) {
|
|
1084
|
-
if (!
|
|
1287
|
+
if (!isObject3(expr["variants"])) {
|
|
1085
1288
|
return { path: path + "/variants", message: "variants must be an object" };
|
|
1086
1289
|
}
|
|
1087
1290
|
for (const [variantKey, variantValue] of Object.entries(expr["variants"])) {
|
|
@@ -1161,7 +1364,7 @@ function validateExpression(expr, path) {
|
|
|
1161
1364
|
return null;
|
|
1162
1365
|
}
|
|
1163
1366
|
function validateActionStep(step, path) {
|
|
1164
|
-
if (!
|
|
1367
|
+
if (!isObject3(step)) {
|
|
1165
1368
|
return { path, message: "must be an object" };
|
|
1166
1369
|
}
|
|
1167
1370
|
const doType = step["do"];
|
|
@@ -1303,7 +1506,7 @@ function validateActionStep(step, path) {
|
|
|
1303
1506
|
return null;
|
|
1304
1507
|
}
|
|
1305
1508
|
function validateStateField(field, path) {
|
|
1306
|
-
if (!
|
|
1509
|
+
if (!isObject3(field)) {
|
|
1307
1510
|
return { path, message: "must be an object" };
|
|
1308
1511
|
}
|
|
1309
1512
|
const fieldType = field["type"];
|
|
@@ -1338,7 +1541,7 @@ function validateStateField(field, path) {
|
|
|
1338
1541
|
}
|
|
1339
1542
|
break;
|
|
1340
1543
|
case "object":
|
|
1341
|
-
if (!
|
|
1544
|
+
if (!isObject3(field["initial"])) {
|
|
1342
1545
|
return { path: path + "/initial", message: "must be an object" };
|
|
1343
1546
|
}
|
|
1344
1547
|
break;
|
|
@@ -1346,7 +1549,7 @@ function validateStateField(field, path) {
|
|
|
1346
1549
|
return null;
|
|
1347
1550
|
}
|
|
1348
1551
|
function validateParamDef(param, path) {
|
|
1349
|
-
if (!
|
|
1552
|
+
if (!isObject3(param)) {
|
|
1350
1553
|
return { path, message: "must be an object" };
|
|
1351
1554
|
}
|
|
1352
1555
|
const paramType = param["type"];
|
|
@@ -1362,13 +1565,13 @@ function validateParamDef(param, path) {
|
|
|
1362
1565
|
return null;
|
|
1363
1566
|
}
|
|
1364
1567
|
function validateComponentDef(def, path) {
|
|
1365
|
-
if (!
|
|
1568
|
+
if (!isObject3(def)) {
|
|
1366
1569
|
return { path, message: "must be an object" };
|
|
1367
1570
|
}
|
|
1368
1571
|
if (!("view" in def)) {
|
|
1369
1572
|
return { path: path + "/view", message: "view is required" };
|
|
1370
1573
|
}
|
|
1371
|
-
if ("params" in def &&
|
|
1574
|
+
if ("params" in def && isObject3(def["params"])) {
|
|
1372
1575
|
for (const [paramName, paramDef] of Object.entries(def["params"])) {
|
|
1373
1576
|
const error = validateParamDef(paramDef, path + "/params/" + paramName);
|
|
1374
1577
|
if (error) return error;
|
|
@@ -1379,7 +1582,7 @@ function validateComponentDef(def, path) {
|
|
|
1379
1582
|
return null;
|
|
1380
1583
|
}
|
|
1381
1584
|
function validateStylePreset(preset, path) {
|
|
1382
|
-
if (!
|
|
1585
|
+
if (!isObject3(preset)) {
|
|
1383
1586
|
return { path, message: "must be an object" };
|
|
1384
1587
|
}
|
|
1385
1588
|
if (!("base" in preset)) {
|
|
@@ -1389,11 +1592,11 @@ function validateStylePreset(preset, path) {
|
|
|
1389
1592
|
return { path: path + "/base", message: "base must be a string" };
|
|
1390
1593
|
}
|
|
1391
1594
|
if ("variants" in preset && preset["variants"] !== void 0) {
|
|
1392
|
-
if (!
|
|
1595
|
+
if (!isObject3(preset["variants"])) {
|
|
1393
1596
|
return { path: path + "/variants", message: "variants must be an object" };
|
|
1394
1597
|
}
|
|
1395
1598
|
for (const [variantKey, variantOptions] of Object.entries(preset["variants"])) {
|
|
1396
|
-
if (!
|
|
1599
|
+
if (!isObject3(variantOptions)) {
|
|
1397
1600
|
return { path: path + "/variants/" + variantKey, message: "variant options must be an object" };
|
|
1398
1601
|
}
|
|
1399
1602
|
for (const [optionKey, optionValue] of Object.entries(variantOptions)) {
|
|
@@ -1404,10 +1607,10 @@ function validateStylePreset(preset, path) {
|
|
|
1404
1607
|
}
|
|
1405
1608
|
}
|
|
1406
1609
|
if ("defaultVariants" in preset && preset["defaultVariants"] !== void 0) {
|
|
1407
|
-
if (!
|
|
1610
|
+
if (!isObject3(preset["defaultVariants"])) {
|
|
1408
1611
|
return { path: path + "/defaultVariants", message: "defaultVariants must be an object" };
|
|
1409
1612
|
}
|
|
1410
|
-
const variantKeys =
|
|
1613
|
+
const variantKeys = isObject3(preset["variants"]) ? Object.keys(preset["variants"]) : [];
|
|
1411
1614
|
for (const [key, value] of Object.entries(preset["defaultVariants"])) {
|
|
1412
1615
|
if (typeof value !== "string") {
|
|
1413
1616
|
return { path: path + "/defaultVariants/" + key, message: "default variant value must be a string" };
|
|
@@ -1423,7 +1626,7 @@ function validateStylePreset(preset, path) {
|
|
|
1423
1626
|
}
|
|
1424
1627
|
for (let i = 0; i < preset["compoundVariants"].length; i++) {
|
|
1425
1628
|
const compound = preset["compoundVariants"][i];
|
|
1426
|
-
if (!
|
|
1629
|
+
if (!isObject3(compound)) {
|
|
1427
1630
|
return { path: path + "/compoundVariants/" + i, message: "compound variant must be an object" };
|
|
1428
1631
|
}
|
|
1429
1632
|
if (typeof compound["class"] !== "string") {
|
|
@@ -1434,13 +1637,13 @@ function validateStylePreset(preset, path) {
|
|
|
1434
1637
|
return null;
|
|
1435
1638
|
}
|
|
1436
1639
|
function customValidateAst(input) {
|
|
1437
|
-
if (
|
|
1640
|
+
if (isObject3(input["state"])) {
|
|
1438
1641
|
for (const [name, field] of Object.entries(input["state"])) {
|
|
1439
1642
|
const error = validateStateField(field, "/state/" + name);
|
|
1440
1643
|
if (error) return error;
|
|
1441
1644
|
}
|
|
1442
1645
|
}
|
|
1443
|
-
if ("styles" in input &&
|
|
1646
|
+
if ("styles" in input && isObject3(input["styles"])) {
|
|
1444
1647
|
for (const [name, preset] of Object.entries(input["styles"])) {
|
|
1445
1648
|
const error = validateStylePreset(preset, "/styles/" + name);
|
|
1446
1649
|
if (error) return error;
|
|
@@ -1449,7 +1652,7 @@ function customValidateAst(input) {
|
|
|
1449
1652
|
if (Array.isArray(input["actions"])) {
|
|
1450
1653
|
for (let i = 0; i < input["actions"].length; i++) {
|
|
1451
1654
|
const action = input["actions"][i];
|
|
1452
|
-
if (
|
|
1655
|
+
if (isObject3(action) && Array.isArray(action["steps"])) {
|
|
1453
1656
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1454
1657
|
const error = validateActionStep(action["steps"][j], "/actions/" + i + "/steps/" + j);
|
|
1455
1658
|
if (error) return error;
|
|
@@ -1461,7 +1664,7 @@ function customValidateAst(input) {
|
|
|
1461
1664
|
const error = validateViewNode(input["view"], "/view");
|
|
1462
1665
|
if (error) return error;
|
|
1463
1666
|
}
|
|
1464
|
-
if ("components" in input &&
|
|
1667
|
+
if ("components" in input && isObject3(input["components"])) {
|
|
1465
1668
|
for (const [name, def] of Object.entries(input["components"])) {
|
|
1466
1669
|
const error = validateComponentDef(def, "/components/" + name);
|
|
1467
1670
|
if (error) return error;
|
|
@@ -1481,14 +1684,14 @@ function createErrorOptionsWithSuggestion(name, availableNames) {
|
|
|
1481
1684
|
function collectSemanticContext(ast) {
|
|
1482
1685
|
const stateNames = /* @__PURE__ */ new Set();
|
|
1483
1686
|
const actionNames = /* @__PURE__ */ new Set();
|
|
1484
|
-
if (
|
|
1687
|
+
if (isObject3(ast["state"])) {
|
|
1485
1688
|
for (const name of Object.keys(ast["state"])) {
|
|
1486
1689
|
stateNames.add(name);
|
|
1487
1690
|
}
|
|
1488
1691
|
}
|
|
1489
1692
|
if (Array.isArray(ast["actions"])) {
|
|
1490
1693
|
for (const action of ast["actions"]) {
|
|
1491
|
-
if (
|
|
1694
|
+
if (isObject3(action) && typeof action["name"] === "string") {
|
|
1492
1695
|
actionNames.add(action["name"]);
|
|
1493
1696
|
}
|
|
1494
1697
|
}
|
|
@@ -1496,7 +1699,26 @@ function collectSemanticContext(ast) {
|
|
|
1496
1699
|
return { stateNames, actionNames };
|
|
1497
1700
|
}
|
|
1498
1701
|
function validateStateReferences(node, path, stateNames) {
|
|
1499
|
-
if (!
|
|
1702
|
+
if (!isObject3(node)) return null;
|
|
1703
|
+
if (node["kind"] === "island") {
|
|
1704
|
+
const islandStateNames = new Set(stateNames);
|
|
1705
|
+
if (isObject3(node["state"])) {
|
|
1706
|
+
for (const name of Object.keys(node["state"])) {
|
|
1707
|
+
islandStateNames.add(name);
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
if (isObject3(node["content"])) {
|
|
1711
|
+
const error = validateStateReferences(node["content"], path + "/content", islandStateNames);
|
|
1712
|
+
if (error) return error;
|
|
1713
|
+
}
|
|
1714
|
+
if (Array.isArray(node["actions"])) {
|
|
1715
|
+
for (let i = 0; i < node["actions"].length; i++) {
|
|
1716
|
+
const error = validateStateReferences(node["actions"][i], path + "/actions/" + i, islandStateNames);
|
|
1717
|
+
if (error) return error;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
return null;
|
|
1721
|
+
}
|
|
1500
1722
|
if (node["expr"] === "state" && typeof node["name"] === "string") {
|
|
1501
1723
|
if (!stateNames.has(node["name"])) {
|
|
1502
1724
|
const errorOptions = createErrorOptionsWithSuggestion(node["name"], stateNames);
|
|
@@ -1504,7 +1726,7 @@ function validateStateReferences(node, path, stateNames) {
|
|
|
1504
1726
|
}
|
|
1505
1727
|
}
|
|
1506
1728
|
for (const [key, value] of Object.entries(node)) {
|
|
1507
|
-
if (
|
|
1729
|
+
if (isObject3(value)) {
|
|
1508
1730
|
const error = validateStateReferences(value, path + "/" + key, stateNames);
|
|
1509
1731
|
if (error) return error;
|
|
1510
1732
|
} else if (Array.isArray(value)) {
|
|
@@ -1520,10 +1742,10 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1520
1742
|
if (!Array.isArray(ast["actions"])) return null;
|
|
1521
1743
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1522
1744
|
const action = ast["actions"][i];
|
|
1523
|
-
if (!
|
|
1745
|
+
if (!isObject3(action) || !Array.isArray(action["steps"])) continue;
|
|
1524
1746
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1525
1747
|
const step = action["steps"][j];
|
|
1526
|
-
if (!
|
|
1748
|
+
if (!isObject3(step)) continue;
|
|
1527
1749
|
if ((step["do"] === "set" || step["do"] === "update") && typeof step["target"] === "string") {
|
|
1528
1750
|
if (!stateNames.has(step["target"])) {
|
|
1529
1751
|
const errorOptions = createErrorOptionsWithSuggestion(step["target"], stateNames);
|
|
@@ -1535,10 +1757,25 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1535
1757
|
return null;
|
|
1536
1758
|
}
|
|
1537
1759
|
function validateActionReferences(node, path, actionNames) {
|
|
1538
|
-
if (!
|
|
1539
|
-
if (
|
|
1760
|
+
if (!isObject3(node)) return null;
|
|
1761
|
+
if (node["kind"] === "island") {
|
|
1762
|
+
const islandActionNames = new Set(actionNames);
|
|
1763
|
+
if (Array.isArray(node["actions"])) {
|
|
1764
|
+
for (const action of node["actions"]) {
|
|
1765
|
+
if (isObject3(action) && typeof action["name"] === "string") {
|
|
1766
|
+
islandActionNames.add(action["name"]);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
if (isObject3(node["content"])) {
|
|
1771
|
+
const error = validateActionReferences(node["content"], path + "/content", islandActionNames);
|
|
1772
|
+
if (error) return error;
|
|
1773
|
+
}
|
|
1774
|
+
return null;
|
|
1775
|
+
}
|
|
1776
|
+
if (isObject3(node["props"])) {
|
|
1540
1777
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
1541
|
-
if (
|
|
1778
|
+
if (isObject3(propValue) && "event" in propValue && "action" in propValue) {
|
|
1542
1779
|
const actionName = propValue["action"];
|
|
1543
1780
|
if (typeof actionName === "string" && !actionNames.has(actionName)) {
|
|
1544
1781
|
const errorOptions = createErrorOptionsWithSuggestion(actionName, actionNames);
|
|
@@ -1557,15 +1794,15 @@ function validateActionReferences(node, path, actionNames) {
|
|
|
1557
1794
|
if (error) return error;
|
|
1558
1795
|
}
|
|
1559
1796
|
}
|
|
1560
|
-
if (
|
|
1797
|
+
if (isObject3(node["then"])) {
|
|
1561
1798
|
const error = validateActionReferences(node["then"], path + "/then", actionNames);
|
|
1562
1799
|
if (error) return error;
|
|
1563
1800
|
}
|
|
1564
|
-
if (
|
|
1801
|
+
if (isObject3(node["else"])) {
|
|
1565
1802
|
const error = validateActionReferences(node["else"], path + "/else", actionNames);
|
|
1566
1803
|
if (error) return error;
|
|
1567
1804
|
}
|
|
1568
|
-
if (
|
|
1805
|
+
if (isObject3(node["body"])) {
|
|
1569
1806
|
const error = validateActionReferences(node["body"], path + "/body", actionNames);
|
|
1570
1807
|
if (error) return error;
|
|
1571
1808
|
}
|
|
@@ -1576,7 +1813,7 @@ function validateDuplicateActions(ast) {
|
|
|
1576
1813
|
const seenNames = /* @__PURE__ */ new Set();
|
|
1577
1814
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1578
1815
|
const action = ast["actions"][i];
|
|
1579
|
-
if (!
|
|
1816
|
+
if (!isObject3(action) || typeof action["name"] !== "string") continue;
|
|
1580
1817
|
const name = action["name"];
|
|
1581
1818
|
if (seenNames.has(name)) {
|
|
1582
1819
|
return createDuplicateActionError(name, "/actions/" + i);
|
|
@@ -1589,20 +1826,20 @@ function performSemanticValidation(ast) {
|
|
|
1589
1826
|
const { stateNames, actionNames } = collectSemanticContext(ast);
|
|
1590
1827
|
const duplicateError = validateDuplicateActions(ast);
|
|
1591
1828
|
if (duplicateError) return duplicateError;
|
|
1592
|
-
if (
|
|
1829
|
+
if (isObject3(ast["view"])) {
|
|
1593
1830
|
const stateRefError = validateStateReferences(ast["view"], "/view", stateNames);
|
|
1594
1831
|
if (stateRefError) return stateRefError;
|
|
1595
1832
|
}
|
|
1596
1833
|
const actionTargetError = validateActionTargets(ast, stateNames);
|
|
1597
1834
|
if (actionTargetError) return actionTargetError;
|
|
1598
|
-
if (
|
|
1835
|
+
if (isObject3(ast["view"])) {
|
|
1599
1836
|
const actionRefError = validateActionReferences(ast["view"], "/view", actionNames);
|
|
1600
1837
|
if (actionRefError) return actionRefError;
|
|
1601
1838
|
}
|
|
1602
1839
|
return null;
|
|
1603
1840
|
}
|
|
1604
1841
|
function validateAst(input) {
|
|
1605
|
-
if (!
|
|
1842
|
+
if (!isObject3(input)) {
|
|
1606
1843
|
return {
|
|
1607
1844
|
ok: false,
|
|
1608
1845
|
error: createSchemaError("Input must be an object", "/")
|
|
@@ -2267,16 +2504,80 @@ var astSchema = {
|
|
|
2267
2504
|
}
|
|
2268
2505
|
}
|
|
2269
2506
|
};
|
|
2507
|
+
|
|
2508
|
+
// src/types/streaming.ts
|
|
2509
|
+
var FLUSH_STRATEGIES = ["immediate", "batched", "manual"];
|
|
2510
|
+
var STREAM_CHUNK_TYPES = [
|
|
2511
|
+
"html",
|
|
2512
|
+
"shell",
|
|
2513
|
+
"fallback",
|
|
2514
|
+
"resolved",
|
|
2515
|
+
"end",
|
|
2516
|
+
"error"
|
|
2517
|
+
];
|
|
2518
|
+
function isStreamingRenderOptions(value) {
|
|
2519
|
+
if (typeof value !== "object" || value === null) {
|
|
2520
|
+
return false;
|
|
2521
|
+
}
|
|
2522
|
+
const obj = value;
|
|
2523
|
+
if (typeof obj["streaming"] !== "boolean") {
|
|
2524
|
+
return false;
|
|
2525
|
+
}
|
|
2526
|
+
if (typeof obj["flushStrategy"] !== "string" || !FLUSH_STRATEGIES.includes(obj["flushStrategy"])) {
|
|
2527
|
+
return false;
|
|
2528
|
+
}
|
|
2529
|
+
if (obj["batchTimeout"] !== void 0 && typeof obj["batchTimeout"] !== "number") {
|
|
2530
|
+
return false;
|
|
2531
|
+
}
|
|
2532
|
+
return true;
|
|
2533
|
+
}
|
|
2534
|
+
function isSuspenseBoundary(value) {
|
|
2535
|
+
if (typeof value !== "object" || value === null) {
|
|
2536
|
+
return false;
|
|
2537
|
+
}
|
|
2538
|
+
const obj = value;
|
|
2539
|
+
if (typeof obj["id"] !== "string") {
|
|
2540
|
+
return false;
|
|
2541
|
+
}
|
|
2542
|
+
if (typeof obj["fallback"] !== "object" || obj["fallback"] === null) {
|
|
2543
|
+
return false;
|
|
2544
|
+
}
|
|
2545
|
+
if (!(obj["promise"] instanceof Promise)) {
|
|
2546
|
+
return false;
|
|
2547
|
+
}
|
|
2548
|
+
return true;
|
|
2549
|
+
}
|
|
2550
|
+
function isStreamChunk(value) {
|
|
2551
|
+
if (typeof value !== "object" || value === null) {
|
|
2552
|
+
return false;
|
|
2553
|
+
}
|
|
2554
|
+
const obj = value;
|
|
2555
|
+
if (typeof obj["type"] !== "string" || !STREAM_CHUNK_TYPES.includes(obj["type"])) {
|
|
2556
|
+
return false;
|
|
2557
|
+
}
|
|
2558
|
+
if (typeof obj["content"] !== "string") {
|
|
2559
|
+
return false;
|
|
2560
|
+
}
|
|
2561
|
+
if (obj["boundaryId"] !== void 0 && typeof obj["boundaryId"] !== "string") {
|
|
2562
|
+
return false;
|
|
2563
|
+
}
|
|
2564
|
+
if (obj["error"] !== void 0 && !(obj["error"] instanceof Error)) {
|
|
2565
|
+
return false;
|
|
2566
|
+
}
|
|
2567
|
+
return true;
|
|
2568
|
+
}
|
|
2270
2569
|
export {
|
|
2271
2570
|
AI_OUTPUT_TYPES,
|
|
2272
2571
|
AI_PROVIDER_TYPES,
|
|
2273
2572
|
BINARY_OPERATORS,
|
|
2274
2573
|
CLIPBOARD_OPERATIONS,
|
|
2574
|
+
COLOR_SCHEMES,
|
|
2275
2575
|
ConstelaError,
|
|
2276
2576
|
DATA_SOURCE_TYPES,
|
|
2277
2577
|
DATA_TRANSFORMS,
|
|
2278
2578
|
FOCUS_OPERATIONS,
|
|
2279
2579
|
HTTP_METHODS,
|
|
2580
|
+
ISLAND_STRATEGIES,
|
|
2280
2581
|
NAVIGATE_TARGETS,
|
|
2281
2582
|
PARAM_TYPES,
|
|
2282
2583
|
STORAGE_OPERATIONS,
|
|
@@ -2293,6 +2594,7 @@ export {
|
|
|
2293
2594
|
createDataNotDefinedError,
|
|
2294
2595
|
createDuplicateActionError,
|
|
2295
2596
|
createDuplicateDefaultSlotError,
|
|
2597
|
+
createDuplicateIslandIdError,
|
|
2296
2598
|
createDuplicateSlotNameError,
|
|
2297
2599
|
createImportsNotDefinedError,
|
|
2298
2600
|
createInvalidClipboardOperationError,
|
|
@@ -2333,6 +2635,7 @@ export {
|
|
|
2333
2635
|
isCallStep,
|
|
2334
2636
|
isClipboardStep,
|
|
2335
2637
|
isCodeNode,
|
|
2638
|
+
isColorScheme,
|
|
2336
2639
|
isComponentNode,
|
|
2337
2640
|
isConcatExpr,
|
|
2338
2641
|
isCondExpr,
|
|
@@ -2343,6 +2646,7 @@ export {
|
|
|
2343
2646
|
isDisposeStep,
|
|
2344
2647
|
isEachNode,
|
|
2345
2648
|
isElementNode,
|
|
2649
|
+
isErrorBoundaryNode,
|
|
2346
2650
|
isEventHandler,
|
|
2347
2651
|
isExpression,
|
|
2348
2652
|
isFetchStep,
|
|
@@ -2352,6 +2656,9 @@ export {
|
|
|
2352
2656
|
isIfNode,
|
|
2353
2657
|
isImportExpr,
|
|
2354
2658
|
isImportStep,
|
|
2659
|
+
isIslandNode,
|
|
2660
|
+
isIslandStrategy,
|
|
2661
|
+
isIslandStrategyOptions,
|
|
2355
2662
|
isLayoutProgram,
|
|
2356
2663
|
isLifecycleHooks,
|
|
2357
2664
|
isListField,
|
|
@@ -2376,10 +2683,17 @@ export {
|
|
|
2376
2683
|
isStateField,
|
|
2377
2684
|
isStaticPathsDefinition,
|
|
2378
2685
|
isStorageStep,
|
|
2686
|
+
isStreamChunk,
|
|
2687
|
+
isStreamingRenderOptions,
|
|
2379
2688
|
isStringField,
|
|
2380
2689
|
isStyleExpr,
|
|
2381
2690
|
isSubscribeStep,
|
|
2691
|
+
isSuspenseBoundary,
|
|
2692
|
+
isSuspenseNode,
|
|
2382
2693
|
isTextNode,
|
|
2694
|
+
isThemeColors,
|
|
2695
|
+
isThemeConfig,
|
|
2696
|
+
isThemeFonts,
|
|
2383
2697
|
isUpdateStep,
|
|
2384
2698
|
isValidityExpr,
|
|
2385
2699
|
isVarExpr,
|