@object-ui/types 0.3.0 → 0.5.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 (169) hide show
  1. package/README.md +19 -11
  2. package/dist/api-types.d.ts +7 -0
  3. package/dist/api-types.d.ts.map +1 -1
  4. package/dist/api-types.js +4 -6
  5. package/dist/app.d.ts +17 -0
  6. package/dist/app.d.ts.map +1 -1
  7. package/dist/app.js +4 -3
  8. package/dist/base.d.ts +7 -0
  9. package/dist/base.d.ts.map +1 -1
  10. package/dist/base.js +4 -6
  11. package/dist/blocks.d.ts +332 -0
  12. package/dist/blocks.d.ts.map +1 -0
  13. package/dist/blocks.js +8 -0
  14. package/dist/complex.d.ts +68 -1
  15. package/dist/complex.d.ts.map +1 -1
  16. package/dist/complex.js +4 -5
  17. package/dist/crud.d.ts +181 -3
  18. package/dist/crud.d.ts.map +1 -1
  19. package/dist/crud.js +4 -6
  20. package/dist/data-display.d.ts +54 -2
  21. package/dist/data-display.d.ts.map +1 -1
  22. package/dist/data-display.js +4 -5
  23. package/dist/data-protocol.d.ts +1268 -0
  24. package/dist/data-protocol.d.ts.map +1 -0
  25. package/dist/data-protocol.js +8 -0
  26. package/dist/data.d.ts +22 -1
  27. package/dist/data.d.ts.map +1 -1
  28. package/dist/data.js +4 -6
  29. package/dist/disclosure.d.ts +70 -1
  30. package/dist/disclosure.d.ts.map +1 -1
  31. package/dist/disclosure.js +4 -5
  32. package/dist/feedback.d.ts +68 -1
  33. package/dist/feedback.d.ts.map +1 -1
  34. package/dist/feedback.js +4 -5
  35. package/dist/field-types.d.ts +728 -0
  36. package/dist/field-types.d.ts.map +1 -0
  37. package/dist/field-types.js +8 -0
  38. package/dist/form.d.ts +123 -1
  39. package/dist/form.d.ts.map +1 -1
  40. package/dist/form.js +4 -5
  41. package/dist/index.d.ts +48 -13
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +4 -37
  44. package/dist/layout.d.ts +66 -16
  45. package/dist/layout.d.ts.map +1 -1
  46. package/dist/layout.js +4 -6
  47. package/dist/navigation.d.ts +102 -2
  48. package/dist/navigation.d.ts.map +1 -1
  49. package/dist/navigation.js +4 -5
  50. package/dist/objectql.d.ts +491 -54
  51. package/dist/objectql.d.ts.map +1 -1
  52. package/dist/objectql.js +4 -6
  53. package/dist/overlay.d.ts +31 -1
  54. package/dist/overlay.d.ts.map +1 -1
  55. package/dist/overlay.js +4 -5
  56. package/dist/plugin-scope.d.ts +194 -0
  57. package/dist/plugin-scope.d.ts.map +1 -0
  58. package/dist/plugin-scope.js +8 -0
  59. package/dist/registry.d.ts +7 -0
  60. package/dist/registry.d.ts.map +1 -1
  61. package/dist/registry.js +7 -0
  62. package/dist/reports.d.ts +336 -0
  63. package/dist/reports.d.ts.map +1 -0
  64. package/dist/reports.js +8 -0
  65. package/dist/theme.d.ts +289 -0
  66. package/dist/theme.d.ts.map +1 -0
  67. package/dist/theme.js +8 -0
  68. package/dist/ui-action.d.ts +175 -0
  69. package/dist/ui-action.d.ts.map +1 -0
  70. package/dist/ui-action.js +8 -0
  71. package/dist/views.d.ts +417 -0
  72. package/dist/views.d.ts.map +1 -0
  73. package/dist/views.js +8 -0
  74. package/dist/zod/app.zod.d.ts +120 -0
  75. package/dist/zod/app.zod.d.ts.map +1 -0
  76. package/dist/zod/app.zod.js +60 -0
  77. package/dist/zod/base.zod.d.ts +202 -0
  78. package/dist/zod/base.zod.d.ts.map +1 -0
  79. package/dist/zod/base.zod.js +198 -0
  80. package/dist/zod/blocks.zod.d.ts +834 -0
  81. package/dist/zod/blocks.zod.d.ts.map +1 -0
  82. package/dist/zod/blocks.zod.js +145 -0
  83. package/dist/zod/complex.zod.d.ts +742 -0
  84. package/dist/zod/complex.zod.d.ts.map +1 -0
  85. package/dist/zod/complex.zod.js +233 -0
  86. package/dist/zod/crud.zod.d.ts +598 -0
  87. package/dist/zod/crud.zod.d.ts.map +1 -0
  88. package/dist/zod/crud.zod.js +230 -0
  89. package/dist/zod/data-display.zod.d.ts +996 -0
  90. package/dist/zod/data-display.zod.d.ts.map +1 -0
  91. package/dist/zod/data-display.zod.js +266 -0
  92. package/dist/zod/disclosure.zod.d.ts +267 -0
  93. package/dist/zod/disclosure.zod.d.ts.map +1 -0
  94. package/dist/zod/disclosure.zod.js +84 -0
  95. package/dist/zod/feedback.zod.d.ts +538 -0
  96. package/dist/zod/feedback.zod.d.ts.map +1 -0
  97. package/dist/zod/feedback.zod.js +127 -0
  98. package/dist/zod/form.zod.d.ts +1308 -0
  99. package/dist/zod/form.zod.d.ts.map +1 -0
  100. package/dist/zod/form.zod.js +406 -0
  101. package/dist/zod/index.zod.d.ts +4985 -0
  102. package/dist/zod/index.zod.d.ts.map +1 -0
  103. package/dist/zod/index.zod.js +183 -0
  104. package/dist/zod/layout.zod.d.ts +1048 -0
  105. package/dist/zod/layout.zod.d.ts.map +1 -0
  106. package/dist/zod/layout.zod.js +241 -0
  107. package/dist/zod/navigation.zod.d.ts +486 -0
  108. package/dist/zod/navigation.zod.d.ts.map +1 -0
  109. package/dist/zod/navigation.zod.js +142 -0
  110. package/dist/zod/objectql.zod.d.ts +1261 -0
  111. package/dist/zod/objectql.zod.d.ts.map +1 -0
  112. package/dist/zod/objectql.zod.js +248 -0
  113. package/dist/zod/overlay.zod.d.ts +691 -0
  114. package/dist/zod/overlay.zod.d.ts.map +1 -0
  115. package/dist/zod/overlay.zod.js +179 -0
  116. package/dist/zod/reports.zod.d.ts +1628 -0
  117. package/dist/zod/reports.zod.d.ts.map +1 -0
  118. package/dist/zod/reports.zod.js +152 -0
  119. package/dist/zod/theme.zod.d.ts +611 -0
  120. package/dist/zod/theme.zod.d.ts.map +1 -0
  121. package/dist/zod/theme.zod.js +130 -0
  122. package/dist/zod/views.zod.d.ts +675 -0
  123. package/dist/zod/views.zod.d.ts.map +1 -0
  124. package/dist/zod/views.zod.js +159 -0
  125. package/package.json +9 -1
  126. package/src/__tests__/namespace-exports.test.ts +80 -0
  127. package/src/__tests__/phase2-schemas.test.ts +639 -0
  128. package/src/api-types.ts +8 -0
  129. package/src/app.ts +20 -0
  130. package/src/base.ts +8 -0
  131. package/src/blocks.ts +405 -0
  132. package/src/complex.ts +69 -1
  133. package/src/crud.ts +185 -3
  134. package/src/data-display.ts +60 -2
  135. package/src/data-protocol.ts +1679 -0
  136. package/src/data.ts +21 -1
  137. package/src/disclosure.ts +74 -1
  138. package/src/feedback.ts +76 -2
  139. package/src/field-types.ts +846 -0
  140. package/src/form.ts +131 -1
  141. package/src/index.ts +305 -8
  142. package/src/layout.ts +70 -15
  143. package/src/navigation.ts +109 -2
  144. package/src/objectql.ts +563 -59
  145. package/src/overlay.ts +35 -1
  146. package/src/plugin-scope.ts +210 -0
  147. package/src/registry.ts +8 -0
  148. package/src/reports.ts +408 -0
  149. package/src/theme.ts +351 -0
  150. package/src/ui-action.ts +276 -0
  151. package/src/views.ts +429 -0
  152. package/src/zod/README.md +329 -0
  153. package/src/zod/app.zod.ts +72 -0
  154. package/src/zod/base.zod.ts +229 -0
  155. package/src/zod/blocks.zod.ts +170 -0
  156. package/src/zod/complex.zod.ts +258 -0
  157. package/src/zod/crud.zod.ts +259 -0
  158. package/src/zod/data-display.zod.ts +290 -0
  159. package/src/zod/disclosure.zod.ts +92 -0
  160. package/src/zod/feedback.zod.ts +138 -0
  161. package/src/zod/form.zod.ts +434 -0
  162. package/src/zod/index.zod.ts +425 -0
  163. package/src/zod/layout.zod.ts +262 -0
  164. package/src/zod/navigation.zod.ts +159 -0
  165. package/src/zod/objectql.zod.ts +268 -0
  166. package/src/zod/overlay.zod.ts +196 -0
  167. package/src/zod/reports.zod.ts +183 -0
  168. package/src/zod/theme.zod.ts +155 -0
  169. package/src/zod/views.zod.ts +182 -0
