@geekmidas/schema 9.0.2 → 10.0.0-alpha.1
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 +6 -6
- package/package.json +4 -1
- package/CHANGELOG.md +0 -63
- package/src/__benchmarks__/conversion.bench.ts +0 -88
- package/src/__tests__/conversion.spec.ts +0 -502
- package/src/__tests__/openapi.spec.ts +0 -396
- package/src/__tests__/parser.spec.ts +0 -236
- package/src/conversion.ts +0 -220
- package/src/index.ts +0 -15
- package/src/openapi.ts +0 -75
- package/src/parser.ts +0 -30
- package/src/types.ts +0 -37
- package/tsconfig.json +0 -9
- package/tsdown.config.ts +0 -5
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
buildOpenApiSchema,
|
|
4
|
-
type ComponentCollector,
|
|
5
|
-
createComponentCollector,
|
|
6
|
-
} from '../openapi';
|
|
7
|
-
|
|
8
|
-
describe('OpenAPI Schema', () => {
|
|
9
|
-
describe('createComponentCollector', () => {
|
|
10
|
-
it('should create a component collector', () => {
|
|
11
|
-
const collector = createComponentCollector();
|
|
12
|
-
|
|
13
|
-
expect(collector).toHaveProperty('schemas');
|
|
14
|
-
expect(collector).toHaveProperty('addSchema');
|
|
15
|
-
expect(collector).toHaveProperty('getReference');
|
|
16
|
-
expect(collector.schemas).toEqual({});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should add schema to collector', () => {
|
|
20
|
-
const collector = createComponentCollector();
|
|
21
|
-
|
|
22
|
-
collector.addSchema('User', {
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: {
|
|
25
|
-
name: { type: 'string' },
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
expect(collector.schemas).toHaveProperty('User');
|
|
30
|
-
expect(collector.schemas.User).toEqual({
|
|
31
|
-
type: 'object',
|
|
32
|
-
properties: {
|
|
33
|
-
name: { type: 'string' },
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('should get reference to schema', () => {
|
|
39
|
-
const collector = createComponentCollector();
|
|
40
|
-
|
|
41
|
-
const reference = collector.getReference('User');
|
|
42
|
-
|
|
43
|
-
expect(reference).toEqual({ $ref: '#/components/schemas/User' });
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should add multiple schemas', () => {
|
|
47
|
-
const collector = createComponentCollector();
|
|
48
|
-
|
|
49
|
-
collector.addSchema('User', {
|
|
50
|
-
type: 'object',
|
|
51
|
-
properties: { name: { type: 'string' } },
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
collector.addSchema('Post', {
|
|
55
|
-
type: 'object',
|
|
56
|
-
properties: { title: { type: 'string' } },
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
expect(Object.keys(collector.schemas)).toHaveLength(2);
|
|
60
|
-
expect(collector.schemas).toHaveProperty('User');
|
|
61
|
-
expect(collector.schemas).toHaveProperty('Post');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should overwrite existing schema with same name', () => {
|
|
65
|
-
const collector = createComponentCollector();
|
|
66
|
-
|
|
67
|
-
collector.addSchema('User', {
|
|
68
|
-
type: 'object',
|
|
69
|
-
properties: { name: { type: 'string' } },
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
collector.addSchema('User', {
|
|
73
|
-
type: 'object',
|
|
74
|
-
properties: { email: { type: 'string' } },
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
expect(collector.schemas.User.properties).toHaveProperty('email');
|
|
78
|
-
expect(collector.schemas.User.properties).not.toHaveProperty('name');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should handle complex nested schemas', () => {
|
|
82
|
-
const collector = createComponentCollector();
|
|
83
|
-
|
|
84
|
-
collector.addSchema('User', {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {
|
|
87
|
-
name: { type: 'string' },
|
|
88
|
-
address: {
|
|
89
|
-
type: 'object',
|
|
90
|
-
properties: {
|
|
91
|
-
street: { type: 'string' },
|
|
92
|
-
city: { type: 'string' },
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
expect(collector.schemas.User.properties?.address).toBeDefined();
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe('buildOpenApiSchema', () => {
|
|
103
|
-
it('should build OpenAPI schema with default options', async () => {
|
|
104
|
-
const mockEndpoint = {
|
|
105
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
106
|
-
return {
|
|
107
|
-
'/users': {
|
|
108
|
-
get: {
|
|
109
|
-
operationId: 'getUsers',
|
|
110
|
-
responses: {
|
|
111
|
-
'200': {
|
|
112
|
-
description: 'Success',
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
122
|
-
|
|
123
|
-
expect(doc).toHaveProperty('openapi', '3.0.0');
|
|
124
|
-
expect(doc).toHaveProperty('info');
|
|
125
|
-
expect(doc.info).toEqual({
|
|
126
|
-
title: 'API',
|
|
127
|
-
version: '1.0.0',
|
|
128
|
-
});
|
|
129
|
-
expect(doc).toHaveProperty('paths');
|
|
130
|
-
expect(doc.paths).toHaveProperty('/users');
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('should build OpenAPI schema with custom options', async () => {
|
|
134
|
-
const mockEndpoint = {
|
|
135
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
136
|
-
return {
|
|
137
|
-
'/posts': {
|
|
138
|
-
get: {
|
|
139
|
-
operationId: 'getPosts',
|
|
140
|
-
responses: {
|
|
141
|
-
'200': {
|
|
142
|
-
description: 'Success',
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const doc = await buildOpenApiSchema([mockEndpoint], {
|
|
152
|
-
title: 'My API',
|
|
153
|
-
version: '2.0.0',
|
|
154
|
-
description: 'API Description',
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
expect(doc.info).toEqual({
|
|
158
|
-
title: 'My API',
|
|
159
|
-
version: '2.0.0',
|
|
160
|
-
description: 'API Description',
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should merge multiple endpoints into paths', async () => {
|
|
165
|
-
const endpoint1 = {
|
|
166
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
167
|
-
return {
|
|
168
|
-
'/users': {
|
|
169
|
-
get: {
|
|
170
|
-
operationId: 'getUsers',
|
|
171
|
-
responses: { '200': { description: 'Success' } },
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const endpoint2 = {
|
|
179
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
180
|
-
return {
|
|
181
|
-
'/posts': {
|
|
182
|
-
get: {
|
|
183
|
-
operationId: 'getPosts',
|
|
184
|
-
responses: { '200': { description: 'Success' } },
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
},
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const doc = await buildOpenApiSchema([endpoint1, endpoint2]);
|
|
192
|
-
|
|
193
|
-
expect(Object.keys(doc.paths)).toHaveLength(2);
|
|
194
|
-
expect(doc.paths).toHaveProperty('/users');
|
|
195
|
-
expect(doc.paths).toHaveProperty('/posts');
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should merge multiple methods for same path', async () => {
|
|
199
|
-
const endpoint1 = {
|
|
200
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
201
|
-
return {
|
|
202
|
-
'/users': {
|
|
203
|
-
get: {
|
|
204
|
-
operationId: 'getUsers',
|
|
205
|
-
responses: { '200': { description: 'Success' } },
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
};
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const endpoint2 = {
|
|
213
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
214
|
-
return {
|
|
215
|
-
'/users': {
|
|
216
|
-
post: {
|
|
217
|
-
operationId: 'createUser',
|
|
218
|
-
responses: { '201': { description: 'Created' } },
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
};
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const doc = await buildOpenApiSchema([endpoint1, endpoint2]);
|
|
226
|
-
|
|
227
|
-
expect(doc.paths['/users']).toHaveProperty('get');
|
|
228
|
-
expect(doc.paths['/users']).toHaveProperty('post');
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it('should add components when schemas are collected', async () => {
|
|
232
|
-
const mockEndpoint = {
|
|
233
|
-
async toOpenApi3Route(collector?: ComponentCollector) {
|
|
234
|
-
if (collector) {
|
|
235
|
-
collector.addSchema('User', {
|
|
236
|
-
type: 'object',
|
|
237
|
-
properties: {
|
|
238
|
-
name: { type: 'string' },
|
|
239
|
-
},
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
return {
|
|
244
|
-
'/users': {
|
|
245
|
-
get: {
|
|
246
|
-
operationId: 'getUsers',
|
|
247
|
-
responses: {
|
|
248
|
-
'200': {
|
|
249
|
-
description: 'Success',
|
|
250
|
-
content: {
|
|
251
|
-
'application/json': {
|
|
252
|
-
schema: collector?.getReference('User'),
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
},
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
264
|
-
|
|
265
|
-
expect(doc).toHaveProperty('components');
|
|
266
|
-
expect(doc.components).toHaveProperty('schemas');
|
|
267
|
-
expect(doc.components?.schemas).toHaveProperty('User');
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
it('should not add components when no schemas collected', async () => {
|
|
271
|
-
const mockEndpoint = {
|
|
272
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
273
|
-
return {
|
|
274
|
-
'/health': {
|
|
275
|
-
get: {
|
|
276
|
-
operationId: 'healthCheck',
|
|
277
|
-
responses: {
|
|
278
|
-
'200': {
|
|
279
|
-
description: 'Healthy',
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
};
|
|
285
|
-
},
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
289
|
-
|
|
290
|
-
expect(doc).not.toHaveProperty('components');
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it('should handle empty endpoints array', async () => {
|
|
294
|
-
const doc = await buildOpenApiSchema([]);
|
|
295
|
-
|
|
296
|
-
expect(doc.paths).toEqual({});
|
|
297
|
-
expect(doc).not.toHaveProperty('components');
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('should handle endpoints with parameters', async () => {
|
|
301
|
-
const mockEndpoint = {
|
|
302
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
303
|
-
return {
|
|
304
|
-
'/users/{id}': {
|
|
305
|
-
get: {
|
|
306
|
-
operationId: 'getUserById',
|
|
307
|
-
parameters: [
|
|
308
|
-
{
|
|
309
|
-
name: 'id',
|
|
310
|
-
in: 'path',
|
|
311
|
-
required: true,
|
|
312
|
-
schema: { type: 'string' },
|
|
313
|
-
},
|
|
314
|
-
],
|
|
315
|
-
responses: {
|
|
316
|
-
'200': {
|
|
317
|
-
description: 'Success',
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
},
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
327
|
-
|
|
328
|
-
expect(doc.paths['/users/{id}']?.get?.parameters).toBeDefined();
|
|
329
|
-
expect(doc.paths['/users/{id}']?.get?.parameters).toHaveLength(1);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
it('should handle endpoints with request body', async () => {
|
|
333
|
-
const mockEndpoint = {
|
|
334
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
335
|
-
return {
|
|
336
|
-
'/users': {
|
|
337
|
-
post: {
|
|
338
|
-
operationId: 'createUser',
|
|
339
|
-
requestBody: {
|
|
340
|
-
required: true,
|
|
341
|
-
content: {
|
|
342
|
-
'application/json': {
|
|
343
|
-
schema: {
|
|
344
|
-
type: 'object',
|
|
345
|
-
properties: {
|
|
346
|
-
name: { type: 'string' },
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
responses: {
|
|
353
|
-
'201': {
|
|
354
|
-
description: 'Created',
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
},
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
},
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
364
|
-
|
|
365
|
-
expect(doc.paths['/users']?.post?.requestBody).toBeDefined();
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
it('should handle endpoints with multiple response codes', async () => {
|
|
369
|
-
const mockEndpoint = {
|
|
370
|
-
async toOpenApi3Route(_collector?: ComponentCollector) {
|
|
371
|
-
return {
|
|
372
|
-
'/users': {
|
|
373
|
-
get: {
|
|
374
|
-
operationId: 'getUsers',
|
|
375
|
-
responses: {
|
|
376
|
-
'200': { description: 'Success' },
|
|
377
|
-
'400': { description: 'Bad Request' },
|
|
378
|
-
'401': { description: 'Unauthorized' },
|
|
379
|
-
'500': { description: 'Server Error' },
|
|
380
|
-
},
|
|
381
|
-
},
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
|
-
|
|
387
|
-
const doc = await buildOpenApiSchema([mockEndpoint]);
|
|
388
|
-
|
|
389
|
-
const responses = doc.paths['/users']?.get?.responses;
|
|
390
|
-
expect(responses).toHaveProperty('200');
|
|
391
|
-
expect(responses).toHaveProperty('400');
|
|
392
|
-
expect(responses).toHaveProperty('401');
|
|
393
|
-
expect(responses).toHaveProperty('500');
|
|
394
|
-
});
|
|
395
|
-
});
|
|
396
|
-
});
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { z } from 'zod/v4';
|
|
3
|
-
import { parseSchema, validate } from '../parser';
|
|
4
|
-
|
|
5
|
-
describe('Schema Parser', () => {
|
|
6
|
-
describe('validate', () => {
|
|
7
|
-
it('should validate data against a Zod schema', async () => {
|
|
8
|
-
const schema = z.object({
|
|
9
|
-
name: z.string(),
|
|
10
|
-
age: z.number(),
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const result = await validate(schema, { name: 'John', age: 30 });
|
|
14
|
-
|
|
15
|
-
expect(result.issues).toBeUndefined();
|
|
16
|
-
if ('value' in result) {
|
|
17
|
-
expect(result.value).toEqual({ name: 'John', age: 30 });
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should return issues for invalid data', async () => {
|
|
22
|
-
const schema = z.object({
|
|
23
|
-
name: z.string(),
|
|
24
|
-
age: z.number(),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const result = await validate(schema, { name: 'John', age: 'invalid' });
|
|
28
|
-
|
|
29
|
-
expect(result.issues).toBeDefined();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should validate string schema', async () => {
|
|
33
|
-
const schema = z.string();
|
|
34
|
-
|
|
35
|
-
const result = await validate(schema, 'test string');
|
|
36
|
-
|
|
37
|
-
expect(result.issues).toBeUndefined();
|
|
38
|
-
if ('value' in result) {
|
|
39
|
-
expect(result.value).toBe('test string');
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('should validate array schema', async () => {
|
|
44
|
-
const schema = z.array(z.number());
|
|
45
|
-
|
|
46
|
-
const result = await validate(schema, [1, 2, 3]);
|
|
47
|
-
|
|
48
|
-
expect(result.issues).toBeUndefined();
|
|
49
|
-
if ('value' in result) {
|
|
50
|
-
expect(result.value).toEqual([1, 2, 3]);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('should return issues for invalid array items', async () => {
|
|
55
|
-
const schema = z.array(z.number());
|
|
56
|
-
|
|
57
|
-
const result = await validate(schema, [1, 'invalid', 3]);
|
|
58
|
-
|
|
59
|
-
expect(result.issues).toBeDefined();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should validate nested objects', async () => {
|
|
63
|
-
const schema = z.object({
|
|
64
|
-
user: z.object({
|
|
65
|
-
name: z.string(),
|
|
66
|
-
profile: z.object({
|
|
67
|
-
bio: z.string(),
|
|
68
|
-
}),
|
|
69
|
-
}),
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const result = await validate(schema, {
|
|
73
|
-
user: {
|
|
74
|
-
name: 'John',
|
|
75
|
-
profile: { bio: 'Developer' },
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
expect(result.issues).toBeUndefined();
|
|
80
|
-
if ('value' in result) {
|
|
81
|
-
expect(result.value).toEqual({
|
|
82
|
-
user: {
|
|
83
|
-
name: 'John',
|
|
84
|
-
profile: { bio: 'Developer' },
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
describe('parseSchema', () => {
|
|
92
|
-
it('should parse valid data', async () => {
|
|
93
|
-
const schema = z.object({
|
|
94
|
-
name: z.string(),
|
|
95
|
-
age: z.number(),
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
const result = await parseSchema(schema, { name: 'John', age: 30 });
|
|
99
|
-
|
|
100
|
-
expect(result).toEqual({ name: 'John', age: 30 });
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('should throw for invalid data', async () => {
|
|
104
|
-
const schema = z.object({
|
|
105
|
-
name: z.string(),
|
|
106
|
-
age: z.number(),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
await expect(
|
|
110
|
-
parseSchema(schema, { name: 'John', age: 'invalid' }),
|
|
111
|
-
).rejects.toBeDefined();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should return undefined for undefined schema', async () => {
|
|
115
|
-
const result = await parseSchema(undefined as any, { name: 'John' });
|
|
116
|
-
|
|
117
|
-
expect(result).toBeUndefined();
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should parse string schema', async () => {
|
|
121
|
-
const schema = z.string().min(3);
|
|
122
|
-
|
|
123
|
-
const result = await parseSchema(schema, 'test');
|
|
124
|
-
|
|
125
|
-
expect(result).toBe('test');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should throw for string that is too short', async () => {
|
|
129
|
-
const schema = z.string().min(5);
|
|
130
|
-
|
|
131
|
-
await expect(parseSchema(schema, 'abc')).rejects.toBeDefined();
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('should parse number schema', async () => {
|
|
135
|
-
const schema = z.number().positive();
|
|
136
|
-
|
|
137
|
-
const result = await parseSchema(schema, 42);
|
|
138
|
-
|
|
139
|
-
expect(result).toBe(42);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should throw for negative number when positive required', async () => {
|
|
143
|
-
const schema = z.number().positive();
|
|
144
|
-
|
|
145
|
-
await expect(parseSchema(schema, -5)).rejects.toBeDefined();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('should parse optional fields', async () => {
|
|
149
|
-
const schema = z.object({
|
|
150
|
-
required: z.string(),
|
|
151
|
-
optional: z.string().optional(),
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const result = await parseSchema(schema, { required: 'value' });
|
|
155
|
-
|
|
156
|
-
expect(result).toEqual({ required: 'value' });
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('should parse with defaults', async () => {
|
|
160
|
-
const schema = z.object({
|
|
161
|
-
name: z.string(),
|
|
162
|
-
role: z.string().default('user'),
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
const result = await parseSchema(schema, { name: 'John' });
|
|
166
|
-
|
|
167
|
-
expect(result).toEqual({ name: 'John', role: 'user' });
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should parse enum values', async () => {
|
|
171
|
-
const schema = z.object({
|
|
172
|
-
status: z.enum(['active', 'inactive', 'pending']),
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
const result = await parseSchema(schema, { status: 'active' });
|
|
176
|
-
|
|
177
|
-
expect(result).toEqual({ status: 'active' });
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should throw for invalid enum value', async () => {
|
|
181
|
-
const schema = z.object({
|
|
182
|
-
status: z.enum(['active', 'inactive']),
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
await expect(
|
|
186
|
-
parseSchema(schema, { status: 'invalid' }),
|
|
187
|
-
).rejects.toBeDefined();
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('should parse union types', async () => {
|
|
191
|
-
const schema = z.union([z.string(), z.number()]);
|
|
192
|
-
|
|
193
|
-
const result1 = await parseSchema(schema, 'text');
|
|
194
|
-
const result2 = await parseSchema(schema, 42);
|
|
195
|
-
|
|
196
|
-
expect(result1).toBe('text');
|
|
197
|
-
expect(result2).toBe(42);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it('should throw for invalid union value', async () => {
|
|
201
|
-
const schema = z.union([z.string(), z.number()]);
|
|
202
|
-
|
|
203
|
-
await expect(parseSchema(schema, true)).rejects.toBeDefined();
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
it('should parse array of objects', async () => {
|
|
207
|
-
const schema = z.array(
|
|
208
|
-
z.object({
|
|
209
|
-
id: z.number(),
|
|
210
|
-
name: z.string(),
|
|
211
|
-
}),
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
const result = await parseSchema(schema, [
|
|
215
|
-
{ id: 1, name: 'Alice' },
|
|
216
|
-
{ id: 2, name: 'Bob' },
|
|
217
|
-
]);
|
|
218
|
-
|
|
219
|
-
expect(result).toEqual([
|
|
220
|
-
{ id: 1, name: 'Alice' },
|
|
221
|
-
{ id: 2, name: 'Bob' },
|
|
222
|
-
]);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
it('should validate required fields', async () => {
|
|
226
|
-
const schema = z.object({
|
|
227
|
-
required: z.string(),
|
|
228
|
-
optional: z.string().optional(),
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
await expect(
|
|
232
|
-
parseSchema(schema, { optional: 'value' }),
|
|
233
|
-
).rejects.toBeDefined();
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
});
|