@kubuild/schema 0.5.0 → 0.6.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/actions.d.ts +24 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/document.d.ts +442 -0
- package/dist/document.d.ts.map +1 -1
- package/dist/index.cjs +373 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +361 -199
- package/dist/index.js.map +1 -1
- package/dist/template.d.ts +98 -0
- package/dist/template.d.ts.map +1 -1
- package/dist/tracking.d.ts +201 -0
- package/dist/tracking.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,154 @@
|
|
|
1
1
|
// src/document.ts
|
|
2
|
-
import { z as
|
|
2
|
+
import { z as z4 } from "zod";
|
|
3
3
|
|
|
4
4
|
// src/actions.ts
|
|
5
|
+
import { z as z2 } from "zod";
|
|
6
|
+
|
|
7
|
+
// src/tracking.ts
|
|
5
8
|
import { z } from "zod";
|
|
6
|
-
var
|
|
9
|
+
var TrackingProviderTypeSchema = z.enum([
|
|
10
|
+
"meta",
|
|
11
|
+
"google",
|
|
12
|
+
"gtm",
|
|
13
|
+
"tiktok",
|
|
14
|
+
"custom"
|
|
15
|
+
]);
|
|
16
|
+
var TrackingDeliverySchema = z.enum(["both", "client_only", "server_only"]);
|
|
17
|
+
var MetaTrackingProviderConfigSchema = z.object({
|
|
18
|
+
enabled: z.boolean().default(true),
|
|
19
|
+
/** Optional linked account/workspace credential ID */
|
|
20
|
+
credentialId: z.string().optional(),
|
|
21
|
+
/** Meta Pixel ID (e.g. 123456789012345) */
|
|
22
|
+
pixelId: z.string().optional().default(""),
|
|
23
|
+
/** Enable Server-Side Conversions API */
|
|
24
|
+
capiEnabled: z.boolean().optional().default(false),
|
|
25
|
+
/**
|
|
26
|
+
* System User Access Token for Meta Graph API.
|
|
27
|
+
* Note: For security in production, prefer configuring tokens on your server backend
|
|
28
|
+
* or proxying via `serverRelayUrl`.
|
|
29
|
+
*/
|
|
30
|
+
capiAccessToken: z.string().optional().default(""),
|
|
31
|
+
/** Test Event Code from Meta Events Manager (e.g. "TEST12345") */
|
|
32
|
+
testEventCode: z.string().optional().default(""),
|
|
33
|
+
/**
|
|
34
|
+
* Host Server Relay URL (e.g. "/api/tracking/meta").
|
|
35
|
+
* Recommended for browser clients to post CAPI events safely without exposing the secret token.
|
|
36
|
+
*/
|
|
37
|
+
serverRelayUrl: z.string().optional().default("")
|
|
38
|
+
});
|
|
39
|
+
var GoogleTrackingProviderConfigSchema = z.object({
|
|
40
|
+
enabled: z.boolean().default(true),
|
|
41
|
+
/** Optional linked account/workspace credential ID */
|
|
42
|
+
credentialId: z.string().optional(),
|
|
43
|
+
/** GA4 Measurement ID (e.g. "G-XXXXXXXXXX") */
|
|
44
|
+
measurementId: z.string().optional().default(""),
|
|
45
|
+
/** GA4 Measurement Protocol API Secret (for server-side events) */
|
|
46
|
+
measurementProtocolSecret: z.string().optional().default(""),
|
|
47
|
+
/** Host Server Relay URL (e.g. "/api/tracking/ga4") */
|
|
48
|
+
serverRelayUrl: z.string().optional().default("")
|
|
49
|
+
});
|
|
50
|
+
var GtmTrackingProviderConfigSchema = z.object({
|
|
51
|
+
enabled: z.boolean().default(true),
|
|
52
|
+
/** Optional linked account/workspace credential ID */
|
|
53
|
+
credentialId: z.string().optional(),
|
|
54
|
+
/** GTM Container ID (e.g. "GTM-XXXXXXX") */
|
|
55
|
+
containerId: z.string().optional().default(""),
|
|
56
|
+
/** Host Server Relay URL */
|
|
57
|
+
serverRelayUrl: z.string().optional().default("")
|
|
58
|
+
});
|
|
59
|
+
var TikTokTrackingProviderConfigSchema = z.object({
|
|
60
|
+
enabled: z.boolean().default(true),
|
|
61
|
+
/** Optional linked account/workspace credential ID */
|
|
62
|
+
credentialId: z.string().optional(),
|
|
63
|
+
/** TikTok Pixel ID (e.g. "C1234567890") */
|
|
64
|
+
pixelId: z.string().optional().default(""),
|
|
65
|
+
/** Enable TikTok Events API (server-side) */
|
|
66
|
+
eventsApiEnabled: z.boolean().optional().default(false),
|
|
67
|
+
/** Long-term Access Token for TikTok Events API */
|
|
68
|
+
accessToken: z.string().optional().default(""),
|
|
69
|
+
/** Test Event Code from TikTok Event Manager */
|
|
70
|
+
testEventCode: z.string().optional().default(""),
|
|
71
|
+
/** Host Server Relay URL (e.g. "/api/tracking/tiktok") */
|
|
72
|
+
serverRelayUrl: z.string().optional().default("")
|
|
73
|
+
});
|
|
74
|
+
var CustomTrackingProviderConfigSchema = z.object({
|
|
75
|
+
enabled: z.boolean().default(true),
|
|
76
|
+
/** Optional linked account/workspace credential ID */
|
|
77
|
+
credentialId: z.string().optional(),
|
|
78
|
+
/** Custom Webhook endpoint URL */
|
|
79
|
+
endpointUrl: z.string().optional().default(""),
|
|
80
|
+
/** Optional headers sent with the webhook POST request */
|
|
81
|
+
headers: z.record(z.string(), z.string()).optional().default({})
|
|
82
|
+
});
|
|
83
|
+
var TrackingConfigSchema = z.object({
|
|
84
|
+
/** Master toggle: dynamically enables or disables all tracking operations */
|
|
85
|
+
enabled: z.boolean().default(true),
|
|
86
|
+
/** When enabled, events are logged to console and can bypass live API calls for safe debugging */
|
|
87
|
+
debugMode: z.boolean().optional().default(false),
|
|
88
|
+
/** Automatically trigger PageView event upon page load */
|
|
89
|
+
autoPageView: z.boolean().optional().default(true),
|
|
90
|
+
/** Default delivery method when not explicitly overridden in an action step */
|
|
91
|
+
defaultDelivery: TrackingDeliverySchema.optional().default("both"),
|
|
92
|
+
/** Provider-specific settings */
|
|
93
|
+
providers: z.object({
|
|
94
|
+
meta: MetaTrackingProviderConfigSchema.optional(),
|
|
95
|
+
google: GoogleTrackingProviderConfigSchema.optional(),
|
|
96
|
+
gtm: GtmTrackingProviderConfigSchema.optional(),
|
|
97
|
+
tiktok: TikTokTrackingProviderConfigSchema.optional(),
|
|
98
|
+
custom: CustomTrackingProviderConfigSchema.optional()
|
|
99
|
+
}).optional().default({})
|
|
100
|
+
});
|
|
101
|
+
var StandardTrackingEventSchema = z.enum([
|
|
102
|
+
"PageView",
|
|
103
|
+
"ViewContent",
|
|
104
|
+
"AddToCart",
|
|
105
|
+
"InitiateCheckout",
|
|
106
|
+
"Purchase",
|
|
107
|
+
"Lead",
|
|
108
|
+
"Contact",
|
|
109
|
+
"CompleteRegistration",
|
|
110
|
+
"Subscribe",
|
|
111
|
+
"Search",
|
|
112
|
+
"SubmitApplication",
|
|
113
|
+
"Schedule"
|
|
114
|
+
]);
|
|
115
|
+
var TrackEventStepPayloadSchema = z.object({
|
|
116
|
+
/** Event name: e.g. "Purchase", "Lead", or custom string */
|
|
117
|
+
eventName: z.string().min(1, "Event name cannot be empty"),
|
|
118
|
+
/** Standard event vs custom event identifier */
|
|
119
|
+
eventType: z.enum(["standard", "custom"]).optional().default("standard"),
|
|
120
|
+
/** Target provider: 'all' or a specific provider */
|
|
121
|
+
provider: z.enum(["all", "meta", "google", "tiktok", "custom"]).optional().default("all"),
|
|
122
|
+
/** Delivery channel: 'both', 'client_only', or 'server_only' */
|
|
123
|
+
delivery: TrackingDeliverySchema.optional().default("both"),
|
|
124
|
+
/**
|
|
125
|
+
* Deduplication Event ID.
|
|
126
|
+
* If omitted, a unique ID is automatically generated so Meta/TikTok CAPI
|
|
127
|
+
* deduplicates cleanly with the browser pixel.
|
|
128
|
+
*/
|
|
129
|
+
eventId: z.string().optional(),
|
|
130
|
+
/**
|
|
131
|
+
* Event parameters/properties (e.g. currency, value, content_name, order_id).
|
|
132
|
+
* Supports runtime variable interpolation (e.g. {{ form.price }} or {{ variables.currency }}).
|
|
133
|
+
*/
|
|
134
|
+
params: z.record(z.string(), z.unknown()).optional().default({}),
|
|
135
|
+
/**
|
|
136
|
+
* User Data for advanced matching and server CAPI (e.g. email, phone, firstName, lastName).
|
|
137
|
+
* Supports runtime variable interpolation (e.g. {{ form.email }}).
|
|
138
|
+
*/
|
|
139
|
+
userData: z.record(z.string(), z.unknown()).optional().default({}),
|
|
140
|
+
/** Step-level active toggle */
|
|
141
|
+
enabled: z.boolean().optional().default(true)
|
|
142
|
+
});
|
|
143
|
+
function isTrackingConfig(value) {
|
|
144
|
+
return TrackingConfigSchema.safeParse(value).success;
|
|
145
|
+
}
|
|
146
|
+
function isTrackEventStepPayload(value) {
|
|
147
|
+
return TrackEventStepPayloadSchema.safeParse(value).success;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/actions.ts
|
|
151
|
+
var ActionTriggerTypeSchema = z2.enum([
|
|
7
152
|
"click",
|
|
8
153
|
"submit",
|
|
9
154
|
"change",
|
|
@@ -12,7 +157,7 @@ var ActionTriggerTypeSchema = z.enum([
|
|
|
12
157
|
"load"
|
|
13
158
|
]);
|
|
14
159
|
var ActionTriggerSchema = ActionTriggerTypeSchema;
|
|
15
|
-
var ActionStepTypeSchema =
|
|
160
|
+
var ActionStepTypeSchema = z2.enum([
|
|
16
161
|
"api_request",
|
|
17
162
|
"navigate",
|
|
18
163
|
"set_state",
|
|
@@ -21,9 +166,10 @@ var ActionStepTypeSchema = z.enum([
|
|
|
21
166
|
"open_modal",
|
|
22
167
|
"close_modal",
|
|
23
168
|
"copy_clipboard",
|
|
24
|
-
"custom_event"
|
|
169
|
+
"custom_event",
|
|
170
|
+
"track_event"
|
|
25
171
|
]);
|
|
26
|
-
var ConditionOperatorSchema =
|
|
172
|
+
var ConditionOperatorSchema = z2.enum([
|
|
27
173
|
"equals",
|
|
28
174
|
"not_equals",
|
|
29
175
|
"contains",
|
|
@@ -36,10 +182,10 @@ var ConditionOperatorSchema = z.enum([
|
|
|
36
182
|
"lte",
|
|
37
183
|
"regex"
|
|
38
184
|
]);
|
|
39
|
-
var ActionStepConditionSchema =
|
|
40
|
-
field:
|
|
185
|
+
var ActionStepConditionSchema = z2.object({
|
|
186
|
+
field: z2.string().min(1, "Condition field cannot be empty"),
|
|
41
187
|
operator: ConditionOperatorSchema,
|
|
42
|
-
value:
|
|
188
|
+
value: z2.unknown().optional()
|
|
43
189
|
});
|
|
44
190
|
var DANGEROUS_URL_PATTERN = /(javascript:|vbscript:|data:text\/html)/i;
|
|
45
191
|
var DANGEROUS_SCRIPT_PATTERN = /<\s*script/i;
|
|
@@ -50,68 +196,68 @@ function isSafeActionUrl(url) {
|
|
|
50
196
|
if (DANGEROUS_SCRIPT_PATTERN.test(trimmed)) return false;
|
|
51
197
|
return true;
|
|
52
198
|
}
|
|
53
|
-
var SafeUrlStringSchema =
|
|
199
|
+
var SafeUrlStringSchema = z2.string().min(1, "URL cannot be empty").refine(isSafeActionUrl, {
|
|
54
200
|
message: "URL contains disallowed or unsafe protocol/script pattern"
|
|
55
201
|
});
|
|
56
|
-
var SafeEventNameSchema =
|
|
202
|
+
var SafeEventNameSchema = z2.string().min(1, "Event name cannot be empty").regex(/^[a-zA-Z0-9_\-:]+$/, {
|
|
57
203
|
message: "Event name must contain only alphanumeric characters, dashes, colons, or underscores"
|
|
58
204
|
});
|
|
59
|
-
var ApiRequestStepPayloadSchema =
|
|
205
|
+
var ApiRequestStepPayloadSchema = z2.object({
|
|
60
206
|
url: SafeUrlStringSchema,
|
|
61
|
-
method:
|
|
62
|
-
headers:
|
|
63
|
-
queryParams:
|
|
64
|
-
body:
|
|
65
|
-
bodyFormat:
|
|
66
|
-
bodyType:
|
|
67
|
-
timeout:
|
|
68
|
-
responseMapping:
|
|
207
|
+
method: z2.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).default("GET"),
|
|
208
|
+
headers: z2.record(z2.string(), z2.string()).optional(),
|
|
209
|
+
queryParams: z2.record(z2.string(), z2.union([z2.string(), z2.number(), z2.boolean()])).optional(),
|
|
210
|
+
body: z2.union([z2.string(), z2.record(z2.string(), z2.unknown()), z2.array(z2.unknown())]).optional(),
|
|
211
|
+
bodyFormat: z2.enum(["json", "form-data", "formData", "urlencoded", "url-encoded", "raw", "text"]).optional(),
|
|
212
|
+
bodyType: z2.enum(["json", "form-data", "formData", "urlencoded", "url-encoded", "raw", "text"]).optional(),
|
|
213
|
+
timeout: z2.number().positive("Timeout must be greater than 0 ms").optional(),
|
|
214
|
+
responseMapping: z2.record(z2.string(), z2.string()).optional()
|
|
69
215
|
});
|
|
70
|
-
var NavigateStepPayloadSchema =
|
|
216
|
+
var NavigateStepPayloadSchema = z2.object({
|
|
71
217
|
url: SafeUrlStringSchema,
|
|
72
|
-
target:
|
|
73
|
-
replace:
|
|
74
|
-
scroll:
|
|
75
|
-
behavior:
|
|
218
|
+
target: z2.enum(["_self", "_blank", "_parent", "_top"]).optional().default("_self"),
|
|
219
|
+
replace: z2.boolean().optional(),
|
|
220
|
+
scroll: z2.boolean().optional(),
|
|
221
|
+
behavior: z2.enum(["smooth", "auto"]).optional()
|
|
76
222
|
});
|
|
77
|
-
var SetStateStepPayloadSchema =
|
|
78
|
-
key:
|
|
79
|
-
value:
|
|
80
|
-
scope:
|
|
223
|
+
var SetStateStepPayloadSchema = z2.object({
|
|
224
|
+
key: z2.string().min(1, "State key cannot be empty"),
|
|
225
|
+
value: z2.unknown(),
|
|
226
|
+
scope: z2.enum(["runtime", "document", "session", "local"]).optional().default("runtime")
|
|
81
227
|
});
|
|
82
|
-
var ResetFormStepPayloadSchema =
|
|
83
|
-
formId:
|
|
228
|
+
var ResetFormStepPayloadSchema = z2.object({
|
|
229
|
+
formId: z2.string().optional()
|
|
84
230
|
});
|
|
85
|
-
var ShowToastStepPayloadSchema =
|
|
86
|
-
message:
|
|
87
|
-
type:
|
|
88
|
-
variant:
|
|
89
|
-
title:
|
|
90
|
-
duration:
|
|
91
|
-
position:
|
|
231
|
+
var ShowToastStepPayloadSchema = z2.object({
|
|
232
|
+
message: z2.string().min(1, "Toast message cannot be empty"),
|
|
233
|
+
type: z2.enum(["success", "error", "warning", "info"]).optional().default("info"),
|
|
234
|
+
variant: z2.enum(["success", "error", "warning", "info"]).optional(),
|
|
235
|
+
title: z2.string().optional(),
|
|
236
|
+
duration: z2.number().nonnegative("Duration must be >= 0 ms").optional(),
|
|
237
|
+
position: z2.enum(["top-right", "top-left", "bottom-right", "bottom-left", "top-center", "bottom-center"]).optional()
|
|
92
238
|
});
|
|
93
|
-
var OpenModalStepPayloadSchema =
|
|
94
|
-
modalId:
|
|
95
|
-
modalNodeId:
|
|
96
|
-
toggle:
|
|
239
|
+
var OpenModalStepPayloadSchema = z2.object({
|
|
240
|
+
modalId: z2.string().optional(),
|
|
241
|
+
modalNodeId: z2.string().optional(),
|
|
242
|
+
toggle: z2.boolean().optional()
|
|
97
243
|
}).refine((data) => Boolean(data.modalId || data.modalNodeId), {
|
|
98
244
|
message: "Modal ID or Modal Node ID cannot be empty"
|
|
99
245
|
});
|
|
100
|
-
var CloseModalStepPayloadSchema =
|
|
101
|
-
modalId:
|
|
102
|
-
modalNodeId:
|
|
246
|
+
var CloseModalStepPayloadSchema = z2.object({
|
|
247
|
+
modalId: z2.string().optional(),
|
|
248
|
+
modalNodeId: z2.string().optional()
|
|
103
249
|
});
|
|
104
|
-
var CopyClipboardStepPayloadSchema =
|
|
105
|
-
text:
|
|
106
|
-
value:
|
|
107
|
-
notify:
|
|
108
|
-
toastMessage:
|
|
250
|
+
var CopyClipboardStepPayloadSchema = z2.object({
|
|
251
|
+
text: z2.string().optional(),
|
|
252
|
+
value: z2.unknown().optional(),
|
|
253
|
+
notify: z2.boolean().optional(),
|
|
254
|
+
toastMessage: z2.string().optional()
|
|
109
255
|
});
|
|
110
|
-
var CustomEventStepPayloadSchema =
|
|
256
|
+
var CustomEventStepPayloadSchema = z2.object({
|
|
111
257
|
eventName: SafeEventNameSchema,
|
|
112
|
-
detail:
|
|
113
|
-
bubbles:
|
|
114
|
-
cancelable:
|
|
258
|
+
detail: z2.record(z2.string(), z2.unknown()).optional(),
|
|
259
|
+
bubbles: z2.boolean().optional().default(true),
|
|
260
|
+
cancelable: z2.boolean().optional().default(true)
|
|
115
261
|
});
|
|
116
262
|
var StepPayloadSchemas = {
|
|
117
263
|
api_request: ApiRequestStepPayloadSchema,
|
|
@@ -122,29 +268,30 @@ var StepPayloadSchemas = {
|
|
|
122
268
|
open_modal: OpenModalStepPayloadSchema,
|
|
123
269
|
close_modal: CloseModalStepPayloadSchema,
|
|
124
270
|
copy_clipboard: CopyClipboardStepPayloadSchema,
|
|
125
|
-
custom_event: CustomEventStepPayloadSchema
|
|
271
|
+
custom_event: CustomEventStepPayloadSchema,
|
|
272
|
+
track_event: TrackEventStepPayloadSchema
|
|
126
273
|
};
|
|
127
|
-
var ActionStepSchema =
|
|
128
|
-
() =>
|
|
129
|
-
id:
|
|
274
|
+
var ActionStepSchema = z2.lazy(
|
|
275
|
+
() => z2.object({
|
|
276
|
+
id: z2.string().min(1, "Step ID cannot be empty"),
|
|
130
277
|
type: ActionStepTypeSchema,
|
|
131
|
-
label:
|
|
132
|
-
payload:
|
|
278
|
+
label: z2.string().optional(),
|
|
279
|
+
payload: z2.record(z2.string(), z2.unknown()).optional().default({}),
|
|
133
280
|
condition: ActionStepConditionSchema.optional(),
|
|
134
|
-
timeout:
|
|
135
|
-
continueOnError:
|
|
136
|
-
onSuccess:
|
|
137
|
-
onError:
|
|
281
|
+
timeout: z2.number().positive().optional(),
|
|
282
|
+
continueOnError: z2.boolean().optional(),
|
|
283
|
+
onSuccess: z2.array(ActionStepSchema).optional(),
|
|
284
|
+
onError: z2.array(ActionStepSchema).optional()
|
|
138
285
|
})
|
|
139
286
|
);
|
|
140
|
-
var ActionPipelineSchema =
|
|
141
|
-
id:
|
|
287
|
+
var ActionPipelineSchema = z2.object({
|
|
288
|
+
id: z2.string().min(1, "Pipeline ID cannot be empty"),
|
|
142
289
|
trigger: ActionTriggerTypeSchema,
|
|
143
|
-
label:
|
|
144
|
-
debounceMs:
|
|
145
|
-
preventDuplicate:
|
|
146
|
-
enabled:
|
|
147
|
-
steps:
|
|
290
|
+
label: z2.string().optional(),
|
|
291
|
+
debounceMs: z2.number().nonnegative("Debounce ms must be >= 0").optional(),
|
|
292
|
+
preventDuplicate: z2.boolean().optional(),
|
|
293
|
+
enabled: z2.boolean().optional().default(true),
|
|
294
|
+
steps: z2.array(ActionStepSchema).min(1, "Action pipeline must contain at least one step")
|
|
148
295
|
});
|
|
149
296
|
function isActionTriggerType(value) {
|
|
150
297
|
return ActionTriggerTypeSchema.safeParse(value).success;
|
|
@@ -169,9 +316,9 @@ function validateActionStepPayload(type, payload) {
|
|
|
169
316
|
if (!schema) {
|
|
170
317
|
return {
|
|
171
318
|
success: false,
|
|
172
|
-
error: new
|
|
319
|
+
error: new z2.ZodError([
|
|
173
320
|
{
|
|
174
|
-
code:
|
|
321
|
+
code: z2.ZodIssueCode.custom,
|
|
175
322
|
message: `Unknown step type: ${type}`,
|
|
176
323
|
path: ["type"]
|
|
177
324
|
}
|
|
@@ -259,8 +406,8 @@ function sanitizeActionPipeline(pipeline) {
|
|
|
259
406
|
}
|
|
260
407
|
|
|
261
408
|
// src/form.ts
|
|
262
|
-
import { z as
|
|
263
|
-
var ValidationRuleTypeSchema =
|
|
409
|
+
import { z as z3 } from "zod";
|
|
410
|
+
var ValidationRuleTypeSchema = z3.enum([
|
|
264
411
|
"required",
|
|
265
412
|
"email",
|
|
266
413
|
"url",
|
|
@@ -272,29 +419,29 @@ var ValidationRuleTypeSchema = z2.enum([
|
|
|
272
419
|
"match_field",
|
|
273
420
|
"custom_regex"
|
|
274
421
|
]);
|
|
275
|
-
var ValidateOnEventSchema =
|
|
276
|
-
var ValidationRuleSchema =
|
|
422
|
+
var ValidateOnEventSchema = z3.enum(["blur", "change", "submit"]);
|
|
423
|
+
var ValidationRuleSchema = z3.object({
|
|
277
424
|
type: ValidationRuleTypeSchema,
|
|
278
|
-
value:
|
|
279
|
-
message:
|
|
425
|
+
value: z3.unknown().optional(),
|
|
426
|
+
message: z3.string().min(1, "Validation error message cannot be empty")
|
|
280
427
|
});
|
|
281
|
-
var FormFieldBindingSchema =
|
|
282
|
-
name:
|
|
283
|
-
label:
|
|
284
|
-
defaultValue:
|
|
285
|
-
rules:
|
|
428
|
+
var FormFieldBindingSchema = z3.object({
|
|
429
|
+
name: z3.string().min(1, "Field name cannot be empty"),
|
|
430
|
+
label: z3.string().optional(),
|
|
431
|
+
defaultValue: z3.unknown().optional(),
|
|
432
|
+
rules: z3.array(ValidationRuleSchema).optional().default([]),
|
|
286
433
|
validateOn: ValidateOnEventSchema.optional().default("blur"),
|
|
287
|
-
transform:
|
|
288
|
-
disabled:
|
|
289
|
-
required:
|
|
434
|
+
transform: z3.enum(["trim", "lowercase", "uppercase", "number"]).optional(),
|
|
435
|
+
disabled: z3.boolean().optional(),
|
|
436
|
+
required: z3.boolean().optional()
|
|
290
437
|
});
|
|
291
|
-
var FormConfigSchema =
|
|
292
|
-
formId:
|
|
293
|
-
resetOnSubmit:
|
|
294
|
-
scrollToFirstError:
|
|
438
|
+
var FormConfigSchema = z3.object({
|
|
439
|
+
formId: z3.string().min(1, "Form ID cannot be empty"),
|
|
440
|
+
resetOnSubmit: z3.boolean().optional().default(false),
|
|
441
|
+
scrollToFirstError: z3.boolean().optional().default(true),
|
|
295
442
|
validateOn: ValidateOnEventSchema.optional().default("blur"),
|
|
296
|
-
initialValues:
|
|
297
|
-
rules:
|
|
443
|
+
initialValues: z3.record(z3.string(), z3.unknown()).optional(),
|
|
444
|
+
rules: z3.array(ValidationRuleSchema).optional()
|
|
298
445
|
});
|
|
299
446
|
function isValidationRuleType(value) {
|
|
300
447
|
return ValidationRuleTypeSchema.safeParse(value).success;
|
|
@@ -315,55 +462,55 @@ function isFormConfig(value) {
|
|
|
315
462
|
// src/document.ts
|
|
316
463
|
var SCHEMA_NAME = "stora.page";
|
|
317
464
|
var CURRENT_SCHEMA_VERSION = "1.0.0";
|
|
318
|
-
var AssetReferenceSchema =
|
|
319
|
-
type:
|
|
320
|
-
assetId:
|
|
321
|
-
filename:
|
|
322
|
-
mimeType:
|
|
323
|
-
fallbackUrl:
|
|
465
|
+
var AssetReferenceSchema = z4.object({
|
|
466
|
+
type: z4.literal("asset"),
|
|
467
|
+
assetId: z4.string().min(1, "Asset ID cannot be empty"),
|
|
468
|
+
filename: z4.string().optional(),
|
|
469
|
+
mimeType: z4.string().optional(),
|
|
470
|
+
fallbackUrl: z4.string().url().optional()
|
|
324
471
|
});
|
|
325
|
-
var VariableBindingSchema =
|
|
326
|
-
type:
|
|
327
|
-
key:
|
|
328
|
-
fallback:
|
|
472
|
+
var VariableBindingSchema = z4.object({
|
|
473
|
+
type: z4.literal("variable"),
|
|
474
|
+
key: z4.string().min(1, "Variable key cannot be empty"),
|
|
475
|
+
fallback: z4.unknown().optional()
|
|
329
476
|
});
|
|
330
|
-
var ActionBindingSchema =
|
|
331
|
-
type:
|
|
332
|
-
payload:
|
|
477
|
+
var ActionBindingSchema = z4.object({
|
|
478
|
+
type: z4.string().min(1, "Action type cannot be empty"),
|
|
479
|
+
payload: z4.record(z4.string(), z4.unknown()).optional()
|
|
333
480
|
});
|
|
334
481
|
var DANGEROUS_STYLE_VALUE_PATTERN = /javascript:|expression\(|@import|<script|vbscript:|data:text\/html/i;
|
|
335
|
-
var StyleValueSchema =
|
|
336
|
-
|
|
482
|
+
var StyleValueSchema = z4.union([
|
|
483
|
+
z4.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
337
484
|
message: "Style value contains a disallowed or unsafe pattern"
|
|
338
485
|
}),
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
486
|
+
z4.number(),
|
|
487
|
+
z4.boolean(),
|
|
488
|
+
z4.null(),
|
|
489
|
+
z4.undefined()
|
|
343
490
|
]);
|
|
344
|
-
var StyleDefinitionSchema =
|
|
345
|
-
var PseudoStateStylesSchema =
|
|
346
|
-
var ResponsiveStylesSchema =
|
|
491
|
+
var StyleDefinitionSchema = z4.record(z4.string(), StyleValueSchema);
|
|
492
|
+
var PseudoStateStylesSchema = z4.record(z4.string(), StyleDefinitionSchema);
|
|
493
|
+
var ResponsiveStylesSchema = z4.object({
|
|
347
494
|
base: StyleDefinitionSchema.optional(),
|
|
348
495
|
desktop: StyleDefinitionSchema.optional(),
|
|
349
496
|
tablet: StyleDefinitionSchema.optional(),
|
|
350
497
|
mobile: StyleDefinitionSchema.optional(),
|
|
351
498
|
states: PseudoStateStylesSchema.optional()
|
|
352
499
|
}).passthrough().default({});
|
|
353
|
-
var AnimationConfigSchema =
|
|
354
|
-
type:
|
|
500
|
+
var AnimationConfigSchema = z4.object({
|
|
501
|
+
type: z4.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
355
502
|
message: "Animation type contains a disallowed or unsafe pattern"
|
|
356
503
|
}).optional().default("none"),
|
|
357
|
-
duration:
|
|
358
|
-
delay:
|
|
359
|
-
easing:
|
|
504
|
+
duration: z4.number().min(0, "Duration must be non-negative").optional().default(600),
|
|
505
|
+
delay: z4.number().min(0, "Delay must be non-negative").optional().default(0),
|
|
506
|
+
easing: z4.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
360
507
|
message: "Animation easing contains a disallowed or unsafe pattern"
|
|
361
508
|
}).optional().default("ease-out"),
|
|
362
|
-
once:
|
|
363
|
-
hoverEffect:
|
|
509
|
+
once: z4.boolean().optional().default(true),
|
|
510
|
+
hoverEffect: z4.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
364
511
|
message: "Hover effect contains a disallowed or unsafe pattern"
|
|
365
512
|
}).optional().default("none"),
|
|
366
|
-
loopEffect:
|
|
513
|
+
loopEffect: z4.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
|
|
367
514
|
message: "Loop effect contains a disallowed or unsafe pattern"
|
|
368
515
|
}).optional().default("none")
|
|
369
516
|
});
|
|
@@ -376,16 +523,16 @@ var DEFAULT_ANIMATION_CONFIG = {
|
|
|
376
523
|
hoverEffect: "none",
|
|
377
524
|
loopEffect: "none"
|
|
378
525
|
};
|
|
379
|
-
var NodeSchema =
|
|
380
|
-
() =>
|
|
381
|
-
id:
|
|
382
|
-
type:
|
|
383
|
-
props:
|
|
526
|
+
var NodeSchema = z4.lazy(
|
|
527
|
+
() => z4.object({
|
|
528
|
+
id: z4.string().min(1, "Node ID must be a non-empty string"),
|
|
529
|
+
type: z4.string().min(1, "Node type must be a non-empty string"),
|
|
530
|
+
props: z4.record(z4.string(), z4.unknown()).optional().default({}),
|
|
384
531
|
styles: ResponsiveStylesSchema.optional().default({}),
|
|
385
532
|
animation: AnimationConfigSchema.optional(),
|
|
386
|
-
actions:
|
|
533
|
+
actions: z4.array(ActionPipelineSchema).optional(),
|
|
387
534
|
formConfig: FormConfigSchema.optional(),
|
|
388
|
-
children:
|
|
535
|
+
children: z4.array(NodeSchema).optional().default([])
|
|
389
536
|
})
|
|
390
537
|
);
|
|
391
538
|
var RootPageNodeSchema = NodeSchema.refine(
|
|
@@ -395,61 +542,64 @@ var RootPageNodeSchema = NodeSchema.refine(
|
|
|
395
542
|
path: ["type"]
|
|
396
543
|
}
|
|
397
544
|
);
|
|
398
|
-
var DocumentMetadataSchema =
|
|
399
|
-
title:
|
|
400
|
-
description:
|
|
401
|
-
author:
|
|
402
|
-
createdAt:
|
|
403
|
-
updatedAt:
|
|
404
|
-
tags:
|
|
405
|
-
category:
|
|
406
|
-
version:
|
|
407
|
-
custom:
|
|
545
|
+
var DocumentMetadataSchema = z4.object({
|
|
546
|
+
title: z4.string().min(1, "Title is required").default("Untitled Page"),
|
|
547
|
+
description: z4.string().optional().default(""),
|
|
548
|
+
author: z4.string().optional().default(""),
|
|
549
|
+
createdAt: z4.string().optional(),
|
|
550
|
+
updatedAt: z4.string().optional(),
|
|
551
|
+
tags: z4.array(z4.string()).optional().default([]),
|
|
552
|
+
category: z4.string().optional().default("general"),
|
|
553
|
+
version: z4.string().optional().default("1.0.0"),
|
|
554
|
+
custom: z4.record(z4.string(), z4.unknown()).optional(),
|
|
555
|
+
tracking: TrackingConfigSchema.optional()
|
|
408
556
|
});
|
|
409
|
-
var PageDocumentSchema =
|
|
410
|
-
schema:
|
|
411
|
-
version:
|
|
557
|
+
var PageDocumentSchema = z4.object({
|
|
558
|
+
schema: z4.literal(SCHEMA_NAME),
|
|
559
|
+
version: z4.string().min(1, "Schema version is required").default(CURRENT_SCHEMA_VERSION),
|
|
412
560
|
metadata: DocumentMetadataSchema.optional(),
|
|
561
|
+
tracking: TrackingConfigSchema.optional(),
|
|
413
562
|
document: RootPageNodeSchema
|
|
414
563
|
});
|
|
415
564
|
var PROJECT_SCHEMA_NAME = "stora.project";
|
|
416
565
|
var CURRENT_PROJECT_SCHEMA_VERSION = "1.0.0";
|
|
417
566
|
var ARTBOARD_REFERENCE_NODE_TYPE = "artboard-reference";
|
|
418
|
-
var ArtboardTypeSchema =
|
|
419
|
-
var ArtboardSchema =
|
|
420
|
-
id:
|
|
421
|
-
name:
|
|
567
|
+
var ArtboardTypeSchema = z4.enum(["page", "component"]);
|
|
568
|
+
var ArtboardSchema = z4.object({
|
|
569
|
+
id: z4.string().min(1, "Artboard ID is required"),
|
|
570
|
+
name: z4.string().min(1, "Artboard name is required"),
|
|
422
571
|
artboardType: ArtboardTypeSchema,
|
|
423
572
|
/** Route for page artboards (e.g. "/about"). */
|
|
424
|
-
slug:
|
|
573
|
+
slug: z4.string().optional(),
|
|
425
574
|
/**
|
|
426
575
|
* For component artboards: the id that `open_modal` / `close_modal` actions target.
|
|
427
576
|
* Mirrors the detached node's own `props.modalId` so ModalManager keeps working unchanged.
|
|
428
577
|
*/
|
|
429
|
-
triggerId:
|
|
578
|
+
triggerId: z4.string().optional(),
|
|
430
579
|
/**
|
|
431
580
|
* Viewport/breakpoint this artboard is currently authored at. Declared inline
|
|
432
581
|
* (rather than imported) because viewport is otherwise an editor/renderer concept.
|
|
433
582
|
*/
|
|
434
|
-
viewport:
|
|
583
|
+
viewport: z4.enum(["desktop", "tablet", "mobile"]).optional(),
|
|
435
584
|
/** Persisted artboard width in px, matching the canvas ViewportResizer's `width`. */
|
|
436
|
-
width:
|
|
585
|
+
width: z4.number().positive().optional(),
|
|
437
586
|
/**
|
|
438
587
|
* Free position on the builder's infinite canvas, in unscaled canvas px. Absent means
|
|
439
588
|
* "not placed yet" — the canvas then falls back to laying the artboard out in a row.
|
|
440
589
|
*/
|
|
441
|
-
position:
|
|
442
|
-
x:
|
|
443
|
-
y:
|
|
590
|
+
position: z4.object({
|
|
591
|
+
x: z4.number(),
|
|
592
|
+
y: z4.number()
|
|
444
593
|
}).optional(),
|
|
445
594
|
document: PageDocumentSchema
|
|
446
595
|
});
|
|
447
|
-
var ProjectDocumentSchema =
|
|
448
|
-
schema:
|
|
449
|
-
version:
|
|
596
|
+
var ProjectDocumentSchema = z4.object({
|
|
597
|
+
schema: z4.literal(PROJECT_SCHEMA_NAME),
|
|
598
|
+
version: z4.string().min(1, "Schema version is required").default(CURRENT_PROJECT_SCHEMA_VERSION),
|
|
450
599
|
metadata: DocumentMetadataSchema.optional(),
|
|
451
|
-
|
|
452
|
-
|
|
600
|
+
tracking: TrackingConfigSchema.optional(),
|
|
601
|
+
artboards: z4.array(ArtboardSchema).min(1, "A project needs at least one artboard"),
|
|
602
|
+
activeArtboardId: z4.string().optional()
|
|
453
603
|
});
|
|
454
604
|
function isAssetReference(value) {
|
|
455
605
|
return AssetReferenceSchema.safeParse(value).success;
|
|
@@ -505,30 +655,30 @@ function validateNodeIdUniqueness(node) {
|
|
|
505
655
|
}
|
|
506
656
|
|
|
507
657
|
// src/manifest.ts
|
|
508
|
-
import { z as
|
|
509
|
-
var ManifestAssetItemSchema =
|
|
510
|
-
id:
|
|
511
|
-
path:
|
|
512
|
-
mimeType:
|
|
513
|
-
size:
|
|
514
|
-
checksum:
|
|
658
|
+
import { z as z5 } from "zod";
|
|
659
|
+
var ManifestAssetItemSchema = z5.object({
|
|
660
|
+
id: z5.string().min(1, "Asset ID cannot be empty"),
|
|
661
|
+
path: z5.string().min(1, "Asset archive path cannot be empty"),
|
|
662
|
+
mimeType: z5.string().min(1, "MIME type cannot be empty"),
|
|
663
|
+
size: z5.number().nonnegative("Asset size must be non-negative"),
|
|
664
|
+
checksum: z5.string().optional()
|
|
515
665
|
});
|
|
516
|
-
var ManifestSchema =
|
|
517
|
-
schema:
|
|
518
|
-
schemaVersion:
|
|
519
|
-
packageVersion:
|
|
520
|
-
builderCompatibility:
|
|
521
|
-
requiredComponents:
|
|
522
|
-
requiredCapabilities:
|
|
523
|
-
assets:
|
|
524
|
-
createdAt:
|
|
666
|
+
var ManifestSchema = z5.object({
|
|
667
|
+
schema: z5.literal(SCHEMA_NAME).default(SCHEMA_NAME),
|
|
668
|
+
schemaVersion: z5.string().min(1, "Schema version cannot be empty").default("1.0.0"),
|
|
669
|
+
packageVersion: z5.string().min(1, "Package version cannot be empty").default("1.0.0"),
|
|
670
|
+
builderCompatibility: z5.string().default(">=0.1.0"),
|
|
671
|
+
requiredComponents: z5.array(z5.string()).default([]),
|
|
672
|
+
requiredCapabilities: z5.array(z5.string()).default([]),
|
|
673
|
+
assets: z5.array(ManifestAssetItemSchema).default([]),
|
|
674
|
+
createdAt: z5.string().optional()
|
|
525
675
|
});
|
|
526
676
|
function isManifest(value) {
|
|
527
677
|
return ManifestSchema.safeParse(value).success;
|
|
528
678
|
}
|
|
529
679
|
|
|
530
680
|
// src/template.ts
|
|
531
|
-
import { z as
|
|
681
|
+
import { z as z6 } from "zod";
|
|
532
682
|
var DANGEROUS_URI_PATTERN = /^(javascript:|vbscript:|data:(?!image\/))|<script/i;
|
|
533
683
|
function isSafeThumbnailUrl(url) {
|
|
534
684
|
if (!url || typeof url !== "string") return false;
|
|
@@ -537,49 +687,49 @@ function isSafeThumbnailUrl(url) {
|
|
|
537
687
|
if (DANGEROUS_URI_PATTERN.test(trimmed)) return false;
|
|
538
688
|
return true;
|
|
539
689
|
}
|
|
540
|
-
var SafeThumbnailUrlSchema =
|
|
690
|
+
var SafeThumbnailUrlSchema = z6.string().min(1, "Thumbnail URL cannot be empty").refine(
|
|
541
691
|
(url) => isSafeThumbnailUrl(url),
|
|
542
692
|
{ message: "Thumbnail URL contains an unsafe protocol or payload" }
|
|
543
693
|
);
|
|
544
|
-
var SafeThumbnailObjectSchema =
|
|
694
|
+
var SafeThumbnailObjectSchema = z6.object({
|
|
545
695
|
url: SafeThumbnailUrlSchema,
|
|
546
|
-
alt:
|
|
547
|
-
width:
|
|
548
|
-
height:
|
|
696
|
+
alt: z6.string().optional(),
|
|
697
|
+
width: z6.number().positive().optional(),
|
|
698
|
+
height: z6.number().positive().optional()
|
|
549
699
|
});
|
|
550
|
-
var SafeThumbnailSchema =
|
|
700
|
+
var SafeThumbnailSchema = z6.union([
|
|
551
701
|
AssetReferenceSchema,
|
|
552
702
|
SafeThumbnailObjectSchema,
|
|
553
703
|
SafeThumbnailUrlSchema
|
|
554
704
|
]);
|
|
555
|
-
var TemplatePackageRefSchema =
|
|
556
|
-
path:
|
|
705
|
+
var TemplatePackageRefSchema = z6.object({
|
|
706
|
+
path: z6.string().optional(),
|
|
557
707
|
url: SafeThumbnailUrlSchema.optional(),
|
|
558
|
-
checksum:
|
|
559
|
-
format:
|
|
708
|
+
checksum: z6.string().optional(),
|
|
709
|
+
format: z6.enum(["stora", "json"]).default("stora")
|
|
560
710
|
});
|
|
561
|
-
var TemplateRequirementsSchema =
|
|
562
|
-
requiredComponents:
|
|
563
|
-
requiredCapabilities:
|
|
711
|
+
var TemplateRequirementsSchema = z6.object({
|
|
712
|
+
requiredComponents: z6.array(z6.string()).default([]),
|
|
713
|
+
requiredCapabilities: z6.array(z6.string()).default([])
|
|
564
714
|
});
|
|
565
|
-
var TemplateRecordSchema =
|
|
566
|
-
id:
|
|
567
|
-
name:
|
|
568
|
-
description:
|
|
569
|
-
category:
|
|
570
|
-
tags:
|
|
715
|
+
var TemplateRecordSchema = z6.object({
|
|
716
|
+
id: z6.string().min(1, "Template ID must be a non-empty string"),
|
|
717
|
+
name: z6.string().min(1, "Template name must be a non-empty string"),
|
|
718
|
+
description: z6.string().optional().default(""),
|
|
719
|
+
category: z6.string().optional().default("general"),
|
|
720
|
+
tags: z6.array(z6.string()).optional().default([]),
|
|
571
721
|
thumbnail: SafeThumbnailSchema.optional(),
|
|
572
|
-
author:
|
|
573
|
-
version:
|
|
722
|
+
author: z6.string().optional().default(""),
|
|
723
|
+
version: z6.string().optional().default("1.0.0"),
|
|
574
724
|
document: PageDocumentSchema.optional(),
|
|
575
725
|
packageReference: TemplatePackageRefSchema.optional(),
|
|
576
726
|
requirements: TemplateRequirementsSchema.default({
|
|
577
727
|
requiredComponents: [],
|
|
578
728
|
requiredCapabilities: []
|
|
579
729
|
}),
|
|
580
|
-
createdAt:
|
|
581
|
-
updatedAt:
|
|
582
|
-
custom:
|
|
730
|
+
createdAt: z6.string().optional(),
|
|
731
|
+
updatedAt: z6.string().optional(),
|
|
732
|
+
custom: z6.record(z6.string(), z6.unknown()).optional()
|
|
583
733
|
});
|
|
584
734
|
function isTemplateRecord(value) {
|
|
585
735
|
return TemplateRecordSchema.safeParse(value).success;
|
|
@@ -1628,15 +1778,19 @@ export {
|
|
|
1628
1778
|
ConditionOperatorSchema,
|
|
1629
1779
|
CopyClipboardStepPayloadSchema,
|
|
1630
1780
|
CustomEventStepPayloadSchema,
|
|
1781
|
+
CustomTrackingProviderConfigSchema,
|
|
1631
1782
|
DEFAULT_ANIMATION_CONFIG,
|
|
1632
1783
|
DocumentMetadataSchema,
|
|
1633
1784
|
FORM_CONFIG_JSON_SCHEMA_V1,
|
|
1634
1785
|
FORM_FIELD_BINDING_JSON_SCHEMA_V1,
|
|
1635
1786
|
FormConfigSchema,
|
|
1636
1787
|
FormFieldBindingSchema,
|
|
1788
|
+
GoogleTrackingProviderConfigSchema,
|
|
1789
|
+
GtmTrackingProviderConfigSchema,
|
|
1637
1790
|
MANIFEST_JSON_SCHEMA_V1,
|
|
1638
1791
|
ManifestAssetItemSchema,
|
|
1639
1792
|
ManifestSchema,
|
|
1793
|
+
MetaTrackingProviderConfigSchema,
|
|
1640
1794
|
NavigateStepPayloadSchema,
|
|
1641
1795
|
NodeSchema,
|
|
1642
1796
|
OpenModalStepPayloadSchema,
|
|
@@ -1654,6 +1808,7 @@ export {
|
|
|
1654
1808
|
SafeThumbnailUrlSchema,
|
|
1655
1809
|
SetStateStepPayloadSchema,
|
|
1656
1810
|
ShowToastStepPayloadSchema,
|
|
1811
|
+
StandardTrackingEventSchema,
|
|
1657
1812
|
StepPayloadSchemas,
|
|
1658
1813
|
StyleDefinitionSchema,
|
|
1659
1814
|
StyleValueSchema,
|
|
@@ -1661,6 +1816,11 @@ export {
|
|
|
1661
1816
|
TemplatePackageRefSchema,
|
|
1662
1817
|
TemplateRecordSchema,
|
|
1663
1818
|
TemplateRequirementsSchema,
|
|
1819
|
+
TikTokTrackingProviderConfigSchema,
|
|
1820
|
+
TrackEventStepPayloadSchema,
|
|
1821
|
+
TrackingConfigSchema,
|
|
1822
|
+
TrackingDeliverySchema,
|
|
1823
|
+
TrackingProviderTypeSchema,
|
|
1664
1824
|
ValidateOnEventSchema,
|
|
1665
1825
|
ValidationRuleSchema,
|
|
1666
1826
|
ValidationRuleTypeSchema,
|
|
@@ -1691,6 +1851,8 @@ export {
|
|
|
1691
1851
|
isSafeThumbnail,
|
|
1692
1852
|
isSafeThumbnailUrl,
|
|
1693
1853
|
isTemplateRecord,
|
|
1854
|
+
isTrackEventStepPayload,
|
|
1855
|
+
isTrackingConfig,
|
|
1694
1856
|
isValidateOnEvent,
|
|
1695
1857
|
isValidationRule,
|
|
1696
1858
|
isValidationRuleType,
|