@@ -0,0 +1,329 @@
1
+ # ObjectUI Zod Validation Schemas
2
+
3
+ Complete Zod validation schemas for all ObjectUI components, following the @objectstack/spec UI specification format.
4
+
5
+ ## Overview
6
+
7
+ This directory contains runtime validation schemas using [Zod](https://github.com/colinhacks/zod) for all ObjectUI component types. These schemas provide:
8
+
9
+ - **Type-safe runtime validation** of component configurations
10
+ - **Compliance with @objectstack/spec** UI specification format
11
+ - **Auto-completion and IntelliSense** through TypeScript integration
12
+ - **Detailed error messages** for invalid configurations
13
+
14
+ ## Installation
15
+
16
+ The Zod schemas are included in the `@object-ui/types` package:
17
+
18
+ ```bash
19
+ npm install @object-ui/types zod
20
+ # or
21
+ pnpm add @object-ui/types zod
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Basic Validation
27
+
28
+ ```typescript
29
+ import { ButtonSchema, InputSchema } from '@object-ui/types/zod';
30
+
31
+ // Validate a button configuration
32
+ const buttonConfig = {
33
+ type: 'button',
34
+ label: 'Click Me',
35
+ variant: 'primary',
36
+ onClick: () => console.log('clicked'),
37
+ };
38
+
39
+ const result = ButtonSchema.safeParse(buttonConfig);
40
+
41
+ if (result.success) {
42
+ console.log('Valid config:', result.data);
43
+ } else {
44
+ console.error('Validation errors:', result.error);
45
+ }
46
+ ```
47
+
48
+ ### Form Validation
49
+
50
+ ```typescript
51
+ import { FormSchema } from '@object-ui/types/zod';
52
+
53
+ const formConfig = {
54
+ type: 'form',
55
+ fields: [
56
+ {
57
+ name: 'email',
58
+ label: 'Email',
59
+ type: 'input',
60
+ inputType: 'email',
61
+ required: true,
62
+ },
63
+ {
64
+ name: 'password',
65
+ label: 'Password',
66
+ type: 'input',
67
+ inputType: 'password',
68
+ required: true,
69
+ },
70
+ ],
71
+ submitLabel: 'Sign In',
72
+ layout: 'vertical',
73
+ };
74
+
75
+ const result = FormSchema.safeParse(formConfig);
76
+ ```
77
+
78
+ ### Runtime Type Inference
79
+
80
+ ```typescript
81
+ import { z } from 'zod';
82
+ import { ButtonSchema, InputSchema } from '@object-ui/types/zod';
83
+
84
+ // Infer TypeScript type from schema
85
+ type Button = z.infer<typeof ButtonSchema>;
86
+ type Input = z.infer<typeof InputSchema>;
87
+ ```
88
+
89
+ ### Generic Component Validation
90
+
91
+ ```typescript
92
+ import { AnyComponentSchema } from '@object-ui/types/zod';
93
+
94
+ function validateComponent(config: unknown) {
95
+ const result = AnyComponentSchema.safeParse(config);
96
+
97
+ if (!result.success) {
98
+ throw new Error(`Invalid component: ${result.error.message}`);
99
+ }
100
+
101
+ return result.data;
102
+ }
103
+ ```
104
+
105
+ ## Available Schemas
106
+
107
+ ### Base Schemas
108
+ - `BaseSchema` - Foundation for all components
109
+ - `SchemaNodeSchema` - Recursive schema node type
110
+
111
+ ### Layout Components (17)
112
+ - `DivSchema`, `SpanSchema`, `TextSchema`
113
+ - `ImageSchema`, `IconSchema`, `SeparatorSchema`
114
+ - `ContainerSchema`, `FlexSchema`, `StackSchema`
115
+ - `GridSchema`, `CardSchema`, `TabsSchema`
116
+ - `ScrollAreaSchema`, `ResizableSchema`
117
+ - `AspectRatioSchema`, `PageSchema`
118
+
119
+ ### Form Components (17)
120
+ - `ButtonSchema`, `InputSchema`, `TextareaSchema`
121
+ - `SelectSchema`, `CheckboxSchema`, `RadioGroupSchema`
122
+ - `SwitchSchema`, `ToggleSchema`, `SliderSchema`
123
+ - `FileUploadSchema`, `DatePickerSchema`, `CalendarSchema`
124
+ - `InputOTPSchema`, `ComboboxSchema`, `LabelSchema`
125
+ - `CommandSchema`, `FormSchema`
126
+
127
+ ### Data Display Components (14)
128
+ - `AlertSchema`, `BadgeSchema`, `AvatarSchema`
129
+ - `ListSchema`, `TableSchema`, `DataTableSchema`
130
+ - `MarkdownSchema`, `TreeViewSchema`, `ChartSchema`
131
+ - `TimelineSchema`, `BreadcrumbSchema`
132
+ - `KbdSchema`, `HtmlSchema`, `StatisticSchema`
133
+
134
+ ### Feedback Components (8)
135
+ - `LoadingSchema`, `ProgressSchema`, `SkeletonSchema`
136
+ - `ToastSchema`, `ToasterSchema`, `SpinnerSchema`
137
+ - `EmptySchema`, `SonnerSchema`
138
+
139
+ ### Disclosure Components (3)
140
+ - `AccordionSchema`, `CollapsibleSchema`, `ToggleGroupSchema`
141
+
142
+ ### Overlay Components (10)
143
+ - `DialogSchema`, `AlertDialogSchema`, `SheetSchema`
144
+ - `DrawerSchema`, `PopoverSchema`, `TooltipSchema`
145
+ - `HoverCardSchema`, `DropdownMenuSchema`
146
+ - `ContextMenuSchema`, `MenubarSchema`
147
+
148
+ ### Navigation Components (6)
149
+ - `HeaderBarSchema`, `SidebarSchema`, `BreadcrumbSchema`
150
+ - `PaginationSchema`, `NavigationMenuSchema`, `ButtonGroupSchema`
151
+
152
+ ### Complex Components (5)
153
+ - `KanbanSchema`, `CalendarViewSchema`
154
+ - `FilterBuilderSchema`, `CarouselSchema`, `ChatbotSchema`
155
+
156
+ ## Schema Structure
157
+
158
+ All component schemas follow the @objectstack/spec UI specification format:
159
+
160
+ ```typescript
161
+ {
162
+ // Required
163
+ type: string, // Component type identifier
164
+
165
+ // Common Optional Properties
166
+ id?: string, // Unique identifier
167
+ name?: string, // Component name
168
+ label?: string, // Display label
169
+ className?: string, // Tailwind classes
170
+ visible?: boolean, // Visibility control
171
+ disabled?: boolean, // Disabled state
172
+
173
+ // Type-specific properties...
174
+ }
175
+ ```
176
+
177
+ ## Validation Features
178
+
179
+ ### Type Safety
180
+ - Strict type checking for all properties
181
+ - Enum validation for predefined values
182
+ - Recursive validation for nested structures
183
+
184
+ ### Error Messages
185
+ ```typescript
186
+ const result = ButtonSchema.safeParse({
187
+ type: 'button',
188
+ variant: 'invalid-variant'
189
+ });
190
+
191
+ // result.error.errors:
192
+ // [
193
+ // {
194
+ // code: 'invalid_enum_value',
195
+ // path: ['variant'],
196
+ // message: "Invalid enum value. Expected 'default' | 'secondary' | ...",
197
+ // }
198
+ // ]
199
+ ```
200
+
201
+ ### Nested Validation
202
+ ```typescript
203
+ // Validates nested components in Card
204
+ const cardWithChildren = CardSchema.parse({
205
+ type: 'card',
206
+ title: 'My Card',
207
+ children: [
208
+ { type: 'text', value: 'Hello' },
209
+ { type: 'button', label: 'Click' }
210
+ ]
211
+ });
212
+ ```
213
+
214
+ ## Best Practices
215
+
216
+ 1. **Use safeParse()** for user input validation
217
+ ```typescript
218
+ const result = ButtonSchema.safeParse(userInput);
219
+ if (!result.success) {
220
+ // Handle errors gracefully
221
+ }
222
+ ```
223
+
224
+ 2. **Use parse()** for internal configurations
225
+ ```typescript
226
+ // Throws error on invalid data
227
+ const config = ButtonSchema.parse(internalConfig);
228
+ ```
229
+
230
+ 3. **Validate at boundaries**
231
+ - API endpoints receiving component configs
232
+ - Form submissions
233
+ - Configuration file parsing
234
+ - Component registration
235
+
236
+ 4. **Combine with TypeScript types**
237
+ ```typescript
238
+ import type { ButtonSchema as ButtonType } from '@object-ui/types';
239
+ import { ButtonSchema } from '@object-ui/types/zod';
240
+
241
+ // Use type for declarations
242
+ const config: ButtonType = { ... };
243
+
244
+ // Use schema for validation
245
+ ButtonSchema.parse(config);
246
+ ```
247
+
248
+ ## Performance
249
+
250
+ Zod schemas are designed for runtime validation:
251
+
252
+ - **Lazy evaluation** for recursive schemas (trees, menus)
253
+ - **Optional validation** - only validate when needed
254
+ - **Partial validation** - validate specific properties
255
+ - **Caching** - Zod internally caches schema structures
256
+
257
+ ## Integration Examples
258
+
259
+ ### With React Hook Form
260
+ ```typescript
261
+ import { zodResolver } from '@hookform/resolvers/zod';
262
+ import { FormSchema } from '@object-ui/types/zod';
263
+
264
+ const form = useForm({
265
+ resolver: zodResolver(FormSchema),
266
+ });
267
+ ```
268
+
269
+ ### With API Routes
270
+ ```typescript
271
+ import { ButtonSchema } from '@object-ui/types/zod';
272
+
273
+ export async function POST(req: Request) {
274
+ const body = await req.json();
275
+ const result = ButtonSchema.safeParse(body);
276
+
277
+ if (!result.success) {
278
+ return Response.json(
279
+ { error: result.error },
280
+ { status: 400 }
281
+ );
282
+ }
283
+
284
+ // Process valid data
285
+ return Response.json(result.data);
286
+ }
287
+ ```
288
+
289
+ ### With Component Registry
290
+ ```typescript
291
+ import { AnyComponentSchema } from '@object-ui/types/zod';
292
+
293
+ function registerComponent(config: unknown) {
294
+ // Validate before registration
295
+ const validated = AnyComponentSchema.parse(config);
296
+ registry.set(validated.type, validated);
297
+ }
298
+ ```
299
+
300
+ ## Migration from TypeScript-only Types
301
+
302
+ If you're currently using only TypeScript types:
303
+
304
+ ```typescript
305
+ // Before (TypeScript only)
306
+ import type { ButtonSchema } from '@object-ui/types';
307
+ const button: ButtonSchema = { ... };
308
+
309
+ // After (with runtime validation)
310
+ import type { ButtonSchema as ButtonType } from '@object-ui/types';
311
+ import { ButtonSchema } from '@object-ui/types/zod';
312
+
313
+ const button: ButtonType = { ... };
314
+ const validated = ButtonSchema.parse(button);
315
+ ```
316
+
317
+ ## Contributing
318
+
319
+ When adding new component types:
320
+
321
+ 1. Define TypeScript interface in `src/`
322
+ 2. Create corresponding Zod schema in `src/zod/`
323
+ 3. Export from `src/zod/index.zod.ts`
324
+ 4. Add tests in `examples/zod-validation-example.ts`
325
+ 5. Update this README
326
+
327
+ ## License
328
+
329
+ MIT - Copyright (c) 2024-present ObjectStack Inc.
@@ -0,0 +1,72 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ /**
10
+ * @object-ui/types/zod - Application Schema Zod Validators
11
+ *
12
+ * Zod validation schemas for top-level application configuration.
13
+ * Following @objectstack/spec UI specification format.
14
+ *
15
+ * @module zod/app
16
+ * @packageDocumentation
17
+ */
18
+
19
+ import { z } from 'zod';
20
+ import { BaseSchema } from './base.zod.js';
21
+
22
+ /**
23
+ * Menu Item Schema - Navigation menu item
24
+ */
25
+ export const MenuItemSchema: z.ZodType<any> = z.lazy(() => z.object({
26
+ type: z.enum(['item', 'group', 'separator']).optional().describe('Item type'),
27
+ label: z.string().optional().describe('Display label'),
28
+ icon: z.string().optional().describe('Icon name (Lucide)'),
29
+ path: z.string().optional().describe('Target path (route)'),
30
+ href: z.string().optional().describe('External link'),
31
+ children: z.array(MenuItemSchema).optional().describe('Child items (submenu)'),
32
+ badge: z.union([z.string(), z.number()]).optional().describe('Badge or count'),
33
+ hidden: z.union([z.boolean(), z.string()]).optional().describe('Visibility condition'),
34
+ }));
35
+
36
+ /**
37
+ * App Action Schema - Application header/toolbar action
38
+ */
39
+ export const AppActionSchema = z.object({
40
+ type: z.enum(['button', 'dropdown', 'user']).describe('Action type'),
41
+ label: z.string().optional().describe('Action label'),
42
+ icon: z.string().optional().describe('Icon name'),
43
+ onClick: z.string().optional().describe('Click handler expression'),
44
+ avatar: z.string().optional().describe('User avatar URL (for type="user")'),
45
+ description: z.string().optional().describe('Additional description (e.g., email for user)'),
46
+ items: z.array(MenuItemSchema).optional().describe('Dropdown menu items (for type="dropdown" or "user")'),
47
+ shortcut: z.string().optional().describe('Keyboard shortcut'),
48
+ variant: z.enum(['default', 'destructive', 'outline', 'secondary', 'ghost', 'link']).optional().describe('Button variant'),
49
+ size: z.enum(['default', 'sm', 'lg', 'icon']).optional().describe('Button size'),
50
+ });
51
+
52
+ /**
53
+ * App Schema - Top-level application configuration
54
+ */
55
+ export const AppSchema = BaseSchema.extend({
56
+ type: z.literal('app'),
57
+ name: z.string().optional().describe('Application name (system ID)'),
58
+ title: z.string().optional().describe('Display title'),
59
+ description: z.string().optional().describe('Application description'),
60
+ logo: z.string().optional().describe('Logo URL or icon name'),
61
+ favicon: z.string().optional().describe('Favicon URL'),
62
+ layout: z.enum(['sidebar', 'header', 'empty']).optional().default('sidebar').describe('Global layout strategy'),
63
+ menu: z.array(MenuItemSchema).optional().describe('Global navigation menu'),
64
+ actions: z.array(AppActionSchema).optional().describe('Global actions (user profile, settings, etc.)'),
65
+ });
66
+
67
+ /**
68
+ * Export type inference helpers
69
+ */
70
+ export type MenuItemSchemaType = z.infer<typeof MenuItemSchema>;
71
+ export type AppActionSchemaType = z.infer<typeof AppActionSchema>;
72
+ export type AppSchemaType = z.infer<typeof AppSchema>;
@@ -0,0 +1,229 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ /**
10
+ * @object-ui/types/zod - Base Schema Zod Validators
11
+ *
12
+ * Zod validation schemas for base component types.
13
+ * These schemas follow the @objectstack/spec UI specification format.
14
+ *
15
+ * @module zod/base
16
+ * @packageDocumentation
17
+ */
18
+
19
+ import { z } from 'zod';
20
+
21
+ /**
22
+ * Schema Node - Can be a schema object or primitive value
23
+ */
24
+ export const SchemaNodeSchema: z.ZodType<any> = z.lazy(() =>
25
+ z.union([
26
+ BaseSchemaCore,
27
+ z.string(),
28
+ z.number(),
29
+ z.boolean(),
30
+ z.null(),
31
+ z.undefined(),
32
+ ])
33
+ );
34
+
35
+ /**
36
+ * Base Schema - Core validation schema that all components extend
37
+ *
38
+ * This is the foundation for all UI component schemas in ObjectUI.
39
+ * Following @objectstack/spec UI specification format.
40
+ */
41
+ const BaseSchemaCore = z.object({
42
+ /**
43
+ * Component type identifier
44
+ */
45
+ type: z.string().describe('Component type identifier'),
46
+
47
+ /**
48
+ * Unique identifier for the component
49
+ */
50
+ id: z.string().optional().describe('Unique component identifier'),
51
+
52
+ /**
53
+ * Human-readable name
54
+ */
55
+ name: z.string().optional().describe('Component name'),
56
+
57
+ /**
58
+ * Display label
59
+ */
60
+ label: z.string().optional().describe('Display label'),
61
+
62
+ /**
63
+ * Description text
64
+ */
65
+ description: z.string().optional().describe('Description text'),
66
+
67
+ /**
68
+ * Placeholder text
69
+ */
70
+ placeholder: z.string().optional().describe('Placeholder text'),
71
+
72
+ /**
73
+ * Tailwind CSS classes
74
+ */
75
+ className: z.string().optional().describe('Tailwind CSS classes'),
76
+
77
+ /**
78
+ * Inline styles
79
+ */
80
+ style: z.record(z.string(), z.union([z.string(), z.number()])).optional().describe('Inline CSS styles'),
81
+
82
+ /**
83
+ * Arbitrary data
84
+ */
85
+ data: z.any().optional().describe('Custom data payload'),
86
+
87
+ /**
88
+ * Child components or content
89
+ */
90
+ body: z.union([SchemaNodeSchema, z.array(SchemaNodeSchema)]).optional().describe('Child components'),
91
+
92
+ /**
93
+ * Alternative children property
94
+ */
95
+ children: z.union([SchemaNodeSchema, z.array(SchemaNodeSchema)]).optional().describe('Child components (React-style)'),
96
+
97
+ /**
98
+ * Visibility control
99
+ */
100
+ visible: z.boolean().optional().describe('Visibility control'),
101
+
102
+ /**
103
+ * Conditional visibility expression
104
+ */
105
+ visibleOn: z.string().optional().describe('Expression for conditional visibility'),
106
+
107
+ /**
108
+ * Hidden control
109
+ */
110
+ hidden: z.boolean().optional().describe('Hidden control'),
111
+
112
+ /**
113
+ * Conditional hidden expression
114
+ */
115
+ hiddenOn: z.string().optional().describe('Expression for conditional hiding'),
116
+
117
+ /**
118
+ * Disabled state
119
+ */
120
+ disabled: z.boolean().optional().describe('Disabled state'),
121
+
122
+ /**
123
+ * Conditional disabled expression
124
+ */
125
+ disabledOn: z.string().optional().describe('Expression for conditional disabling'),
126
+
127
+ /**
128
+ * Test ID for automated testing
129
+ */
130
+ testId: z.string().optional().describe('Test identifier'),
131
+
132
+ /**
133
+ * Accessibility label
134
+ */
135
+ ariaLabel: z.string().optional().describe('Accessibility label'),
136
+ }).passthrough(); // Allow additional properties for type-specific extensions
137
+
138
+ /**
139
+ * Base Schema - Export for use in other schemas
140
+ */
141
+ export const BaseSchema = BaseSchemaCore;
142
+
143
+ /**
144
+ * Component Input Configuration
145
+ */
146
+ export const ComponentInputSchema = z.object({
147
+ name: z.string().describe('Property name'),
148
+ type: z.enum([
149
+ 'string',
150
+ 'number',
151
+ 'boolean',
152
+ 'enum',
153
+ 'array',
154
+ 'object',
155
+ 'color',
156
+ 'date',
157
+ 'code',
158
+ 'file',
159
+ 'slot',
160
+ ]).describe('Input control type'),
161
+ label: z.string().optional().describe('Display label'),
162
+ defaultValue: z.any().optional().describe('Default value'),
163
+ required: z.boolean().optional().describe('Required flag'),
164
+ enum: z.union([
165
+ z.array(z.string()),
166
+ z.array(z.object({
167
+ label: z.string(),
168
+ value: z.any(),
169
+ })),
170
+ ]).optional().describe('Enum options'),
171
+ description: z.string().optional().describe('Help text'),
172
+ advanced: z.boolean().optional().describe('Advanced option flag'),
173
+ inputType: z.string().optional().describe('Specific input type'),
174
+ min: z.number().optional().describe('Minimum value'),
175
+ max: z.number().optional().describe('Maximum value'),
176
+ step: z.number().optional().describe('Step value'),
177
+ placeholder: z.string().optional().describe('Placeholder text'),
178
+ });
179
+
180
+ /**
181
+ * Component Metadata
182
+ */
183
+ export const ComponentMetaSchema = z.object({
184
+ label: z.string().optional().describe('Display name'),
185
+ icon: z.string().optional().describe('Icon name or SVG'),
186
+ category: z.string().optional().describe('Component category'),
187
+ inputs: z.array(ComponentInputSchema).optional().describe('Configurable properties'),
188
+ defaultProps: z.record(z.string(), z.any()).optional().describe('Default property values'),
189
+ defaultChildren: z.array(SchemaNodeSchema).optional().describe('Default children'),
190
+ examples: z.record(z.string(), z.any()).optional().describe('Example configurations'),
191
+ isContainer: z.boolean().optional().describe('Can have children'),
192
+ resizable: z.boolean().optional().describe('Can be resized'),
193
+ resizeConstraints: z.object({
194
+ width: z.boolean().optional(),
195
+ height: z.boolean().optional(),
196
+ minWidth: z.number().optional(),
197
+ maxWidth: z.number().optional(),
198
+ minHeight: z.number().optional(),
199
+ maxHeight: z.number().optional(),
200
+ }).optional().describe('Resize constraints'),
201
+ tags: z.array(z.string()).optional().describe('Search tags'),
202
+ description: z.string().optional().describe('Component description'),
203
+ });
204
+
205
+ /**
206
+ * Component Configuration
207
+ */
208
+ export const ComponentConfigSchema = ComponentMetaSchema.extend({
209
+ type: z.string().describe('Component type identifier'),
210
+ component: z.any().describe('Component renderer'),
211
+ });
212
+
213
+ /**
214
+ * HTML Attributes (generic)
215
+ */
216
+ export const HTMLAttributesSchema = z.record(z.string(), z.any()).describe('HTML attributes');
217
+
218
+ /**
219
+ * Event Handlers
220
+ */
221
+ export const EventHandlersSchema = z.record(z.string(), z.function()).describe('Event handlers');
222
+
223
+ /**
224
+ * Style Props
225
+ */
226
+ export const StylePropsSchema = z.object({
227
+ className: z.string().optional(),
228
+ style: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
229
+ }).describe('Style properties');