@nordcraft/core 1.0.75 → 1.0.76

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.
Files changed (62) hide show
  1. package/README.md +5 -1
  2. package/dist/api/LegacyToddleApi.d.ts +17 -16
  3. package/dist/api/LegacyToddleApi.js.map +1 -1
  4. package/dist/api/ToddleApiV2.d.ts +46 -45
  5. package/dist/api/ToddleApiV2.js.map +1 -1
  6. package/dist/api/api.d.ts +16 -15
  7. package/dist/api/api.js +3 -3
  8. package/dist/api/api.js.map +1 -1
  9. package/dist/api/apiTypes.d.ts +68 -68
  10. package/dist/api/headers.d.ts +6 -5
  11. package/dist/api/headers.js.map +1 -1
  12. package/dist/component/ToddleComponent.d.ts +11 -11
  13. package/dist/component/ToddleComponent.js +2 -2
  14. package/dist/component/ToddleComponent.js.map +1 -1
  15. package/dist/component/actionUtils.d.ts +2 -2
  16. package/dist/component/actionUtils.js +1 -0
  17. package/dist/component/actionUtils.js.map +1 -1
  18. package/dist/component/component.types.d.ts +140 -140
  19. package/dist/component/component.types.js.map +1 -1
  20. package/dist/component/schemas/zod-schemas.d.ts +4 -0
  21. package/dist/component/schemas/zod-schemas.js +1106 -0
  22. package/dist/component/schemas/zod-schemas.js.map +1 -0
  23. package/dist/formula/formula.d.ts +14 -14
  24. package/dist/formula/formula.js +1 -1
  25. package/dist/formula/formula.js.map +1 -1
  26. package/dist/formula/formulaTypes.d.ts +10 -9
  27. package/dist/formula/formulaUtils.d.ts +11 -10
  28. package/dist/formula/formulaUtils.js +8 -2
  29. package/dist/formula/formulaUtils.js.map +1 -1
  30. package/dist/styling/customProperty.d.ts +2 -1
  31. package/dist/styling/customProperty.js.map +1 -1
  32. package/dist/styling/style.css.js +2 -2
  33. package/dist/styling/style.css.js.map +1 -1
  34. package/dist/styling/theme.d.ts +3 -2
  35. package/dist/styling/theme.js.map +1 -1
  36. package/dist/styling/variantSelector.d.ts +36 -35
  37. package/dist/styling/variantSelector.js.map +1 -1
  38. package/dist/types.d.ts +16 -15
  39. package/dist/utils/collections.d.ts +2 -1
  40. package/dist/utils/collections.js.map +1 -1
  41. package/dist/utils/getNodeSelector.d.ts +4 -3
  42. package/dist/utils/getNodeSelector.js.map +1 -1
  43. package/package.json +4 -1
  44. package/src/api/LegacyToddleApi.ts +2 -1
  45. package/src/api/ToddleApiV2.ts +2 -1
  46. package/src/api/api.ts +10 -9
  47. package/src/api/apiTypes.ts +73 -70
  48. package/src/api/headers.ts +7 -5
  49. package/src/component/ToddleComponent.ts +2 -2
  50. package/src/component/actionUtils.ts +3 -2
  51. package/src/component/component.types.ts +136 -131
  52. package/src/component/schemas/zod-schemas.ts +1535 -0
  53. package/src/formula/formula.ts +21 -18
  54. package/src/formula/formulaTypes.ts +12 -9
  55. package/src/formula/formulaUtils.ts +20 -13
  56. package/src/styling/customProperty.ts +2 -1
  57. package/src/styling/style.css.ts +6 -3
  58. package/src/styling/theme.ts +3 -2
  59. package/src/styling/variantSelector.ts +36 -35
  60. package/src/types.ts +27 -15
  61. package/src/utils/collections.ts +2 -1
  62. package/src/utils/getNodeSelector.ts +4 -3
