@constela/core 0.16.1 → 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 +326 -5
- package/dist/index.js +460 -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,46 +89,49 @@ 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
|
-
var DATA_SOURCE_TYPES = ["glob", "file", "api"];
|
|
95
|
+
var DATA_SOURCE_TYPES = ["glob", "file", "api", "ai"];
|
|
96
|
+
var AI_PROVIDER_TYPES = ["anthropic", "openai"];
|
|
97
|
+
var AI_OUTPUT_TYPES = ["component", "view"];
|
|
49
98
|
|
|
50
99
|
// src/types/guards.ts
|
|
51
|
-
function
|
|
100
|
+
function isObject2(value) {
|
|
52
101
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
53
102
|
}
|
|
54
103
|
function isLitExpr(value) {
|
|
55
|
-
if (!
|
|
104
|
+
if (!isObject2(value)) return false;
|
|
56
105
|
if (value["expr"] !== "lit") return false;
|
|
57
106
|
return "value" in value;
|
|
58
107
|
}
|
|
59
108
|
function isStateExpr(value) {
|
|
60
|
-
if (!
|
|
109
|
+
if (!isObject2(value)) return false;
|
|
61
110
|
if (value["expr"] !== "state") return false;
|
|
62
111
|
return typeof value["name"] === "string";
|
|
63
112
|
}
|
|
64
113
|
function isVarExpr(value) {
|
|
65
|
-
if (!
|
|
114
|
+
if (!isObject2(value)) return false;
|
|
66
115
|
if (value["expr"] !== "var") return false;
|
|
67
116
|
return typeof value["name"] === "string";
|
|
68
117
|
}
|
|
69
118
|
function isBinExpr(value) {
|
|
70
|
-
if (!
|
|
119
|
+
if (!isObject2(value)) return false;
|
|
71
120
|
if (value["expr"] !== "bin") return false;
|
|
72
121
|
if (!BINARY_OPERATORS.includes(value["op"])) {
|
|
73
122
|
return false;
|
|
74
123
|
}
|
|
75
|
-
if (!
|
|
124
|
+
if (!isObject2(value["left"]) || !isObject2(value["right"])) return false;
|
|
76
125
|
return true;
|
|
77
126
|
}
|
|
78
127
|
function isNotExpr(value) {
|
|
79
|
-
if (!
|
|
128
|
+
if (!isObject2(value)) return false;
|
|
80
129
|
if (value["expr"] !== "not") return false;
|
|
81
|
-
if (!
|
|
130
|
+
if (!isObject2(value["operand"])) return false;
|
|
82
131
|
return true;
|
|
83
132
|
}
|
|
84
133
|
function isParamExpr(value) {
|
|
85
|
-
if (!
|
|
134
|
+
if (!isObject2(value)) return false;
|
|
86
135
|
if (value["expr"] !== "param") return false;
|
|
87
136
|
if (typeof value["name"] !== "string") return false;
|
|
88
137
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -91,20 +140,20 @@ function isParamExpr(value) {
|
|
|
91
140
|
return true;
|
|
92
141
|
}
|
|
93
142
|
function isCondExpr(value) {
|
|
94
|
-
if (!
|
|
143
|
+
if (!isObject2(value)) return false;
|
|
95
144
|
if (value["expr"] !== "cond") return false;
|
|
96
|
-
if (!
|
|
145
|
+
if (!isObject2(value["if"]) || !isObject2(value["then"]) || !isObject2(value["else"])) return false;
|
|
97
146
|
return true;
|
|
98
147
|
}
|
|
99
148
|
function isGetExpr(value) {
|
|
100
|
-
if (!
|
|
149
|
+
if (!isObject2(value)) return false;
|
|
101
150
|
if (value["expr"] !== "get") return false;
|
|
102
|
-
if (!
|
|
151
|
+
if (!isObject2(value["base"])) return false;
|
|
103
152
|
if (typeof value["path"] !== "string") return false;
|
|
104
153
|
return true;
|
|
105
154
|
}
|
|
106
155
|
function isRouteExpr(value) {
|
|
107
|
-
if (!
|
|
156
|
+
if (!isObject2(value)) return false;
|
|
108
157
|
if (value["expr"] !== "route") return false;
|
|
109
158
|
if (typeof value["name"] !== "string") return false;
|
|
110
159
|
if ("source" in value && value["source"] !== void 0) {
|
|
@@ -114,7 +163,7 @@ function isRouteExpr(value) {
|
|
|
114
163
|
return true;
|
|
115
164
|
}
|
|
116
165
|
function isImportExpr(value) {
|
|
117
|
-
if (!
|
|
166
|
+
if (!isObject2(value)) return false;
|
|
118
167
|
if (value["expr"] !== "import") return false;
|
|
119
168
|
if (typeof value["name"] !== "string") return false;
|
|
120
169
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -123,7 +172,7 @@ function isImportExpr(value) {
|
|
|
123
172
|
return true;
|
|
124
173
|
}
|
|
125
174
|
function isDataExpr(value) {
|
|
126
|
-
if (!
|
|
175
|
+
if (!isObject2(value)) return false;
|
|
127
176
|
if (value["expr"] !== "data") return false;
|
|
128
177
|
if (typeof value["name"] !== "string") return false;
|
|
129
178
|
if ("path" in value && value["path"] !== void 0) {
|
|
@@ -132,23 +181,23 @@ function isDataExpr(value) {
|
|
|
132
181
|
return true;
|
|
133
182
|
}
|
|
134
183
|
function isRefExpr(value) {
|
|
135
|
-
if (!
|
|
184
|
+
if (!isObject2(value)) return false;
|
|
136
185
|
if (value["expr"] !== "ref") return false;
|
|
137
186
|
return typeof value["name"] === "string";
|
|
138
187
|
}
|
|
139
188
|
function isIndexExpr(value) {
|
|
140
|
-
if (!
|
|
189
|
+
if (!isObject2(value)) return false;
|
|
141
190
|
if (value["expr"] !== "index") return false;
|
|
142
191
|
if (!("base" in value)) return false;
|
|
143
192
|
if (!("key" in value)) return false;
|
|
144
193
|
return true;
|
|
145
194
|
}
|
|
146
195
|
function isStyleExpr(value) {
|
|
147
|
-
if (!
|
|
196
|
+
if (!isObject2(value)) return false;
|
|
148
197
|
if (value["expr"] !== "style") return false;
|
|
149
198
|
if (typeof value["name"] !== "string") return false;
|
|
150
199
|
if ("variants" in value && value["variants"] !== void 0) {
|
|
151
|
-
if (!
|
|
200
|
+
if (!isObject2(value["variants"])) return false;
|
|
152
201
|
}
|
|
153
202
|
return true;
|
|
154
203
|
}
|
|
@@ -159,7 +208,7 @@ function isArrayExpr(value) {
|
|
|
159
208
|
return typeof value === "object" && value !== null && value.expr === "array" && Array.isArray(value.elements);
|
|
160
209
|
}
|
|
161
210
|
function isValidityExpr(value) {
|
|
162
|
-
if (!
|
|
211
|
+
if (!isObject2(value)) return false;
|
|
163
212
|
if (value["expr"] !== "validity") return false;
|
|
164
213
|
if (typeof value["ref"] !== "string") return false;
|
|
165
214
|
if ("property" in value && value["property"] !== void 0) {
|
|
@@ -170,7 +219,7 @@ function isValidityExpr(value) {
|
|
|
170
219
|
return true;
|
|
171
220
|
}
|
|
172
221
|
function isDataSource(value) {
|
|
173
|
-
if (!
|
|
222
|
+
if (!isObject2(value)) return false;
|
|
174
223
|
const type = value["type"];
|
|
175
224
|
if (!DATA_SOURCE_TYPES.includes(type)) {
|
|
176
225
|
return false;
|
|
@@ -190,17 +239,36 @@ function isDataSource(value) {
|
|
|
190
239
|
case "api":
|
|
191
240
|
if (typeof value["url"] !== "string") return false;
|
|
192
241
|
break;
|
|
242
|
+
case "ai":
|
|
243
|
+
return isAiDataSource(value);
|
|
193
244
|
}
|
|
194
245
|
return true;
|
|
195
246
|
}
|
|
247
|
+
function isAiDataSource(value) {
|
|
248
|
+
if (!isObject2(value)) return false;
|
|
249
|
+
if (value["type"] !== "ai") return false;
|
|
250
|
+
if (!AI_PROVIDER_TYPES.includes(value["provider"])) return false;
|
|
251
|
+
if (typeof value["prompt"] !== "string") return false;
|
|
252
|
+
if (!AI_OUTPUT_TYPES.includes(value["output"])) return false;
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
function isGenerateStep(value) {
|
|
256
|
+
if (!isObject2(value)) return false;
|
|
257
|
+
if (value["do"] !== "generate") return false;
|
|
258
|
+
if (!AI_PROVIDER_TYPES.includes(value["provider"])) return false;
|
|
259
|
+
if (!("prompt" in value)) return false;
|
|
260
|
+
if (!AI_OUTPUT_TYPES.includes(value["output"])) return false;
|
|
261
|
+
if (typeof value["result"] !== "string") return false;
|
|
262
|
+
return true;
|
|
263
|
+
}
|
|
196
264
|
function isStaticPathsDefinition(value) {
|
|
197
|
-
if (!
|
|
265
|
+
if (!isObject2(value)) return false;
|
|
198
266
|
if (typeof value["source"] !== "string") return false;
|
|
199
|
-
if (!("params" in value) || !
|
|
267
|
+
if (!("params" in value) || !isObject2(value["params"])) return false;
|
|
200
268
|
return true;
|
|
201
269
|
}
|
|
202
270
|
function isRouteDefinition(value) {
|
|
203
|
-
if (!
|
|
271
|
+
if (!isObject2(value)) return false;
|
|
204
272
|
if (typeof value["path"] !== "string") return false;
|
|
205
273
|
return true;
|
|
206
274
|
}
|
|
@@ -208,36 +276,36 @@ function isExpression(value) {
|
|
|
208
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);
|
|
209
277
|
}
|
|
210
278
|
function isElementNode(value) {
|
|
211
|
-
if (!
|
|
279
|
+
if (!isObject2(value)) return false;
|
|
212
280
|
if (value["kind"] !== "element") return false;
|
|
213
281
|
return typeof value["tag"] === "string";
|
|
214
282
|
}
|
|
215
283
|
function isTextNode(value) {
|
|
216
|
-
if (!
|
|
284
|
+
if (!isObject2(value)) return false;
|
|
217
285
|
if (value["kind"] !== "text") return false;
|
|
218
|
-
return
|
|
286
|
+
return isObject2(value["value"]);
|
|
219
287
|
}
|
|
220
288
|
function isIfNode(value) {
|
|
221
|
-
if (!
|
|
289
|
+
if (!isObject2(value)) return false;
|
|
222
290
|
if (value["kind"] !== "if") return false;
|
|
223
|
-
if (!
|
|
224
|
-
if (!
|
|
291
|
+
if (!isObject2(value["condition"])) return false;
|
|
292
|
+
if (!isObject2(value["then"])) return false;
|
|
225
293
|
return true;
|
|
226
294
|
}
|
|
227
295
|
function isEachNode(value) {
|
|
228
|
-
if (!
|
|
296
|
+
if (!isObject2(value)) return false;
|
|
229
297
|
if (value["kind"] !== "each") return false;
|
|
230
|
-
if (!
|
|
298
|
+
if (!isObject2(value["items"])) return false;
|
|
231
299
|
if (typeof value["as"] !== "string") return false;
|
|
232
|
-
if (!
|
|
300
|
+
if (!isObject2(value["body"])) return false;
|
|
233
301
|
return true;
|
|
234
302
|
}
|
|
235
303
|
function isComponentNode(value) {
|
|
236
|
-
if (!
|
|
304
|
+
if (!isObject2(value)) return false;
|
|
237
305
|
if (value["kind"] !== "component") return false;
|
|
238
306
|
if (typeof value["name"] !== "string") return false;
|
|
239
307
|
if ("props" in value && value["props"] !== void 0) {
|
|
240
|
-
if (!
|
|
308
|
+
if (!isObject2(value["props"])) return false;
|
|
241
309
|
}
|
|
242
310
|
if ("children" in value && value["children"] !== void 0) {
|
|
243
311
|
if (!Array.isArray(value["children"])) return false;
|
|
@@ -245,40 +313,107 @@ function isComponentNode(value) {
|
|
|
245
313
|
return true;
|
|
246
314
|
}
|
|
247
315
|
function isSlotNode(value) {
|
|
248
|
-
if (!
|
|
316
|
+
if (!isObject2(value)) return false;
|
|
249
317
|
return value["kind"] === "slot";
|
|
250
318
|
}
|
|
251
319
|
function isMarkdownNode(value) {
|
|
252
|
-
if (!
|
|
320
|
+
if (!isObject2(value)) return false;
|
|
253
321
|
if (value["kind"] !== "markdown") return false;
|
|
254
|
-
return "content" in value &&
|
|
322
|
+
return "content" in value && isObject2(value["content"]);
|
|
255
323
|
}
|
|
256
324
|
function isCodeNode(value) {
|
|
257
|
-
if (!
|
|
325
|
+
if (!isObject2(value)) return false;
|
|
258
326
|
if (value["kind"] !== "code") return false;
|
|
259
|
-
if (!("language" in value) || !
|
|
260
|
-
if (!("content" in value) || !
|
|
327
|
+
if (!("language" in value) || !isObject2(value["language"])) return false;
|
|
328
|
+
if (!("content" in value) || !isObject2(value["content"])) return false;
|
|
261
329
|
return true;
|
|
262
330
|
}
|
|
263
331
|
function isPortalNode(value) {
|
|
264
|
-
if (!
|
|
332
|
+
if (!isObject2(value)) return false;
|
|
265
333
|
if (value["kind"] !== "portal") return false;
|
|
266
334
|
if (typeof value["target"] !== "string") return false;
|
|
267
335
|
if (!Array.isArray(value["children"])) return false;
|
|
268
336
|
return true;
|
|
269
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
|
+
}
|
|
270
405
|
function isViewNode(value) {
|
|
271
|
-
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);
|
|
272
407
|
}
|
|
273
408
|
function isSetStep(value) {
|
|
274
|
-
if (!
|
|
409
|
+
if (!isObject2(value)) return false;
|
|
275
410
|
if (value["do"] !== "set") return false;
|
|
276
411
|
if (typeof value["target"] !== "string") return false;
|
|
277
|
-
if (!
|
|
412
|
+
if (!isObject2(value["value"])) return false;
|
|
278
413
|
return true;
|
|
279
414
|
}
|
|
280
415
|
function isUpdateStep(value) {
|
|
281
|
-
if (!
|
|
416
|
+
if (!isObject2(value)) return false;
|
|
282
417
|
if (value["do"] !== "update") return false;
|
|
283
418
|
if (typeof value["target"] !== "string") return false;
|
|
284
419
|
if (!UPDATE_OPERATIONS.includes(value["operation"])) {
|
|
@@ -287,17 +422,17 @@ function isUpdateStep(value) {
|
|
|
287
422
|
return true;
|
|
288
423
|
}
|
|
289
424
|
function isSetPathStep(value) {
|
|
290
|
-
if (!
|
|
425
|
+
if (!isObject2(value)) return false;
|
|
291
426
|
if (value["do"] !== "setPath") return false;
|
|
292
427
|
if (typeof value["target"] !== "string") return false;
|
|
293
|
-
if (!
|
|
294
|
-
if (!
|
|
428
|
+
if (!isObject2(value["path"])) return false;
|
|
429
|
+
if (!isObject2(value["value"])) return false;
|
|
295
430
|
return true;
|
|
296
431
|
}
|
|
297
432
|
function isFetchStep(value) {
|
|
298
|
-
if (!
|
|
433
|
+
if (!isObject2(value)) return false;
|
|
299
434
|
if (value["do"] !== "fetch") return false;
|
|
300
|
-
if (!
|
|
435
|
+
if (!isObject2(value["url"])) return false;
|
|
301
436
|
if ("method" in value && value["method"] !== void 0) {
|
|
302
437
|
if (!HTTP_METHODS.includes(value["method"])) {
|
|
303
438
|
return false;
|
|
@@ -306,7 +441,7 @@ function isFetchStep(value) {
|
|
|
306
441
|
return true;
|
|
307
442
|
}
|
|
308
443
|
function isStorageStep(value) {
|
|
309
|
-
if (!
|
|
444
|
+
if (!isObject2(value)) return false;
|
|
310
445
|
if (value["do"] !== "storage") return false;
|
|
311
446
|
if (!STORAGE_OPERATIONS.includes(value["operation"])) {
|
|
312
447
|
return false;
|
|
@@ -318,7 +453,7 @@ function isStorageStep(value) {
|
|
|
318
453
|
return true;
|
|
319
454
|
}
|
|
320
455
|
function isClipboardStep(value) {
|
|
321
|
-
if (!
|
|
456
|
+
if (!isObject2(value)) return false;
|
|
322
457
|
if (value["do"] !== "clipboard") return false;
|
|
323
458
|
if (!CLIPBOARD_OPERATIONS.includes(value["operation"])) {
|
|
324
459
|
return false;
|
|
@@ -326,7 +461,7 @@ function isClipboardStep(value) {
|
|
|
326
461
|
return true;
|
|
327
462
|
}
|
|
328
463
|
function isNavigateStep(value) {
|
|
329
|
-
if (!
|
|
464
|
+
if (!isObject2(value)) return false;
|
|
330
465
|
if (value["do"] !== "navigate") return false;
|
|
331
466
|
if (!("url" in value)) return false;
|
|
332
467
|
if ("target" in value && value["target"] !== void 0) {
|
|
@@ -337,69 +472,69 @@ function isNavigateStep(value) {
|
|
|
337
472
|
return true;
|
|
338
473
|
}
|
|
339
474
|
function isImportStep(value) {
|
|
340
|
-
if (!
|
|
475
|
+
if (!isObject2(value)) return false;
|
|
341
476
|
if (value["do"] !== "import") return false;
|
|
342
477
|
if (typeof value["module"] !== "string") return false;
|
|
343
478
|
if (typeof value["result"] !== "string") return false;
|
|
344
479
|
return true;
|
|
345
480
|
}
|
|
346
481
|
function isCallStep(value) {
|
|
347
|
-
if (!
|
|
482
|
+
if (!isObject2(value)) return false;
|
|
348
483
|
if (value["do"] !== "call") return false;
|
|
349
|
-
if (!
|
|
484
|
+
if (!isObject2(value["target"])) return false;
|
|
350
485
|
return true;
|
|
351
486
|
}
|
|
352
487
|
function isSubscribeStep(value) {
|
|
353
|
-
if (!
|
|
488
|
+
if (!isObject2(value)) return false;
|
|
354
489
|
if (value["do"] !== "subscribe") return false;
|
|
355
|
-
if (!
|
|
490
|
+
if (!isObject2(value["target"])) return false;
|
|
356
491
|
if (typeof value["event"] !== "string") return false;
|
|
357
492
|
if (typeof value["action"] !== "string") return false;
|
|
358
493
|
return true;
|
|
359
494
|
}
|
|
360
495
|
function isDisposeStep(value) {
|
|
361
|
-
if (!
|
|
496
|
+
if (!isObject2(value)) return false;
|
|
362
497
|
if (value["do"] !== "dispose") return false;
|
|
363
|
-
if (!
|
|
498
|
+
if (!isObject2(value["target"])) return false;
|
|
364
499
|
return true;
|
|
365
500
|
}
|
|
366
501
|
function isDelayStep(value) {
|
|
367
|
-
if (!
|
|
502
|
+
if (!isObject2(value)) return false;
|
|
368
503
|
if (value["do"] !== "delay") return false;
|
|
369
|
-
if (!
|
|
504
|
+
if (!isObject2(value["ms"])) return false;
|
|
370
505
|
if (!Array.isArray(value["then"])) return false;
|
|
371
506
|
return true;
|
|
372
507
|
}
|
|
373
508
|
function isIntervalStep(value) {
|
|
374
|
-
if (!
|
|
509
|
+
if (!isObject2(value)) return false;
|
|
375
510
|
if (value["do"] !== "interval") return false;
|
|
376
|
-
if (!
|
|
511
|
+
if (!isObject2(value["ms"])) return false;
|
|
377
512
|
if (typeof value["action"] !== "string") return false;
|
|
378
513
|
return true;
|
|
379
514
|
}
|
|
380
515
|
function isClearTimerStep(value) {
|
|
381
|
-
if (!
|
|
516
|
+
if (!isObject2(value)) return false;
|
|
382
517
|
if (value["do"] !== "clearTimer") return false;
|
|
383
|
-
if (!
|
|
518
|
+
if (!isObject2(value["target"])) return false;
|
|
384
519
|
return true;
|
|
385
520
|
}
|
|
386
521
|
function isFocusStep(value) {
|
|
387
|
-
if (!
|
|
522
|
+
if (!isObject2(value)) return false;
|
|
388
523
|
if (value["do"] !== "focus") return false;
|
|
389
|
-
if (!
|
|
524
|
+
if (!isObject2(value["target"])) return false;
|
|
390
525
|
if (!FOCUS_OPERATIONS.includes(value["operation"])) {
|
|
391
526
|
return false;
|
|
392
527
|
}
|
|
393
528
|
return true;
|
|
394
529
|
}
|
|
395
530
|
function isActionStep(value) {
|
|
396
|
-
return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value) || isFetchStep(value) || isStorageStep(value) || isClipboardStep(value) || isNavigateStep(value) || isImportStep(value) || isCallStep(value) || isSubscribeStep(value) || isDisposeStep(value) || isDelayStep(value) || isIntervalStep(value) || isClearTimerStep(value) || isFocusStep(value);
|
|
531
|
+
return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value) || isFetchStep(value) || isStorageStep(value) || isClipboardStep(value) || isNavigateStep(value) || isImportStep(value) || isCallStep(value) || isSubscribeStep(value) || isDisposeStep(value) || isDelayStep(value) || isIntervalStep(value) || isClearTimerStep(value) || isFocusStep(value) || isGenerateStep(value);
|
|
397
532
|
}
|
|
398
533
|
function isLocalActionStep(value) {
|
|
399
534
|
return isSetStep(value) || isUpdateStep(value) || isSetPathStep(value);
|
|
400
535
|
}
|
|
401
536
|
function isLocalActionDefinition(value) {
|
|
402
|
-
if (!
|
|
537
|
+
if (!isObject2(value)) return false;
|
|
403
538
|
if (typeof value["name"] !== "string") return false;
|
|
404
539
|
if (!Array.isArray(value["steps"])) return false;
|
|
405
540
|
for (const step of value["steps"]) {
|
|
@@ -408,7 +543,7 @@ function isLocalActionDefinition(value) {
|
|
|
408
543
|
return true;
|
|
409
544
|
}
|
|
410
545
|
function isNumberField(value) {
|
|
411
|
-
if (!
|
|
546
|
+
if (!isObject2(value)) return false;
|
|
412
547
|
if (value["type"] !== "number") return false;
|
|
413
548
|
return typeof value["initial"] === "number";
|
|
414
549
|
}
|
|
@@ -416,22 +551,22 @@ function isCookieInitialExpr(value) {
|
|
|
416
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";
|
|
417
552
|
}
|
|
418
553
|
function isStringField(value) {
|
|
419
|
-
if (!
|
|
554
|
+
if (!isObject2(value)) return false;
|
|
420
555
|
if (value["type"] !== "string") return false;
|
|
421
556
|
return typeof value["initial"] === "string" || isCookieInitialExpr(value["initial"]);
|
|
422
557
|
}
|
|
423
558
|
function isListField(value) {
|
|
424
|
-
if (!
|
|
559
|
+
if (!isObject2(value)) return false;
|
|
425
560
|
if (value["type"] !== "list") return false;
|
|
426
561
|
return Array.isArray(value["initial"]);
|
|
427
562
|
}
|
|
428
563
|
function isBooleanField(value) {
|
|
429
|
-
if (!
|
|
564
|
+
if (!isObject2(value)) return false;
|
|
430
565
|
if (value["type"] !== "boolean") return false;
|
|
431
566
|
return typeof value["initial"] === "boolean";
|
|
432
567
|
}
|
|
433
568
|
function isObjectField(value) {
|
|
434
|
-
if (!
|
|
569
|
+
if (!isObject2(value)) return false;
|
|
435
570
|
if (value["type"] !== "object") return false;
|
|
436
571
|
return typeof value["initial"] === "object" && value["initial"] !== null;
|
|
437
572
|
}
|
|
@@ -439,20 +574,20 @@ function isStateField(value) {
|
|
|
439
574
|
return isNumberField(value) || isStringField(value) || isListField(value) || isBooleanField(value) || isObjectField(value);
|
|
440
575
|
}
|
|
441
576
|
function isEventHandler(value) {
|
|
442
|
-
if (!
|
|
577
|
+
if (!isObject2(value)) return false;
|
|
443
578
|
if (!("event" in value) || typeof value["event"] !== "string") return false;
|
|
444
579
|
if (!("action" in value) || typeof value["action"] !== "string") return false;
|
|
445
580
|
return true;
|
|
446
581
|
}
|
|
447
582
|
function isLayoutProgram(value) {
|
|
448
|
-
if (!
|
|
583
|
+
if (!isObject2(value)) return false;
|
|
449
584
|
if (value["version"] !== "1.0") return false;
|
|
450
585
|
if (value["type"] !== "layout") return false;
|
|
451
586
|
if (!("view" in value)) return false;
|
|
452
587
|
return true;
|
|
453
588
|
}
|
|
454
589
|
function isNamedSlotNode(value) {
|
|
455
|
-
if (!
|
|
590
|
+
if (!isObject2(value)) return false;
|
|
456
591
|
if (value["kind"] !== "slot") return false;
|
|
457
592
|
if (typeof value["name"] !== "string") return false;
|
|
458
593
|
return true;
|
|
@@ -798,6 +933,16 @@ function createLocalActionInvalidStepError(stepType, path) {
|
|
|
798
933
|
path
|
|
799
934
|
);
|
|
800
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
|
+
}
|
|
801
946
|
function levenshteinDistance(a, b) {
|
|
802
947
|
const aLen = a.length;
|
|
803
948
|
const bLen = b.length;
|
|
@@ -839,10 +984,10 @@ function findSimilarNames(target, candidates, maxDistance = 2) {
|
|
|
839
984
|
}
|
|
840
985
|
|
|
841
986
|
// src/schema/validator.ts
|
|
842
|
-
function
|
|
987
|
+
function isObject3(value) {
|
|
843
988
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
844
989
|
}
|
|
845
|
-
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"];
|
|
846
991
|
var VALID_EXPR_TYPES = ["lit", "state", "var", "bin", "not", "param", "cond", "get", "style", "validity", "index", "call", "lambda", "array"];
|
|
847
992
|
var VALID_PARAM_TYPES = ["string", "number", "boolean", "json"];
|
|
848
993
|
var VALID_ACTION_TYPES = ["set", "update", "setPath", "fetch", "delay", "interval", "clearTimer", "focus", "if"];
|
|
@@ -851,7 +996,7 @@ var VALID_BIN_OPS = BINARY_OPERATORS;
|
|
|
851
996
|
var VALID_UPDATE_OPS = UPDATE_OPERATIONS;
|
|
852
997
|
var VALID_HTTP_METHODS = HTTP_METHODS;
|
|
853
998
|
function validateViewNode(node, path) {
|
|
854
|
-
if (!
|
|
999
|
+
if (!isObject3(node)) {
|
|
855
1000
|
return { path, message: "must be an object" };
|
|
856
1001
|
}
|
|
857
1002
|
const kind = node["kind"];
|
|
@@ -866,9 +1011,9 @@ function validateViewNode(node, path) {
|
|
|
866
1011
|
if (typeof node["tag"] !== "string") {
|
|
867
1012
|
return { path: path + "/tag", message: "tag is required" };
|
|
868
1013
|
}
|
|
869
|
-
if (node["props"] !== void 0 &&
|
|
1014
|
+
if (node["props"] !== void 0 && isObject3(node["props"])) {
|
|
870
1015
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
871
|
-
if (
|
|
1016
|
+
if (isObject3(propValue) && "event" in propValue) {
|
|
872
1017
|
} else {
|
|
873
1018
|
const error = validateExpression(propValue, path + "/props/" + propName);
|
|
874
1019
|
if (error) return error;
|
|
@@ -926,7 +1071,7 @@ function validateViewNode(node, path) {
|
|
|
926
1071
|
if (typeof node["name"] !== "string") {
|
|
927
1072
|
return { path: path + "/name", message: "name is required" };
|
|
928
1073
|
}
|
|
929
|
-
if (node["props"] !== void 0 &&
|
|
1074
|
+
if (node["props"] !== void 0 && isObject3(node["props"])) {
|
|
930
1075
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
931
1076
|
const error = validateExpression(propValue, path + "/props/" + propName);
|
|
932
1077
|
if (error) return error;
|
|
@@ -969,11 +1114,90 @@ function validateViewNode(node, path) {
|
|
|
969
1114
|
}
|
|
970
1115
|
}
|
|
971
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;
|
|
972
1196
|
}
|
|
973
1197
|
return null;
|
|
974
1198
|
}
|
|
975
1199
|
function validateExpression(expr, path) {
|
|
976
|
-
if (!
|
|
1200
|
+
if (!isObject3(expr)) {
|
|
977
1201
|
return { path, message: "must be an object" };
|
|
978
1202
|
}
|
|
979
1203
|
const exprType = expr["expr"];
|
|
@@ -1060,7 +1284,7 @@ function validateExpression(expr, path) {
|
|
|
1060
1284
|
return { path: path + "/name", message: "name is required" };
|
|
1061
1285
|
}
|
|
1062
1286
|
if ("variants" in expr && expr["variants"] !== void 0) {
|
|
1063
|
-
if (!
|
|
1287
|
+
if (!isObject3(expr["variants"])) {
|
|
1064
1288
|
return { path: path + "/variants", message: "variants must be an object" };
|
|
1065
1289
|
}
|
|
1066
1290
|
for (const [variantKey, variantValue] of Object.entries(expr["variants"])) {
|
|
@@ -1140,7 +1364,7 @@ function validateExpression(expr, path) {
|
|
|
1140
1364
|
return null;
|
|
1141
1365
|
}
|
|
1142
1366
|
function validateActionStep(step, path) {
|
|
1143
|
-
if (!
|
|
1367
|
+
if (!isObject3(step)) {
|
|
1144
1368
|
return { path, message: "must be an object" };
|
|
1145
1369
|
}
|
|
1146
1370
|
const doType = step["do"];
|
|
@@ -1282,7 +1506,7 @@ function validateActionStep(step, path) {
|
|
|
1282
1506
|
return null;
|
|
1283
1507
|
}
|
|
1284
1508
|
function validateStateField(field, path) {
|
|
1285
|
-
if (!
|
|
1509
|
+
if (!isObject3(field)) {
|
|
1286
1510
|
return { path, message: "must be an object" };
|
|
1287
1511
|
}
|
|
1288
1512
|
const fieldType = field["type"];
|
|
@@ -1317,7 +1541,7 @@ function validateStateField(field, path) {
|
|
|
1317
1541
|
}
|
|
1318
1542
|
break;
|
|
1319
1543
|
case "object":
|
|
1320
|
-
if (!
|
|
1544
|
+
if (!isObject3(field["initial"])) {
|
|
1321
1545
|
return { path: path + "/initial", message: "must be an object" };
|
|
1322
1546
|
}
|
|
1323
1547
|
break;
|
|
@@ -1325,7 +1549,7 @@ function validateStateField(field, path) {
|
|
|
1325
1549
|
return null;
|
|
1326
1550
|
}
|
|
1327
1551
|
function validateParamDef(param, path) {
|
|
1328
|
-
if (!
|
|
1552
|
+
if (!isObject3(param)) {
|
|
1329
1553
|
return { path, message: "must be an object" };
|
|
1330
1554
|
}
|
|
1331
1555
|
const paramType = param["type"];
|
|
@@ -1341,13 +1565,13 @@ function validateParamDef(param, path) {
|
|
|
1341
1565
|
return null;
|
|
1342
1566
|
}
|
|
1343
1567
|
function validateComponentDef(def, path) {
|
|
1344
|
-
if (!
|
|
1568
|
+
if (!isObject3(def)) {
|
|
1345
1569
|
return { path, message: "must be an object" };
|
|
1346
1570
|
}
|
|
1347
1571
|
if (!("view" in def)) {
|
|
1348
1572
|
return { path: path + "/view", message: "view is required" };
|
|
1349
1573
|
}
|
|
1350
|
-
if ("params" in def &&
|
|
1574
|
+
if ("params" in def && isObject3(def["params"])) {
|
|
1351
1575
|
for (const [paramName, paramDef] of Object.entries(def["params"])) {
|
|
1352
1576
|
const error = validateParamDef(paramDef, path + "/params/" + paramName);
|
|
1353
1577
|
if (error) return error;
|
|
@@ -1358,7 +1582,7 @@ function validateComponentDef(def, path) {
|
|
|
1358
1582
|
return null;
|
|
1359
1583
|
}
|
|
1360
1584
|
function validateStylePreset(preset, path) {
|
|
1361
|
-
if (!
|
|
1585
|
+
if (!isObject3(preset)) {
|
|
1362
1586
|
return { path, message: "must be an object" };
|
|
1363
1587
|
}
|
|
1364
1588
|
if (!("base" in preset)) {
|
|
@@ -1368,11 +1592,11 @@ function validateStylePreset(preset, path) {
|
|
|
1368
1592
|
return { path: path + "/base", message: "base must be a string" };
|
|
1369
1593
|
}
|
|
1370
1594
|
if ("variants" in preset && preset["variants"] !== void 0) {
|
|
1371
|
-
if (!
|
|
1595
|
+
if (!isObject3(preset["variants"])) {
|
|
1372
1596
|
return { path: path + "/variants", message: "variants must be an object" };
|
|
1373
1597
|
}
|
|
1374
1598
|
for (const [variantKey, variantOptions] of Object.entries(preset["variants"])) {
|
|
1375
|
-
if (!
|
|
1599
|
+
if (!isObject3(variantOptions)) {
|
|
1376
1600
|
return { path: path + "/variants/" + variantKey, message: "variant options must be an object" };
|
|
1377
1601
|
}
|
|
1378
1602
|
for (const [optionKey, optionValue] of Object.entries(variantOptions)) {
|
|
@@ -1383,10 +1607,10 @@ function validateStylePreset(preset, path) {
|
|
|
1383
1607
|
}
|
|
1384
1608
|
}
|
|
1385
1609
|
if ("defaultVariants" in preset && preset["defaultVariants"] !== void 0) {
|
|
1386
|
-
if (!
|
|
1610
|
+
if (!isObject3(preset["defaultVariants"])) {
|
|
1387
1611
|
return { path: path + "/defaultVariants", message: "defaultVariants must be an object" };
|
|
1388
1612
|
}
|
|
1389
|
-
const variantKeys =
|
|
1613
|
+
const variantKeys = isObject3(preset["variants"]) ? Object.keys(preset["variants"]) : [];
|
|
1390
1614
|
for (const [key, value] of Object.entries(preset["defaultVariants"])) {
|
|
1391
1615
|
if (typeof value !== "string") {
|
|
1392
1616
|
return { path: path + "/defaultVariants/" + key, message: "default variant value must be a string" };
|
|
@@ -1402,7 +1626,7 @@ function validateStylePreset(preset, path) {
|
|
|
1402
1626
|
}
|
|
1403
1627
|
for (let i = 0; i < preset["compoundVariants"].length; i++) {
|
|
1404
1628
|
const compound = preset["compoundVariants"][i];
|
|
1405
|
-
if (!
|
|
1629
|
+
if (!isObject3(compound)) {
|
|
1406
1630
|
return { path: path + "/compoundVariants/" + i, message: "compound variant must be an object" };
|
|
1407
1631
|
}
|
|
1408
1632
|
if (typeof compound["class"] !== "string") {
|
|
@@ -1413,13 +1637,13 @@ function validateStylePreset(preset, path) {
|
|
|
1413
1637
|
return null;
|
|
1414
1638
|
}
|
|
1415
1639
|
function customValidateAst(input) {
|
|
1416
|
-
if (
|
|
1640
|
+
if (isObject3(input["state"])) {
|
|
1417
1641
|
for (const [name, field] of Object.entries(input["state"])) {
|
|
1418
1642
|
const error = validateStateField(field, "/state/" + name);
|
|
1419
1643
|
if (error) return error;
|
|
1420
1644
|
}
|
|
1421
1645
|
}
|
|
1422
|
-
if ("styles" in input &&
|
|
1646
|
+
if ("styles" in input && isObject3(input["styles"])) {
|
|
1423
1647
|
for (const [name, preset] of Object.entries(input["styles"])) {
|
|
1424
1648
|
const error = validateStylePreset(preset, "/styles/" + name);
|
|
1425
1649
|
if (error) return error;
|
|
@@ -1428,7 +1652,7 @@ function customValidateAst(input) {
|
|
|
1428
1652
|
if (Array.isArray(input["actions"])) {
|
|
1429
1653
|
for (let i = 0; i < input["actions"].length; i++) {
|
|
1430
1654
|
const action = input["actions"][i];
|
|
1431
|
-
if (
|
|
1655
|
+
if (isObject3(action) && Array.isArray(action["steps"])) {
|
|
1432
1656
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1433
1657
|
const error = validateActionStep(action["steps"][j], "/actions/" + i + "/steps/" + j);
|
|
1434
1658
|
if (error) return error;
|
|
@@ -1440,7 +1664,7 @@ function customValidateAst(input) {
|
|
|
1440
1664
|
const error = validateViewNode(input["view"], "/view");
|
|
1441
1665
|
if (error) return error;
|
|
1442
1666
|
}
|
|
1443
|
-
if ("components" in input &&
|
|
1667
|
+
if ("components" in input && isObject3(input["components"])) {
|
|
1444
1668
|
for (const [name, def] of Object.entries(input["components"])) {
|
|
1445
1669
|
const error = validateComponentDef(def, "/components/" + name);
|
|
1446
1670
|
if (error) return error;
|
|
@@ -1460,14 +1684,14 @@ function createErrorOptionsWithSuggestion(name, availableNames) {
|
|
|
1460
1684
|
function collectSemanticContext(ast) {
|
|
1461
1685
|
const stateNames = /* @__PURE__ */ new Set();
|
|
1462
1686
|
const actionNames = /* @__PURE__ */ new Set();
|
|
1463
|
-
if (
|
|
1687
|
+
if (isObject3(ast["state"])) {
|
|
1464
1688
|
for (const name of Object.keys(ast["state"])) {
|
|
1465
1689
|
stateNames.add(name);
|
|
1466
1690
|
}
|
|
1467
1691
|
}
|
|
1468
1692
|
if (Array.isArray(ast["actions"])) {
|
|
1469
1693
|
for (const action of ast["actions"]) {
|
|
1470
|
-
if (
|
|
1694
|
+
if (isObject3(action) && typeof action["name"] === "string") {
|
|
1471
1695
|
actionNames.add(action["name"]);
|
|
1472
1696
|
}
|
|
1473
1697
|
}
|
|
@@ -1475,7 +1699,26 @@ function collectSemanticContext(ast) {
|
|
|
1475
1699
|
return { stateNames, actionNames };
|
|
1476
1700
|
}
|
|
1477
1701
|
function validateStateReferences(node, path, stateNames) {
|
|
1478
|
-
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
|
+
}
|
|
1479
1722
|
if (node["expr"] === "state" && typeof node["name"] === "string") {
|
|
1480
1723
|
if (!stateNames.has(node["name"])) {
|
|
1481
1724
|
const errorOptions = createErrorOptionsWithSuggestion(node["name"], stateNames);
|
|
@@ -1483,7 +1726,7 @@ function validateStateReferences(node, path, stateNames) {
|
|
|
1483
1726
|
}
|
|
1484
1727
|
}
|
|
1485
1728
|
for (const [key, value] of Object.entries(node)) {
|
|
1486
|
-
if (
|
|
1729
|
+
if (isObject3(value)) {
|
|
1487
1730
|
const error = validateStateReferences(value, path + "/" + key, stateNames);
|
|
1488
1731
|
if (error) return error;
|
|
1489
1732
|
} else if (Array.isArray(value)) {
|
|
@@ -1499,10 +1742,10 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1499
1742
|
if (!Array.isArray(ast["actions"])) return null;
|
|
1500
1743
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1501
1744
|
const action = ast["actions"][i];
|
|
1502
|
-
if (!
|
|
1745
|
+
if (!isObject3(action) || !Array.isArray(action["steps"])) continue;
|
|
1503
1746
|
for (let j = 0; j < action["steps"].length; j++) {
|
|
1504
1747
|
const step = action["steps"][j];
|
|
1505
|
-
if (!
|
|
1748
|
+
if (!isObject3(step)) continue;
|
|
1506
1749
|
if ((step["do"] === "set" || step["do"] === "update") && typeof step["target"] === "string") {
|
|
1507
1750
|
if (!stateNames.has(step["target"])) {
|
|
1508
1751
|
const errorOptions = createErrorOptionsWithSuggestion(step["target"], stateNames);
|
|
@@ -1514,10 +1757,25 @@ function validateActionTargets(ast, stateNames) {
|
|
|
1514
1757
|
return null;
|
|
1515
1758
|
}
|
|
1516
1759
|
function validateActionReferences(node, path, actionNames) {
|
|
1517
|
-
if (!
|
|
1518
|
-
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"])) {
|
|
1519
1777
|
for (const [propName, propValue] of Object.entries(node["props"])) {
|
|
1520
|
-
if (
|
|
1778
|
+
if (isObject3(propValue) && "event" in propValue && "action" in propValue) {
|
|
1521
1779
|
const actionName = propValue["action"];
|
|
1522
1780
|
if (typeof actionName === "string" && !actionNames.has(actionName)) {
|
|
1523
1781
|
const errorOptions = createErrorOptionsWithSuggestion(actionName, actionNames);
|
|
@@ -1536,15 +1794,15 @@ function validateActionReferences(node, path, actionNames) {
|
|
|
1536
1794
|
if (error) return error;
|
|
1537
1795
|
}
|
|
1538
1796
|
}
|
|
1539
|
-
if (
|
|
1797
|
+
if (isObject3(node["then"])) {
|
|
1540
1798
|
const error = validateActionReferences(node["then"], path + "/then", actionNames);
|
|
1541
1799
|
if (error) return error;
|
|
1542
1800
|
}
|
|
1543
|
-
if (
|
|
1801
|
+
if (isObject3(node["else"])) {
|
|
1544
1802
|
const error = validateActionReferences(node["else"], path + "/else", actionNames);
|
|
1545
1803
|
if (error) return error;
|
|
1546
1804
|
}
|
|
1547
|
-
if (
|
|
1805
|
+
if (isObject3(node["body"])) {
|
|
1548
1806
|
const error = validateActionReferences(node["body"], path + "/body", actionNames);
|
|
1549
1807
|
if (error) return error;
|
|
1550
1808
|
}
|
|
@@ -1555,7 +1813,7 @@ function validateDuplicateActions(ast) {
|
|
|
1555
1813
|
const seenNames = /* @__PURE__ */ new Set();
|
|
1556
1814
|
for (let i = 0; i < ast["actions"].length; i++) {
|
|
1557
1815
|
const action = ast["actions"][i];
|
|
1558
|
-
if (!
|
|
1816
|
+
if (!isObject3(action) || typeof action["name"] !== "string") continue;
|
|
1559
1817
|
const name = action["name"];
|
|
1560
1818
|
if (seenNames.has(name)) {
|
|
1561
1819
|
return createDuplicateActionError(name, "/actions/" + i);
|
|
@@ -1568,20 +1826,20 @@ function performSemanticValidation(ast) {
|
|
|
1568
1826
|
const { stateNames, actionNames } = collectSemanticContext(ast);
|
|
1569
1827
|
const duplicateError = validateDuplicateActions(ast);
|
|
1570
1828
|
if (duplicateError) return duplicateError;
|
|
1571
|
-
if (
|
|
1829
|
+
if (isObject3(ast["view"])) {
|
|
1572
1830
|
const stateRefError = validateStateReferences(ast["view"], "/view", stateNames);
|
|
1573
1831
|
if (stateRefError) return stateRefError;
|
|
1574
1832
|
}
|
|
1575
1833
|
const actionTargetError = validateActionTargets(ast, stateNames);
|
|
1576
1834
|
if (actionTargetError) return actionTargetError;
|
|
1577
|
-
if (
|
|
1835
|
+
if (isObject3(ast["view"])) {
|
|
1578
1836
|
const actionRefError = validateActionReferences(ast["view"], "/view", actionNames);
|
|
1579
1837
|
if (actionRefError) return actionRefError;
|
|
1580
1838
|
}
|
|
1581
1839
|
return null;
|
|
1582
1840
|
}
|
|
1583
1841
|
function validateAst(input) {
|
|
1584
|
-
if (!
|
|
1842
|
+
if (!isObject3(input)) {
|
|
1585
1843
|
return {
|
|
1586
1844
|
ok: false,
|
|
1587
1845
|
error: createSchemaError("Input must be an object", "/")
|
|
@@ -2246,14 +2504,80 @@ var astSchema = {
|
|
|
2246
2504
|
}
|
|
2247
2505
|
}
|
|
2248
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
|
+
}
|
|
2249
2569
|
export {
|
|
2570
|
+
AI_OUTPUT_TYPES,
|
|
2571
|
+
AI_PROVIDER_TYPES,
|
|
2250
2572
|
BINARY_OPERATORS,
|
|
2251
2573
|
CLIPBOARD_OPERATIONS,
|
|
2574
|
+
COLOR_SCHEMES,
|
|
2252
2575
|
ConstelaError,
|
|
2253
2576
|
DATA_SOURCE_TYPES,
|
|
2254
2577
|
DATA_TRANSFORMS,
|
|
2255
2578
|
FOCUS_OPERATIONS,
|
|
2256
2579
|
HTTP_METHODS,
|
|
2580
|
+
ISLAND_STRATEGIES,
|
|
2257
2581
|
NAVIGATE_TARGETS,
|
|
2258
2582
|
PARAM_TYPES,
|
|
2259
2583
|
STORAGE_OPERATIONS,
|
|
@@ -2270,6 +2594,7 @@ export {
|
|
|
2270
2594
|
createDataNotDefinedError,
|
|
2271
2595
|
createDuplicateActionError,
|
|
2272
2596
|
createDuplicateDefaultSlotError,
|
|
2597
|
+
createDuplicateIslandIdError,
|
|
2273
2598
|
createDuplicateSlotNameError,
|
|
2274
2599
|
createImportsNotDefinedError,
|
|
2275
2600
|
createInvalidClipboardOperationError,
|
|
@@ -2303,12 +2628,14 @@ export {
|
|
|
2303
2628
|
createUnsupportedVersionError,
|
|
2304
2629
|
findSimilarNames,
|
|
2305
2630
|
isActionStep,
|
|
2631
|
+
isAiDataSource,
|
|
2306
2632
|
isArrayExpr,
|
|
2307
2633
|
isBinExpr,
|
|
2308
2634
|
isBooleanField,
|
|
2309
2635
|
isCallStep,
|
|
2310
2636
|
isClipboardStep,
|
|
2311
2637
|
isCodeNode,
|
|
2638
|
+
isColorScheme,
|
|
2312
2639
|
isComponentNode,
|
|
2313
2640
|
isConcatExpr,
|
|
2314
2641
|
isCondExpr,
|
|
@@ -2319,14 +2646,19 @@ export {
|
|
|
2319
2646
|
isDisposeStep,
|
|
2320
2647
|
isEachNode,
|
|
2321
2648
|
isElementNode,
|
|
2649
|
+
isErrorBoundaryNode,
|
|
2322
2650
|
isEventHandler,
|
|
2323
2651
|
isExpression,
|
|
2324
2652
|
isFetchStep,
|
|
2325
2653
|
isFocusStep,
|
|
2654
|
+
isGenerateStep,
|
|
2326
2655
|
isGetExpr,
|
|
2327
2656
|
isIfNode,
|
|
2328
2657
|
isImportExpr,
|
|
2329
2658
|
isImportStep,
|
|
2659
|
+
isIslandNode,
|
|
2660
|
+
isIslandStrategy,
|
|
2661
|
+
isIslandStrategyOptions,
|
|
2330
2662
|
isLayoutProgram,
|
|
2331
2663
|
isLifecycleHooks,
|
|
2332
2664
|
isListField,
|
|
@@ -2351,10 +2683,17 @@ export {
|
|
|
2351
2683
|
isStateField,
|
|
2352
2684
|
isStaticPathsDefinition,
|
|
2353
2685
|
isStorageStep,
|
|
2686
|
+
isStreamChunk,
|
|
2687
|
+
isStreamingRenderOptions,
|
|
2354
2688
|
isStringField,
|
|
2355
2689
|
isStyleExpr,
|
|
2356
2690
|
isSubscribeStep,
|
|
2691
|
+
isSuspenseBoundary,
|
|
2692
|
+
isSuspenseNode,
|
|
2357
2693
|
isTextNode,
|
|
2694
|
+
isThemeColors,
|
|
2695
|
+
isThemeConfig,
|
|
2696
|
+
isThemeFonts,
|
|
2358
2697
|
isUpdateStep,
|
|
2359
2698
|
isValidityExpr,
|
|
2360
2699
|
isVarExpr,
|