@constela/core 0.16.2 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -3
- package/dist/index.d.ts +284 -4
- package/dist/index.js +454 -125
- 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"];
|
|
@@ -1322,11 +1525,26 @@ function validateStateField(field, path) {
|
|
|
1322
1525
|
return { path: path + "/initial", message: "must be a number" };
|
|
1323
1526
|
}
|
|
1324
1527
|
break;
|
|
1325
|
-
case "string":
|
|
1326
|
-
|
|
1327
|
-
|
|
1528
|
+
case "string": {
|
|
1529
|
+
const initial = field["initial"];
|
|
1530
|
+
if (typeof initial === "string") {
|
|
1531
|
+
break;
|
|
1532
|
+
}
|
|
1533
|
+
if (typeof initial === "object" && initial !== null) {
|
|
1534
|
+
const obj = initial;
|
|
1535
|
+
if (obj["expr"] !== "cookie") {
|
|
1536
|
+
return { path: path + "/initial", message: "must be a string or a valid cookie expression" };
|
|
1537
|
+
}
|
|
1538
|
+
if (typeof obj["key"] !== "string") {
|
|
1539
|
+
return { path: path + "/initial/key", message: "key must be a string" };
|
|
1540
|
+
}
|
|
1541
|
+
if (typeof obj["default"] !== "string") {
|
|
1542
|
+
return { path: path + "/initial/default", message: "default must be a string" };
|
|
1543
|
+
}
|
|
1544
|
+
break;
|
|
1328
1545
|
}
|
|
1329
|
-
|
|
1546
|
+
return { path: path + "/initial", message: "must be a string or a valid cookie expression" };
|
|
1547
|
+
}
|
|
1330
1548
|
case "list":
|
|
1331
1549
|
if (!Array.isArray(field["initial"])) {
|
|
1332
1550
|
return { path: path + "/initial", message: "must be an array" };
|
|
@@ -1338,7 +1556,7 @@ function validateStateField(field, path) {
|
|
|
1338
1556
|
}
|
|
1339
1557
|
break;
|
|
1340
1558
|
case "object":
|
|
1341
|
-
if (!
|
|
1559
|
+
if (!isObject3(field["initial"])) {
|
|
1342
1560
|
return { path: path + "/initial", message: "must be an object" };
|
|
1343
1561
|
}
|
|
1344
1562
|
break;
|
|
@@ -1346,7 +1564,7 @@ function validateStateField(field, path) {
|
|
|
1346
1564
|
return null;
|
|
1347
1565
|
}
|
|
1348
1566
|
function validateParamDef(param, path) {
|
|
1349
|
-
if (!
|
|
1567
|
+
if (!isObject3(param)) {
|
|
1350
1568
|
return { path, message: "must be an object" };
|
|
1351
1569
|
}
|
|
1352
1570
|
const paramType = param["type"];
|
|
@@ -1362,13 +1580,13 @@ function validateParamDef(param, path) {
|
|
|
1362
1580
|
return null;
|
|
1363
1581
|
}
|
|
1364
1582
|
function validateComponentDef(def, path) {
|
|
1365
|
-
if (!
|
|
1583
|
+
if (!isObject3(def)) {
|
|
1366
1584
|
return { path, message: "must be an object" };
|
|
1367
1585
|
}
|
|
1368
1586
|
if (!("view" in def)) {
|
|
1369
1587
|
return { path: path + "/view", message: "view is required" };
|
|
1370
1588
|
}
|
|
1371
|
-
if ("params" in def &&
|
|
1589
|
+
if ("params" in def && isObject3(def["params"])) {
|
|
1372
1590
|
for (const [paramName, paramDef] of Object.entries(def["params"])) {
|
|
1373
1591
|
const error = validateParamDef(paramDef, path + "/params/" + paramName);
|
|
1374
1592
|
if (error) return error;
|
|
@@ -1379,7 +1597,7 @@ function validateComponentDef(def, path) {
|
|
|
1379
1597
|
return null;
|
|
1380
1598
|
}
|
|
1381
1599
|
function validateStylePreset(preset, path) {
|
|
1382
|
-
if (!
|
|
1600
|
+
if (!isObject3(preset)) {
|
|
1383
1601
|
return { path, message: "must be an object" };
|
|
1384
1602
|
}
|
|
1385
1603
|
if (!("base" in preset)) {
|
|
@@ -1389,11 +1607,11 @@ function validateStylePreset(preset, path) {
|
|
|
1389
1607
|
return { path: path + "/base", message: "base must be a string" };
|
|
1390
1608
|
}
|
|
1391
1609
|
if ("variants" in preset && preset["variants"] !== void 0) {
|
|
1392
|
-
if (!
|
|
1610
|
+
if (!isObject3(preset["variants"])) {
|
|
1393
1611
|
return { path: path + "/variants", message: "variants must be an object" };
|
|
1394
1612
|
}
|
|
1395
1613
|
for (const [variantKey, variantOptions] of Object.entries(preset["variants"])) {
|
|
1396
|
-
if (!
|
|
1614
|
+
if (!isObject3(variantOptions)) {
|
|
1397
1615
|
return { path: path + "/variants/" + variantKey, message: "variant options must be an object" };
|
|
1398
1616
|
}
|
|
1399
1617
|
for (const [optionKey, optionValue] of Object.entries(variantOptions)) {
|
|
@@ -1404,10 +1622,10 @@ function validateStylePreset(preset, path) {
|
|
|
1404
1622
|
}
|
|
1405
1623
|
}
|
|
1406
1624
|
if ("defaultVariants" in preset && preset["defaultVariants"] !== void 0) {
|
|
1407
|
-
if (!
|
|
1625
|
+
if (!isObject3(preset["defaultVariants"])) {
|
|
1408
1626
|
return { path: path + "/defaultVariants", message: "defaultVariants must be an object" };
|
|
1409
1627
|
}
|
|
1410
|
-
const variantKeys =
|
|
1628
|
+
const variantKeys = isObject3(preset["variants"]) ? Object.keys(preset["variants"]) : [];
|
|
1411
1629
|
for (const [key, value] of Object.entries(preset["defaultVariants"])) {
|
|
1412
1630
|
if (typeof value !== "string") {
|
|
1413
1631
|
return { path: path + "/defaultVariants/" + key, message: "default variant value must be a string" };
|
|
@@ -1423,7 +1641,7 @@ function validateStylePreset(preset, path) {
|
|
|
1423
1641
|
}
|
|
1424
1642
|
for (let i = 0; i < preset["compoundVariants"].length; i++) {
|
|
1425
1643
|
const compound = preset["compoundVariants"][i];
|
|
1426
|
-
if (!
|
|
1644
|
+
if (!isObject3(compound)) {
|
|
1427
1645
|
return { path: path + "/compoundVariants/" + i, message: "compound variant must be an object" };
|
|
1428
1646
|
}
|
|
1429
1647
|
if (typeof compound["class"] !== "string") {
|
|
@@ -1434,13 +1652,13 @@ function validateStylePreset(preset, path) {
|
|
|
1434
1652
|
return null;
|
|
1435
1653
|
}
|
|
1436
1654
|
function customValidateAst(input) {
|
|
1437
|
-
if (
|
|
1655
|
+
if (isObject3(input["state"])) {
|
|
1438
1656
|
for (const [name, field] of Object.entries(input["state"])) {
|
|
1439
1657
|
const error = validateStateField(field, "/state/" + name);
|
|
1440
1658
|
if (error) return error;
|
|
1441
1659
|
}
|
|
1442
1660
|
}
|
|
1443
|
-
if ("styles" in input &&
|
|
1661
|
+
if ("styles" in input && isObject3(input["styles"])) {
|
|
1444
1662
|
for (const [name, preset] of Object.entries(input["styles"])) {
|
|
1445
1663
|
const error = validateStylePreset(preset, "/styles/" + name);
|
|
1446
1664
|
if (error) return error;
|
|
@@ -1449,7 +1667,7 @@ function customValidateAst(input) {
|
|
|
1449
1667
|
if (Array.isArray(input["actions"])) {
|
|
1450
1668
|
for (let i = 0; i < input["actions"].length; i++) {
|
|
1451
1669
|
const action = input["actions"][i];
|
|
1452
|
-
if (
|
|
1670
|
+
if (isObject3(action) && Array.isArray(action["steps"])) {
|
|
1453
1671
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1454
1672
|
const error = validateActionStep(action["steps"][j], "/actions/" + i + "/steps/" + j);
|
|
1455
1673
|
if (error) return error;
|
|
@@ -1461,7 +1679,7 @@ function customValidateAst(input) {
|
|
|
1461
1679
|
const error = validateViewNode(input["view"], "/view");
|
|
1462
1680
|
if (error) return error;
|
|
1463
1681
|
}
|
|
1464
|
-
if ("components" in input &&
|
|
1682
|
+
if ("components" in input && isObject3(input["components"])) {
|
|
1465
1683
|
for (const [name, def] of Object.entries(input["components"])) {
|
|
1466
1684
|
const error = validateComponentDef(def, "/components/" + name);
|
|
1467
1685
|
if (error) return error;
|
|
@@ -1481,14 +1699,14 @@ function createErrorOptionsWithSuggestion(name, availableNames) {
|
|
|
1481
1699
|
function collectSemanticContext(ast) {
|
|
1482
1700
|
const stateNames = /* @__PURE__ */ new Set();
|
|
1483
1701
|
const actionNames = /* @__PURE__ */ new Set();
|
|
1484
|
-
if (
|
|
1702
|
+
if (isObject3(ast["state"])) {
|
|
1485
1703
|
for (const name of Object.keys(ast["state"])) {
|
|
1486
1704
|
stateNames.add(name);
|
|
1487
1705
|
}
|
|
1488
1706
|
}
|
|
1489
1707
|
if (Array.isArray(ast["actions"])) {
|
|
1490
1708
|
for (const action of ast["actions"]) {
|
|
1491
|
-
if (
|
|
1709
|
+
if (isObject3(action) && typeof action["name"] === "string") {
|
|
1492
1710
|
actionNames.add(action["name"]);
|
|
1493
1711
|
}
|
|
1494
1712
|
}
|
|
@@ -1496,7 +1714,26 @@ function collectSemanticContext(ast) {
|
|
|
1496
1714
|
return { stateNames, actionNames };
|
|
1497
1715
|
}
|
|
1498
1716
|
function validateStateReferences(node, path, stateNames) {
|
|
1499
|
-
if (!
|
|
1717
|
+
if (!isObject3(node)) return null;
|
|
1718
|
+
if (node["kind"] === "island") {
|
|
1719
|
+
const islandStateNames = new Set(stateNames);
|
|
1720
|
+
if (isObject3(node["state"])) {
|
|
1721
|
+
for (const name of Object.keys(node["state"])) {
|
|
1722
|
+
islandStateNames.add(name);
|
|
1723
|
+
}
|
|
1724
|
+
}
|
|
1725
|
+
if (isObject3(node["content"])) {
|
|
1726
|
+
const error = validateStateReferences(node["content"], path + "/content", islandStateNames);
|
|
1727
|
+
if (error) return error;
|
|
1728
|
+
}
|
|
1729
|
+
if (Array.isArray(node["actions"])) {
|
|
1730
|
+
for (let i = 0; i < node["actions"].length; i++) {
|
|
1731
|
+
const error = validateStateReferences(node["actions"][i], path + "/actions/" + i, islandStateNames);
|
|
1732
|
+
if (error) return error;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
return null;
|
|
1736
|
+
}
|
|
1500
1737
|
if (node["expr"] === "state" && typeof node["name"] === "string") {
|
|
1501
1738
|
if (!stateNames.has(node["name"])) {
|
|
1502
1739
|
const errorOptions = createErrorOptionsWithSuggestion(node["name"], stateNames);
|
|
@@ -1504,7 +1741,7 @@ function validateStateReferences(node, path, stateNames) {
|
|
|
1504
1741
|
}
|
|
1505
1742
|
}
|
|
1506
1743
|
for (const [key, value] of Object.entries(node)) {
|
|
1507
|
-
if (
|
|
1744
|
+
if (isObject3(value)) {
|
|
1508
1745
|
const error = validateStateReferences(value, path + "/" + key, stateNames);
|
|
1509
1746
|
if (error) return error;
|
|
1510
1747
|
} else if (Array.isArray(value)) {
|
|
@@ -1520,10 +1757,10 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1520
1757
|
if (!Array.isArray(ast["actions"])) return null;
|
|
1521
1758
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1522
1759
|
const action = ast["actions"][i];
|
|
1523
|
-
if (!
|
|
1760
|
+
if (!isObject3(action) || !Array.isArray(action["steps"])) continue;
|
|
1524
1761
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1525
1762
|
const step = action["steps"][j];
|
|
1526
|
-
if (!
|
|
1763
|
+
if (!isObject3(step)) continue;
|
|
1527
1764
|
if ((step["do"] === "set" || step["do"] === "update") && typeof step["target"] === "string") {
|
|
1528
1765
|
if (!stateNames.has(step["target"])) {
|
|
1529
1766
|
const errorOptions = createErrorOptionsWithSuggestion(step["target"], stateNames);
|
|
@@ -1535,10 +1772,25 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1535
1772
|
return null;
|
|
1536
1773
|
}
|
|
1537
1774
|
function validateActionReferences(node, path, actionNames) {
|
|
1538
|
-
if (!
|
|
1539
|
-
if (
|
|
1775
|
+
if (!isObject3(node)) return null;
|
|
1776
|
+
if (node["kind"] === "island") {
|
|
1777
|
+
const islandActionNames = new Set(actionNames);
|
|
1778
|
+
if (Array.isArray(node["actions"])) {
|
|
1779
|
+
for (const action of node["actions"]) {
|
|
1780
|
+
if (isObject3(action) && typeof action["name"] === "string") {
|
|
1781
|
+
islandActionNames.add(action["name"]);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
if (isObject3(node["content"])) {
|
|
1786
|
+
const error = validateActionReferences(node["content"], path + "/content", islandActionNames);
|
|
1787
|
+
if (error) return error;
|
|
1788
|
+
}
|
|
1789
|
+
return null;
|
|
1790
|
+
}
|
|
1791
|
+
if (isObject3(node["props"])) {
|
|
1540
1792
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
1541
|
-
if (
|
|
1793
|
+
if (isObject3(propValue) && "event" in propValue && "action" in propValue) {
|
|
1542
1794
|
const actionName = propValue["action"];
|
|
1543
1795
|
if (typeof actionName === "string" && !actionNames.has(actionName)) {
|
|
1544
1796
|
const errorOptions = createErrorOptionsWithSuggestion(actionName, actionNames);
|
|
@@ -1557,15 +1809,15 @@ function validateActionReferences(node, path, actionNames) {
|
|
|
1557
1809
|
if (error) return error;
|
|
1558
1810
|
}
|
|
1559
1811
|
}
|
|
1560
|
-
if (
|
|
1812
|
+
if (isObject3(node["then"])) {
|
|
1561
1813
|
const error = validateActionReferences(node["then"], path + "/then", actionNames);
|
|
1562
1814
|
if (error) return error;
|
|
1563
1815
|
}
|
|
1564
|
-
if (
|
|
1816
|
+
if (isObject3(node["else"])) {
|
|
1565
1817
|
const error = validateActionReferences(node["else"], path + "/else", actionNames);
|
|
1566
1818
|
if (error) return error;
|
|
1567
1819
|
}
|
|
1568
|
-
if (
|
|
1820
|
+
if (isObject3(node["body"])) {
|
|
1569
1821
|
const error = validateActionReferences(node["body"], path + "/body", actionNames);
|
|
1570
1822
|
if (error) return error;
|
|
1571
1823
|
}
|
|
@@ -1576,7 +1828,7 @@ function validateDuplicateActions(ast) {
|
|
|
1576
1828
|
const seenNames = /* @__PURE__ */ new Set();
|
|
1577
1829
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1578
1830
|
const action = ast["actions"][i];
|
|
1579
|
-
if (!
|
|
1831
|
+
if (!isObject3(action) || typeof action["name"] !== "string") continue;
|
|
1580
1832
|
const name = action["name"];
|
|
1581
1833
|
if (seenNames.has(name)) {
|
|
1582
1834
|
return createDuplicateActionError(name, "/actions/" + i);
|
|
@@ -1589,20 +1841,20 @@ function performSemanticValidation(ast) {
|
|
|
1589
1841
|
const { stateNames, actionNames } = collectSemanticContext(ast);
|
|
1590
1842
|
const duplicateError = validateDuplicateActions(ast);
|
|
1591
1843
|
if (duplicateError) return duplicateError;
|
|
1592
|
-
if (
|
|
1844
|
+
if (isObject3(ast["view"])) {
|
|
1593
1845
|
const stateRefError = validateStateReferences(ast["view"], "/view", stateNames);
|
|
1594
1846
|
if (stateRefError) return stateRefError;
|
|
1595
1847
|
}
|
|
1596
1848
|
const actionTargetError = validateActionTargets(ast, stateNames);
|
|
1597
1849
|
if (actionTargetError) return actionTargetError;
|
|
1598
|
-
if (
|
|
1850
|
+
if (isObject3(ast["view"])) {
|
|
1599
1851
|
const actionRefError = validateActionReferences(ast["view"], "/view", actionNames);
|
|
1600
1852
|
if (actionRefError) return actionRefError;
|
|
1601
1853
|
}
|
|
1602
1854
|
return null;
|
|
1603
1855
|
}
|
|
1604
1856
|
function validateAst(input) {
|
|
1605
|
-
if (!
|
|
1857
|
+
if (!isObject3(input)) {
|
|
1606
1858
|
return {
|
|
1607
1859
|
ok: false,
|
|
1608
1860
|
error: createSchemaError("Input must be an object", "/")
|
|
@@ -2267,16 +2519,80 @@ var astSchema = {
|
|
|
2267
2519
|
}
|
|
2268
2520
|
}
|
|
2269
2521
|
};
|
|
2522
|
+
|
|
2523
|
+
// src/types/streaming.ts
|
|
2524
|
+
var FLUSH_STRATEGIES = ["immediate", "batched", "manual"];
|
|
2525
|
+
var STREAM_CHUNK_TYPES = [
|
|
2526
|
+
"html",
|
|
2527
|
+
"shell",
|
|
2528
|
+
"fallback",
|
|
2529
|
+
"resolved",
|
|
2530
|
+
"end",
|
|
2531
|
+
"error"
|
|
2532
|
+
];
|
|
2533
|
+
function isStreamingRenderOptions(value) {
|
|
2534
|
+
if (typeof value !== "object" || value === null) {
|
|
2535
|
+
return false;
|
|
2536
|
+
}
|
|
2537
|
+
const obj = value;
|
|
2538
|
+
if (typeof obj["streaming"] !== "boolean") {
|
|
2539
|
+
return false;
|
|
2540
|
+
}
|
|
2541
|
+
if (typeof obj["flushStrategy"] !== "string" || !FLUSH_STRATEGIES.includes(obj["flushStrategy"])) {
|
|
2542
|
+
return false;
|
|
2543
|
+
}
|
|
2544
|
+
if (obj["batchTimeout"] !== void 0 && typeof obj["batchTimeout"] !== "number") {
|
|
2545
|
+
return false;
|
|
2546
|
+
}
|
|
2547
|
+
return true;
|
|
2548
|
+
}
|
|
2549
|
+
function isSuspenseBoundary(value) {
|
|
2550
|
+
if (typeof value !== "object" || value === null) {
|
|
2551
|
+
return false;
|
|
2552
|
+
}
|
|
2553
|
+
const obj = value;
|
|
2554
|
+
if (typeof obj["id"] !== "string") {
|
|
2555
|
+
return false;
|
|
2556
|
+
}
|
|
2557
|
+
if (typeof obj["fallback"] !== "object" || obj["fallback"] === null) {
|
|
2558
|
+
return false;
|
|
2559
|
+
}
|
|
2560
|
+
if (!(obj["promise"] instanceof Promise)) {
|
|
2561
|
+
return false;
|
|
2562
|
+
}
|
|
2563
|
+
return true;
|
|
2564
|
+
}
|
|
2565
|
+
function isStreamChunk(value) {
|
|
2566
|
+
if (typeof value !== "object" || value === null) {
|
|
2567
|
+
return false;
|
|
2568
|
+
}
|
|
2569
|
+
const obj = value;
|
|
2570
|
+
if (typeof obj["type"] !== "string" || !STREAM_CHUNK_TYPES.includes(obj["type"])) {
|
|
2571
|
+
return false;
|
|
2572
|
+
}
|
|
2573
|
+
if (typeof obj["content"] !== "string") {
|
|
2574
|
+
return false;
|
|
2575
|
+
}
|
|
2576
|
+
if (obj["boundaryId"] !== void 0 && typeof obj["boundaryId"] !== "string") {
|
|
2577
|
+
return false;
|
|
2578
|
+
}
|
|
2579
|
+
if (obj["error"] !== void 0 && !(obj["error"] instanceof Error)) {
|
|
2580
|
+
return false;
|
|
2581
|
+
}
|
|
2582
|
+
return true;
|
|
2583
|
+
}
|
|
2270
2584
|
export {
|
|
2271
2585
|
AI_OUTPUT_TYPES,
|
|
2272
2586
|
AI_PROVIDER_TYPES,
|
|
2273
2587
|
BINARY_OPERATORS,
|
|
2274
2588
|
CLIPBOARD_OPERATIONS,
|
|
2589
|
+
COLOR_SCHEMES,
|
|
2275
2590
|
ConstelaError,
|
|
2276
2591
|
DATA_SOURCE_TYPES,
|
|
2277
2592
|
DATA_TRANSFORMS,
|
|
2278
2593
|
FOCUS_OPERATIONS,
|
|
2279
2594
|
HTTP_METHODS,
|
|
2595
|
+
ISLAND_STRATEGIES,
|
|
2280
2596
|
NAVIGATE_TARGETS,
|
|
2281
2597
|
PARAM_TYPES,
|
|
2282
2598
|
STORAGE_OPERATIONS,
|
|
@@ -2293,6 +2609,7 @@ export {
|
|
|
2293
2609
|
createDataNotDefinedError,
|
|
2294
2610
|
createDuplicateActionError,
|
|
2295
2611
|
createDuplicateDefaultSlotError,
|
|
2612
|
+
createDuplicateIslandIdError,
|
|
2296
2613
|
createDuplicateSlotNameError,
|
|
2297
2614
|
createImportsNotDefinedError,
|
|
2298
2615
|
createInvalidClipboardOperationError,
|
|
@@ -2333,6 +2650,7 @@ export {
|
|
|
2333
2650
|
isCallStep,
|
|
2334
2651
|
isClipboardStep,
|
|
2335
2652
|
isCodeNode,
|
|
2653
|
+
isColorScheme,
|
|
2336
2654
|
isComponentNode,
|
|
2337
2655
|
isConcatExpr,
|
|
2338
2656
|
isCondExpr,
|
|
@@ -2343,6 +2661,7 @@ export {
|
|
|
2343
2661
|
isDisposeStep,
|
|
2344
2662
|
isEachNode,
|
|
2345
2663
|
isElementNode,
|
|
2664
|
+
isErrorBoundaryNode,
|
|
2346
2665
|
isEventHandler,
|
|
2347
2666
|
isExpression,
|
|
2348
2667
|
isFetchStep,
|
|
@@ -2352,6 +2671,9 @@ export {
|
|
|
2352
2671
|
isIfNode,
|
|
2353
2672
|
isImportExpr,
|
|
2354
2673
|
isImportStep,
|
|
2674
|
+
isIslandNode,
|
|
2675
|
+
isIslandStrategy,
|
|
2676
|
+
isIslandStrategyOptions,
|
|
2355
2677
|
isLayoutProgram,
|
|
2356
2678
|
isLifecycleHooks,
|
|
2357
2679
|
isListField,
|
|
@@ -2376,10 +2698,17 @@ export {
|
|
|
2376
2698
|
isStateField,
|
|
2377
2699
|
isStaticPathsDefinition,
|
|
2378
2700
|
isStorageStep,
|
|
2701
|
+
isStreamChunk,
|
|
2702
|
+
isStreamingRenderOptions,
|
|
2379
2703
|
isStringField,
|
|
2380
2704
|
isStyleExpr,
|
|
2381
2705
|
isSubscribeStep,
|
|
2706
|
+
isSuspenseBoundary,
|
|
2707
|
+
isSuspenseNode,
|
|
2382
2708
|
isTextNode,
|
|
2709
|
+
isThemeColors,
|
|
2710
|
+
isThemeConfig,
|
|
2711
|
+
isThemeFonts,
|
|
2383
2712
|
isUpdateStep,
|
|
2384
2713
|
isValidityExpr,
|
|
2385
2714
|
isVarExpr,
|