@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/index.js CHANGED
@@ -1,9 +1,154 @@
1
1
  // src/document.ts
2
- import { z as z3 } from "zod";
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 ActionTriggerTypeSchema = z.enum([
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 = z.enum([
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 = z.enum([
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 = z.object({
40
- field: z.string().min(1, "Condition field cannot be empty"),
185
+ var ActionStepConditionSchema = z2.object({
186
+ field: z2.string().min(1, "Condition field cannot be empty"),
41
187
  operator: ConditionOperatorSchema,
42
- value: z.unknown().optional()
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 = z.string().min(1, "URL cannot be empty").refine(isSafeActionUrl, {
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 = z.string().min(1, "Event name cannot be empty").regex(/^[a-zA-Z0-9_\-:]+$/, {
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 = z.object({
205
+ var ApiRequestStepPayloadSchema = z2.object({
60
206
  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()
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 = z.object({
216
+ var NavigateStepPayloadSchema = z2.object({
71
217
  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()
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 = 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")
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 = z.object({
83
- formId: z.string().optional()
228
+ var ResetFormStepPayloadSchema = z2.object({
229
+ formId: z2.string().optional()
84
230
  });
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()
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 = z.object({
94
- modalId: z.string().optional(),
95
- modalNodeId: z.string().optional(),
96
- toggle: z.boolean().optional()
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 = z.object({
101
- modalId: z.string().optional(),
102
- modalNodeId: z.string().optional()
246
+ var CloseModalStepPayloadSchema = z2.object({
247
+ modalId: z2.string().optional(),
248
+ modalNodeId: z2.string().optional()
103
249
  });
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()
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 = z.object({
256
+ var CustomEventStepPayloadSchema = z2.object({
111
257
  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)
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 = z.lazy(
128
- () => z.object({
129
- id: z.string().min(1, "Step ID cannot be empty"),
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: z.string().optional(),
132
- payload: z.record(z.string(), z.unknown()).optional().default({}),
278
+ label: z2.string().optional(),
279
+ payload: z2.record(z2.string(), z2.unknown()).optional().default({}),
133
280
  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()
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 = z.object({
141
- id: z.string().min(1, "Pipeline ID cannot be empty"),
287
+ var ActionPipelineSchema = z2.object({
288
+ id: z2.string().min(1, "Pipeline ID cannot be empty"),
142
289
  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")
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 z.ZodError([
319
+ error: new z2.ZodError([
173
320
  {
174
- code: z.ZodIssueCode.custom,
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 z2 } from "zod";
263
- var ValidationRuleTypeSchema = z2.enum([
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 = z2.enum(["blur", "change", "submit"]);
276
- var ValidationRuleSchema = z2.object({
422
+ var ValidateOnEventSchema = z3.enum(["blur", "change", "submit"]);
423
+ var ValidationRuleSchema = z3.object({
277
424
  type: ValidationRuleTypeSchema,
278
- value: z2.unknown().optional(),
279
- message: z2.string().min(1, "Validation error message cannot be empty")
425
+ value: z3.unknown().optional(),
426
+ message: z3.string().min(1, "Validation error message cannot be empty")
280
427
  });
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([]),
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: z2.enum(["trim", "lowercase", "uppercase", "number"]).optional(),
288
- disabled: z2.boolean().optional(),
289
- required: z2.boolean().optional()
434
+ transform: z3.enum(["trim", "lowercase", "uppercase", "number"]).optional(),
435
+ disabled: z3.boolean().optional(),
436
+ required: z3.boolean().optional()
290
437
  });
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),
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: z2.record(z2.string(), z2.unknown()).optional(),
297
- rules: z2.array(ValidationRuleSchema).optional()
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 = 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()
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 = z3.object({
326
- type: z3.literal("variable"),
327
- key: z3.string().min(1, "Variable key cannot be empty"),
328
- fallback: z3.unknown().optional()
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 = z3.object({
331
- type: z3.string().min(1, "Action type cannot be empty"),
332
- payload: z3.record(z3.string(), z3.unknown()).optional()
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 = z3.union([
336
- z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
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
- z3.number(),
340
- z3.boolean(),
341
- z3.null(),
342
- z3.undefined()
486
+ z4.number(),
487
+ z4.boolean(),
488
+ z4.null(),
489
+ z4.undefined()
343
490
  ]);
344
- var StyleDefinitionSchema = z3.record(z3.string(), StyleValueSchema);
345
- var PseudoStateStylesSchema = z3.record(z3.string(), StyleDefinitionSchema);
346
- var ResponsiveStylesSchema = z3.object({
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 = z3.object({
354
- type: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
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: 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), {
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: z3.boolean().optional().default(true),
363
- hoverEffect: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
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: z3.string().refine((value) => !DANGEROUS_STYLE_VALUE_PATTERN.test(value), {
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 = 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({}),
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: z3.array(ActionPipelineSchema).optional(),
533
+ actions: z4.array(ActionPipelineSchema).optional(),
387
534
  formConfig: FormConfigSchema.optional(),
388
- children: z3.array(NodeSchema).optional().default([])
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 = 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()
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 = z3.object({
410
- schema: z3.literal(SCHEMA_NAME),
411
- version: z3.string().min(1, "Schema version is required").default(CURRENT_SCHEMA_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 = 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"),
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: z3.string().optional(),
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: z3.string().optional(),
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: z3.enum(["desktop", "tablet", "mobile"]).optional(),
583
+ viewport: z4.enum(["desktop", "tablet", "mobile"]).optional(),
435
584
  /** Persisted artboard width in px, matching the canvas ViewportResizer's `width`. */
436
- width: z3.number().positive().optional(),
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: z3.object({
442
- x: z3.number(),
443
- y: z3.number()
590
+ position: z4.object({
591
+ x: z4.number(),
592
+ y: z4.number()
444
593
  }).optional(),
445
594
  document: PageDocumentSchema
446
595
  });
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),
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
- artboards: z3.array(ArtboardSchema).min(1, "A project needs at least one artboard"),
452
- activeArtboardId: z3.string().optional()
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 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()
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 = 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()
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 z5 } from "zod";
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 = z5.string().min(1, "Thumbnail URL cannot be empty").refine(
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 = z5.object({
694
+ var SafeThumbnailObjectSchema = z6.object({
545
695
  url: SafeThumbnailUrlSchema,
546
- alt: z5.string().optional(),
547
- width: z5.number().positive().optional(),
548
- height: z5.number().positive().optional()
696
+ alt: z6.string().optional(),
697
+ width: z6.number().positive().optional(),
698
+ height: z6.number().positive().optional()
549
699
  });
550
- var SafeThumbnailSchema = z5.union([
700
+ var SafeThumbnailSchema = z6.union([
551
701
  AssetReferenceSchema,
552
702
  SafeThumbnailObjectSchema,
553
703
  SafeThumbnailUrlSchema
554
704
  ]);
555
- var TemplatePackageRefSchema = z5.object({
556
- path: z5.string().optional(),
705
+ var TemplatePackageRefSchema = z6.object({
706
+ path: z6.string().optional(),
557
707
  url: SafeThumbnailUrlSchema.optional(),
558
- checksum: z5.string().optional(),
559
- format: z5.enum(["stora", "json"]).default("stora")
708
+ checksum: z6.string().optional(),
709
+ format: z6.enum(["stora", "json"]).default("stora")
560
710
  });
561
- var TemplateRequirementsSchema = z5.object({
562
- requiredComponents: z5.array(z5.string()).default([]),
563
- requiredCapabilities: z5.array(z5.string()).default([])
711
+ var TemplateRequirementsSchema = z6.object({
712
+ requiredComponents: z6.array(z6.string()).default([]),
713
+ requiredCapabilities: z6.array(z6.string()).default([])
564
714
  });
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([]),
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: z5.string().optional().default(""),
573
- version: z5.string().optional().default("1.0.0"),
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: z5.string().optional(),
581
- updatedAt: z5.string().optional(),
582
- custom: z5.record(z5.string(), z5.unknown()).optional()
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,