@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.
- package/README.md +19 -11
- package/dist/api-types.d.ts +7 -0
- package/dist/api-types.d.ts.map +1 -1
- package/dist/api-types.js +4 -6
- package/dist/app.d.ts +17 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +4 -3
- package/dist/base.d.ts +7 -0
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +4 -6
- package/dist/blocks.d.ts +332 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +8 -0
- package/dist/complex.d.ts +68 -1
- package/dist/complex.d.ts.map +1 -1
- package/dist/complex.js +4 -5
- package/dist/crud.d.ts +181 -3
- package/dist/crud.d.ts.map +1 -1
- package/dist/crud.js +4 -6
- package/dist/data-display.d.ts +54 -2
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +4 -5
- package/dist/data-protocol.d.ts +1268 -0
- package/dist/data-protocol.d.ts.map +1 -0
- package/dist/data-protocol.js +8 -0
- package/dist/data.d.ts +22 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +4 -6
- package/dist/disclosure.d.ts +70 -1
- package/dist/disclosure.d.ts.map +1 -1
- package/dist/disclosure.js +4 -5
- package/dist/feedback.d.ts +68 -1
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +4 -5
- package/dist/field-types.d.ts +728 -0
- package/dist/field-types.d.ts.map +1 -0
- package/dist/field-types.js +8 -0
- package/dist/form.d.ts +123 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +4 -5
- package/dist/index.d.ts +48 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -37
- package/dist/layout.d.ts +66 -16
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +4 -6
- package/dist/navigation.d.ts +102 -2
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +4 -5
- package/dist/objectql.d.ts +491 -54
- package/dist/objectql.d.ts.map +1 -1
- package/dist/objectql.js +4 -6
- package/dist/overlay.d.ts +31 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +4 -5
- package/dist/plugin-scope.d.ts +194 -0
- package/dist/plugin-scope.d.ts.map +1 -0
- package/dist/plugin-scope.js +8 -0
- package/dist/registry.d.ts +7 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/reports.d.ts +336 -0
- package/dist/reports.d.ts.map +1 -0
- package/dist/reports.js +8 -0
- package/dist/theme.d.ts +289 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +8 -0
- package/dist/ui-action.d.ts +175 -0
- package/dist/ui-action.d.ts.map +1 -0
- package/dist/ui-action.js +8 -0
- package/dist/views.d.ts +417 -0
- package/dist/views.d.ts.map +1 -0
- package/dist/views.js +8 -0
- package/dist/zod/app.zod.d.ts +120 -0
- package/dist/zod/app.zod.d.ts.map +1 -0
- package/dist/zod/app.zod.js +60 -0
- package/dist/zod/base.zod.d.ts +202 -0
- package/dist/zod/base.zod.d.ts.map +1 -0
- package/dist/zod/base.zod.js +198 -0
- package/dist/zod/blocks.zod.d.ts +834 -0
- package/dist/zod/blocks.zod.d.ts.map +1 -0
- package/dist/zod/blocks.zod.js +145 -0
- package/dist/zod/complex.zod.d.ts +742 -0
- package/dist/zod/complex.zod.d.ts.map +1 -0
- package/dist/zod/complex.zod.js +233 -0
- package/dist/zod/crud.zod.d.ts +598 -0
- package/dist/zod/crud.zod.d.ts.map +1 -0
- package/dist/zod/crud.zod.js +230 -0
- package/dist/zod/data-display.zod.d.ts +996 -0
- package/dist/zod/data-display.zod.d.ts.map +1 -0
- package/dist/zod/data-display.zod.js +266 -0
- package/dist/zod/disclosure.zod.d.ts +267 -0
- package/dist/zod/disclosure.zod.d.ts.map +1 -0
- package/dist/zod/disclosure.zod.js +84 -0
- package/dist/zod/feedback.zod.d.ts +538 -0
- package/dist/zod/feedback.zod.d.ts.map +1 -0
- package/dist/zod/feedback.zod.js +127 -0
- package/dist/zod/form.zod.d.ts +1308 -0
- package/dist/zod/form.zod.d.ts.map +1 -0
- package/dist/zod/form.zod.js +406 -0
- package/dist/zod/index.zod.d.ts +4985 -0
- package/dist/zod/index.zod.d.ts.map +1 -0
- package/dist/zod/index.zod.js +183 -0
- package/dist/zod/layout.zod.d.ts +1048 -0
- package/dist/zod/layout.zod.d.ts.map +1 -0
- package/dist/zod/layout.zod.js +241 -0
- package/dist/zod/navigation.zod.d.ts +486 -0
- package/dist/zod/navigation.zod.d.ts.map +1 -0
- package/dist/zod/navigation.zod.js +142 -0
- package/dist/zod/objectql.zod.d.ts +1261 -0
- package/dist/zod/objectql.zod.d.ts.map +1 -0
- package/dist/zod/objectql.zod.js +248 -0
- package/dist/zod/overlay.zod.d.ts +691 -0
- package/dist/zod/overlay.zod.d.ts.map +1 -0
- package/dist/zod/overlay.zod.js +179 -0
- package/dist/zod/reports.zod.d.ts +1628 -0
- package/dist/zod/reports.zod.d.ts.map +1 -0
- package/dist/zod/reports.zod.js +152 -0
- package/dist/zod/theme.zod.d.ts +611 -0
- package/dist/zod/theme.zod.d.ts.map +1 -0
- package/dist/zod/theme.zod.js +130 -0
- package/dist/zod/views.zod.d.ts +675 -0
- package/dist/zod/views.zod.d.ts.map +1 -0
- package/dist/zod/views.zod.js +159 -0
- package/package.json +9 -1
- package/src/__tests__/namespace-exports.test.ts +80 -0
- package/src/__tests__/phase2-schemas.test.ts +639 -0
- package/src/api-types.ts +8 -0
- package/src/app.ts +20 -0
- package/src/base.ts +8 -0
- package/src/blocks.ts +405 -0
- package/src/complex.ts +69 -1
- package/src/crud.ts +185 -3
- package/src/data-display.ts +60 -2
- package/src/data-protocol.ts +1679 -0
- package/src/data.ts +21 -1
- package/src/disclosure.ts +74 -1
- package/src/feedback.ts +76 -2
- package/src/field-types.ts +846 -0
- package/src/form.ts +131 -1
- package/src/index.ts +305 -8
- package/src/layout.ts +70 -15
- package/src/navigation.ts +109 -2
- package/src/objectql.ts +563 -59
- package/src/overlay.ts +35 -1
- package/src/plugin-scope.ts +210 -0
- package/src/registry.ts +8 -0
- package/src/reports.ts +408 -0
- package/src/theme.ts +351 -0
- package/src/ui-action.ts +276 -0
- package/src/views.ts +429 -0
- package/src/zod/README.md +329 -0
- package/src/zod/app.zod.ts +72 -0
- package/src/zod/base.zod.ts +229 -0
- package/src/zod/blocks.zod.ts +170 -0
- package/src/zod/complex.zod.ts +258 -0
- package/src/zod/crud.zod.ts +259 -0
- package/src/zod/data-display.zod.ts +290 -0
- package/src/zod/disclosure.zod.ts +92 -0
- package/src/zod/feedback.zod.ts +138 -0
- package/src/zod/form.zod.ts +434 -0
- package/src/zod/index.zod.ts +425 -0
- package/src/zod/layout.zod.ts +262 -0
- package/src/zod/navigation.zod.ts +159 -0
- package/src/zod/objectql.zod.ts +268 -0
- package/src/zod/overlay.zod.ts +196 -0
- package/src/zod/reports.zod.ts +183 -0
- package/src/zod/theme.zod.ts +155 -0
- 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');
|