@revealui/contracts 1.0.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.
Files changed (191) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +160 -0
  3. package/dist/a2a/index.d.ts +383 -0
  4. package/dist/a2a/index.d.ts.map +1 -0
  5. package/dist/a2a/index.js +276 -0
  6. package/dist/a2a/index.js.map +1 -0
  7. package/dist/actions/action-validator.d.ts +48 -0
  8. package/dist/actions/action-validator.d.ts.map +1 -0
  9. package/dist/actions/action-validator.js +288 -0
  10. package/dist/actions/action-validator.js.map +1 -0
  11. package/dist/actions/index.d.ts +7 -0
  12. package/dist/actions/index.d.ts.map +1 -0
  13. package/dist/actions/index.js +7 -0
  14. package/dist/actions/index.js.map +1 -0
  15. package/dist/agents/index.d.ts +628 -0
  16. package/dist/agents/index.d.ts.map +1 -0
  17. package/dist/agents/index.js +511 -0
  18. package/dist/agents/index.js.map +1 -0
  19. package/dist/agents/types.d.ts +22 -0
  20. package/dist/agents/types.d.ts.map +1 -0
  21. package/dist/agents/types.js +2 -0
  22. package/dist/agents/types.js.map +1 -0
  23. package/dist/api/auth.d.ts +60 -0
  24. package/dist/api/auth.d.ts.map +1 -0
  25. package/dist/api/auth.js +84 -0
  26. package/dist/api/auth.js.map +1 -0
  27. package/dist/api/chat.d.ts +45 -0
  28. package/dist/api/chat.d.ts.map +1 -0
  29. package/dist/api/chat.js +55 -0
  30. package/dist/api/chat.js.map +1 -0
  31. package/dist/api/gdpr.d.ts +39 -0
  32. package/dist/api/gdpr.d.ts.map +1 -0
  33. package/dist/api/gdpr.js +53 -0
  34. package/dist/api/gdpr.js.map +1 -0
  35. package/dist/cms/collection.d.ts +108 -0
  36. package/dist/cms/collection.d.ts.map +1 -0
  37. package/dist/cms/collection.js +144 -0
  38. package/dist/cms/collection.js.map +1 -0
  39. package/dist/cms/compat.d.ts +128 -0
  40. package/dist/cms/compat.d.ts.map +1 -0
  41. package/dist/cms/compat.js +141 -0
  42. package/dist/cms/compat.js.map +1 -0
  43. package/dist/cms/config-contract.d.ts +278 -0
  44. package/dist/cms/config-contract.d.ts.map +1 -0
  45. package/dist/cms/config-contract.js +220 -0
  46. package/dist/cms/config-contract.js.map +1 -0
  47. package/dist/cms/config.d.ts +351 -0
  48. package/dist/cms/config.d.ts.map +1 -0
  49. package/dist/cms/config.js +50 -0
  50. package/dist/cms/config.js.map +1 -0
  51. package/dist/cms/errors.d.ts +122 -0
  52. package/dist/cms/errors.d.ts.map +1 -0
  53. package/dist/cms/errors.js +163 -0
  54. package/dist/cms/errors.js.map +1 -0
  55. package/dist/cms/extensibility.d.ts +211 -0
  56. package/dist/cms/extensibility.d.ts.map +1 -0
  57. package/dist/cms/extensibility.js +313 -0
  58. package/dist/cms/extensibility.js.map +1 -0
  59. package/dist/cms/field.d.ts +69 -0
  60. package/dist/cms/field.d.ts.map +1 -0
  61. package/dist/cms/field.js +94 -0
  62. package/dist/cms/field.js.map +1 -0
  63. package/dist/cms/functions.d.ts +466 -0
  64. package/dist/cms/functions.d.ts.map +1 -0
  65. package/dist/cms/functions.js +19 -0
  66. package/dist/cms/functions.js.map +1 -0
  67. package/dist/cms/global.d.ts +45 -0
  68. package/dist/cms/global.d.ts.map +1 -0
  69. package/dist/cms/global.js +62 -0
  70. package/dist/cms/global.js.map +1 -0
  71. package/dist/cms/index.d.ts +23 -0
  72. package/dist/cms/index.d.ts.map +1 -0
  73. package/dist/cms/index.js +42 -0
  74. package/dist/cms/index.js.map +1 -0
  75. package/dist/cms/structure.d.ts +1601 -0
  76. package/dist/cms/structure.d.ts.map +1 -0
  77. package/dist/cms/structure.js +757 -0
  78. package/dist/cms/structure.js.map +1 -0
  79. package/dist/content/index.d.ts +1542 -0
  80. package/dist/content/index.d.ts.map +1 -0
  81. package/dist/content/index.js +522 -0
  82. package/dist/content/index.js.map +1 -0
  83. package/dist/database/bridge.d.ts +177 -0
  84. package/dist/database/bridge.d.ts.map +1 -0
  85. package/dist/database/bridge.js +139 -0
  86. package/dist/database/bridge.js.map +1 -0
  87. package/dist/database/index.d.ts +8 -0
  88. package/dist/database/index.d.ts.map +1 -0
  89. package/dist/database/index.js +9 -0
  90. package/dist/database/index.js.map +1 -0
  91. package/dist/database/type-bridge.d.ts +178 -0
  92. package/dist/database/type-bridge.d.ts.map +1 -0
  93. package/dist/database/type-bridge.js +154 -0
  94. package/dist/database/type-bridge.js.map +1 -0
  95. package/dist/entities/agent-context.d.ts +280 -0
  96. package/dist/entities/agent-context.d.ts.map +1 -0
  97. package/dist/entities/agent-context.js +390 -0
  98. package/dist/entities/agent-context.js.map +1 -0
  99. package/dist/entities/agent-memory.d.ts +661 -0
  100. package/dist/entities/agent-memory.d.ts.map +1 -0
  101. package/dist/entities/agent-memory.js +544 -0
  102. package/dist/entities/agent-memory.js.map +1 -0
  103. package/dist/entities/board.d.ts +95 -0
  104. package/dist/entities/board.d.ts.map +1 -0
  105. package/dist/entities/board.js +99 -0
  106. package/dist/entities/board.js.map +1 -0
  107. package/dist/entities/code-provenance.d.ts +270 -0
  108. package/dist/entities/code-provenance.d.ts.map +1 -0
  109. package/dist/entities/code-provenance.js +339 -0
  110. package/dist/entities/code-provenance.js.map +1 -0
  111. package/dist/entities/index.d.ts +22 -0
  112. package/dist/entities/index.d.ts.map +1 -0
  113. package/dist/entities/index.js +22 -0
  114. package/dist/entities/index.js.map +1 -0
  115. package/dist/entities/media.d.ts +485 -0
  116. package/dist/entities/media.d.ts.map +1 -0
  117. package/dist/entities/media.js +606 -0
  118. package/dist/entities/media.js.map +1 -0
  119. package/dist/entities/page-revision.d.ts +390 -0
  120. package/dist/entities/page-revision.d.ts.map +1 -0
  121. package/dist/entities/page-revision.js +406 -0
  122. package/dist/entities/page-revision.js.map +1 -0
  123. package/dist/entities/page.d.ts +2349 -0
  124. package/dist/entities/page.d.ts.map +1 -0
  125. package/dist/entities/page.js +377 -0
  126. package/dist/entities/page.js.map +1 -0
  127. package/dist/entities/post.d.ts +619 -0
  128. package/dist/entities/post.d.ts.map +1 -0
  129. package/dist/entities/post.js +555 -0
  130. package/dist/entities/post.js.map +1 -0
  131. package/dist/entities/price.d.ts +772 -0
  132. package/dist/entities/price.d.ts.map +1 -0
  133. package/dist/entities/price.js +308 -0
  134. package/dist/entities/price.js.map +1 -0
  135. package/dist/entities/product.d.ts +753 -0
  136. package/dist/entities/product.d.ts.map +1 -0
  137. package/dist/entities/product.js +307 -0
  138. package/dist/entities/product.js.map +1 -0
  139. package/dist/entities/session.d.ts +222 -0
  140. package/dist/entities/session.d.ts.map +1 -0
  141. package/dist/entities/session.js +253 -0
  142. package/dist/entities/session.js.map +1 -0
  143. package/dist/entities/site.d.ts +387 -0
  144. package/dist/entities/site.d.ts.map +1 -0
  145. package/dist/entities/site.js +348 -0
  146. package/dist/entities/site.js.map +1 -0
  147. package/dist/entities/ticket-comment.d.ts +49 -0
  148. package/dist/entities/ticket-comment.d.ts.map +1 -0
  149. package/dist/entities/ticket-comment.js +58 -0
  150. package/dist/entities/ticket-comment.js.map +1 -0
  151. package/dist/entities/ticket-label.d.ts +64 -0
  152. package/dist/entities/ticket-label.d.ts.map +1 -0
  153. package/dist/entities/ticket-label.js +77 -0
  154. package/dist/entities/ticket-label.js.map +1 -0
  155. package/dist/entities/ticket.d.ts +204 -0
  156. package/dist/entities/ticket.d.ts.map +1 -0
  157. package/dist/entities/ticket.js +205 -0
  158. package/dist/entities/ticket.js.map +1 -0
  159. package/dist/entities/user.d.ts +336 -0
  160. package/dist/entities/user.d.ts.map +1 -0
  161. package/dist/entities/user.js +255 -0
  162. package/dist/entities/user.js.map +1 -0
  163. package/dist/foundation/contract.d.ts +221 -0
  164. package/dist/foundation/contract.d.ts.map +1 -0
  165. package/dist/foundation/contract.js +133 -0
  166. package/dist/foundation/contract.js.map +1 -0
  167. package/dist/foundation/index.d.ts +7 -0
  168. package/dist/foundation/index.d.ts.map +1 -0
  169. package/dist/foundation/index.js +7 -0
  170. package/dist/foundation/index.js.map +1 -0
  171. package/dist/generated/contracts.d.ts +1514 -0
  172. package/dist/generated/contracts.d.ts.map +1 -0
  173. package/dist/generated/contracts.js +959 -0
  174. package/dist/generated/contracts.js.map +1 -0
  175. package/dist/generated/database.d.ts +48 -0
  176. package/dist/generated/database.d.ts.map +1 -0
  177. package/dist/generated/database.js +17 -0
  178. package/dist/generated/database.js.map +1 -0
  179. package/dist/generated/zod-schemas.d.ts +14793 -0
  180. package/dist/generated/zod-schemas.d.ts.map +1 -0
  181. package/dist/generated/zod-schemas.js +547 -0
  182. package/dist/generated/zod-schemas.js.map +1 -0
  183. package/dist/index.d.ts +50 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +81 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/representation/index.d.ts +304 -0
  188. package/dist/representation/index.d.ts.map +1 -0
  189. package/dist/representation/index.js +280 -0
  190. package/dist/representation/index.js.map +1 -0
  191. package/package.json +117 -0
