@kubuild/schema 0.1.0 → 0.3.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/README.md +117 -0
- package/dist/actions.d.ts +425 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/document.d.ts +200 -8
- package/dist/document.d.ts.map +1 -1
- package/dist/form.d.ts +129 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/index.cjs +918 -94
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +858 -90
- package/dist/index.js.map +1 -1
- package/dist/json-schema.d.ts +690 -0
- package/dist/json-schema.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,56 +1,369 @@
|
|
|
1
1
|
// src/document.ts
|
|
2
|
+
import { z as z3 } from "zod";
|
|
3
|
+
|
|
4
|
+
// src/actions.ts
|
|
2
5
|
import { z } from "zod";
|
|
6
|
+
var ActionTriggerTypeSchema = z.enum([
|
|
7
|
+
"click",
|
|
8
|
+
"submit",
|
|
9
|
+
"change",
|
|
10
|
+
"blur",
|
|
11
|
+
"focus",
|
|
12
|
+
"load"
|
|
13
|
+
]);
|
|
14
|
+
var ActionTriggerSchema = ActionTriggerTypeSchema;
|
|
15
|
+
var ActionStepTypeSchema = z.enum([
|
|
16
|
+
"api_request",
|
|
17
|
+
"navigate",
|
|
18
|
+
"set_state",
|
|
19
|
+
"reset_form",
|
|
20
|
+
"show_toast",
|
|
21
|
+
"open_modal",
|
|
22
|
+
"close_modal",
|
|
23
|
+
"copy_clipboard",
|
|
24
|
+
"custom_event"
|
|
25
|
+
]);
|
|
26
|
+
var ConditionOperatorSchema = z.enum([
|
|
27
|
+
"equals",
|
|
28
|
+
"not_equals",
|
|
29
|
+
"contains",
|
|
30
|
+
"not_contains",
|
|
31
|
+
"is_truthy",
|
|
32
|
+
"is_falsy",
|
|
33
|
+
"gt",
|
|
34
|
+
"gte",
|
|
35
|
+
"lt",
|
|
36
|
+
"lte",
|
|
37
|
+
"regex"
|
|
38
|
+
]);
|
|
39
|
+
var ActionStepConditionSchema = z.object({
|
|
40
|
+
field: z.string().min(1, "Condition field cannot be empty"),
|
|
41
|
+
operator: ConditionOperatorSchema,
|
|
42
|
+
value: z.unknown().optional()
|
|
43
|
+
});
|
|
44
|
+
var DANGEROUS_URL_PATTERN = /(javascript:|vbscript:|data:text\/html)/i;
|
|
45
|
+
var DANGEROUS_SCRIPT_PATTERN = /<\s*script/i;
|
|
46
|
+
function isSafeActionUrl(url) {
|
|
47
|
+
if (!url || typeof url !== "string") return false;
|
|
48
|
+
const trimmed = url.trim();
|
|
49
|
+
if (DANGEROUS_URL_PATTERN.test(trimmed)) return false;
|
|
50
|
+
if (DANGEROUS_SCRIPT_PATTERN.test(trimmed)) return false;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
var SafeUrlStringSchema = z.string().min(1, "URL cannot be empty").refine(isSafeActionUrl, {
|
|
54
|
+
message: "URL contains disallowed or unsafe protocol/script pattern"
|
|
55
|
+
});
|
|
56
|
+
var SafeEventNameSchema = z.string().min(1, "Event name cannot be empty").regex(/^[a-zA-Z0-9_\-:]+$/, {
|
|
57
|
+
message: "Event name must contain only alphanumeric characters, dashes, colons, or underscores"
|
|
58
|
+
});
|
|
59
|
+
var ApiRequestStepPayloadSchema = z.object({
|
|
60
|
+
url: SafeUrlStringSchema,
|
|
61
|
+
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).default("GET"),
|
|
62
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
63
|
+
queryParams: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
|
|
64
|
+
body: z.union([z.string(), z.record(z.string(), z.unknown()), z.array(z.unknown())]).optional(),
|
|
65
|
+
bodyFormat: z.enum(["json", "form-data", "formData", "urlencoded", "url-encoded", "raw", "text"]).optional(),
|
|
66
|
+
bodyType: z.enum(["json", "form-data", "formData", "urlencoded", "url-encoded", "raw", "text"]).optional(),
|
|
67
|
+
timeout: z.number().positive("Timeout must be greater than 0 ms").optional(),
|
|
68
|
+
responseMapping: z.record(z.string(), z.string()).optional()
|
|
69
|
+
});
|
|
70
|
+
var NavigateStepPayloadSchema = z.object({
|
|
71
|
+
url: SafeUrlStringSchema,
|
|
72
|
+
target: z.enum(["_self", "_blank", "_parent", "_top"]).optional().default("_self"),
|
|
73
|
+
replace: z.boolean().optional(),
|
|
74
|
+
scroll: z.boolean().optional(),
|
|
75
|
+
behavior: z.enum(["smooth", "auto"]).optional()
|
|
76
|
+
});
|
|
77
|
+
var SetStateStepPayloadSchema = z.object({
|
|
78
|
+
key: z.string().min(1, "State key cannot be empty"),
|
|
79
|
+
value: z.unknown(),
|
|
80
|
+
scope: z.enum(["runtime", "document", "session", "local"]).optional().default("runtime")
|
|
81
|
+
});
|
|
82
|
+
var ResetFormStepPayloadSchema = z.object({
|
|
83
|
+
formId: z.string().optional()
|
|
84
|
+
});
|
|
85
|
+
var ShowToastStepPayloadSchema = z.object({
|
|
86
|
+
message: z.string().min(1, "Toast message cannot be empty"),
|
|
87
|
+
type: z.enum(["success", "error", "warning", "info"]).optional().default("info"),
|
|
88
|
+
variant: z.enum(["success", "error", "warning", "info"]).optional(),
|
|
89
|
+
title: z.string().optional(),
|
|
90
|
+
duration: z.number().nonnegative("Duration must be >= 0 ms").optional(),
|
|
91
|
+
position: z.enum(["top-right", "top-left", "bottom-right", "bottom-left", "top-center", "bottom-center"]).optional()
|
|
92
|
+
});
|
|
93
|
+
var OpenModalStepPayloadSchema = z.object({
|
|
94
|
+
modalId: z.string().optional(),
|
|
95
|
+
modalNodeId: z.string().optional(),
|
|
96
|
+
toggle: z.boolean().optional()
|
|
97
|
+
}).refine((data) => Boolean(data.modalId || data.modalNodeId), {
|
|
98
|
+
message: "Modal ID or Modal Node ID cannot be empty"
|
|
99
|
+
});
|
|
100
|
+
var CloseModalStepPayloadSchema = z.object({
|
|
101
|
+
modalId: z.string().optional(),
|
|
102
|
+
modalNodeId: z.string().optional()
|
|
103
|
+
});
|
|
104
|
+
var CopyClipboardStepPayloadSchema = z.object({
|
|
105
|
+
text: z.string().optional(),
|
|
106
|
+
value: z.unknown().optional(),
|
|
107
|
+
notify: z.boolean().optional(),
|
|
108
|
+
toastMessage: z.string().optional()
|
|
109
|
+
});
|
|
110
|
+
var CustomEventStepPayloadSchema = z.object({
|
|
111
|
+
eventName: SafeEventNameSchema,
|
|
112
|
+
detail: z.record(z.string(), z.unknown()).optional(),
|
|
113
|
+
bubbles: z.boolean().optional().default(true),
|
|
114
|
+
cancelable: z.boolean().optional().default(true)
|
|
115
|
+
});
|
|
116
|
+
var StepPayloadSchemas = {
|
|
117
|
+
api_request: ApiRequestStepPayloadSchema,
|
|
118
|
+
navigate: NavigateStepPayloadSchema,
|
|
119
|
+
set_state: SetStateStepPayloadSchema,
|
|
120
|
+
reset_form: ResetFormStepPayloadSchema,
|
|
121
|
+
show_toast: ShowToastStepPayloadSchema,
|
|
122
|
+
open_modal: OpenModalStepPayloadSchema,
|
|
123
|
+
close_modal: CloseModalStepPayloadSchema,
|
|
124
|
+
copy_clipboard: CopyClipboardStepPayloadSchema,
|
|
125
|
+
custom_event: CustomEventStepPayloadSchema
|
|
126
|
+
};
|
|
127
|
+
var ActionStepSchema = z.lazy(
|
|
128
|
+
() => z.object({
|
|
129
|
+
id: z.string().min(1, "Step ID cannot be empty"),
|
|
130
|
+
type: ActionStepTypeSchema,
|
|
131
|
+
label: z.string().optional(),
|
|
132
|
+
payload: z.record(z.string(), z.unknown()).optional().default({}),
|
|
133
|
+
condition: ActionStepConditionSchema.optional(),
|
|
134
|
+
timeout: z.number().positive().optional(),
|
|
135
|
+
continueOnError: z.boolean().optional(),
|
|
136
|
+
onSuccess: z.array(ActionStepSchema).optional(),
|
|
137
|
+
onError: z.array(ActionStepSchema).optional()
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
var ActionPipelineSchema = z.object({
|
|
141
|
+
id: z.string().min(1, "Pipeline ID cannot be empty"),
|
|
142
|
+
trigger: ActionTriggerTypeSchema,
|
|
143
|
+
label: z.string().optional(),
|
|
144
|
+
debounceMs: z.number().nonnegative("Debounce ms must be >= 0").optional(),
|
|
145
|
+
preventDuplicate: z.boolean().optional(),
|
|
146
|
+
enabled: z.boolean().optional().default(true),
|
|
147
|
+
steps: z.array(ActionStepSchema).min(1, "Action pipeline must contain at least one step")
|
|
148
|
+
});
|
|
149
|
+
function isActionTriggerType(value) {
|
|
150
|
+
return ActionTriggerTypeSchema.safeParse(value).success;
|
|
151
|
+
}
|
|
152
|
+
function isActionStepType(value) {
|
|
153
|
+
return ActionStepTypeSchema.safeParse(value).success;
|
|
154
|
+
}
|
|
155
|
+
function isConditionOperator(value) {
|
|
156
|
+
return ConditionOperatorSchema.safeParse(value).success;
|
|
157
|
+
}
|
|
158
|
+
function isActionStepCondition(value) {
|
|
159
|
+
return ActionStepConditionSchema.safeParse(value).success;
|
|
160
|
+
}
|
|
161
|
+
function isActionStep(value) {
|
|
162
|
+
return ActionStepSchema.safeParse(value).success;
|
|
163
|
+
}
|
|
164
|
+
function isActionPipeline(value) {
|
|
165
|
+
return ActionPipelineSchema.safeParse(value).success;
|
|
166
|
+
}
|
|
167
|
+
function validateActionStepPayload(type, payload) {
|
|
168
|
+
const schema = StepPayloadSchemas[type];
|
|
169
|
+
if (!schema) {
|
|
170
|
+
return {
|
|
171
|
+
success: false,
|
|
172
|
+
error: new z.ZodError([
|
|
173
|
+
{
|
|
174
|
+
code: z.ZodIssueCode.custom,
|
|
175
|
+
message: `Unknown step type: ${type}`,
|
|
176
|
+
path: ["type"]
|
|
177
|
+
}
|
|
178
|
+
])
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
const result = schema.safeParse(payload);
|
|
182
|
+
if (result.success) {
|
|
183
|
+
return { success: true, data: result.data };
|
|
184
|
+
}
|
|
185
|
+
return { success: false, error: result.error };
|
|
186
|
+
}
|
|
187
|
+
function sanitizeActionUrl(url, fallback = "") {
|
|
188
|
+
if (typeof url !== "string") return fallback;
|
|
189
|
+
const trimmed = url.trim();
|
|
190
|
+
if (!isSafeActionUrl(trimmed)) {
|
|
191
|
+
return fallback;
|
|
192
|
+
}
|
|
193
|
+
return trimmed;
|
|
194
|
+
}
|
|
195
|
+
function sanitizeActionString(value, fallback = "") {
|
|
196
|
+
if (typeof value !== "string") return fallback;
|
|
197
|
+
if (DANGEROUS_SCRIPT_PATTERN.test(value)) {
|
|
198
|
+
return value.replace(/<\s*script[^>]*>[\s\S]*?<\s*\/\s*script\s*>/gi, "").replace(/<\s*script[^>]*>/gi, "");
|
|
199
|
+
}
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
202
|
+
function sanitizeActionValue(value) {
|
|
203
|
+
if (value === null || value === void 0) return value;
|
|
204
|
+
if (typeof value === "string") {
|
|
205
|
+
const trimmed = value.trim();
|
|
206
|
+
if (DANGEROUS_URL_PATTERN.test(trimmed)) {
|
|
207
|
+
return "";
|
|
208
|
+
}
|
|
209
|
+
return sanitizeActionString(value);
|
|
210
|
+
}
|
|
211
|
+
if (Array.isArray(value)) {
|
|
212
|
+
return value.map((item) => sanitizeActionValue(item));
|
|
213
|
+
}
|
|
214
|
+
if (typeof value === "object") {
|
|
215
|
+
const result = {};
|
|
216
|
+
for (const [k, v] of Object.entries(value)) {
|
|
217
|
+
if (/^(url|href|src|endpoint|targetUrl)$/i.test(k) && typeof v === "string") {
|
|
218
|
+
result[k] = sanitizeActionUrl(v);
|
|
219
|
+
} else {
|
|
220
|
+
result[k] = sanitizeActionValue(v);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
function sanitizeActionPayload(payload) {
|
|
228
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
229
|
+
return {};
|
|
230
|
+
}
|
|
231
|
+
return sanitizeActionValue(payload);
|
|
232
|
+
}
|
|
233
|
+
function sanitizeActionStep(step) {
|
|
234
|
+
const sanitized = {
|
|
235
|
+
...step,
|
|
236
|
+
label: step.label ? sanitizeActionString(step.label) : step.label,
|
|
237
|
+
payload: sanitizeActionPayload(step.payload)
|
|
238
|
+
};
|
|
239
|
+
if (step.condition && step.condition.value !== void 0) {
|
|
240
|
+
sanitized.condition = {
|
|
241
|
+
...step.condition,
|
|
242
|
+
value: sanitizeActionValue(step.condition.value)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
if (step.onSuccess && Array.isArray(step.onSuccess)) {
|
|
246
|
+
sanitized.onSuccess = step.onSuccess.map((s) => sanitizeActionStep(s));
|
|
247
|
+
}
|
|
248
|
+
if (step.onError && Array.isArray(step.onError)) {
|
|
249
|
+
sanitized.onError = step.onError.map((s) => sanitizeActionStep(s));
|
|
250
|
+
}
|
|
251
|
+
return sanitized;
|
|
252
|
+
}
|
|
253
|
+
function sanitizeActionPipeline(pipeline) {
|
|
254
|
+
return {
|
|
255
|
+
...pipeline,
|
|
256
|
+
label: pipeline.label ? sanitizeActionString(pipeline.label) : pipeline.label,
|
|
257
|
+
steps: Array.isArray(pipeline.steps) ? pipeline.steps.map((s) => sanitizeActionStep(s)) : []
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/form.ts
|
|
262
|
+
import { z as z2 } from "zod";
|
|
263
|
+
var ValidationRuleTypeSchema = z2.enum([
|
|
264
|
+
"required",
|
|
265
|
+
"email",
|
|
266
|
+
"url",
|
|
267
|
+
"min_length",
|
|
268
|
+
"max_length",
|
|
269
|
+
"numeric_min",
|
|
270
|
+
"numeric_max",
|
|
271
|
+
"pattern",
|
|
272
|
+
"match_field",
|
|
273
|
+
"custom_regex"
|
|
274
|
+
]);
|
|
275
|
+
var ValidateOnEventSchema = z2.enum(["blur", "change", "submit"]);
|
|
276
|
+
var ValidationRuleSchema = z2.object({
|
|
277
|
+
type: ValidationRuleTypeSchema,
|
|
278
|
+
value: z2.unknown().optional(),
|
|
279
|
+
message: z2.string().min(1, "Validation error message cannot be empty")
|
|
280
|
+
});
|
|
281
|
+
var FormFieldBindingSchema = z2.object({
|
|
282
|
+
name: z2.string().min(1, "Field name cannot be empty"),
|
|
283
|
+
label: z2.string().optional(),
|
|
284
|
+
defaultValue: z2.unknown().optional(),
|
|
285
|
+
rules: z2.array(ValidationRuleSchema).optional().default([]),
|
|
286
|
+
validateOn: ValidateOnEventSchema.optional().default("blur"),
|
|
287
|
+
transform: z2.enum(["trim", "lowercase", "uppercase", "number"]).optional(),
|
|
288
|
+
disabled: z2.boolean().optional(),
|
|
289
|
+
required: z2.boolean().optional()
|
|
290
|
+
});
|
|
291
|
+
var FormConfigSchema = z2.object({
|
|
292
|
+
formId: z2.string().min(1, "Form ID cannot be empty"),
|
|
293
|
+
resetOnSubmit: z2.boolean().optional().default(false),
|
|
294
|
+
scrollToFirstError: z2.boolean().optional().default(true),
|
|
295
|
+
validateOn: ValidateOnEventSchema.optional().default("blur"),
|
|
296
|
+
initialValues: z2.record(z2.string(), z2.unknown()).optional(),
|
|
297
|
+
rules: z2.array(ValidationRuleSchema).optional()
|
|
298
|
+
});
|
|
299
|
+
function isValidationRuleType(value) {
|
|
300
|
+
return ValidationRuleTypeSchema.safeParse(value).success;
|
|
301
|
+
}
|
|
302
|
+
function isValidationRule(value) {
|
|
303
|
+
return ValidationRuleSchema.safeParse(value).success;
|
|
304
|
+
}
|
|
305
|
+
function isValidateOnEvent(value) {
|
|
306
|
+
return ValidateOnEventSchema.safeParse(value).success;
|
|
307
|
+
}
|
|
308
|
+
function isFormFieldBinding(value) {
|
|
309
|
+
return FormFieldBindingSchema.safeParse(value).success;
|
|
310
|
+
}
|
|
311
|
+
function isFormConfig(value) {
|
|
312
|
+
return FormConfigSchema.safeParse(value).success;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/document.ts
|
|
3
316
|
var SCHEMA_NAME = "stora.page";
|
|
4
317
|
var CURRENT_SCHEMA_VERSION = "1.0.0";
|
|
5
|
-
var AssetReferenceSchema =
|
|
6
|
-
type:
|
|
7
|
-
assetId:
|
|
8
|
-
filename:
|
|
9
|
-
mimeType:
|
|
10
|
-
fallbackUrl:
|
|
318
|
+
var AssetReferenceSchema = z3.object({
|
|
319
|
+
type: z3.literal("asset"),
|
|
320
|
+
assetId: z3.string().min(1, "Asset ID cannot be empty"),
|
|
321
|
+
filename: z3.string().optional(),
|
|
322
|
+
mimeType: z3.string().optional(),
|
|
323
|
+
fallbackUrl: z3.string().url().optional()
|
|
11
324
|
});
|
|
12
|
-
var VariableBindingSchema =
|
|
13
|
-
type:
|
|
14
|
-
key:
|
|
15
|
-
fallback:
|
|
325
|
+
var VariableBindingSchema = z3.object({
|
|
326
|
+
type: z3.literal("variable"),
|
|
327
|
+
key: z3.string().min(1, "Variable key cannot be empty"),
|
|
328
|
+
fallback: z3.unknown().optional()
|
|
16
329
|
});
|
|
17
|
-
var ActionBindingSchema =
|
|
18
|
-
type:
|
|
19
|
-
payload:
|
|
330
|
+
var ActionBindingSchema = z3.object({
|
|
331
|
+
type: z3.string().min(1, "Action type cannot be empty"),
|
|
332
|
+
payload: z3.record(z3.string(), z3.unknown()).optional()
|
|
20
333
|
});
|
|
21
334
|
var DANGEROUS_STYLE_VALUE_PATTERN = /javascript:|expression\(|@import|<script|vbscript:|data:text\/html/i;
|
|
22
|
-
var StyleValueSchema =
|
|
23
|
-
|
|
335
|
+
var StyleValueSchema = z3.union([
|
|
336
|
+
z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
24
337
|
message: "Style value contains a disallowed or unsafe pattern"
|
|
25
338
|
}),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
339
|
+
z3.number(),
|
|
340
|
+
z3.boolean(),
|
|
341
|
+
z3.null(),
|
|
342
|
+
z3.undefined()
|
|
30
343
|
]);
|
|
31
|
-
var StyleDefinitionSchema =
|
|
32
|
-
var PseudoStateStylesSchema =
|
|
33
|
-
var ResponsiveStylesSchema =
|
|
344
|
+
var StyleDefinitionSchema = z3.record(z3.string(), StyleValueSchema);
|
|
345
|
+
var PseudoStateStylesSchema = z3.record(z3.string(), StyleDefinitionSchema);
|
|
346
|
+
var ResponsiveStylesSchema = z3.object({
|
|
34
347
|
base: StyleDefinitionSchema.optional(),
|
|
35
348
|
desktop: StyleDefinitionSchema.optional(),
|
|
36
349
|
tablet: StyleDefinitionSchema.optional(),
|
|
37
350
|
mobile: StyleDefinitionSchema.optional(),
|
|
38
351
|
states: PseudoStateStylesSchema.optional()
|
|
39
352
|
}).passthrough().default({});
|
|
40
|
-
var AnimationConfigSchema =
|
|
41
|
-
type:
|
|
353
|
+
var AnimationConfigSchema = z3.object({
|
|
354
|
+
type: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
42
355
|
message: "Animation type contains a disallowed or unsafe pattern"
|
|
43
356
|
}).optional().default("none"),
|
|
44
|
-
duration:
|
|
45
|
-
delay:
|
|
46
|
-
easing:
|
|
357
|
+
duration: z3.number().min(0, "Duration must be non-negative").optional().default(600),
|
|
358
|
+
delay: z3.number().min(0, "Delay must be non-negative").optional().default(0),
|
|
359
|
+
easing: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
47
360
|
message: "Animation easing contains a disallowed or unsafe pattern"
|
|
48
361
|
}).optional().default("ease-out"),
|
|
49
|
-
once:
|
|
50
|
-
hoverEffect:
|
|
362
|
+
once: z3.boolean().optional().default(true),
|
|
363
|
+
hoverEffect: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
51
364
|
message: "Hover effect contains a disallowed or unsafe pattern"
|
|
52
365
|
}).optional().default("none"),
|
|
53
|
-
loopEffect:
|
|
366
|
+
loopEffect: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
54
367
|
message: "Loop effect contains a disallowed or unsafe pattern"
|
|
55
368
|
}).optional().default("none")
|
|
56
369
|
});
|
|
@@ -63,14 +376,16 @@ var DEFAULT_ANIMATION_CONFIG = {
|
|
|
63
376
|
hoverEffect: "none",
|
|
64
377
|
loopEffect: "none"
|
|
65
378
|
};
|
|
66
|
-
var NodeSchema =
|
|
67
|
-
() =>
|
|
68
|
-
id:
|
|
69
|
-
type:
|
|
70
|
-
props:
|
|
379
|
+
var NodeSchema = z3.lazy(
|
|
380
|
+
() => z3.object({
|
|
381
|
+
id: z3.string().min(1, "Node ID must be a non-empty string"),
|
|
382
|
+
type: z3.string().min(1, "Node type must be a non-empty string"),
|
|
383
|
+
props: z3.record(z3.string(), z3.unknown()).optional().default({}),
|
|
71
384
|
styles: ResponsiveStylesSchema.optional().default({}),
|
|
72
385
|
animation: AnimationConfigSchema.optional(),
|
|
73
|
-
|
|
386
|
+
actions: z3.array(ActionPipelineSchema).optional(),
|
|
387
|
+
formConfig: FormConfigSchema.optional(),
|
|
388
|
+
children: z3.array(NodeSchema).optional().default([])
|
|
74
389
|
})
|
|
75
390
|
);
|
|
76
391
|
var RootPageNodeSchema = NodeSchema.refine(
|
|
@@ -80,23 +395,62 @@ var RootPageNodeSchema = NodeSchema.refine(
|
|
|
80
395
|
path: ["type"]
|
|
81
396
|
}
|
|
82
397
|
);
|
|
83
|
-
var DocumentMetadataSchema =
|
|
84
|
-
title:
|
|
85
|
-
description:
|
|
86
|
-
author:
|
|
87
|
-
createdAt:
|
|
88
|
-
updatedAt:
|
|
89
|
-
tags:
|
|
90
|
-
category:
|
|
91
|
-
version:
|
|
92
|
-
custom:
|
|
398
|
+
var DocumentMetadataSchema = z3.object({
|
|
399
|
+
title: z3.string().min(1, "Title is required").default("Untitled Page"),
|
|
400
|
+
description: z3.string().optional().default(""),
|
|
401
|
+
author: z3.string().optional().default(""),
|
|
402
|
+
createdAt: z3.string().optional(),
|
|
403
|
+
updatedAt: z3.string().optional(),
|
|
404
|
+
tags: z3.array(z3.string()).optional().default([]),
|
|
405
|
+
category: z3.string().optional().default("general"),
|
|
406
|
+
version: z3.string().optional().default("1.0.0"),
|
|
407
|
+
custom: z3.record(z3.string(), z3.unknown()).optional()
|
|
93
408
|
});
|
|
94
|
-
var PageDocumentSchema =
|
|
95
|
-
schema:
|
|
96
|
-
version:
|
|
409
|
+
var PageDocumentSchema = z3.object({
|
|
410
|
+
schema: z3.literal(SCHEMA_NAME),
|
|
411
|
+
version: z3.string().min(1, "Schema version is required").default(CURRENT_SCHEMA_VERSION),
|
|
97
412
|
metadata: DocumentMetadataSchema.optional(),
|
|
98
413
|
document: RootPageNodeSchema
|
|
99
414
|
});
|
|
415
|
+
var PROJECT_SCHEMA_NAME = "stora.project";
|
|
416
|
+
var CURRENT_PROJECT_SCHEMA_VERSION = "1.0.0";
|
|
417
|
+
var ARTBOARD_REFERENCE_NODE_TYPE = "artboard-reference";
|
|
418
|
+
var ArtboardTypeSchema = z3.enum(["page", "component"]);
|
|
419
|
+
var ArtboardSchema = z3.object({
|
|
420
|
+
id: z3.string().min(1, "Artboard ID is required"),
|
|
421
|
+
name: z3.string().min(1, "Artboard name is required"),
|
|
422
|
+
artboardType: ArtboardTypeSchema,
|
|
423
|
+
/** Route for page artboards (e.g. "/about"). */
|
|
424
|
+
slug: z3.string().optional(),
|
|
425
|
+
/**
|
|
426
|
+
* For component artboards: the id that `open_modal` / `close_modal` actions target.
|
|
427
|
+
* Mirrors the detached node's own `props.modalId` so ModalManager keeps working unchanged.
|
|
428
|
+
*/
|
|
429
|
+
triggerId: z3.string().optional(),
|
|
430
|
+
/**
|
|
431
|
+
* Viewport/breakpoint this artboard is currently authored at. Declared inline
|
|
432
|
+
* (rather than imported) because viewport is otherwise an editor/renderer concept.
|
|
433
|
+
*/
|
|
434
|
+
viewport: z3.enum(["desktop", "tablet", "mobile"]).optional(),
|
|
435
|
+
/** Persisted artboard width in px, matching the canvas ViewportResizer's `width`. */
|
|
436
|
+
width: z3.number().positive().optional(),
|
|
437
|
+
/**
|
|
438
|
+
* Free position on the builder's infinite canvas, in unscaled canvas px. Absent means
|
|
439
|
+
* "not placed yet" — the canvas then falls back to laying the artboard out in a row.
|
|
440
|
+
*/
|
|
441
|
+
position: z3.object({
|
|
442
|
+
x: z3.number(),
|
|
443
|
+
y: z3.number()
|
|
444
|
+
}).optional(),
|
|
445
|
+
document: PageDocumentSchema
|
|
446
|
+
});
|
|
447
|
+
var ProjectDocumentSchema = z3.object({
|
|
448
|
+
schema: z3.literal(PROJECT_SCHEMA_NAME),
|
|
449
|
+
version: z3.string().min(1, "Schema version is required").default(CURRENT_PROJECT_SCHEMA_VERSION),
|
|
450
|
+
metadata: DocumentMetadataSchema.optional(),
|
|
451
|
+
artboards: z3.array(ArtboardSchema).min(1, "A project needs at least one artboard"),
|
|
452
|
+
activeArtboardId: z3.string().optional()
|
|
453
|
+
});
|
|
100
454
|
function isAssetReference(value) {
|
|
101
455
|
return AssetReferenceSchema.safeParse(value).success;
|
|
102
456
|
}
|
|
@@ -109,6 +463,17 @@ function isActionBinding(value) {
|
|
|
109
463
|
function isAnimationConfig(value) {
|
|
110
464
|
return AnimationConfigSchema.safeParse(value).success;
|
|
111
465
|
}
|
|
466
|
+
function isProjectDocument(value) {
|
|
467
|
+
return ProjectDocumentSchema.safeParse(value).success;
|
|
468
|
+
}
|
|
469
|
+
function looksLikeProjectDocument(value) {
|
|
470
|
+
if (typeof value !== "object" || value === null) return false;
|
|
471
|
+
const candidate = value;
|
|
472
|
+
return candidate.schema === PROJECT_SCHEMA_NAME || Array.isArray(candidate.artboards);
|
|
473
|
+
}
|
|
474
|
+
function isArtboardReferenceNode(node) {
|
|
475
|
+
return node.type === ARTBOARD_REFERENCE_NODE_TYPE;
|
|
476
|
+
}
|
|
112
477
|
function generateDeterministicNodeId(prefix, indexOrKey) {
|
|
113
478
|
const cleanPrefix = prefix.toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
114
479
|
return `${cleanPrefix}_${indexOrKey}`;
|
|
@@ -140,30 +505,30 @@ function validateNodeIdUniqueness(node) {
|
|
|
140
505
|
}
|
|
141
506
|
|
|
142
507
|
// src/manifest.ts
|
|
143
|
-
import { z as
|
|
144
|
-
var ManifestAssetItemSchema =
|
|
145
|
-
id:
|
|
146
|
-
path:
|
|
147
|
-
mimeType:
|
|
148
|
-
size:
|
|
149
|
-
checksum:
|
|
508
|
+
import { z as z4 } from "zod";
|
|
509
|
+
var ManifestAssetItemSchema = z4.object({
|
|
510
|
+
id: z4.string().min(1, "Asset ID cannot be empty"),
|
|
511
|
+
path: z4.string().min(1, "Asset archive path cannot be empty"),
|
|
512
|
+
mimeType: z4.string().min(1, "MIME type cannot be empty"),
|
|
513
|
+
size: z4.number().nonnegative("Asset size must be non-negative"),
|
|
514
|
+
checksum: z4.string().optional()
|
|
150
515
|
});
|
|
151
|
-
var ManifestSchema =
|
|
152
|
-
schema:
|
|
153
|
-
schemaVersion:
|
|
154
|
-
packageVersion:
|
|
155
|
-
builderCompatibility:
|
|
156
|
-
requiredComponents:
|
|
157
|
-
requiredCapabilities:
|
|
158
|
-
assets:
|
|
159
|
-
createdAt:
|
|
516
|
+
var ManifestSchema = z4.object({
|
|
517
|
+
schema: z4.literal(SCHEMA_NAME).default(SCHEMA_NAME),
|
|
518
|
+
schemaVersion: z4.string().min(1, "Schema version cannot be empty").default("1.0.0"),
|
|
519
|
+
packageVersion: z4.string().min(1, "Package version cannot be empty").default("1.0.0"),
|
|
520
|
+
builderCompatibility: z4.string().default(">=0.1.0"),
|
|
521
|
+
requiredComponents: z4.array(z4.string()).default([]),
|
|
522
|
+
requiredCapabilities: z4.array(z4.string()).default([]),
|
|
523
|
+
assets: z4.array(ManifestAssetItemSchema).default([]),
|
|
524
|
+
createdAt: z4.string().optional()
|
|
160
525
|
});
|
|
161
526
|
function isManifest(value) {
|
|
162
527
|
return ManifestSchema.safeParse(value).success;
|
|
163
528
|
}
|
|
164
529
|
|
|
165
530
|
// src/template.ts
|
|
166
|
-
import { z as
|
|
531
|
+
import { z as z5 } from "zod";
|
|
167
532
|
var DANGEROUS_URI_PATTERN = /^(javascript:|vbscript:|data:(?!image\/))|<script/i;
|
|
168
533
|
function isSafeThumbnailUrl(url) {
|
|
169
534
|
if (!url || typeof url !== "string") return false;
|
|
@@ -172,49 +537,49 @@ function isSafeThumbnailUrl(url) {
|
|
|
172
537
|
if (DANGEROUS_URI_PATTERN.test(trimmed)) return false;
|
|
173
538
|
return true;
|
|
174
539
|
}
|
|
175
|
-
var SafeThumbnailUrlSchema =
|
|
540
|
+
var SafeThumbnailUrlSchema = z5.string().min(1, "Thumbnail URL cannot be empty").refine(
|
|
176
541
|
(url) => isSafeThumbnailUrl(url),
|
|
177
542
|
{ message: "Thumbnail URL contains an unsafe protocol or payload" }
|
|
178
543
|
);
|
|
179
|
-
var SafeThumbnailObjectSchema =
|
|
544
|
+
var SafeThumbnailObjectSchema = z5.object({
|
|
180
545
|
url: SafeThumbnailUrlSchema,
|
|
181
|
-
alt:
|
|
182
|
-
width:
|
|
183
|
-
height:
|
|
546
|
+
alt: z5.string().optional(),
|
|
547
|
+
width: z5.number().positive().optional(),
|
|
548
|
+
height: z5.number().positive().optional()
|
|
184
549
|
});
|
|
185
|
-
var SafeThumbnailSchema =
|
|
550
|
+
var SafeThumbnailSchema = z5.union([
|
|
186
551
|
AssetReferenceSchema,
|
|
187
552
|
SafeThumbnailObjectSchema,
|
|
188
553
|
SafeThumbnailUrlSchema
|
|
189
554
|
]);
|
|
190
|
-
var TemplatePackageRefSchema =
|
|
191
|
-
path:
|
|
555
|
+
var TemplatePackageRefSchema = z5.object({
|
|
556
|
+
path: z5.string().optional(),
|
|
192
557
|
url: SafeThumbnailUrlSchema.optional(),
|
|
193
|
-
checksum:
|
|
194
|
-
format:
|
|
558
|
+
checksum: z5.string().optional(),
|
|
559
|
+
format: z5.enum(["stora", "json"]).default("stora")
|
|
195
560
|
});
|
|
196
|
-
var TemplateRequirementsSchema =
|
|
197
|
-
requiredComponents:
|
|
198
|
-
requiredCapabilities:
|
|
561
|
+
var TemplateRequirementsSchema = z5.object({
|
|
562
|
+
requiredComponents: z5.array(z5.string()).default([]),
|
|
563
|
+
requiredCapabilities: z5.array(z5.string()).default([])
|
|
199
564
|
});
|
|
200
|
-
var TemplateRecordSchema =
|
|
201
|
-
id:
|
|
202
|
-
name:
|
|
203
|
-
description:
|
|
204
|
-
category:
|
|
205
|
-
tags:
|
|
565
|
+
var TemplateRecordSchema = z5.object({
|
|
566
|
+
id: z5.string().min(1, "Template ID must be a non-empty string"),
|
|
567
|
+
name: z5.string().min(1, "Template name must be a non-empty string"),
|
|
568
|
+
description: z5.string().optional().default(""),
|
|
569
|
+
category: z5.string().optional().default("general"),
|
|
570
|
+
tags: z5.array(z5.string()).optional().default([]),
|
|
206
571
|
thumbnail: SafeThumbnailSchema.optional(),
|
|
207
|
-
author:
|
|
208
|
-
version:
|
|
572
|
+
author: z5.string().optional().default(""),
|
|
573
|
+
version: z5.string().optional().default("1.0.0"),
|
|
209
574
|
document: PageDocumentSchema.optional(),
|
|
210
575
|
packageReference: TemplatePackageRefSchema.optional(),
|
|
211
576
|
requirements: TemplateRequirementsSchema.default({
|
|
212
577
|
requiredComponents: [],
|
|
213
578
|
requiredCapabilities: []
|
|
214
579
|
}),
|
|
215
|
-
createdAt:
|
|
216
|
-
updatedAt:
|
|
217
|
-
custom:
|
|
580
|
+
createdAt: z5.string().optional(),
|
|
581
|
+
updatedAt: z5.string().optional(),
|
|
582
|
+
custom: z5.record(z5.string(), z5.unknown()).optional()
|
|
218
583
|
});
|
|
219
584
|
function isTemplateRecord(value) {
|
|
220
585
|
return TemplateRecordSchema.safeParse(value).success;
|
|
@@ -534,6 +899,111 @@ var PAGE_DOCUMENT_JSON_SCHEMA_V1 = {
|
|
|
534
899
|
},
|
|
535
900
|
additionalProperties: false
|
|
536
901
|
},
|
|
902
|
+
actionStep: {
|
|
903
|
+
type: "object",
|
|
904
|
+
required: ["id", "type"],
|
|
905
|
+
properties: {
|
|
906
|
+
id: {
|
|
907
|
+
type: "string",
|
|
908
|
+
minLength: 1
|
|
909
|
+
},
|
|
910
|
+
type: {
|
|
911
|
+
type: "string",
|
|
912
|
+
enum: [
|
|
913
|
+
"api_request",
|
|
914
|
+
"navigate",
|
|
915
|
+
"set_state",
|
|
916
|
+
"reset_form",
|
|
917
|
+
"show_toast",
|
|
918
|
+
"open_modal",
|
|
919
|
+
"close_modal",
|
|
920
|
+
"copy_clipboard",
|
|
921
|
+
"custom_event"
|
|
922
|
+
]
|
|
923
|
+
},
|
|
924
|
+
label: { type: "string" },
|
|
925
|
+
payload: { type: "object" },
|
|
926
|
+
condition: {
|
|
927
|
+
type: "object",
|
|
928
|
+
required: ["field", "operator"],
|
|
929
|
+
properties: {
|
|
930
|
+
field: { type: "string", minLength: 1 },
|
|
931
|
+
operator: {
|
|
932
|
+
type: "string",
|
|
933
|
+
enum: [
|
|
934
|
+
"equals",
|
|
935
|
+
"not_equals",
|
|
936
|
+
"contains",
|
|
937
|
+
"not_contains",
|
|
938
|
+
"is_truthy",
|
|
939
|
+
"is_falsy",
|
|
940
|
+
"gt",
|
|
941
|
+
"gte",
|
|
942
|
+
"lt",
|
|
943
|
+
"lte",
|
|
944
|
+
"regex"
|
|
945
|
+
]
|
|
946
|
+
},
|
|
947
|
+
value: {}
|
|
948
|
+
},
|
|
949
|
+
additionalProperties: false
|
|
950
|
+
},
|
|
951
|
+
timeout: { type: "number", minimum: 1 },
|
|
952
|
+
continueOnError: { type: "boolean" },
|
|
953
|
+
onSuccess: {
|
|
954
|
+
type: "array",
|
|
955
|
+
items: { $ref: "#/definitions/actionStep" }
|
|
956
|
+
},
|
|
957
|
+
onError: {
|
|
958
|
+
type: "array",
|
|
959
|
+
items: { $ref: "#/definitions/actionStep" }
|
|
960
|
+
}
|
|
961
|
+
},
|
|
962
|
+
additionalProperties: false
|
|
963
|
+
},
|
|
964
|
+
actionPipeline: {
|
|
965
|
+
type: "object",
|
|
966
|
+
required: ["id", "trigger", "steps"],
|
|
967
|
+
properties: {
|
|
968
|
+
id: {
|
|
969
|
+
type: "string",
|
|
970
|
+
minLength: 1
|
|
971
|
+
},
|
|
972
|
+
trigger: {
|
|
973
|
+
type: "string",
|
|
974
|
+
enum: ["click", "submit", "change", "blur", "focus", "load"]
|
|
975
|
+
},
|
|
976
|
+
label: { type: "string" },
|
|
977
|
+
debounceMs: { type: "number", minimum: 0 },
|
|
978
|
+
preventDuplicate: { type: "boolean" },
|
|
979
|
+
enabled: { type: "boolean", default: true },
|
|
980
|
+
steps: {
|
|
981
|
+
type: "array",
|
|
982
|
+
items: { $ref: "#/definitions/actionStep" },
|
|
983
|
+
minItems: 1
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
additionalProperties: false
|
|
987
|
+
},
|
|
988
|
+
formConfig: {
|
|
989
|
+
type: "object",
|
|
990
|
+
required: ["formId"],
|
|
991
|
+
properties: {
|
|
992
|
+
formId: {
|
|
993
|
+
type: "string",
|
|
994
|
+
minLength: 1
|
|
995
|
+
},
|
|
996
|
+
resetOnSubmit: { type: "boolean", default: false },
|
|
997
|
+
scrollToFirstError: { type: "boolean", default: true },
|
|
998
|
+
validateOn: {
|
|
999
|
+
type: "string",
|
|
1000
|
+
enum: ["blur", "change", "submit"],
|
|
1001
|
+
default: "blur"
|
|
1002
|
+
},
|
|
1003
|
+
initialValues: { type: "object" }
|
|
1004
|
+
},
|
|
1005
|
+
additionalProperties: false
|
|
1006
|
+
},
|
|
537
1007
|
node: {
|
|
538
1008
|
type: "object",
|
|
539
1009
|
required: ["id", "type"],
|
|
@@ -559,6 +1029,17 @@ var PAGE_DOCUMENT_JSON_SCHEMA_V1 = {
|
|
|
559
1029
|
animation: {
|
|
560
1030
|
$ref: "#/definitions/animationConfig"
|
|
561
1031
|
},
|
|
1032
|
+
actions: {
|
|
1033
|
+
type: "array",
|
|
1034
|
+
items: {
|
|
1035
|
+
$ref: "#/definitions/actionPipeline"
|
|
1036
|
+
},
|
|
1037
|
+
description: "Multi-step action pipelines bound to component events"
|
|
1038
|
+
},
|
|
1039
|
+
formConfig: {
|
|
1040
|
+
$ref: "#/definitions/formConfig",
|
|
1041
|
+
description: "Form container configuration and behavior"
|
|
1042
|
+
},
|
|
562
1043
|
children: {
|
|
563
1044
|
type: "array",
|
|
564
1045
|
items: {
|
|
@@ -895,47 +1376,334 @@ var TEMPLATE_RECORD_JSON_SCHEMA_V1 = {
|
|
|
895
1376
|
function getTemplateRecordJsonSchema() {
|
|
896
1377
|
return TEMPLATE_RECORD_JSON_SCHEMA_V1;
|
|
897
1378
|
}
|
|
1379
|
+
var ACTION_PIPELINE_JSON_SCHEMA_V1 = {
|
|
1380
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
1381
|
+
$id: "https://schema.stora.page/v1/action-pipeline.json",
|
|
1382
|
+
title: "StoraActionPipeline",
|
|
1383
|
+
description: "Action Pipeline schema definition for KUBUILD event workflows",
|
|
1384
|
+
type: "object",
|
|
1385
|
+
required: ["id", "trigger", "steps"],
|
|
1386
|
+
additionalProperties: false,
|
|
1387
|
+
properties: {
|
|
1388
|
+
id: {
|
|
1389
|
+
type: "string",
|
|
1390
|
+
minLength: 1,
|
|
1391
|
+
description: "Unique pipeline identifier"
|
|
1392
|
+
},
|
|
1393
|
+
trigger: {
|
|
1394
|
+
type: "string",
|
|
1395
|
+
enum: ["click", "submit", "change", "blur", "focus", "load"],
|
|
1396
|
+
description: "DOM or component event that triggers the action pipeline"
|
|
1397
|
+
},
|
|
1398
|
+
label: {
|
|
1399
|
+
type: "string",
|
|
1400
|
+
description: "Human readable label for the action pipeline"
|
|
1401
|
+
},
|
|
1402
|
+
debounceMs: {
|
|
1403
|
+
type: "number",
|
|
1404
|
+
minimum: 0,
|
|
1405
|
+
description: "Debounce duration in milliseconds"
|
|
1406
|
+
},
|
|
1407
|
+
preventDuplicate: {
|
|
1408
|
+
type: "boolean",
|
|
1409
|
+
description: "Prevent concurrent duplicate pipeline executions"
|
|
1410
|
+
},
|
|
1411
|
+
enabled: {
|
|
1412
|
+
type: "boolean",
|
|
1413
|
+
default: true,
|
|
1414
|
+
description: "Whether the pipeline is currently active"
|
|
1415
|
+
},
|
|
1416
|
+
steps: {
|
|
1417
|
+
type: "array",
|
|
1418
|
+
items: { $ref: "#/definitions/actionStep" },
|
|
1419
|
+
minItems: 1,
|
|
1420
|
+
description: "Ordered sequence of action steps to execute"
|
|
1421
|
+
}
|
|
1422
|
+
},
|
|
1423
|
+
definitions: {
|
|
1424
|
+
actionStep: {
|
|
1425
|
+
type: "object",
|
|
1426
|
+
required: ["id", "type"],
|
|
1427
|
+
properties: {
|
|
1428
|
+
id: {
|
|
1429
|
+
type: "string",
|
|
1430
|
+
minLength: 1
|
|
1431
|
+
},
|
|
1432
|
+
type: {
|
|
1433
|
+
type: "string",
|
|
1434
|
+
enum: [
|
|
1435
|
+
"api_request",
|
|
1436
|
+
"navigate",
|
|
1437
|
+
"set_state",
|
|
1438
|
+
"reset_form",
|
|
1439
|
+
"show_toast",
|
|
1440
|
+
"open_modal",
|
|
1441
|
+
"close_modal",
|
|
1442
|
+
"copy_clipboard",
|
|
1443
|
+
"custom_event"
|
|
1444
|
+
]
|
|
1445
|
+
},
|
|
1446
|
+
label: { type: "string" },
|
|
1447
|
+
payload: { type: "object" },
|
|
1448
|
+
condition: {
|
|
1449
|
+
type: "object",
|
|
1450
|
+
required: ["field", "operator"],
|
|
1451
|
+
properties: {
|
|
1452
|
+
field: { type: "string", minLength: 1 },
|
|
1453
|
+
operator: {
|
|
1454
|
+
type: "string",
|
|
1455
|
+
enum: [
|
|
1456
|
+
"equals",
|
|
1457
|
+
"not_equals",
|
|
1458
|
+
"contains",
|
|
1459
|
+
"not_contains",
|
|
1460
|
+
"is_truthy",
|
|
1461
|
+
"is_falsy",
|
|
1462
|
+
"gt",
|
|
1463
|
+
"gte",
|
|
1464
|
+
"lt",
|
|
1465
|
+
"lte",
|
|
1466
|
+
"regex"
|
|
1467
|
+
]
|
|
1468
|
+
},
|
|
1469
|
+
value: {}
|
|
1470
|
+
},
|
|
1471
|
+
additionalProperties: false
|
|
1472
|
+
},
|
|
1473
|
+
timeout: { type: "number", minimum: 1 },
|
|
1474
|
+
continueOnError: { type: "boolean" },
|
|
1475
|
+
onSuccess: {
|
|
1476
|
+
type: "array",
|
|
1477
|
+
items: { $ref: "#/definitions/actionStep" }
|
|
1478
|
+
},
|
|
1479
|
+
onError: {
|
|
1480
|
+
type: "array",
|
|
1481
|
+
items: { $ref: "#/definitions/actionStep" }
|
|
1482
|
+
}
|
|
1483
|
+
},
|
|
1484
|
+
additionalProperties: false
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
function getActionPipelineJsonSchema() {
|
|
1489
|
+
return ACTION_PIPELINE_JSON_SCHEMA_V1;
|
|
1490
|
+
}
|
|
1491
|
+
var FORM_CONFIG_JSON_SCHEMA_V1 = {
|
|
1492
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
1493
|
+
$id: "https://schema.stora.page/v1/form-config.json",
|
|
1494
|
+
title: "StoraFormConfig",
|
|
1495
|
+
description: "Form container configuration and behavior definition for KUBUILD",
|
|
1496
|
+
type: "object",
|
|
1497
|
+
required: ["formId"],
|
|
1498
|
+
additionalProperties: false,
|
|
1499
|
+
properties: {
|
|
1500
|
+
formId: {
|
|
1501
|
+
type: "string",
|
|
1502
|
+
minLength: 1,
|
|
1503
|
+
description: "Unique identifier for the form boundary"
|
|
1504
|
+
},
|
|
1505
|
+
resetOnSubmit: {
|
|
1506
|
+
type: "boolean",
|
|
1507
|
+
default: false,
|
|
1508
|
+
description: "Whether to reset form field values after successful submission"
|
|
1509
|
+
},
|
|
1510
|
+
scrollToFirstError: {
|
|
1511
|
+
type: "boolean",
|
|
1512
|
+
default: true,
|
|
1513
|
+
description: "Auto-scroll viewport to the first invalid input on validation failure"
|
|
1514
|
+
},
|
|
1515
|
+
validateOn: {
|
|
1516
|
+
type: "string",
|
|
1517
|
+
enum: ["blur", "change", "submit"],
|
|
1518
|
+
default: "blur",
|
|
1519
|
+
description: "Default trigger event for field validation evaluation"
|
|
1520
|
+
},
|
|
1521
|
+
initialValues: {
|
|
1522
|
+
type: "object",
|
|
1523
|
+
description: "Initial state values populated in form fields"
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
function getFormConfigJsonSchema() {
|
|
1528
|
+
return FORM_CONFIG_JSON_SCHEMA_V1;
|
|
1529
|
+
}
|
|
1530
|
+
var FORM_FIELD_BINDING_JSON_SCHEMA_V1 = {
|
|
1531
|
+
$schema: "http://json-schema.org/draft-07/schema#",
|
|
1532
|
+
$id: "https://schema.stora.page/v1/form-field-binding.json",
|
|
1533
|
+
title: "StoraFormFieldBinding",
|
|
1534
|
+
description: "Form field binding definition connecting input elements to form state runtime",
|
|
1535
|
+
type: "object",
|
|
1536
|
+
required: ["name"],
|
|
1537
|
+
additionalProperties: false,
|
|
1538
|
+
properties: {
|
|
1539
|
+
name: {
|
|
1540
|
+
type: "string",
|
|
1541
|
+
minLength: 1,
|
|
1542
|
+
description: "Field state property key"
|
|
1543
|
+
},
|
|
1544
|
+
label: {
|
|
1545
|
+
type: "string",
|
|
1546
|
+
description: "Display label for the field"
|
|
1547
|
+
},
|
|
1548
|
+
defaultValue: {
|
|
1549
|
+
description: "Initial default value if not overridden by form initialValues"
|
|
1550
|
+
},
|
|
1551
|
+
rules: {
|
|
1552
|
+
type: "array",
|
|
1553
|
+
items: { $ref: "#/definitions/validationRule" },
|
|
1554
|
+
default: [],
|
|
1555
|
+
description: "Validation rules applied to the field value"
|
|
1556
|
+
},
|
|
1557
|
+
validateOn: {
|
|
1558
|
+
type: "string",
|
|
1559
|
+
enum: ["blur", "change", "submit"],
|
|
1560
|
+
default: "blur",
|
|
1561
|
+
description: "Field-specific validation trigger timing"
|
|
1562
|
+
},
|
|
1563
|
+
transform: {
|
|
1564
|
+
type: "string",
|
|
1565
|
+
enum: ["trim", "lowercase", "uppercase", "number"],
|
|
1566
|
+
description: "Value transformation applied prior to validation and state storage"
|
|
1567
|
+
},
|
|
1568
|
+
disabled: {
|
|
1569
|
+
type: "boolean",
|
|
1570
|
+
description: "Whether the field is disabled"
|
|
1571
|
+
},
|
|
1572
|
+
required: {
|
|
1573
|
+
type: "boolean",
|
|
1574
|
+
description: "Whether the field is required (shorthand rule)"
|
|
1575
|
+
}
|
|
1576
|
+
},
|
|
1577
|
+
definitions: {
|
|
1578
|
+
validationRule: {
|
|
1579
|
+
type: "object",
|
|
1580
|
+
required: ["type", "message"],
|
|
1581
|
+
properties: {
|
|
1582
|
+
type: {
|
|
1583
|
+
type: "string",
|
|
1584
|
+
enum: [
|
|
1585
|
+
"required",
|
|
1586
|
+
"email",
|
|
1587
|
+
"url",
|
|
1588
|
+
"min_length",
|
|
1589
|
+
"max_length",
|
|
1590
|
+
"numeric_min",
|
|
1591
|
+
"numeric_max",
|
|
1592
|
+
"pattern",
|
|
1593
|
+
"match_field",
|
|
1594
|
+
"custom_regex"
|
|
1595
|
+
]
|
|
1596
|
+
},
|
|
1597
|
+
value: {},
|
|
1598
|
+
message: {
|
|
1599
|
+
type: "string",
|
|
1600
|
+
minLength: 1
|
|
1601
|
+
}
|
|
1602
|
+
},
|
|
1603
|
+
additionalProperties: false
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
};
|
|
1607
|
+
function getFormFieldBindingJsonSchema() {
|
|
1608
|
+
return FORM_FIELD_BINDING_JSON_SCHEMA_V1;
|
|
1609
|
+
}
|
|
898
1610
|
export {
|
|
1611
|
+
ACTION_PIPELINE_JSON_SCHEMA_V1,
|
|
1612
|
+
ARTBOARD_REFERENCE_NODE_TYPE,
|
|
899
1613
|
ActionBindingSchema,
|
|
1614
|
+
ActionPipelineSchema,
|
|
1615
|
+
ActionStepConditionSchema,
|
|
1616
|
+
ActionStepSchema,
|
|
1617
|
+
ActionStepTypeSchema,
|
|
1618
|
+
ActionTriggerSchema,
|
|
1619
|
+
ActionTriggerTypeSchema,
|
|
900
1620
|
AnimationConfigSchema,
|
|
1621
|
+
ApiRequestStepPayloadSchema,
|
|
1622
|
+
ArtboardSchema,
|
|
1623
|
+
ArtboardTypeSchema,
|
|
901
1624
|
AssetReferenceSchema,
|
|
1625
|
+
CURRENT_PROJECT_SCHEMA_VERSION,
|
|
902
1626
|
CURRENT_SCHEMA_VERSION,
|
|
1627
|
+
CloseModalStepPayloadSchema,
|
|
1628
|
+
ConditionOperatorSchema,
|
|
1629
|
+
CopyClipboardStepPayloadSchema,
|
|
1630
|
+
CustomEventStepPayloadSchema,
|
|
903
1631
|
DEFAULT_ANIMATION_CONFIG,
|
|
904
1632
|
DocumentMetadataSchema,
|
|
1633
|
+
FORM_CONFIG_JSON_SCHEMA_V1,
|
|
1634
|
+
FORM_FIELD_BINDING_JSON_SCHEMA_V1,
|
|
1635
|
+
FormConfigSchema,
|
|
1636
|
+
FormFieldBindingSchema,
|
|
905
1637
|
MANIFEST_JSON_SCHEMA_V1,
|
|
906
1638
|
ManifestAssetItemSchema,
|
|
907
1639
|
ManifestSchema,
|
|
1640
|
+
NavigateStepPayloadSchema,
|
|
908
1641
|
NodeSchema,
|
|
1642
|
+
OpenModalStepPayloadSchema,
|
|
909
1643
|
PAGE_DOCUMENT_JSON_SCHEMA_V1,
|
|
1644
|
+
PROJECT_SCHEMA_NAME,
|
|
910
1645
|
PageDocumentSchema,
|
|
1646
|
+
ProjectDocumentSchema,
|
|
911
1647
|
PseudoStateStylesSchema,
|
|
1648
|
+
ResetFormStepPayloadSchema,
|
|
912
1649
|
ResponsiveStylesSchema,
|
|
913
1650
|
RootPageNodeSchema,
|
|
914
1651
|
SCHEMA_NAME,
|
|
915
1652
|
SafeThumbnailObjectSchema,
|
|
916
1653
|
SafeThumbnailSchema,
|
|
917
1654
|
SafeThumbnailUrlSchema,
|
|
1655
|
+
SetStateStepPayloadSchema,
|
|
1656
|
+
ShowToastStepPayloadSchema,
|
|
1657
|
+
StepPayloadSchemas,
|
|
918
1658
|
StyleDefinitionSchema,
|
|
919
1659
|
StyleValueSchema,
|
|
920
1660
|
TEMPLATE_RECORD_JSON_SCHEMA_V1,
|
|
921
1661
|
TemplatePackageRefSchema,
|
|
922
1662
|
TemplateRecordSchema,
|
|
923
1663
|
TemplateRequirementsSchema,
|
|
1664
|
+
ValidateOnEventSchema,
|
|
1665
|
+
ValidationRuleSchema,
|
|
1666
|
+
ValidationRuleTypeSchema,
|
|
924
1667
|
VariableBindingSchema,
|
|
925
1668
|
collectNodeIds,
|
|
926
1669
|
generateDeterministicNodeId,
|
|
1670
|
+
getActionPipelineJsonSchema,
|
|
1671
|
+
getFormConfigJsonSchema,
|
|
1672
|
+
getFormFieldBindingJsonSchema,
|
|
927
1673
|
getManifestJsonSchema,
|
|
928
1674
|
getPageDocumentJsonSchema,
|
|
929
1675
|
getTemplateRecordJsonSchema,
|
|
930
1676
|
isActionBinding,
|
|
1677
|
+
isActionPipeline,
|
|
1678
|
+
isActionStep,
|
|
1679
|
+
isActionStepCondition,
|
|
1680
|
+
isActionStepType,
|
|
1681
|
+
isActionTriggerType,
|
|
931
1682
|
isAnimationConfig,
|
|
1683
|
+
isArtboardReferenceNode,
|
|
932
1684
|
isAssetReference,
|
|
1685
|
+
isConditionOperator,
|
|
1686
|
+
isFormConfig,
|
|
1687
|
+
isFormFieldBinding,
|
|
933
1688
|
isManifest,
|
|
1689
|
+
isProjectDocument,
|
|
1690
|
+
isSafeActionUrl,
|
|
934
1691
|
isSafeThumbnail,
|
|
935
1692
|
isSafeThumbnailUrl,
|
|
936
1693
|
isTemplateRecord,
|
|
1694
|
+
isValidateOnEvent,
|
|
1695
|
+
isValidationRule,
|
|
1696
|
+
isValidationRuleType,
|
|
937
1697
|
isVariableBinding,
|
|
1698
|
+
looksLikeProjectDocument,
|
|
1699
|
+
sanitizeActionPayload,
|
|
1700
|
+
sanitizeActionPipeline,
|
|
1701
|
+
sanitizeActionStep,
|
|
1702
|
+
sanitizeActionString,
|
|
1703
|
+
sanitizeActionUrl,
|
|
1704
|
+
sanitizeActionValue,
|
|
938
1705
|
starterPageFixture,
|
|
1706
|
+
validateActionStepPayload,
|
|
939
1707
|
validateNodeIdUniqueness
|
|
940
1708
|
};
|
|
941
1709
|
//# sourceMappingURL=index.js.map
|