@@ -0,0 +1,1106 @@
1
+ /* eslint-disable inclusive-language/use-inclusive-words */
2
+ import { z } from 'zod';
3
+ const generalDescriptions = {
4
+ animations: (type) => `Animations defined on this ${type}`,
5
+ animationKey: `Unique key identifying the animation. This should be globally unique. Prefix with the name of the file to ensure uniqueness. Fx "myComponent-fadeIn"`,
6
+ animationKeyframeKey: `Unique key identifying the keyframe`,
7
+ apis: (type) => `All APIs defined in the ${type}. APIs are used to fetch data from external services or backend systems. They can be called via actions and their data can be used in formulas.`,
8
+ children: `A list of child node IDs. Every ID must correspond to a node defined in the "nodes" object of the component/page that includes this component node.`,
9
+ condition: (type) => `Formula evaluating to whether this ${type} is rendered or not. If false, undefined or null the ${type} is not rendered. Any other value means the ${type} is rendered.`,
10
+ formulas: (type) => `All formulas defined in the ${type}. Formulas are used to compute dynamic values based on variables, inputs, or other data.`,
11
+ metadata: (type) => `Metadata associated with this ${type}. This can include comments and other information useful for understanding the ${type}.`,
12
+ onAttributeChange: (type) => `Lifecycle event that is triggered when any of the ${type} attributes change. Declared actions will be executed in response to attribute changes, allowing the ${type} to react dynamically to different configurations.`,
13
+ onLoad: (type) => `Lifecycle event that is triggered when the ${type} is loaded. Declared actions will be executed when the ${type} loads, such as initializing variables or fetching data.`,
14
+ repeat: (type) => `Formula evaluating to an array of items to repeat this ${type} for.`,
15
+ repeatKey: (type) => `A Formula evaluating to a unique key for each repeated item. This is important for ensuring that the ${type} instances are correctly identified and managed during re-renders. This is rarely needed for simple arrays but is critical when rendering complex objects or when the array items can change dynamically.`,
16
+ slot: (type) => `Slot name for when this ${type} is rendered inside a component. Slot name must match the slot defined in the parent component. The default slot name is: "default".`,
17
+ style: (type) => `This is the default style for this ${type}.`,
18
+ testData: (type) => `Test value for the ${type}. Test data is only used while building in the Nordcraft editor.`,
19
+ variables: (type) => `All variables defined in the ${type}. Variables hold dynamic data that can be used throughout the ${type} via formulas. They can be updated via actions.`,
20
+ variants: (type) => `Style variants defined on this ${type}. This could be a variant for hover, active, focus, media queries, or other state-based styles. Or even based on a class.`,
21
+ workflows: (type) => `All workflows defined in the ${type}. Workflows are sequences of actions that can be triggered by events or other workflows. They define the behavior of the ${type}.`,
22
+ };
23
+ // Base metadata schema used throughout
24
+ const MetadataSchema = z
25
+ .object({
26
+ comments: z
27
+ .record(z.string(), z.object({
28
+ index: z.number(),
29
+ text: z.string(),
30
+ }))
31
+ .nullable(),
32
+ })
33
+ .nullable();
34
+ // Value Operation
35
+ const ValueOperationValueSchema = z.union([
36
+ z.string(),
37
+ z.number(),
38
+ z.boolean(),
39
+ z.null(),
40
+ z.object({}),
41
+ ]);
42
+ const ValueOperationSchema = z.object({
43
+ '@nordcraft/metadata': MetadataSchema.optional()
44
+ .nullable()
45
+ .describe(generalDescriptions.metadata('value operation')),
46
+ type: z.literal('value'),
47
+ value: ValueOperationValueSchema.describe('Literal value.'),
48
+ });
49
+ // Path Operation
50
+ const PathOperationSchema = z.object({
51
+ '@nordcraft/metadata': MetadataSchema.optional()
52
+ .nullable()
53
+ .describe(generalDescriptions.metadata('path operation')),
54
+ type: z.literal('path'),
55
+ path: z
56
+ .array(z.string())
57
+ .describe('Path segments for the path operation. Each segment is a string that corresponds to a property name or array index in the Data object passed to the system prompt.'),
58
+ });
59
+ // Formula argument base
60
+ const FormulaArgumentSchema = z
61
+ .object({
62
+ get formula() {
63
+ return FormulaSchema.describe('Formula for the argument.');
64
+ },
65
+ isFunction: z
66
+ .boolean()
67
+ .optional()
68
+ .nullable()
69
+ .describe('Whether the argument is a function. This will be true on array formulas like map, filter, reduce, etc. formulas.'),
70
+ name: z
71
+ .string()
72
+ .describe('The name of the argument. This name corresponds to the argument name from the formula definition.'),
73
+ })
74
+ .describe('Argument for formulas in Nordcraft formulas.');
75
+ // Array Operation
76
+ const ArrayOperationSchema = z
77
+ .object({
78
+ '@nordcraft/metadata': MetadataSchema.optional()
79
+ .nullable()
80
+ .describe(generalDescriptions.metadata('array operation')),
81
+ type: z.literal('array'),
82
+ get arguments() {
83
+ return z
84
+ .array(z.object({ formula: FormulaSchema }))
85
+ .describe('List of formulas for the array elements.');
86
+ },
87
+ })
88
+ .describe('Model for describing an array in Nordcraft formulas.');
89
+ // Object Operation
90
+ const ObjectOperationSchema = z
91
+ .object({
92
+ '@nordcraft/metadata': MetadataSchema.optional()
93
+ .nullable()
94
+ .describe(generalDescriptions.metadata('object operation')),
95
+ type: z.literal('object'),
96
+ get arguments() {
97
+ return z
98
+ .array(FormulaArgumentSchema)
99
+ .optional()
100
+ .nullable()
101
+ .describe('List of key-value pairs for the object. Each entry must have a name and a formula.');
102
+ },
103
+ })
104
+ .describe('Model for describing an object in Nordcraft formulas.');
105
+ // Record Operation
106
+ const RecordOperationSchema = z
107
+ .object({
108
+ '@nordcraft/metadata': MetadataSchema.optional().nullable(),
109
+ type: z.literal('record'),
110
+ get entries() {
111
+ return z.array(FormulaArgumentSchema);
112
+ },
113
+ label: z.string().optional().nullable(),
114
+ })
115
+ .describe('Deprecated - use Object operation instead.');
116
+ // And Operation
117
+ const AndOperationSchema = z
118
+ .object({
119
+ '@nordcraft/metadata': MetadataSchema.optional()
120
+ .nullable()
121
+ .describe(generalDescriptions.metadata('AND operation')),
122
+ type: z.literal('and'),
123
+ get arguments() {
124
+ return z
125
+ .array(z.object({ formula: FormulaSchema }))
126
+ .describe('List of formulas to evaluate in the AND operation. All formulas must evaluate to a truthy value for the AND operation to return true.');
127
+ },
128
+ })
129
+ .describe('Model for describing a logical AND operation. The return value is a boolean value.');
130
+ // Or Operation
131
+ const OrOperationSchema = z
132
+ .object({
133
+ '@nordcraft/metadata': MetadataSchema.optional()
134
+ .nullable()
135
+ .describe(generalDescriptions.metadata('OR operation')),
136
+ type: z.literal('or'),
137
+ get arguments() {
138
+ return z
139
+ .array(z.object({ formula: FormulaSchema }))
140
+ .describe('List of formulas to evaluate in the OR operation. At least one formula must evaluate to a truthy value for the OR operation to return true.');
141
+ },
142
+ })
143
+ .describe('Model for describing a logical OR operation. The return value is a boolean value.');
144
+ // Switch Operation
145
+ const SwitchOperationSchema = z
146
+ .object({
147
+ '@nordcraft/metadata': MetadataSchema.optional().nullable(),
148
+ type: z.literal('switch'),
149
+ cases: z
150
+ .array(z.object({
151
+ get condition() {
152
+ return z
153
+ .lazy(() => FormulaSchema)
154
+ .describe('Condition to evaluate for this case. If truthy, the formula is used.');
155
+ },
156
+ get formula() {
157
+ return z
158
+ .lazy(() => FormulaSchema)
159
+ .describe('Formula to use if the condition is met.');
160
+ },
161
+ }))
162
+ .length(1)
163
+ .describe('Cases for the switch operation. Each case has a condition and a formula. The length of cases cannot exceed 1 at this time as the UI does not currently support this.'),
164
+ get default() {
165
+ return FormulaSchema.describe('Default formula if no case matches.');
166
+ },
167
+ })
168
+ .describe('Model for describing a switch operation. A switch operation allows branching logic based on conditions.');
169
+ // Project Function Operation
170
+ const ProjectFunctionOperationSchema = z
171
+ .object({
172
+ '@nordcraft/metadata': MetadataSchema.optional()
173
+ .nullable()
174
+ .describe(generalDescriptions.metadata('project formula operation')),
175
+ type: z.literal('function'),
176
+ name: z
177
+ .string()
178
+ .describe('Key of the project formula to be called. This must match the key of the project formulas passed to the system prompt.'),
179
+ get arguments() {
180
+ return z.array(FormulaArgumentSchema).describe('Formula arguments.');
181
+ },
182
+ })
183
+ .describe('Model for describing a Project Formula operation. A Project Formula is a user-defined formula that can be reused across the project.');
184
+ // Built-in Function Operation
185
+ const BuiltInFunctionOperationSchema = z.object({
186
+ '@nordcraft/metadata': MetadataSchema.optional()
187
+ .nullable()
188
+ .describe(generalDescriptions.metadata('built-in formula operation')),
189
+ type: z.literal('function'),
190
+ name: z
191
+ .string()
192
+ .describe('Key of the built-in formula to be called. This key is always prefixed with "@toddle/" and can be read from the built-in formula definition.'),
193
+ get arguments() {
194
+ return z.array(FormulaArgumentSchema).describe('Formula arguments.');
195
+ },
196
+ display_name: z
197
+ .string()
198
+ .nullable()
199
+ .describe('Human readable label for the operation. This should be set from the "name" read from the built-in formula definition.'),
200
+ variableArguments: z
201
+ .boolean()
202
+ .optional()
203
+ .nullable()
204
+ .describe('Field defining if the formula accepts variable number of arguments. This value is read from the built-in formula definition.'),
205
+ });
206
+ // Apply Operation
207
+ const ApplyOperationSchema = z
208
+ .object({
209
+ '@nordcraft/metadata': MetadataSchema.optional()
210
+ .nullable()
211
+ .describe(generalDescriptions.formulas('apply operation')),
212
+ type: z.literal('apply'),
213
+ name: z
214
+ .string()
215
+ .describe('Key of the formula to be applied. This is the key defined in the formulas object found in the same file.'),
216
+ arguments: z
217
+ .array(FormulaArgumentSchema)
218
+ .describe('Arguments to pass to the formula being applied.'),
219
+ })
220
+ .describe('Model for describing an Apply operation. An apply operation is used when a formula wants to run another formula defined in the same file.');
221
+ // Formula - union of all operation types
222
+ const FormulaSchema = z.lazy(() => z.union([
223
+ BuiltInFunctionOperationSchema,
224
+ ProjectFunctionOperationSchema,
225
+ RecordOperationSchema,
226
+ ObjectOperationSchema,
227
+ ArrayOperationSchema,
228
+ PathOperationSchema,
229
+ SwitchOperationSchema,
230
+ OrOperationSchema,
231
+ AndOperationSchema,
232
+ ValueOperationSchema,
233
+ ApplyOperationSchema,
234
+ ]));
235
+ // Event Model
236
+ const EventModelSchema = z
237
+ .lazy(() => z.object({
238
+ trigger: z
239
+ .string()
240
+ .describe('Name of the event trigger. Nordcraft does not prefix events with "on", fx a click event is just called: "click".'),
241
+ actions: z
242
+ .array(ActionModelSchema)
243
+ .describe('List of actions to execute.'),
244
+ }))
245
+ .describe('Model describing an event. Events are used to define actions that should be executed in response to specific triggers, such as user interactions or lifecycle events.');
246
+ // Action Models
247
+ const VariableActionModelSchema = z
248
+ .object({
249
+ type: z.literal('SetVariable'),
250
+ variable: z.string().describe('Name of the variable to be set.'),
251
+ data: FormulaSchema.describe('Formula evaluating to the new variable value.'),
252
+ })
253
+ .describe('Model describing the action of setting a variable.');
254
+ const EventActionModelSchema = z
255
+ .object({
256
+ type: z.literal('TriggerEvent'),
257
+ event: z.string().describe('Name of the event to be triggered.'),
258
+ data: FormulaSchema.describe('Data to pass to the event being triggered.'),
259
+ })
260
+ .describe('Model describing the action of triggering an event. This is only relevant on components as they are the only entities that can have events defined.');
261
+ const SwitchActionModelSchema = z
262
+ .object({
263
+ type: z.literal('Switch'),
264
+ cases: z
265
+ .array(z.object({
266
+ condition: FormulaSchema.describe('Condition to evaluate for this case. If truthy the actions are executed.'),
267
+ actions: z
268
+ .array(z.lazy(() => ActionModelSchema))
269
+ .describe('List of actions to execute if the condition is met.'),
270
+ }))
271
+ .describe('Cases for the switch action. Each case has a condition and actions.'),
272
+ default: z
273
+ .object({
274
+ actions: z.array(z.lazy(() => ActionModelSchema)),
275
+ })
276
+ .describe('Actions to execute if no case conditions are met.'),
277
+ })
278
+ .describe('Model describing a switch action. A switch action allows branching logic based on conditions.');
279
+ const FetchActionModelSchema = z
280
+ .object({
281
+ type: z.literal('Fetch'),
282
+ api: z
283
+ .string()
284
+ .describe('Key of the API to fetch data from. This is the key defined in the APIs object in the file.'),
285
+ inputs: z
286
+ .record(z.string().describe('Name of the API input.'), z.object({
287
+ formula: FormulaSchema.nullable().describe('Formula for the input.'),
288
+ }))
289
+ .describe('Inputs overriding the default input values for the API. Available inputs are defined as part of the API definition.'),
290
+ onSuccess: z
291
+ .object({
292
+ actions: z.array(z.lazy(() => ActionModelSchema)),
293
+ })
294
+ .describe('Actions to execute when the fetch is successful.'),
295
+ onError: z
296
+ .object({
297
+ actions: z.array(z.lazy(() => ActionModelSchema)),
298
+ })
299
+ .describe('Actions to execute when the fetch fails.'),
300
+ onMessage: z
301
+ .object({
302
+ actions: z.array(z.lazy(() => ActionModelSchema)),
303
+ })
304
+ .optional()
305
+ .nullable()
306
+ .describe('Actions to execute when a message is received during streaming.'),
307
+ })
308
+ .describe('Model describing the action of fetching data from an API.');
309
+ const CustomActionModelSchema = z
310
+ .object({
311
+ type: z.literal('Custom'),
312
+ name: z.string().describe('Name of the custom action to be executed.'),
313
+ package: z
314
+ .string()
315
+ .optional()
316
+ .nullable()
317
+ .describe('Package where the custom action is defined. Should not be set for local custom actions.'),
318
+ arguments: z
319
+ .array(z.object({
320
+ name: z.string().describe('Name of the argument.'),
321
+ formula: FormulaSchema.describe('Formula evaluating to the argument value.'),
322
+ }))
323
+ .optional()
324
+ .nullable()
325
+ .describe('Arguments to pass to the custom action.'),
326
+ events: z
327
+ .record(z.string().describe('Name of the event.'), z
328
+ .object({
329
+ actions: z
330
+ .array(z.lazy(() => ActionModelSchema))
331
+ .describe('List of actions to execute when the event is triggered.'),
332
+ })
333
+ .describe('Record with one entry called "actions" which is a list of actions to execute when the event is triggered..'))
334
+ .optional()
335
+ .nullable()
336
+ .describe('Record of events defined in the custom action. Each event has a list of actions to execute when the event is emitted.'),
337
+ version: z
338
+ .literal(2)
339
+ .optional()
340
+ .nullable()
341
+ .describe('Version of the custom action model. This should always be 2.'),
342
+ })
343
+ .describe('Model describing the action of a custom action. A custom action is a user-defined action that can be reused across the project. A list of available custom actions has been provided as part of the system prompt.');
344
+ const BuiltInActionModelSchema = z
345
+ .object({
346
+ name: z
347
+ .string()
348
+ .describe('Name of the built-in action. This will always be prefixed with "@toddle/" and should match the action key in the system.'),
349
+ arguments: z
350
+ .array(z.object({
351
+ name: z.string().describe('Name of the argument.'),
352
+ formula: FormulaSchema.describe('Formula evaluating to the argument value.'),
353
+ }))
354
+ .optional()
355
+ .nullable()
356
+ .describe('Arguments to pass to the built-in action.'),
357
+ events: z
358
+ .record(z.string().describe('Name of the event.'), z
359
+ .object({
360
+ actions: z.array(z.lazy(() => ActionModelSchema)),
361
+ })
362
+ .describe('List of actions to execute when the event is triggered.'))
363
+ .optional()
364
+ .nullable()
365
+ .describe('Events that can be triggered by the built-in action. Common events include onSuccess and onError.'),
366
+ label: z
367
+ .string()
368
+ .describe('Label for the built-in action. This label will be used in the UI.'),
369
+ })
370
+ .describe('Model describing a built-in action provided by the Nordcraft system. Built-in actions are pre-defined actions that can be used to perform common tasks within a Nordcraft project.');
371
+ const SetURLParameterActionSchema = z
372
+ .object({
373
+ type: z.literal('SetURLParameter'),
374
+ parameter: z.string(),
375
+ data: FormulaSchema,
376
+ historyMode: z.enum(['replace', 'push']).nullable().optional().nullable(),
377
+ })
378
+ .describe('This model is deprecated. Instead refer to SetMultiUrlParameterActionSchema.');
379
+ const SetMultiUrlParameterActionSchema = z
380
+ .object({
381
+ type: z.literal('SetURLParameters'),
382
+ parameters: z
383
+ .record(z.string(), FormulaSchema)
384
+ .describe('Record of URL parameters to set, where the key is the parameter name and the value is a formula evaluating to the parameter value.'),
385
+ historyMode: z
386
+ .enum(['replace', 'push'])
387
+ .nullable()
388
+ .optional()
389
+ .nullable()
390
+ .describe('This determines how the URL is updated in the browser history. Use "replace" to update the current history entry without adding a new one, or "push" to create a new history entry for the URL change. If not specified, the default behavior is to use "push".'),
391
+ })
392
+ .describe('Model describing the action of setting multiple URL parameters. Use this action to update any number (1-*) of URL parameter(s) in one go.');
393
+ const WorkflowActionModelSchema = z
394
+ .object({
395
+ type: z.literal('TriggerWorkflow'),
396
+ workflow: z.string().describe('ID of the workflow to be triggered.'),
397
+ parameters: z
398
+ .record(z.string().describe('Name of the workflow parameter.'), z
399
+ .object({
400
+ formula: FormulaSchema,
401
+ })
402
+ .describe('Formula evaluating to the parameter value.'))
403
+ .describe('Parameters to pass to the workflow being triggered. '),
404
+ contextProvider: z
405
+ .string()
406
+ .optional()
407
+ .nullable()
408
+ .describe('If the workflow being triggered is from a parent component and exposed via a context provider, this is the ID of that context provider.'),
409
+ })
410
+ .describe('Model describing the action of triggering a workflow.');
411
+ const ActionModelSchema = z.lazy(() => z.union([
412
+ VariableActionModelSchema,
413
+ EventActionModelSchema,
414
+ SwitchActionModelSchema,
415
+ FetchActionModelSchema,
416
+ CustomActionModelSchema,
417
+ SetURLParameterActionSchema,
418
+ SetMultiUrlParameterActionSchema,
419
+ WorkflowActionModelSchema,
420
+ BuiltInActionModelSchema,
421
+ ]));
422
+ // Style and Animation
423
+ const NodeStyleModelSchema = z.record(z.string(), z.string());
424
+ const AnimationKeyframeSchema = z.object({
425
+ position: z
426
+ .number()
427
+ .describe("Value between 0 and 1 representing the keyframe's position in the animation"),
428
+ key: z.string().describe('CSS property to be animated'),
429
+ value: z.string().describe('Value of the CSS property at this keyframe'),
430
+ });
431
+ const StyleTokenCategorySchema = z.enum([
432
+ 'spacing',
433
+ 'color',
434
+ 'font-size',
435
+ 'font-weight',
436
+ 'z-index',
437
+ 'border-radius',
438
+ 'shadow',
439
+ ]);
440
+ const StyleVariantSchema = z.object({
441
+ style: NodeStyleModelSchema,
442
+ id: z.string().optional().nullable(),
443
+ className: z.string().optional().nullable(),
444
+ hover: z.boolean().optional().nullable(),
445
+ active: z.boolean().optional().nullable(),
446
+ focus: z.boolean().optional().nullable(),
447
+ focusWithin: z.boolean().optional().nullable(),
448
+ disabled: z.boolean().optional().nullable(),
449
+ empty: z.boolean().optional().nullable(),
450
+ firstChild: z.boolean().optional().nullable(),
451
+ lastChild: z.boolean().optional().nullable(),
452
+ evenChild: z.boolean().optional().nullable(),
453
+ startingStyle: z.boolean().optional().nullable(),
454
+ mediaQuery: z
455
+ .object({
456
+ 'min-width': z.string().optional().nullable(),
457
+ 'max-width': z.string().optional().nullable(),
458
+ 'min-height': z.string().optional().nullable(),
459
+ 'max-height': z.string().optional().nullable(),
460
+ })
461
+ .optional()
462
+ .nullable(),
463
+ });
464
+ // Node Models
465
+ const TextNodeModelSchema = z
466
+ .object({
467
+ type: z.literal('text'),
468
+ value: FormulaSchema.describe('Formula evaluating to the text content.'),
469
+ condition: FormulaSchema.optional()
470
+ .nullable()
471
+ .describe(generalDescriptions.condition('text node')),
472
+ repeat: FormulaSchema.optional()
473
+ .nullable()
474
+ .describe(generalDescriptions.repeat('text node')),
475
+ repeatKey: FormulaSchema.optional()
476
+ .nullable()
477
+ .describe(generalDescriptions.repeatKey('text node')),
478
+ slot: z
479
+ .string()
480
+ .optional()
481
+ .nullable()
482
+ .describe(generalDescriptions.slot('text node')),
483
+ })
484
+ .describe('Schema defining a Text Node Model. A text node represents text content inside of an element.');
485
+ const SlotNodeModelSchema = z
486
+ .object({
487
+ type: z.literal('slot'),
488
+ children: z
489
+ .array(z.string())
490
+ .describe(`${generalDescriptions.children}. These are the default child nodes for the slot. If no content is passed to the slot when used inside a component, these default child nodes will be rendered.`),
491
+ name: z
492
+ .string()
493
+ .optional()
494
+ .nullable()
495
+ .describe('Name of the slot. This is the name that must be used when passing content to this slot.'),
496
+ condition: FormulaSchema.optional()
497
+ .nullable()
498
+ .describe(generalDescriptions.condition('slot node')),
499
+ slot: z
500
+ .string()
501
+ .optional()
502
+ .nullable()
503
+ .describe(generalDescriptions.slot('slot node')),
504
+ })
505
+ .describe('Schema defining a Slot Node Model. A slot is a placeholder for child nodes. Slot nodes can only exist inside components.');
506
+ const ElementNodeModelSchema = z
507
+ .object({
508
+ type: z.literal('element'),
509
+ tag: z
510
+ .string()
511
+ .describe('The HTML tag of the element node, such as "div", "span", "img", "a", etc.'),
512
+ attrs: z
513
+ .record(z.string(), FormulaSchema)
514
+ .describe('Attributes of the element node such as "src", "alt", "href", or any other attribute that is applicable to the corresponding HTML element.'),
515
+ style: NodeStyleModelSchema.describe(generalDescriptions.style('element node')),
516
+ children: z.array(z.string()).describe(generalDescriptions.children),
517
+ events: z
518
+ .record(z.string(), EventModelSchema)
519
+ .describe('Events on the element node such as "click", "hover", or any other event that is applicable to the corresponding HTML element.'),
520
+ classes: z
521
+ .record(z.string().describe('The class name'), z
522
+ .object({ formula: FormulaSchema.optional().nullable() })
523
+ .describe('Formula that will determine when the class is applied. The class is applied when the formula is truthy.'))
524
+ .describe('Classes applied to this element node.'),
525
+ 'style-variables': z
526
+ .array(z.object({
527
+ category: StyleTokenCategorySchema.describe('Category of the style token.'),
528
+ name: z.string().describe('Name of the style token.'),
529
+ formula: FormulaSchema.describe('Formula defining the value of the token.'),
530
+ unit: z
531
+ .string()
532
+ .optional()
533
+ .nullable()
534
+ .describe('Unit of the style token, if applicable.'),
535
+ }))
536
+ .optional()
537
+ .nullable()
538
+ .describe('Style variables defined on this element node. Style variables can be used to define design tokens such as colors, spacing, font sizes, and other reusable style values.'),
539
+ condition: FormulaSchema.optional()
540
+ .nullable()
541
+ .describe(generalDescriptions.condition('element node')),
542
+ repeat: FormulaSchema.optional()
543
+ .nullable()
544
+ .describe(generalDescriptions.repeat('element node')),
545
+ repeatKey: FormulaSchema.optional()
546
+ .nullable()
547
+ .describe(generalDescriptions.repeatKey('element node')),
548
+ slot: z
549
+ .string()
550
+ .optional()
551
+ .nullable()
552
+ .describe(generalDescriptions.slot('element node')),
553
+ variants: z
554
+ .array(StyleVariantSchema)
555
+ .optional()
556
+ .nullable()
557
+ .describe(generalDescriptions.variants('element node')),
558
+ animations: z
559
+ .record(z.string().describe(generalDescriptions.animationKey), z.record(z.string().describe(generalDescriptions.animationKeyframeKey), AnimationKeyframeSchema))
560
+ .optional()
561
+ .nullable()
562
+ .describe(generalDescriptions.animations('element node')),
563
+ })
564
+ .describe('Schema defining an Element Node Model. An element is a standard HTML element.');
565
+ const ComponentNodeModelSchema = z
566
+ .object({
567
+ type: z.literal('component'),
568
+ name: z.string().describe('Name of the component to render.'),
569
+ package: z
570
+ .string()
571
+ .optional()
572
+ .nullable()
573
+ .describe('Name of the package this component comes from. If empty, it is a component defined in the current project.'),
574
+ attrs: z
575
+ .record(z.string().describe('The name of the attribute'), FormulaSchema.describe('Formula evaluating to the value of the attribute'))
576
+ .describe('Attributes/props passed to the component.'),
577
+ children: z.array(z.string()).describe(generalDescriptions.children),
578
+ events: z
579
+ .record(z.string(), EventModelSchema)
580
+ .describe('Record of events passed to the component. Only custom events defined by the component can be passed here.'),
581
+ style: NodeStyleModelSchema.optional()
582
+ .nullable()
583
+ .describe(generalDescriptions.style('component node')),
584
+ condition: FormulaSchema.optional()
585
+ .nullable()
586
+ .describe(generalDescriptions.condition('component node')),
587
+ repeat: FormulaSchema.optional()
588
+ .nullable()
589
+ .describe(generalDescriptions.repeat('component node')),
590
+ repeatKey: FormulaSchema.optional()
591
+ .nullable()
592
+ .describe(generalDescriptions.repeatKey('component node')),
593
+ slot: z
594
+ .string()
595
+ .optional()
596
+ .nullable()
597
+ .describe(generalDescriptions.slot('component node')),
598
+ variants: z
599
+ .array(StyleVariantSchema)
600
+ .optional()
601
+ .nullable()
602
+ .describe(generalDescriptions.variants('component node')),
603
+ animations: z
604
+ .record(z.string().describe(generalDescriptions.animationKey), z.record(z.string().describe(generalDescriptions.animationKeyframeKey), AnimationKeyframeSchema))
605
+ .optional()
606
+ .nullable()
607
+ .describe(generalDescriptions.animations('component node')),
608
+ })
609
+ .describe('Schema defining a Component Node Model.');
610
+ const NodeModelSchema = z.lazy(() => z.union([
611
+ TextNodeModelSchema,
612
+ SlotNodeModelSchema,
613
+ ElementNodeModelSchema,
614
+ ComponentNodeModelSchema,
615
+ ]));
616
+ // API Models
617
+ const ApiMethodSchema = z
618
+ .enum(['GET', 'POST', 'DELETE', 'PUT', 'PATCH', 'HEAD', 'OPTIONS'])
619
+ .describe('HTTP method for the API request.');
620
+ const ApiParserModeSchema = z
621
+ .enum(['auto', 'text', 'json', 'event-stream', 'json-stream', 'blob'])
622
+ .describe('Available modes for parsing API responses.');
623
+ const RedirectStatusCodes = {
624
+ '300': 300,
625
+ '301': 301,
626
+ '302': 302,
627
+ '303': 303,
628
+ '304': 304,
629
+ '307': 307,
630
+ '308': 308,
631
+ };
632
+ const RedirectStatusCodeSchema = z
633
+ .enum(RedirectStatusCodes)
634
+ .describe('HTTP status code to use for the redirect.');
635
+ const ApiRequestSchema = z
636
+ .object({
637
+ '@nordcraft/metadata': MetadataSchema.optional()
638
+ .nullable()
639
+ .describe('Metadata for the API request'),
640
+ version: z
641
+ .literal(2)
642
+ .describe('Version of the API request schema. This should always be 2.'),
643
+ name: z.string().describe('Name of the API request.'),
644
+ type: z.enum(['http', 'ws']).describe('Type of the API request.'),
645
+ method: ApiMethodSchema.optional()
646
+ .nullable()
647
+ .describe('HTTP method for the API request.'),
648
+ url: FormulaSchema.optional()
649
+ .nullable()
650
+ .describe('Base URL for the API request. Params and query strings are added when this API is called.'),
651
+ service: z
652
+ .string()
653
+ .nullable()
654
+ .optional()
655
+ .nullable()
656
+ .describe('Name of the service to use for the API request. Only Services defined in the project can be used here.'),
657
+ servicePath: z
658
+ .string()
659
+ .nullable()
660
+ .optional()
661
+ .nullable()
662
+ .describe('File path to the service definition. If service is defined, servicePath must also be defined.'),
663
+ inputs: z
664
+ .record(z.string().describe('Name of the input'), z
665
+ .object({
666
+ formula: FormulaSchema.nullable(),
667
+ })
668
+ .describe('Formula evaluating to the input value.'))
669
+ .describe('Inputs to the API request. Inputs have a default value that can be overridden when the API is started from a workflow. Inputs can be used inside any Formula in the API request definition.'),
670
+ path: z
671
+ .record(z.string().describe('Name of the path segment'), z.object({
672
+ formula: FormulaSchema.describe('Formula evaluating to the value of the path segment'),
673
+ index: z
674
+ .number()
675
+ .describe('Index defining the order of the path segments.'),
676
+ }))
677
+ .optional()
678
+ .nullable()
679
+ .describe('Path segments to include in the API request.'),
680
+ queryParams: z
681
+ .record(z.string().describe('Name of the query parameter'), z.object({
682
+ formula: FormulaSchema.describe('Formula evaluating to the value of the query parameter'),
683
+ enabled: FormulaSchema.nullable()
684
+ .optional()
685
+ .nullable()
686
+ .describe('Formula evaluating to whether the query parameter is included or not. If included it should evaluate to true.'),
687
+ }))
688
+ .optional()
689
+ .nullable()
690
+ .describe('Query parameters to include in the API request.'),
691
+ headers: z
692
+ .record(z.string().describe('Name of the header'), z.object({
693
+ formula: FormulaSchema.describe('Formula evaluating to the header value'),
694
+ enabled: FormulaSchema.nullable()
695
+ .optional()
696
+ .nullable()
697
+ .describe('Formula evaluating to whether the header is included or not. If included it should evaluate to true.'),
698
+ }))
699
+ .optional()
700
+ .nullable()
701
+ .describe('Headers to include in the API request.'),
702
+ body: FormulaSchema.optional()
703
+ .nullable()
704
+ .describe('Body of the API request.'),
705
+ autoFetch: FormulaSchema.nullable()
706
+ .optional()
707
+ .nullable()
708
+ .describe('Indicates if the API request should be automatically fetched when the component or page loads.'),
709
+ client: z
710
+ .object({
711
+ parserMode: ApiParserModeSchema.describe('Defines how the API response should be parsed.'),
712
+ credentials: z
713
+ .enum(['include', 'same-origin', 'omit'])
714
+ .optional()
715
+ .nullable()
716
+ .describe('Indicates whether credentials such as cookies or authorization headers should be sent with the request.'),
717
+ debounce: z
718
+ .object({ formula: FormulaSchema })
719
+ .nullable()
720
+ .optional()
721
+ .nullable()
722
+ .describe('Debounce time in milliseconds for the API request. Useful for limiting the number of requests made when inputs change rapidly.'),
723
+ onCompleted: EventModelSchema.nullable()
724
+ .optional()
725
+ .nullable()
726
+ .describe('Event triggered when the API request completes successfully.'),
727
+ onFailed: EventModelSchema.nullable()
728
+ .optional()
729
+ .nullable()
730
+ .describe('Event triggered when the API request fails. This is also triggered when the isError formula evaluates to true.'),
731
+ onMessage: EventModelSchema.nullable()
732
+ .optional()
733
+ .nullable()
734
+ .describe('Event triggered when a message is received from the API. Only applicable for WebSocket and streaming APIs.'),
735
+ })
736
+ .optional()
737
+ .nullable()
738
+ .describe('Client-side settings for the API request.'),
739
+ server: z
740
+ .object({
741
+ proxy: z
742
+ .object({
743
+ enabled: z
744
+ .object({ formula: FormulaSchema })
745
+ .describe('Indicates if the API request should be proxied through the Nordcraft backend server. This is useful for avoiding CORS issues or hiding sensitive information in the request. It is also useful if the request needs access to http-only cookies.'),
746
+ useTemplatesInBody: z
747
+ .object({ formula: FormulaSchema })
748
+ .nullable()
749
+ .optional()
750
+ .nullable()
751
+ .describe('Indicates if templates in the body should be processed when proxying the request. A template could be a http-only cookie that needs to be included in the proxied request. Enabling this flag will ensure that templates in the body are processed before sending the proxied request.'),
752
+ })
753
+ .nullable()
754
+ .optional()
755
+ .nullable()
756
+ .describe('Proxy settings for the API request.'),
757
+ ssr: z
758
+ .object({
759
+ enabled: z
760
+ .object({ formula: FormulaSchema })
761
+ .nullable()
762
+ .optional()
763
+ .nullable()
764
+ .describe('Indicates if server-side rendering is enabled for this API request. This means the API will be executed on the server during the initial page load. Note: This can have performance implications for the loading of a page on slow APIs.'),
765
+ })
766
+ .optional()
767
+ .nullable()
768
+ .describe('Server-side rendering settings.'),
769
+ })
770
+ .optional()
771
+ .nullable()
772
+ .describe('Server-side settings for the API request.'),
773
+ timeout: z
774
+ .object({ formula: FormulaSchema })
775
+ .nullable()
776
+ .optional()
777
+ .nullable()
778
+ .describe('Timeout for the API request in milliseconds.'),
779
+ hash: z.object({ formula: FormulaSchema }).nullable().optional().nullable(),
780
+ isError: z
781
+ .object({ formula: FormulaSchema })
782
+ .nullable()
783
+ .optional()
784
+ .nullable()
785
+ .describe('Indicates if the last API response was an error. Useful for forcing a response to be treated as an error even if status code is 200.'),
786
+ redirectRules: z
787
+ .record(z.string().describe('The key of the redirect rule.'), z
788
+ .object({
789
+ formula: FormulaSchema.describe('Formula evaluating to the URL. If a URL is returned, the redirect will be triggered. If null is returned, no redirect will happen.'),
790
+ index: z
791
+ .number()
792
+ .describe('Index defining the order of the redirect rules.'),
793
+ statusCode: RedirectStatusCodeSchema.nullable()
794
+ .optional()
795
+ .nullable()
796
+ .describe('HTTP status code to use for the redirect.'),
797
+ })
798
+ .describe('Defines a single redirect rule.'))
799
+ .nullable()
800
+ .optional()
801
+ .nullable()
802
+ .describe('Rules for redirecting based on response data. The key is a unique identifier for the rule.'),
803
+ })
804
+ .describe('Schema defining an API request from a component or a page.');
805
+ const LegacyComponentAPISchema = z
806
+ .object({
807
+ type: z.literal('REST'),
808
+ name: z.string(),
809
+ method: z.enum(['GET', 'POST', 'DELETE', 'PUT']),
810
+ url: FormulaSchema.optional().nullable(),
811
+ path: z
812
+ .array(z.object({ formula: FormulaSchema }))
813
+ .optional()
814
+ .nullable(),
815
+ queryParams: z
816
+ .record(z.string(), z.object({
817
+ name: z.string(),
818
+ formula: FormulaSchema,
819
+ }))
820
+ .optional()
821
+ .nullable(),
822
+ headers: z
823
+ .union([z.record(z.string(), FormulaSchema), FormulaSchema])
824
+ .optional()
825
+ .nullable(),
826
+ body: FormulaSchema.optional().nullable(),
827
+ autoFetch: FormulaSchema.nullable().optional().nullable(),
828
+ proxy: z.boolean().optional().nullable(),
829
+ debounce: z.number().nullable().optional().nullable(),
830
+ throttle: z.number().nullable().optional().nullable(),
831
+ onCompleted: EventModelSchema.nullable(),
832
+ onFailed: EventModelSchema.nullable(),
833
+ auth: z
834
+ .object({
835
+ type: z.enum(['Bearer id_token', 'Bearer access_token']),
836
+ })
837
+ .optional()
838
+ .nullable(),
839
+ })
840
+ .describe('Legacy API schema for backward compatibility. Never use this for new APIs.');
841
+ const ComponentAPISchema = z.union([
842
+ LegacyComponentAPISchema,
843
+ ApiRequestSchema,
844
+ ]);
845
+ const ComponentFormulaSchema = z.object({
846
+ '@nordcraft/metadata': MetadataSchema.optional()
847
+ .nullable()
848
+ .describe(generalDescriptions.metadata('formula')),
849
+ name: z.string().describe('Name of the formula'),
850
+ formula: FormulaSchema.describe('Contains the "code" that will be executed when this formula is called.'),
851
+ arguments: z
852
+ .array(z.object({
853
+ name: z.string().describe('Name of the formula argument'),
854
+ testValue: z.any().describe('Test value for the formula argument'),
855
+ }))
856
+ .nullable()
857
+ .optional()
858
+ .nullable()
859
+ .describe('List of arguments accepted by the formula.'),
860
+ memoize: z
861
+ .boolean()
862
+ .optional()
863
+ .nullable()
864
+ .describe('Indicates if the formula result should be memoized.'),
865
+ exposeInContext: z
866
+ .boolean()
867
+ .optional()
868
+ .nullable()
869
+ .describe('Indicates if the formula should be exposed in the component context for child components to subscribe to.'),
870
+ });
871
+ const ComponentVariableSchema = z.object({
872
+ '@nordcraft/metadata': MetadataSchema.optional()
873
+ .nullable()
874
+ .describe(generalDescriptions.metadata('variable')),
875
+ initialValue: FormulaSchema.describe('Initial value of the variable'),
876
+ });
877
+ const ComponentWorkflowSchema = z
878
+ .object({
879
+ '@nordcraft/metadata': MetadataSchema.optional()
880
+ .nullable()
881
+ .describe(generalDescriptions.metadata('workflow')),
882
+ name: z.string().describe('Name of the workflow'),
883
+ parameters: z
884
+ .array(z.object({
885
+ name: z.string().describe('Name of the workflow parameter'),
886
+ testValue: z.any().describe('Test value for the workflow parameter'),
887
+ }))
888
+ .describe('Parameters accepted by the workflow'),
889
+ actions: z
890
+ .array(ActionModelSchema)
891
+ .describe('List of actions that make up the workflow'),
892
+ exposeInContext: z
893
+ .boolean()
894
+ .optional()
895
+ .nullable()
896
+ .describe('Indicates if the workflow should be exposed in the context for child components to subscribe to.'),
897
+ })
898
+ .describe('Schema defining a workflow.');
899
+ // Route Models
900
+ const StaticPathSegmentSchema = z
901
+ .object({
902
+ type: z.literal('static').describe('Static path segment'),
903
+ name: z.string().describe('Name of the static path segment'),
904
+ optional: z
905
+ .boolean()
906
+ .optional()
907
+ .nullable()
908
+ .describe('Indicates if the segment is optional'),
909
+ })
910
+ .describe('Schema for static path segments');
911
+ const DynamicPathSegmentSchema = z
912
+ .object({
913
+ type: z
914
+ .literal('param')
915
+ .describe('Dynamic path segment representing a URL parameter'),
916
+ name: z.string().describe('Name of the URL parameter'),
917
+ testValue: z
918
+ .string()
919
+ .describe(generalDescriptions.testData('dynamic URL parameter')),
920
+ optional: z
921
+ .boolean()
922
+ .optional()
923
+ .nullable()
924
+ .describe('Indicates if the URL parameter is optional'),
925
+ })
926
+ .describe('Schema for dynamic path segments (URL parameters)');
927
+ const HeadTagTypesSchema = z
928
+ .enum(['meta', 'link', 'script', 'noscript', 'style'])
929
+ .describe('Available head tags.');
930
+ const MetaEntrySchema = z
931
+ .object({
932
+ tag: HeadTagTypesSchema.describe('Type of the head tag such as meta, link, script.'),
933
+ attrs: z
934
+ .record(z.string().describe('The name of the head tag attribute'), FormulaSchema.describe('The Formula evaluating to the value of the head tag attribute'))
935
+ .describe('Attributes for the head tag.'),
936
+ content: FormulaSchema.describe('Optional content for the head tag, used for tags like style or script.'),
937
+ })
938
+ .describe('Schema defining a single meta entry for the head of the document.');
939
+ const RouteSchema = z
940
+ .object({
941
+ path: z
942
+ .array(z.union([StaticPathSegmentSchema, DynamicPathSegmentSchema]))
943
+ .describe('Array of path segments defining the route path. Each segment can be static or dynamic (parameterized). Each segment must be unique.'),
944
+ query: z.record(z.string().describe('Name of the query parameter. This must be unique.'), z
945
+ .object({
946
+ name: z
947
+ .string()
948
+ .describe('Name of the query parameter. Same as the key'),
949
+ testValue: z
950
+ .any()
951
+ .describe('Test value for the query parameter. Test data is only used while building the component in the Nordcraft editor.'),
952
+ })
953
+ .describe('Schema defining a query parameter. Nordcraft supports having query parameters with multiple values. Defining a query parameter as an array will allow multiple values for that parameter.')),
954
+ info: z
955
+ .object({
956
+ title: z
957
+ .object({ formula: FormulaSchema })
958
+ .optional()
959
+ .nullable()
960
+ .describe('Title of the page, used in the document title and SEO metadata.'),
961
+ description: z
962
+ .object({ formula: FormulaSchema })
963
+ .optional()
964
+ .nullable()
965
+ .describe('Description of the page, used in SEO metadata and social sharing previews.'),
966
+ icon: z
967
+ .object({ formula: FormulaSchema })
968
+ .optional()
969
+ .nullable()
970
+ .describe('URL to the icon of the page, used in SEO metadata and social sharing previews.'),
971
+ language: z
972
+ .object({ formula: FormulaSchema })
973
+ .optional()
974
+ .nullable()
975
+ .describe('Language of the page, used in the lang attribute of the HTML document.'),
976
+ charset: z
977
+ .object({ formula: FormulaSchema })
978
+ .optional()
979
+ .nullable()
980
+ .describe('Character set of the page, used in the meta charset tag of the HTML document.'),
981
+ meta: z
982
+ .record(z.string().describe('The key of the meta data record.'), MetaEntrySchema)
983
+ .optional()
984
+ .nullable()
985
+ .describe('Additional meta tags to include in the head of the document. Each entry defines a tag and its attributes.'),
986
+ })
987
+ .optional()
988
+ .nullable()
989
+ .describe('Contains additional information for the route such as SEO metadata.'),
990
+ })
991
+ .describe('Schema defining the route information for a page as well as SEO related metadata.');
992
+ const ComponentAttributeSchema = z
993
+ .object({
994
+ '@nordcraft/metadata': MetadataSchema.optional()
995
+ .nullable()
996
+ .describe(generalDescriptions.metadata('component attribute')),
997
+ name: z.string().describe('Name of the component attribute'),
998
+ testValue: z
999
+ .any()
1000
+ .describe(generalDescriptions.testData('component attribute')),
1001
+ })
1002
+ .describe('Schema for a component attribute.');
1003
+ const ComponentEventSchema = z
1004
+ .object({
1005
+ '@nordcraft/metadata': MetadataSchema.optional()
1006
+ .nullable()
1007
+ .describe(generalDescriptions.metadata('component event')),
1008
+ name: z.string().describe('Name of the component event'),
1009
+ dummyEvent: z
1010
+ .any()
1011
+ .describe(generalDescriptions.testData('component event')),
1012
+ })
1013
+ .describe('Schema for a component event.');
1014
+ const ComponentContextSchema = z
1015
+ .object({
1016
+ package: z
1017
+ .string()
1018
+ .optional()
1019
+ .nullable()
1020
+ .describe('Package name of the component providing the context'),
1021
+ componentName: z
1022
+ .string()
1023
+ .optional()
1024
+ .nullable()
1025
+ .describe('Name of the component providing the context'),
1026
+ formulas: z
1027
+ .array(z.string())
1028
+ .describe('Names of the formulas from the context to subscribe to'),
1029
+ workflows: z
1030
+ .array(z.string())
1031
+ .describe('Names of the workflows from the context to subscribe to'),
1032
+ })
1033
+ .describe('Schema defining a component context subscription.');
1034
+ const commonComponentSchema = (type) => z
1035
+ .object({
1036
+ name: z.string().describe(`Name of the ${type}`),
1037
+ exported: z
1038
+ .boolean()
1039
+ .optional()
1040
+ .nullable()
1041
+ .describe(`Whether the ${type} is exported in a package project for use in other projects. Do not change this value. It should be managed by the user.`),
1042
+ nodes: z
1043
+ .record(z.string(), NodeModelSchema)
1044
+ .optional()
1045
+ .nullable()
1046
+ .describe(`All nodes in the ${type}, indexed by their unique IDs. Nodes represent HTML elements, text, slots, or ${type === 'component' ? 'other components' : 'components'}. They defined the UI structure of the ${type}.`),
1047
+ variables: z
1048
+ .record(z.string(), ComponentVariableSchema)
1049
+ .optional()
1050
+ .nullable()
1051
+ .describe(generalDescriptions.variables(type)),
1052
+ formulas: z
1053
+ .record(z.string(), ComponentFormulaSchema)
1054
+ .optional()
1055
+ .nullable()
1056
+ .describe(generalDescriptions.formulas(type)),
1057
+ workflows: z
1058
+ .record(z.string(), ComponentWorkflowSchema)
1059
+ .optional()
1060
+ .nullable()
1061
+ .describe(generalDescriptions.workflows(type)),
1062
+ apis: z
1063
+ .record(z.string(), ComponentAPISchema)
1064
+ .optional()
1065
+ .nullable()
1066
+ .describe(generalDescriptions.apis(type)),
1067
+ events: z
1068
+ .array(ComponentEventSchema)
1069
+ .optional()
1070
+ .nullable()
1071
+ .describe('All events this the component can emit. Events allow the component to communicate with its parent or other components. They can be triggered via actions.'),
1072
+ contexts: z
1073
+ .record(z.string(), ComponentContextSchema)
1074
+ .optional()
1075
+ .nullable()
1076
+ .describe('Defines which contexts this component is subscribed to. Contexts allow the component to access formulas and workflows from other components, enabling reusability and modular design.'),
1077
+ onLoad: z
1078
+ .object({
1079
+ trigger: z.literal('Load'),
1080
+ actions: z.array(ActionModelSchema),
1081
+ })
1082
+ .optional()
1083
+ .nullable()
1084
+ .describe(generalDescriptions.onLoad(type)),
1085
+ onAttributeChange: z
1086
+ .object({
1087
+ trigger: z.literal('Attribute change'),
1088
+ actions: z.array(ActionModelSchema),
1089
+ })
1090
+ .optional()
1091
+ .nullable()
1092
+ .describe(generalDescriptions.onAttributeChange(type)),
1093
+ })
1094
+ .describe('Schema defining a reusable Nordcraft component.');
1095
+ export const ComponentSchema = commonComponentSchema('component').extend({
1096
+ attributes: z
1097
+ .record(z.string(), ComponentAttributeSchema)
1098
+ .describe('All attributes that can be passed into the component when it is used. Attributes allow for customization and configuration of the component instance. When the value of an attribute changes, any formulas depending on it will automatically recalculate and the onAttributeChange lifecycle event is triggered.'),
1099
+ });
1100
+ export const PageSchema = commonComponentSchema('page').extend({
1101
+ attributes: z
1102
+ .object({})
1103
+ .describe('Attributes for the page (currently none). Should always be an empty object.'),
1104
+ route: RouteSchema.describe('Route information for the page, including path segments, query parameters, and metadata such as title and description.'),
1105
+ });
1106
+ //# sourceMappingURL=zod-schemas.js.map