@@ -0,0 +1,757 @@
1
+ /**
2
+ * Structure Schemas (Zod)
3
+ *
4
+ * These schemas validate the STRUCTURE of CMS configurations.
5
+ *
6
+ * IMPORTANT: These schemas do NOT validate function types (hooks, access, validate).
7
+ * Function types are handled by TypeScript contracts in functions.ts.
8
+ *
9
+ * Why this split?
10
+ * 1. Zod's z.function() only validates callability, not signatures
11
+ * 2. Generic type parameters (e.g., <T>) cannot be represented in Zod
12
+ * 3. Complex return types with conditional types don't work in Zod
13
+ *
14
+ * @module @revealui/contracts/core/contracts/structure
15
+ */
16
+ import { z } from 'zod/v4';
17
+ // ============================================
18
+ // SCHEMA VERSIONS
19
+ // ============================================
20
+ export const FIELD_SCHEMA_VERSION = 1;
21
+ export const COLLECTION_SCHEMA_VERSION = 1;
22
+ export const GLOBAL_SCHEMA_VERSION = 1;
23
+ // ============================================
24
+ // FIELD STRUCTURE SCHEMAS
25
+ // ============================================
26
+ /**
27
+ * Valid field types in RevealUI CMS
28
+ */
29
+ export const FieldTypeSchema = z.enum([
30
+ // Basic fields
31
+ 'text',
32
+ 'textarea',
33
+ 'number',
34
+ 'email',
35
+ 'password',
36
+ 'code',
37
+ 'date',
38
+ 'checkbox',
39
+ // Selection fields
40
+ 'select',
41
+ 'radio',
42
+ // Relationship fields
43
+ 'relationship',
44
+ 'upload',
45
+ // Structural fields
46
+ 'array',
47
+ 'blocks',
48
+ 'group',
49
+ 'row',
50
+ 'collapsible',
51
+ 'tabs',
52
+ // Special fields
53
+ 'richText',
54
+ 'json',
55
+ 'point',
56
+ 'ui',
57
+ ]);
58
+ /**
59
+ * Field admin configuration (UI-related settings)
60
+ *
61
+ * Note: This uses passthrough() to allow custom properties
62
+ * that plugins might add.
63
+ */
64
+ export const FieldAdminConfigSchema = z
65
+ .object({
66
+ // Position and layout
67
+ position: z.string().optional(),
68
+ width: z.union([z.string(), z.number()]).optional(),
69
+ // State
70
+ disabled: z.boolean().optional(),
71
+ readOnly: z.boolean().optional(),
72
+ hidden: z.boolean().optional(),
73
+ initCollapsed: z.boolean().optional(),
74
+ // Help text
75
+ description: z.string().optional(),
76
+ placeholder: z.string().optional(),
77
+ // Layout
78
+ layout: z.enum(['horizontal', 'vertical']).optional(),
79
+ // Styling
80
+ style: z.record(z.string(), z.string()).optional(),
81
+ className: z.string().optional(),
82
+ // Note: 'components', 'condition' are functions - not validated here
83
+ })
84
+ .passthrough()
85
+ .optional();
86
+ /**
87
+ * Option for select/radio fields
88
+ */
89
+ export const FieldOptionSchema = z.union([
90
+ z.string(),
91
+ z.object({
92
+ label: z.string(),
93
+ value: z.string(),
94
+ }),
95
+ ]);
96
+ /**
97
+ * Block definition within a blocks field
98
+ */
99
+ export const BlockDefinitionSchema = z
100
+ .object({
101
+ slug: z.string().min(1),
102
+ labels: z
103
+ .object({
104
+ singular: z.string(),
105
+ plural: z.string().optional(),
106
+ })
107
+ .optional(),
108
+ imageURL: z.string().optional(),
109
+ imageAltText: z.string().optional(),
110
+ // Fields are recursive - handled in FieldStructureSchema
111
+ fields: z.array(z.lazy(() => FieldStructureSchema)),
112
+ })
113
+ .passthrough();
114
+ /**
115
+ * Tab definition within a tabs field
116
+ */
117
+ export const TabDefinitionSchema = z
118
+ .object({
119
+ label: z.string(),
120
+ name: z.string().optional(),
121
+ description: z.string().optional(),
122
+ // Fields are recursive
123
+ fields: z.array(z.lazy(() => FieldStructureSchema)),
124
+ })
125
+ .passthrough();
126
+ // =============================================================================
127
+ // FIELD ACCESS/HOOKS SCHEMAS
128
+ // =============================================================================
129
+ /**
130
+ * Field access control schema
131
+ *
132
+ * Access functions are runtime functions, typed as unknown for schema flexibility
133
+ */
134
+ export const FieldAccessConfigSchema = z
135
+ .object({
136
+ create: z.unknown().optional(),
137
+ read: z.unknown().optional(),
138
+ update: z.unknown().optional(),
139
+ })
140
+ .optional();
141
+ /**
142
+ * Field hooks schema
143
+ *
144
+ * Hooks are typed as unknown arrays because they're runtime functions
145
+ */
146
+ export const FieldHooksConfigSchema = z
147
+ .object({
148
+ beforeChange: z.array(z.unknown()).optional(),
149
+ afterChange: z.array(z.unknown()).optional(),
150
+ beforeValidate: z.array(z.unknown()).optional(),
151
+ afterRead: z.array(z.unknown()).optional(),
152
+ })
153
+ .optional();
154
+ // =============================================================================
155
+ // BASE FIELD STRUCTURE
156
+ // =============================================================================
157
+ /**
158
+ * Base field structure (common to all field types)
159
+ *
160
+ * This validates the structural properties of fields.
161
+ * Function properties (access, hooks, validate) are typed separately.
162
+ */
163
+ export const FieldStructureSchema = z
164
+ .object({
165
+ // Type (required)
166
+ type: FieldTypeSchema,
167
+ // Identity
168
+ name: z.string().min(1).optional(),
169
+ // Labels
170
+ label: z.union([z.string(), z.literal(false)]).optional(),
171
+ // Constraints
172
+ required: z.boolean().optional(),
173
+ unique: z.boolean().optional(),
174
+ index: z.boolean().optional(),
175
+ localized: z.boolean().optional(),
176
+ hidden: z.boolean().optional(),
177
+ saveToJWT: z.union([z.boolean(), z.string()]).optional(),
178
+ // Text field specific
179
+ minLength: z.number().optional(),
180
+ maxLength: z.number().optional(),
181
+ // Number field specific
182
+ min: z.number().optional(),
183
+ max: z.number().optional(),
184
+ // Relationship specific
185
+ relationTo: z.union([z.string(), z.array(z.string())]).optional(),
186
+ hasMany: z.boolean().optional(),
187
+ maxDepth: z.number().optional(),
188
+ // Select/Radio specific
189
+ options: z.array(FieldOptionSchema).optional(),
190
+ // Default value (any type)
191
+ defaultValue: z.unknown().optional(),
192
+ // Admin config
193
+ admin: FieldAdminConfigSchema,
194
+ // Nested fields (for array, group, row, collapsible)
195
+ fields: z.array(z.lazy(() => FieldStructureSchema)).optional(),
196
+ // Blocks (for blocks field)
197
+ blocks: z.array(z.lazy(() => BlockDefinitionSchema)).optional(),
198
+ // Tabs (for tabs field)
199
+ tabs: z.array(z.lazy(() => TabDefinitionSchema)).optional(),
200
+ // TypeScript interface name (for code generation)
201
+ interfaceName: z.string().optional(),
202
+ // Note: access, hooks, validate, condition, filterOptions, editor
203
+ // are functions and are NOT validated by this schema.
204
+ // They are typed in the Field interface which extends this.
205
+ })
206
+ .passthrough();
207
+ // =============================================================================
208
+ // FULL FIELD SCHEMA (includes access/hooks)
209
+ // =============================================================================
210
+ /**
211
+ * Base field properties schema (non-recursive parts)
212
+ *
213
+ * This includes all field properties from FieldStructureSchema plus access/hooks
214
+ * but excludes nested fields/blocks/tabs which require recursion.
215
+ */
216
+ const BaseFieldPropertiesSchema = z
217
+ .object({
218
+ // Include all properties from FieldStructureSchema
219
+ type: FieldTypeSchema,
220
+ name: z.string().min(1).optional(),
221
+ label: z.union([z.string(), z.literal(false)]).optional(),
222
+ labels: z
223
+ .object({
224
+ singular: z.string().optional(),
225
+ plural: z.string().optional(),
226
+ })
227
+ .optional(),
228
+ required: z.boolean().optional(),
229
+ unique: z.boolean().optional(),
230
+ index: z.boolean().optional(),
231
+ localized: z.boolean().optional(),
232
+ hidden: z.boolean().optional(),
233
+ saveToJWT: z.union([z.boolean(), z.string()]).optional(),
234
+ minLength: z.number().optional(),
235
+ maxLength: z.number().optional(),
236
+ min: z.number().optional(),
237
+ max: z.number().optional(),
238
+ minRows: z.number().optional(),
239
+ maxRows: z.number().optional(),
240
+ relationTo: z.union([z.string(), z.array(z.string())]).optional(),
241
+ hasMany: z.boolean().optional(),
242
+ maxDepth: z.number().optional(),
243
+ depth: z.number().optional(),
244
+ options: z.array(FieldOptionSchema).optional(),
245
+ defaultValue: z.unknown().optional(),
246
+ admin: FieldAdminConfigSchema,
247
+ interfaceName: z.string().optional(),
248
+ custom: z.record(z.string(), z.unknown()).optional(),
249
+ // Add function properties
250
+ schemaVersion: z.number().int().default(FIELD_SCHEMA_VERSION).optional(),
251
+ access: FieldAccessConfigSchema,
252
+ hooks: FieldHooksConfigSchema,
253
+ validate: z.unknown().optional(),
254
+ condition: z.unknown().optional(),
255
+ filterOptions: z.unknown().optional(),
256
+ editor: z.unknown().optional(),
257
+ })
258
+ .passthrough();
259
+ /**
260
+ * Full Field Schema (recursive - includes nested fields)
261
+ *
262
+ * This is the complete field schema that includes access, hooks, and nested fields.
263
+ * For structure-only validation, use FieldStructureSchema.
264
+ */
265
+ export const FieldSchema = z.lazy(() => BaseFieldPropertiesSchema.extend({
266
+ /** Nested fields (recursive) */
267
+ fields: z.array(FieldSchema).optional(),
268
+ /** Tabs (for tabs field) */
269
+ tabs: z.array(TabDefinitionSchema).optional(),
270
+ }));
271
+ // =============================================================================
272
+ // SPECIFIC FIELD TYPE SCHEMAS
273
+ // =============================================================================
274
+ /**
275
+ * Text field schema
276
+ */
277
+ export const TextFieldSchema = BaseFieldPropertiesSchema.extend({
278
+ type: z.literal('text'),
279
+ name: z.string(), // Required for text fields
280
+ });
281
+ /**
282
+ * Number field schema
283
+ */
284
+ export const NumberFieldSchema = BaseFieldPropertiesSchema.extend({
285
+ type: z.literal('number'),
286
+ name: z.string(),
287
+ min: z.number().optional(),
288
+ max: z.number().optional(),
289
+ });
290
+ /**
291
+ * Relationship field schema
292
+ */
293
+ export const RelationshipFieldSchema = BaseFieldPropertiesSchema.extend({
294
+ type: z.literal('relationship'),
295
+ name: z.string(),
296
+ relationTo: z.union([z.string(), z.array(z.string())]),
297
+ });
298
+ /**
299
+ * Array field schema (recursive)
300
+ */
301
+ export const ArrayFieldSchema = z.lazy(() => BaseFieldPropertiesSchema.extend({
302
+ type: z.literal('array'),
303
+ name: z.string(),
304
+ fields: z.array(FieldSchema),
305
+ }));
306
+ /**
307
+ * Group field schema (recursive)
308
+ */
309
+ export const GroupFieldSchema = z.lazy(() => BaseFieldPropertiesSchema.extend({
310
+ type: z.literal('group'),
311
+ name: z.string(),
312
+ fields: z.array(FieldSchema),
313
+ }));
314
+ /**
315
+ * Select field schema
316
+ */
317
+ export const SelectFieldSchema = BaseFieldPropertiesSchema.extend({
318
+ type: z.literal('select'),
319
+ name: z.string(),
320
+ options: z.array(FieldOptionSchema),
321
+ });
322
+ /**
323
+ * Row field schema (layout field - recursive)
324
+ */
325
+ export const RowFieldSchema = z.lazy(() => BaseFieldPropertiesSchema.extend({
326
+ type: z.literal('row'),
327
+ fields: z.array(FieldSchema),
328
+ }));
329
+ /**
330
+ * Tabs field schema (layout field - recursive)
331
+ */
332
+ export const TabsFieldSchema = z.lazy(() => BaseFieldPropertiesSchema.extend({
333
+ type: z.literal('tabs'),
334
+ tabs: z.array(TabDefinitionSchema),
335
+ }));
336
+ // ============================================
337
+ // COLLECTION STRUCTURE SCHEMAS
338
+ // ============================================
339
+ /**
340
+ * Collection labels configuration
341
+ */
342
+ export const CollectionLabelsSchema = z
343
+ .object({
344
+ singular: z.string(),
345
+ plural: z.string().optional(),
346
+ })
347
+ .optional();
348
+ /**
349
+ * Collection access control schema
350
+ *
351
+ * Access functions are runtime functions, typed as unknown for schema flexibility
352
+ */
353
+ export const CollectionAccessSchema = z
354
+ .object({
355
+ /** Create access */
356
+ create: z.unknown().optional(),
357
+ /** Read access */
358
+ read: z.unknown().optional(),
359
+ /** Update access */
360
+ update: z.unknown().optional(),
361
+ /** Delete access */
362
+ delete: z.unknown().optional(),
363
+ /** Admin panel access */
364
+ admin: z.unknown().optional(),
365
+ /** Unlock (for locked documents) */
366
+ unlock: z.unknown().optional(),
367
+ /** Read versions */
368
+ readVersions: z.unknown().optional(),
369
+ })
370
+ .optional();
371
+ /**
372
+ * Collection hooks schema
373
+ *
374
+ * Hooks are typed as unknown arrays because they're runtime functions
375
+ */
376
+ export const CollectionHooksSchema = z
377
+ .object({
378
+ // Document lifecycle hooks
379
+ beforeOperation: z.array(z.unknown()).optional(),
380
+ afterOperation: z.array(z.unknown()).optional(),
381
+ beforeValidate: z.array(z.unknown()).optional(),
382
+ beforeChange: z.array(z.unknown()).optional(),
383
+ afterChange: z.array(z.unknown()).optional(),
384
+ beforeRead: z.array(z.unknown()).optional(),
385
+ afterRead: z.array(z.unknown()).optional(),
386
+ beforeDelete: z.array(z.unknown()).optional(),
387
+ afterDelete: z.array(z.unknown()).optional(),
388
+ // Auth hooks (for auth collections)
389
+ beforeLogin: z.array(z.unknown()).optional(),
390
+ afterLogin: z.array(z.unknown()).optional(),
391
+ afterLogout: z.array(z.unknown()).optional(),
392
+ afterRefresh: z.array(z.unknown()).optional(),
393
+ afterMe: z.array(z.unknown()).optional(),
394
+ afterForgotPassword: z.array(z.unknown()).optional(),
395
+ })
396
+ .optional();
397
+ /**
398
+ * Collection admin configuration
399
+ */
400
+ export const CollectionAdminConfigSchema = z
401
+ .object({
402
+ useAsTitle: z.string().optional(),
403
+ defaultColumns: z.array(z.string()).optional(),
404
+ group: z.string().optional(),
405
+ hidden: z.boolean().optional(),
406
+ description: z.string().optional(),
407
+ preview: z.unknown().optional(), // Function - not validated
408
+ livePreview: z
409
+ .object({
410
+ url: z.unknown().optional(), // Function
411
+ breakpoints: z
412
+ .array(z.object({
413
+ name: z.string(),
414
+ width: z.number(),
415
+ height: z.number(),
416
+ }))
417
+ .optional(),
418
+ })
419
+ .optional(),
420
+ pagination: z
421
+ .object({
422
+ defaultLimit: z.number().optional(),
423
+ limits: z.array(z.number()).optional(),
424
+ })
425
+ .optional(),
426
+ listSearchableFields: z.array(z.string()).optional(),
427
+ enableRichTextLink: z.boolean().optional(),
428
+ enableRichTextRelationship: z.boolean().optional(),
429
+ })
430
+ .passthrough()
431
+ .optional();
432
+ /**
433
+ * Versions configuration schema (for collections)
434
+ */
435
+ export const VersionsConfigSchema = z
436
+ .union([
437
+ z.boolean(),
438
+ z.object({
439
+ maxPerDoc: z.number().int().optional(),
440
+ drafts: z
441
+ .union([
442
+ z.boolean(),
443
+ z.object({
444
+ autosave: z
445
+ .union([
446
+ z.boolean(),
447
+ z.object({
448
+ interval: z.number().int().optional(),
449
+ }),
450
+ ])
451
+ .optional(),
452
+ validate: z.boolean().optional(),
453
+ }),
454
+ ])
455
+ .optional(),
456
+ }),
457
+ ])
458
+ .optional();
459
+ // Alias for backward compatibility - use VersionsConfigSchema for collections/globals
460
+ export const VersionConfigSchema = VersionsConfigSchema;
461
+ /**
462
+ * Global versions configuration schema
463
+ * (Same as VersionsConfigSchema but exported separately for clarity)
464
+ */
465
+ export const GlobalVersionsConfigSchema = z
466
+ .union([
467
+ z.boolean(),
468
+ z.object({
469
+ /** Max versions to keep */
470
+ max: z.number().int().optional(),
471
+ /** Enable drafts */
472
+ drafts: z
473
+ .union([
474
+ z.boolean(),
475
+ z.object({
476
+ autosave: z
477
+ .union([
478
+ z.boolean(),
479
+ z.object({
480
+ interval: z.number().int().optional(),
481
+ }),
482
+ ])
483
+ .optional(),
484
+ validate: z.boolean().optional(),
485
+ }),
486
+ ])
487
+ .optional(),
488
+ }),
489
+ ])
490
+ .optional();
491
+ /**
492
+ * Upload configuration
493
+ */
494
+ export const UploadConfigSchema = z
495
+ .union([
496
+ z.boolean(),
497
+ z.object({
498
+ staticURL: z.string().optional(),
499
+ staticDir: z.string().optional(),
500
+ mimeTypes: z.array(z.string()).optional(),
501
+ filesRequiredOnCreate: z.boolean().optional(),
502
+ imageSizes: z
503
+ .array(z.object({
504
+ name: z.string(),
505
+ width: z.number().optional(),
506
+ height: z.number().optional(),
507
+ position: z
508
+ .enum(['centre', 'center', 'top', 'right', 'bottom', 'left', 'entropy', 'attention'])
509
+ .optional(),
510
+ fit: z.enum(['cover', 'contain', 'fill', 'inside', 'outside']).optional(),
511
+ }))
512
+ .optional(),
513
+ adminThumbnail: z.union([z.string(), z.unknown()]).optional(),
514
+ focalPoint: z.boolean().optional(),
515
+ crop: z.boolean().optional(),
516
+ }),
517
+ ])
518
+ .optional();
519
+ /**
520
+ * Auth configuration
521
+ */
522
+ export const AuthConfigSchema = z
523
+ .union([
524
+ z.boolean(),
525
+ z.object({
526
+ tokenExpiration: z.number().optional(),
527
+ verify: z
528
+ .union([
529
+ z.boolean(),
530
+ z.object({
531
+ generateEmailHTML: z.unknown().optional(),
532
+ generateEmailSubject: z.unknown().optional(),
533
+ }),
534
+ ])
535
+ .optional(),
536
+ maxLoginAttempts: z.number().optional(),
537
+ lockTime: z.number().optional(),
538
+ useAPIKey: z.boolean().optional(),
539
+ depth: z.number().optional(),
540
+ cookies: z
541
+ .object({
542
+ secure: z.boolean().optional(),
543
+ sameSite: z.enum(['strict', 'lax', 'none']).or(z.boolean()).optional(),
544
+ domain: z.string().optional(),
545
+ })
546
+ .optional(),
547
+ forgotPassword: z
548
+ .object({
549
+ generateEmailHTML: z.unknown().optional(),
550
+ generateEmailSubject: z.unknown().optional(),
551
+ })
552
+ .optional(),
553
+ disableLocalStrategy: z.boolean().optional(),
554
+ strategies: z.array(z.unknown()).optional(),
555
+ }),
556
+ ])
557
+ .optional();
558
+ /**
559
+ * TypeScript generation configuration
560
+ */
561
+ export const TypeScriptConfigSchema = z
562
+ .object({
563
+ interface: z.string().optional(),
564
+ })
565
+ .optional();
566
+ /**
567
+ * Collection structure schema
568
+ *
569
+ * Validates the structural parts of a collection configuration.
570
+ * Does NOT validate: access, hooks, endpoints (functions)
571
+ */
572
+ export const CollectionStructureSchema = z
573
+ .object({
574
+ // Required
575
+ slug: z
576
+ .string()
577
+ .min(1)
578
+ .regex(/^[a-z][a-z0-9-]*$/, {
579
+ message: 'Slug must start with lowercase letter and contain only lowercase letters, numbers, and hyphens',
580
+ }),
581
+ // Labels
582
+ labels: CollectionLabelsSchema,
583
+ // Fields
584
+ fields: z.array(FieldStructureSchema),
585
+ // Timestamps
586
+ timestamps: z.boolean().optional(),
587
+ // Admin
588
+ admin: CollectionAdminConfigSchema,
589
+ // Versions
590
+ versions: VersionsConfigSchema,
591
+ // Upload
592
+ upload: UploadConfigSchema,
593
+ // Auth
594
+ auth: AuthConfigSchema,
595
+ // TypeScript
596
+ typescript: TypeScriptConfigSchema,
597
+ // Custom ID type
598
+ custom: z.record(z.string(), z.unknown()).optional(),
599
+ // Database settings
600
+ dbName: z.string().optional(),
601
+ // Default sort
602
+ defaultSort: z.string().optional(),
603
+ // Note: access, hooks, endpoints are functions - not validated here
604
+ })
605
+ .passthrough();
606
+ /**
607
+ * Full Collection Config Schema (includes access/hooks)
608
+ *
609
+ * This is the complete collection config schema including function properties.
610
+ * For structure-only validation, use CollectionStructureSchema.
611
+ */
612
+ export const CollectionConfigSchema = CollectionStructureSchema.extend({
613
+ /** Access control */
614
+ access: CollectionAccessSchema,
615
+ /** Lifecycle hooks */
616
+ hooks: CollectionHooksSchema,
617
+ /** Custom endpoints */
618
+ endpoints: z
619
+ .array(z.object({
620
+ path: z.string(),
621
+ method: z.enum(['get', 'post', 'put', 'patch', 'delete', 'connect', 'options', 'head']),
622
+ handler: z.unknown(), // Function - not validated
623
+ root: z.boolean().optional(),
624
+ }))
625
+ .optional(),
626
+ /** Schema version */
627
+ schemaVersion: z.number().int().default(COLLECTION_SCHEMA_VERSION).optional(),
628
+ }).passthrough();
629
+ /**
630
+ * Sanitized Collection Config Schema (after processing)
631
+ */
632
+ export const SanitizedCollectionConfigSchema = CollectionConfigSchema.extend({
633
+ /** Flattened field paths */
634
+ flattenedFields: z.array(FieldStructureSchema).optional(),
635
+ });
636
+ // ============================================
637
+ // GLOBAL STRUCTURE SCHEMAS
638
+ // ============================================
639
+ /**
640
+ * Global labels configuration
641
+ */
642
+ export const GlobalLabelsSchema = z
643
+ .object({
644
+ singular: z.string(),
645
+ plural: z.string().optional(),
646
+ })
647
+ .optional();
648
+ /**
649
+ * Global access control schema
650
+ */
651
+ export const GlobalAccessSchema = z
652
+ .object({
653
+ /** Read access */
654
+ read: z.unknown().optional(),
655
+ /** Update access */
656
+ update: z.unknown().optional(),
657
+ /** Read versions */
658
+ readVersions: z.unknown().optional(),
659
+ })
660
+ .optional();
661
+ /**
662
+ * Global hooks schema
663
+ */
664
+ export const GlobalHooksSchema = z
665
+ .object({
666
+ beforeValidate: z.array(z.unknown()).optional(),
667
+ beforeChange: z.array(z.unknown()).optional(),
668
+ afterChange: z.array(z.unknown()).optional(),
669
+ beforeRead: z.array(z.unknown()).optional(),
670
+ afterRead: z.array(z.unknown()).optional(),
671
+ })
672
+ .optional();
673
+ /**
674
+ * Global admin configuration
675
+ */
676
+ export const GlobalAdminConfigSchema = z
677
+ .object({
678
+ group: z.string().optional(),
679
+ hidden: z.boolean().optional(),
680
+ description: z.string().optional(),
681
+ preview: z.unknown().optional(),
682
+ livePreview: z
683
+ .object({
684
+ url: z.unknown().optional(),
685
+ breakpoints: z
686
+ .array(z.object({
687
+ name: z.string(),
688
+ width: z.number(),
689
+ height: z.number(),
690
+ }))
691
+ .optional(),
692
+ })
693
+ .optional(),
694
+ })
695
+ .passthrough()
696
+ .optional();
697
+ /**
698
+ * Global structure schema
699
+ */
700
+ export const GlobalStructureSchema = z
701
+ .object({
702
+ // Required
703
+ slug: z
704
+ .string()
705
+ .min(1)
706
+ .regex(/^[a-z][a-z0-9-]*$/, {
707
+ message: 'Slug must start with lowercase letter and contain only lowercase letters, numbers, and hyphens',
708
+ }),
709
+ // Labels
710
+ label: z.string().optional(),
711
+ labels: GlobalLabelsSchema,
712
+ // Fields
713
+ fields: z.array(FieldStructureSchema),
714
+ // Admin
715
+ admin: GlobalAdminConfigSchema,
716
+ // Versions
717
+ versions: VersionsConfigSchema,
718
+ // TypeScript
719
+ typescript: TypeScriptConfigSchema,
720
+ // Database
721
+ dbName: z.string().optional(),
722
+ // Note: access, hooks, endpoints are functions - not validated here
723
+ })
724
+ .passthrough();
725
+ /**
726
+ * Full Global Config Schema (includes access/hooks)
727
+ *
728
+ * This is the complete global config schema including function properties.
729
+ * For structure-only validation, use GlobalStructureSchema.
730
+ */
731
+ export const GlobalConfigSchema = GlobalStructureSchema.extend({
732
+ /** Access control */
733
+ access: GlobalAccessSchema,
734
+ /** Lifecycle hooks */
735
+ hooks: GlobalHooksSchema,
736
+ /** Versions config (use GlobalVersionsConfigSchema) */
737
+ versions: GlobalVersionsConfigSchema,
738
+ /** Custom endpoints */
739
+ endpoints: z
740
+ .array(z.object({
741
+ path: z.string(),
742
+ method: z.enum(['get', 'post', 'put', 'patch', 'delete', 'connect', 'options', 'head']),
743
+ handler: z.unknown(), // Function - not validated
744
+ root: z.boolean().optional(),
745
+ }))
746
+ .optional(),
747
+ /** Schema version */
748
+ schemaVersion: z.number().int().default(GLOBAL_SCHEMA_VERSION).optional(),
749
+ }).passthrough();
750
+ /**
751
+ * Sanitized Global Config Schema (after processing)
752
+ */
753
+ export const SanitizedGlobalConfigSchema = GlobalConfigSchema.extend({
754
+ /** Flattened field paths */
755
+ flattenedFields: z.array(FieldStructureSchema).optional(),
756
+ });
757
+ //# sourceMappingURL=structure.js.map