@agentuity/schema 0.0.69
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/AGENTS.md +86 -0
- package/README.md +323 -0
- package/dist/base.d.ts +111 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +93 -0
- package/dist/base.js.map +1 -0
- package/dist/coerce/boolean.d.ts +37 -0
- package/dist/coerce/boolean.d.ts.map +1 -0
- package/dist/coerce/boolean.js +49 -0
- package/dist/coerce/boolean.js.map +1 -0
- package/dist/coerce/date.d.ts +36 -0
- package/dist/coerce/date.d.ts.map +1 -0
- package/dist/coerce/date.js +60 -0
- package/dist/coerce/date.js.map +1 -0
- package/dist/coerce/number.d.ts +36 -0
- package/dist/coerce/number.d.ts.map +1 -0
- package/dist/coerce/number.js +59 -0
- package/dist/coerce/number.js.map +1 -0
- package/dist/coerce/string.d.ts +35 -0
- package/dist/coerce/string.d.ts.map +1 -0
- package/dist/coerce/string.js +47 -0
- package/dist/coerce/string.js.map +1 -0
- package/dist/complex/array.d.ts +56 -0
- package/dist/complex/array.d.ts.map +1 -0
- package/dist/complex/array.js +96 -0
- package/dist/complex/array.js.map +1 -0
- package/dist/complex/object.d.ts +76 -0
- package/dist/complex/object.d.ts.map +1 -0
- package/dist/complex/object.js +104 -0
- package/dist/complex/object.js.map +1 -0
- package/dist/complex/record.d.ts +53 -0
- package/dist/complex/record.d.ts.map +1 -0
- package/dist/complex/record.js +109 -0
- package/dist/complex/record.js.map +1 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +128 -0
- package/dist/index.js.map +1 -0
- package/dist/json-schema.d.ts +60 -0
- package/dist/json-schema.d.ts.map +1 -0
- package/dist/json-schema.js +280 -0
- package/dist/json-schema.js.map +1 -0
- package/dist/primitives/any.d.ts +44 -0
- package/dist/primitives/any.d.ts.map +1 -0
- package/dist/primitives/any.js +57 -0
- package/dist/primitives/any.js.map +1 -0
- package/dist/primitives/boolean.d.ts +39 -0
- package/dist/primitives/boolean.d.ts.map +1 -0
- package/dist/primitives/boolean.js +53 -0
- package/dist/primitives/boolean.js.map +1 -0
- package/dist/primitives/null.d.ts +26 -0
- package/dist/primitives/null.d.ts.map +1 -0
- package/dist/primitives/null.js +40 -0
- package/dist/primitives/null.js.map +1 -0
- package/dist/primitives/number.d.ts +87 -0
- package/dist/primitives/number.d.ts.map +1 -0
- package/dist/primitives/number.js +129 -0
- package/dist/primitives/number.js.map +1 -0
- package/dist/primitives/string.d.ts +64 -0
- package/dist/primitives/string.d.ts.map +1 -0
- package/dist/primitives/string.js +102 -0
- package/dist/primitives/string.js.map +1 -0
- package/dist/primitives/undefined.d.ts +26 -0
- package/dist/primitives/undefined.d.ts.map +1 -0
- package/dist/primitives/undefined.js +40 -0
- package/dist/primitives/undefined.js.map +1 -0
- package/dist/primitives/unknown.d.ts +47 -0
- package/dist/primitives/unknown.d.ts.map +1 -0
- package/dist/primitives/unknown.js +56 -0
- package/dist/primitives/unknown.js.map +1 -0
- package/dist/utils/literal.d.ts +47 -0
- package/dist/utils/literal.d.ts.map +1 -0
- package/dist/utils/literal.js +64 -0
- package/dist/utils/literal.js.map +1 -0
- package/dist/utils/nullable.d.ts +50 -0
- package/dist/utils/nullable.d.ts.map +1 -0
- package/dist/utils/nullable.js +69 -0
- package/dist/utils/nullable.js.map +1 -0
- package/dist/utils/optional.d.ts +50 -0
- package/dist/utils/optional.d.ts.map +1 -0
- package/dist/utils/optional.js +69 -0
- package/dist/utils/optional.js.map +1 -0
- package/dist/utils/union.d.ts +60 -0
- package/dist/utils/union.d.ts.map +1 -0
- package/dist/utils/union.js +87 -0
- package/dist/utils/union.js.map +1 -0
- package/package.json +39 -0
- package/src/__tests__/coerce.test.ts +88 -0
- package/src/__tests__/complex.test.ts +124 -0
- package/src/__tests__/errors.test.ts +129 -0
- package/src/__tests__/json-schema.test.ts +138 -0
- package/src/__tests__/primitives.test.ts +184 -0
- package/src/__tests__/type-inference.test.ts +68 -0
- package/src/__tests__/utils.test.ts +100 -0
- package/src/base.ts +185 -0
- package/src/coerce/boolean.ts +56 -0
- package/src/coerce/date.ts +68 -0
- package/src/coerce/number.ts +67 -0
- package/src/coerce/string.ts +54 -0
- package/src/complex/array.ts +108 -0
- package/src/complex/object.ts +141 -0
- package/src/complex/record.ts +129 -0
- package/src/index.ts +177 -0
- package/src/json-schema.ts +331 -0
- package/src/primitives/any.ts +64 -0
- package/src/primitives/boolean.ts +60 -0
- package/src/primitives/null.ts +47 -0
- package/src/primitives/number.ts +141 -0
- package/src/primitives/string.ts +113 -0
- package/src/primitives/undefined.ts +47 -0
- package/src/primitives/unknown.ts +63 -0
- package/src/utils/literal.ts +71 -0
- package/src/utils/nullable.ts +80 -0
- package/src/utils/optional.ts +80 -0
- package/src/utils/union.ts +103 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Agent Guidelines for @agentuity/schema
|
|
2
|
+
|
|
3
|
+
## Package Overview
|
|
4
|
+
|
|
5
|
+
Lightweight schema validation library with StandardSchema v1 support. Provides type-safe runtime validation for the Agentuity platform.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
- **Build**: `bun run build` (compiles TypeScript with tsc)
|
|
10
|
+
- **Typecheck**: `bun run typecheck` (runs TypeScript type checking)
|
|
11
|
+
- **Clean**: `rm -rf dist` (removes build artifacts)
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
- **Runtime**: Node/Bun/Browser compatible, no runtime-specific code
|
|
16
|
+
- **Build target**: ESNext with TypeScript declaration files
|
|
17
|
+
- **Exports**: All public APIs exported from `src/index.ts`
|
|
18
|
+
- **Dependencies**: Only depends on `@agentuity/core` for StandardSchema types
|
|
19
|
+
|
|
20
|
+
## Structure
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
src/
|
|
24
|
+
├── index.ts # Main entry point, exports all schemas
|
|
25
|
+
├── base.ts # Base schema class and types
|
|
26
|
+
├── primitives/ # Primitive type schemas
|
|
27
|
+
│ ├── string.ts
|
|
28
|
+
│ ├── number.ts
|
|
29
|
+
│ ├── boolean.ts
|
|
30
|
+
│ ├── null.ts
|
|
31
|
+
│ └── undefined.ts
|
|
32
|
+
├── complex/ # Complex type schemas
|
|
33
|
+
│ ├── object.ts
|
|
34
|
+
│ └── array.ts
|
|
35
|
+
├── utils/ # Utility schemas
|
|
36
|
+
│ ├── optional.ts
|
|
37
|
+
│ ├── nullable.ts
|
|
38
|
+
│ ├── union.ts
|
|
39
|
+
│ └── literal.ts
|
|
40
|
+
├── coerce/ # Type coercion schemas
|
|
41
|
+
│ ├── string.ts
|
|
42
|
+
│ ├── number.ts
|
|
43
|
+
│ ├── boolean.ts
|
|
44
|
+
│ └── date.ts
|
|
45
|
+
├── json-schema.ts # JSON Schema conversion utilities
|
|
46
|
+
└── __tests__/ # Bun unit tests
|
|
47
|
+
├── primitives.test.ts
|
|
48
|
+
├── complex.test.ts
|
|
49
|
+
├── utils.test.ts
|
|
50
|
+
├── coerce.test.ts
|
|
51
|
+
├── type-inference.test.ts
|
|
52
|
+
├── json-schema.test.ts
|
|
53
|
+
└── errors.test.ts
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Code Style
|
|
57
|
+
|
|
58
|
+
- **StandardSchema compliant** - All schemas implement StandardSchemaV1
|
|
59
|
+
- **Fluent API** - Chainable methods where appropriate
|
|
60
|
+
- **Type-safe** - Full TypeScript support with type inference
|
|
61
|
+
- **Vendor name**: "agentuity" for all schemas
|
|
62
|
+
- **No side effects** - Pure validation functions
|
|
63
|
+
|
|
64
|
+
## Important Conventions
|
|
65
|
+
|
|
66
|
+
- All schemas must implement `StandardSchemaV1` from `@agentuity/core`
|
|
67
|
+
- Use `'~standard'` property for StandardSchema interface
|
|
68
|
+
- Export main builder as `s` (e.g., `s.string()`, `s.object()`)
|
|
69
|
+
- Error messages should be clear and actionable
|
|
70
|
+
- Support type inference via `Infer<T>` utility type
|
|
71
|
+
|
|
72
|
+
## Testing
|
|
73
|
+
|
|
74
|
+
- **Test Framework**: Bun's built-in test runner
|
|
75
|
+
- **Test Count**: 72 tests across 7 test files
|
|
76
|
+
- **Command**: `bun test` (run from package directory)
|
|
77
|
+
- **Coverage**: Primitives, complex types, utilities, coercion, type inference, JSON Schema, error handling
|
|
78
|
+
- **CI**: Tests run automatically on PR builds
|
|
79
|
+
- All tests must pass before merging
|
|
80
|
+
|
|
81
|
+
## Publishing Checklist
|
|
82
|
+
|
|
83
|
+
1. Run `bun run build` to compile
|
|
84
|
+
2. Verify `dist/` contains `.js` and `.d.ts` files
|
|
85
|
+
3. Ensure StandardSchema compliance
|
|
86
|
+
4. This package depends on `@agentuity/core` (must be published first)
|
package/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# @agentuity/schema
|
|
2
|
+
|
|
3
|
+
A lightweight, type-safe schema validation library for the Agentuity platform. Supports the [StandardSchema](https://standardschema.dev/) specification.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎯 Type-safe schema validation
|
|
8
|
+
- 📦 Lightweight with zero runtime dependencies
|
|
9
|
+
- 🔗 StandardSchema v1 compliant
|
|
10
|
+
- 🌐 Works in browser and server environments (Node.js, Bun)
|
|
11
|
+
- ⚡ Simple, fluent API
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @agentuity/schema
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { s, ValidationError } from '@agentuity/schema';
|
|
23
|
+
|
|
24
|
+
// Define a schema
|
|
25
|
+
const userSchema = s.object({
|
|
26
|
+
name: s.string(),
|
|
27
|
+
age: s.number(),
|
|
28
|
+
email: s.string(),
|
|
29
|
+
isActive: s.boolean(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Extract the inferred type (like zod's z.infer)
|
|
33
|
+
type User = s.infer<typeof userSchema>;
|
|
34
|
+
|
|
35
|
+
// Parse with validation (throws on error)
|
|
36
|
+
try {
|
|
37
|
+
const user: User = userSchema.parse({
|
|
38
|
+
name: 'John',
|
|
39
|
+
age: 30,
|
|
40
|
+
email: 'john@example.com',
|
|
41
|
+
isActive: true,
|
|
42
|
+
});
|
|
43
|
+
console.log('Valid user:', user);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (error instanceof ValidationError) {
|
|
46
|
+
console.error('Validation failed:', error.message);
|
|
47
|
+
console.error('Issues:', error.issues);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Safe parse (returns result object)
|
|
52
|
+
const result = userSchema.safeParse(data);
|
|
53
|
+
if (result.success) {
|
|
54
|
+
console.log('Valid data:', result.data);
|
|
55
|
+
} else {
|
|
56
|
+
console.error('Validation failed:', result.error.message);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Optional and nullable
|
|
60
|
+
const optionalSchema = s.object({
|
|
61
|
+
name: s.string(),
|
|
62
|
+
nickname: s.optional(s.string()),
|
|
63
|
+
age: s.nullable(s.number()),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Arrays
|
|
67
|
+
const stringArraySchema = s.array(s.string());
|
|
68
|
+
const userArraySchema = s.array(userSchema);
|
|
69
|
+
|
|
70
|
+
// Unions
|
|
71
|
+
const statusSchema = s.union(s.literal('active'), s.literal('inactive'), s.literal('pending'));
|
|
72
|
+
|
|
73
|
+
// Enums (shorthand for union of literals)
|
|
74
|
+
const roleSchema = s.enum(['admin', 'user', 'guest']);
|
|
75
|
+
const prioritySchema = s.enum([1, 2, 3, 4, 5]);
|
|
76
|
+
|
|
77
|
+
// Literal values
|
|
78
|
+
const roleSchema = s.literal('admin');
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
### Basic Types
|
|
84
|
+
|
|
85
|
+
- `s.string()` - String validation
|
|
86
|
+
- `s.number()` - Number validation
|
|
87
|
+
- `s.boolean()` - Boolean validation
|
|
88
|
+
- `s.null()` - Null validation
|
|
89
|
+
- `s.undefined()` - Undefined validation
|
|
90
|
+
|
|
91
|
+
### Complex Types
|
|
92
|
+
|
|
93
|
+
- `s.object(shape)` - Object validation with typed properties
|
|
94
|
+
- `s.array(schema)` - Array validation with typed elements
|
|
95
|
+
|
|
96
|
+
### Utility Types
|
|
97
|
+
|
|
98
|
+
- `s.optional(schema)` - Makes a schema optional
|
|
99
|
+
- `s.nullable(schema)` - Makes a schema nullable
|
|
100
|
+
- `s.union(...schemas)` - Union of multiple schemas
|
|
101
|
+
- `s.literal(value)` - Exact value matching
|
|
102
|
+
- `s.enum([...values])` - Enum type (union of literals)
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// Enum (shorthand for union of literals)
|
|
106
|
+
const roleSchema = s.enum(['admin', 'user', 'guest']);
|
|
107
|
+
const role = roleSchema.parse('admin'); // 'admin'
|
|
108
|
+
|
|
109
|
+
// Equivalent to:
|
|
110
|
+
const roleSchema2 = s.union(s.literal('admin'), s.literal('user'), s.literal('guest'));
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Coercion
|
|
114
|
+
|
|
115
|
+
Automatically convert values to the correct type (like zod.coerce):
|
|
116
|
+
|
|
117
|
+
- `s.coerce.string()` - Coerce to string using `String(value)`
|
|
118
|
+
- `s.coerce.number()` - Coerce to number using `Number(value)`
|
|
119
|
+
- `s.coerce.boolean()` - Coerce to boolean using `Boolean(value)`
|
|
120
|
+
- `s.coerce.date()` - Coerce to Date using `new Date(value)`
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Parse form data where everything is a string
|
|
124
|
+
const formSchema = s.object({
|
|
125
|
+
name: s.string(),
|
|
126
|
+
age: s.coerce.number(), // "30" → 30
|
|
127
|
+
newsletter: s.coerce.boolean(), // "on" → true
|
|
128
|
+
createdAt: s.coerce.date(), // "2025-01-01" → Date
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const formData = formSchema.parse({
|
|
132
|
+
name: 'John',
|
|
133
|
+
age: '30', // String coerced to number
|
|
134
|
+
newsletter: 'on', // String coerced to boolean
|
|
135
|
+
createdAt: '2025-01-01', // String coerced to Date
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Query parameters (always strings)
|
|
139
|
+
const querySchema = s.object({
|
|
140
|
+
page: s.coerce.number(),
|
|
141
|
+
limit: s.coerce.number(),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const params = querySchema.parse({
|
|
145
|
+
page: '1', // "1" → 1
|
|
146
|
+
limit: '20', // "20" → 20
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Documentation
|
|
151
|
+
|
|
152
|
+
All schemas support a `.describe(description: string)` method for adding documentation:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
const userSchema = s
|
|
156
|
+
.object({
|
|
157
|
+
id: s.string().describe('The unique identifier'),
|
|
158
|
+
name: s.string().describe('The user full name'),
|
|
159
|
+
age: s.number().describe('Age in years'),
|
|
160
|
+
})
|
|
161
|
+
.describe('User profile');
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### JSON Schema Conversion
|
|
165
|
+
|
|
166
|
+
Convert schemas to JSON Schema format:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const schema = s.object({
|
|
170
|
+
name: s.string().describe('User name'),
|
|
171
|
+
age: s.number().describe('User age'),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const jsonSchema = s.toJSONSchema(schema);
|
|
175
|
+
// {
|
|
176
|
+
// "type": "object",
|
|
177
|
+
// "properties": {
|
|
178
|
+
// "name": { "type": "string", "description": "User name" },
|
|
179
|
+
// "age": { "type": "number", "description": "User age" }
|
|
180
|
+
// },
|
|
181
|
+
// "required": ["name", "age"]
|
|
182
|
+
// }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Convert JSON Schema to schemas:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const jsonSchema = {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
firstName: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
description: 'First name',
|
|
194
|
+
},
|
|
195
|
+
lastName: {
|
|
196
|
+
type: 'string',
|
|
197
|
+
description: 'Last name',
|
|
198
|
+
},
|
|
199
|
+
age: {
|
|
200
|
+
type: 'number',
|
|
201
|
+
description: 'Age',
|
|
202
|
+
},
|
|
203
|
+
hobbies: {
|
|
204
|
+
type: 'array',
|
|
205
|
+
items: { type: 'string' },
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
required: ['firstName', 'lastName', 'age', 'hobbies'],
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const schema = s.fromJSONSchema(jsonSchema);
|
|
212
|
+
// Now you can use schema for validation
|
|
213
|
+
const result = schema['~standard'].validate(data);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Round-trip conversion is supported:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const original = s.object({ name: s.string() });
|
|
220
|
+
const json = s.toJSONSchema(original);
|
|
221
|
+
const reconstructed = s.fromJSONSchema(json);
|
|
222
|
+
// reconstructed works exactly like original
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Parsing & Validation
|
|
226
|
+
|
|
227
|
+
#### `.parse(value)` - Throws on validation error
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
try {
|
|
231
|
+
const user = userSchema.parse(data);
|
|
232
|
+
// user is typed and validated
|
|
233
|
+
} catch (error) {
|
|
234
|
+
if (error instanceof ValidationError) {
|
|
235
|
+
console.error(error.message); // Human-readable error
|
|
236
|
+
console.error(error.issues); // Detailed issue array with paths
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### `.safeParse(value)` - Returns result object
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const result = userSchema.safeParse(data);
|
|
245
|
+
|
|
246
|
+
if (result.success) {
|
|
247
|
+
console.log(result.data); // Typed data
|
|
248
|
+
} else {
|
|
249
|
+
console.error(result.error); // ValidationError instance
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Type Inference
|
|
254
|
+
|
|
255
|
+
Use `s.infer` to extract TypeScript types from schemas (like zod's `z.infer`):
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
import { s } from '@agentuity/schema';
|
|
259
|
+
|
|
260
|
+
const Player = s.object({
|
|
261
|
+
username: s.string(),
|
|
262
|
+
xp: s.number(),
|
|
263
|
+
inventory: s.array(s.string()),
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Extract the inferred type (like zod's z.infer)
|
|
267
|
+
type Player = s.infer<typeof Player>;
|
|
268
|
+
// { username: string; xp: number; inventory: string[] }
|
|
269
|
+
|
|
270
|
+
const player: Player = Player.parse(data);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
You can also import the `Infer` type directly if preferred:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
import { s, type Infer } from '@agentuity/schema';
|
|
277
|
+
|
|
278
|
+
type Player = Infer<typeof Player>; // Alternative syntax
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Error Handling
|
|
282
|
+
|
|
283
|
+
Validation errors are structured and include paths to the failed fields:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
const profileSchema = s.object({
|
|
287
|
+
user: s.object({
|
|
288
|
+
name: s.string(),
|
|
289
|
+
age: s.number(),
|
|
290
|
+
}),
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
profileSchema.parse({ user: { name: 'John', age: 'thirty' } });
|
|
295
|
+
} catch (error) {
|
|
296
|
+
if (error instanceof ValidationError) {
|
|
297
|
+
console.log(error.message);
|
|
298
|
+
// "[user.age]: Expected number, got string"
|
|
299
|
+
|
|
300
|
+
console.log(error.issues);
|
|
301
|
+
// [{ message: "Expected number, got string", path: ["user", "age"] }]
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## StandardSchema Support
|
|
307
|
+
|
|
308
|
+
All schemas implement the StandardSchema v1 interface:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
interface StandardSchemaV1<Input, Output> {
|
|
312
|
+
readonly '~standard': {
|
|
313
|
+
readonly version: 1;
|
|
314
|
+
readonly vendor: string;
|
|
315
|
+
readonly validate: (value: unknown) => Result<Output>;
|
|
316
|
+
readonly types?: { input: Input; output: Output };
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## License
|
|
322
|
+
|
|
323
|
+
Apache-2.0
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@agentuity/core';
|
|
2
|
+
/**
|
|
3
|
+
* A validation issue from a failed schema validation.
|
|
4
|
+
*/
|
|
5
|
+
export type ValidationIssue = StandardSchemaV1.Issue;
|
|
6
|
+
/**
|
|
7
|
+
* The result of a schema validation (success or failure).
|
|
8
|
+
*/
|
|
9
|
+
export type ValidationResult<T> = StandardSchemaV1.Result<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Successful parse result containing validated data.
|
|
12
|
+
*/
|
|
13
|
+
export interface SafeParseSuccess<T> {
|
|
14
|
+
/** Indicates successful validation */
|
|
15
|
+
success: true;
|
|
16
|
+
/** The validated and typed data */
|
|
17
|
+
data: T;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Failed parse result containing validation error.
|
|
21
|
+
*/
|
|
22
|
+
export interface SafeParseError {
|
|
23
|
+
/** Indicates failed validation */
|
|
24
|
+
success: false;
|
|
25
|
+
/** The validation error with detailed issues */
|
|
26
|
+
error: ValidationError;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Result of safeParse - either success with data or failure with error.
|
|
30
|
+
*/
|
|
31
|
+
export type SafeParseResult<T> = SafeParseSuccess<T> | SafeParseError;
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when schema validation fails.
|
|
34
|
+
* Contains detailed information about all validation issues including field paths.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* try {
|
|
39
|
+
* schema.parse(data);
|
|
40
|
+
* } catch (error) {
|
|
41
|
+
* if (error instanceof ValidationError) {
|
|
42
|
+
* console.log(error.message); // Human-readable error
|
|
43
|
+
* console.log(error.issues); // Detailed issues array
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare class ValidationError extends Error {
|
|
49
|
+
/** Array of validation issues with paths and messages */
|
|
50
|
+
readonly issues: readonly ValidationIssue[];
|
|
51
|
+
constructor(issues: readonly ValidationIssue[]);
|
|
52
|
+
toString(): string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Base schema interface that all schemas implement.
|
|
56
|
+
* Provides StandardSchema v1 compliance plus additional methods for parsing and description.
|
|
57
|
+
*/
|
|
58
|
+
export interface Schema<Input = unknown, Output = Input> extends StandardSchemaV1<Input, Output> {
|
|
59
|
+
readonly '~standard': StandardSchemaV1.Props<Input, Output>;
|
|
60
|
+
/** Optional description for documentation */
|
|
61
|
+
description?: string;
|
|
62
|
+
/** Add a description to the schema for documentation and JSON Schema */
|
|
63
|
+
describe(description: string): this;
|
|
64
|
+
/** Parse and validate data, throwing ValidationError on failure */
|
|
65
|
+
parse(value: unknown): Output;
|
|
66
|
+
/** Parse and validate data, returning result object without throwing */
|
|
67
|
+
safeParse(value: unknown): SafeParseResult<Output>;
|
|
68
|
+
/** Make this schema optional (allow undefined) */
|
|
69
|
+
optional(): Schema<Input | undefined, Output | undefined>;
|
|
70
|
+
/** Make this schema nullable (allow null) */
|
|
71
|
+
nullable(): Schema<Input | null, Output | null>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Extract the output type from a schema (like zod's z.infer).
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const User = s.object({ name: s.string(), age: s.number() });
|
|
79
|
+
* type User = Infer<typeof User>; // { name: string; age: number }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export type Infer<T extends Schema<any, any>> = StandardSchemaV1.InferOutput<T>;
|
|
83
|
+
/**
|
|
84
|
+
* Extract the input type from a schema.
|
|
85
|
+
*/
|
|
86
|
+
export type InferInput<T extends Schema<any, any>> = StandardSchemaV1.InferInput<T>;
|
|
87
|
+
/**
|
|
88
|
+
* Extract the output type from a schema (alias for Infer).
|
|
89
|
+
*/
|
|
90
|
+
export type InferOutput<T extends Schema<any, any>> = StandardSchemaV1.InferOutput<T>;
|
|
91
|
+
/**
|
|
92
|
+
* Create a validation issue with an optional field path.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createIssue(message: string, path?: ReadonlyArray<PropertyKey | StandardSchemaV1.PathSegment>): ValidationIssue;
|
|
95
|
+
/**
|
|
96
|
+
* Create a successful validation result.
|
|
97
|
+
*/
|
|
98
|
+
export declare function success<T>(value: T): StandardSchemaV1.SuccessResult<T>;
|
|
99
|
+
/**
|
|
100
|
+
* Create a failed validation result.
|
|
101
|
+
*/
|
|
102
|
+
export declare function failure(issues: ValidationIssue[]): StandardSchemaV1.FailureResult;
|
|
103
|
+
/**
|
|
104
|
+
* Create parse and safeParse methods for a schema.
|
|
105
|
+
* @internal
|
|
106
|
+
*/
|
|
107
|
+
export declare function createParseMethods<Output>(): {
|
|
108
|
+
parse(this: Schema<any, Output>, value: unknown): Output;
|
|
109
|
+
safeParse(this: Schema<any, Output>, value: unknown): SafeParseResult<Output>;
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
|
package/dist/base.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when schema validation fails.
|
|
3
|
+
* Contains detailed information about all validation issues including field paths.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* try {
|
|
8
|
+
* schema.parse(data);
|
|
9
|
+
* } catch (error) {
|
|
10
|
+
* if (error instanceof ValidationError) {
|
|
11
|
+
* console.log(error.message); // Human-readable error
|
|
12
|
+
* console.log(error.issues); // Detailed issues array
|
|
13
|
+
* }
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class ValidationError extends Error {
|
|
18
|
+
/** Array of validation issues with paths and messages */
|
|
19
|
+
issues;
|
|
20
|
+
constructor(issues) {
|
|
21
|
+
const message = issues
|
|
22
|
+
.map((issue) => {
|
|
23
|
+
const path = issue.path
|
|
24
|
+
? `[${issue.path
|
|
25
|
+
.map((p) =>
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
typeof p === 'object' ? p.key : p)
|
|
28
|
+
.join('.')}]`
|
|
29
|
+
: '';
|
|
30
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
31
|
+
})
|
|
32
|
+
.join('\n');
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'ValidationError';
|
|
35
|
+
this.issues = issues;
|
|
36
|
+
// Maintain proper stack trace for where our error was thrown
|
|
37
|
+
if (Error.captureStackTrace) {
|
|
38
|
+
Error.captureStackTrace(this, ValidationError);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
toString() {
|
|
42
|
+
return `${this.name}: ${this.message}`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a validation issue with an optional field path.
|
|
47
|
+
*/
|
|
48
|
+
export function createIssue(message, path) {
|
|
49
|
+
return path ? { message, path } : { message };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a successful validation result.
|
|
53
|
+
*/
|
|
54
|
+
export function success(value) {
|
|
55
|
+
return { value };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a failed validation result.
|
|
59
|
+
*/
|
|
60
|
+
export function failure(issues) {
|
|
61
|
+
return { issues };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Create parse and safeParse methods for a schema.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export function createParseMethods() {
|
|
68
|
+
return {
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
parse(value) {
|
|
71
|
+
const result = this['~standard'].validate(value);
|
|
72
|
+
if (result instanceof Promise) {
|
|
73
|
+
throw new Error('Async validation not supported in parse()');
|
|
74
|
+
}
|
|
75
|
+
if (result.issues) {
|
|
76
|
+
throw new ValidationError(result.issues);
|
|
77
|
+
}
|
|
78
|
+
return result.value;
|
|
79
|
+
},
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
safeParse(value) {
|
|
82
|
+
const result = this['~standard'].validate(value);
|
|
83
|
+
if (result instanceof Promise) {
|
|
84
|
+
throw new Error('Async validation not supported in safeParse()');
|
|
85
|
+
}
|
|
86
|
+
if (result.issues) {
|
|
87
|
+
return { success: false, error: new ValidationError(result.issues) };
|
|
88
|
+
}
|
|
89
|
+
return { success: true, data: result.value };
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=base.js.map
|
package/dist/base.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Schema } from '../base';
|
|
2
|
+
/**
|
|
3
|
+
* Schema that coerces values to booleans using Boolean(value).
|
|
4
|
+
* Uses JavaScript truthy/falsy rules.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const schema = s.coerce.boolean();
|
|
9
|
+
* schema.parse(1); // true
|
|
10
|
+
* schema.parse(0); // false
|
|
11
|
+
* schema.parse(''); // false
|
|
12
|
+
* schema.parse('hello'); // true
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare class CoerceBooleanSchema implements Schema<unknown, boolean> {
|
|
16
|
+
description?: string;
|
|
17
|
+
readonly '~standard': {
|
|
18
|
+
version: 1;
|
|
19
|
+
vendor: string;
|
|
20
|
+
validate: (value: unknown) => import("@agentuity/core").StandardSchemaV1.SuccessResult<boolean>;
|
|
21
|
+
types: {
|
|
22
|
+
input: unknown;
|
|
23
|
+
output: boolean;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
describe(description: string): this;
|
|
27
|
+
optional(): import("..").OptionalSchema<this>;
|
|
28
|
+
nullable(): import("..").NullableSchema<this>;
|
|
29
|
+
parse: (this: Schema<any, boolean>, value: unknown) => boolean;
|
|
30
|
+
safeParse: (this: Schema<any, boolean>, value: unknown) => import("..").SafeParseResult<boolean>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a schema that coerces values to booleans.
|
|
34
|
+
* Useful for parsing checkboxes or boolean flags from strings.
|
|
35
|
+
*/
|
|
36
|
+
export declare function coerceBoolean(): CoerceBooleanSchema;
|
|
37
|
+
//# sourceMappingURL=boolean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boolean.d.ts","sourceRoot":"","sources":["../../src/coerce/boolean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOtC;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,YAAW,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,WAAW;;;0BAGD,OAAO;eAIM;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,MAAM,EAAE,OAAO,CAAA;SAAE;MACjE;IAEF,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKnC,QAAQ;IAIR,QAAQ;IAGR,KAAK,0DAAsB;IAC3B,SAAS,wFAA0B;CACnC;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,mBAAmB,CAEnD"}
|