@ai-sdk/provider-utils 4.0.7 → 4.0.9
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/CHANGELOG.md +15 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -2
- package/src/__snapshots__/schema.test.ts.snap +0 -346
- package/src/add-additional-properties-to-json-schema.test.ts +0 -289
- package/src/convert-async-iterator-to-readable-stream.test.ts +0 -78
- package/src/convert-image-model-file-to-data-uri.test.ts +0 -85
- package/src/convert-to-form-data.test.ts +0 -167
- package/src/create-tool-name-mapping.test.ts +0 -163
- package/src/delay.test.ts +0 -212
- package/src/delayed-promise.test.ts +0 -132
- package/src/download-blob.test.ts +0 -145
- package/src/generate-id.test.ts +0 -31
- package/src/get-from-api.test.ts +0 -199
- package/src/get-runtime-environment-user-agent.test.ts +0 -47
- package/src/inject-json-instruction.test.ts +0 -404
- package/src/is-url-supported.test.ts +0 -282
- package/src/media-type-to-extension.test.ts +0 -26
- package/src/normalize-headers.test.ts +0 -64
- package/src/parse-json.test.ts +0 -191
- package/src/remove-undefined-entries.test.ts +0 -57
- package/src/resolve.test.ts +0 -125
- package/src/response-handler.test.ts +0 -89
- package/src/schema.test-d.ts +0 -11
- package/src/schema.test.ts +0 -502
- package/src/secure-json-parse.test.ts +0 -59
- package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +0 -224
- package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +0 -98
- package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +0 -51
- package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +0 -16
- package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +0 -15
- package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +0 -97
- package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +0 -54
- package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +0 -41
- package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +0 -92
- package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +0 -48
- package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +0 -102
- package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +0 -67
- package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +0 -65
- package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +0 -149
- package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +0 -147
- package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +0 -35
- package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +0 -15
- package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +0 -20
- package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +0 -108
- package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +0 -20
- package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +0 -438
- package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +0 -33
- package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +0 -226
- package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +0 -919
- package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +0 -862
- package/src/types/tool.test-d.ts +0 -228
- package/src/validate-types.test.ts +0 -105
- package/src/with-user-agent-suffix.test.ts +0 -84
|
@@ -1,919 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { JSONSchema7 } from '@ai-sdk/provider';
|
|
3
|
-
import { z } from 'zod/v3';
|
|
4
|
-
import { zod3ToJsonSchema } from './zod3-to-json-schema';
|
|
5
|
-
|
|
6
|
-
describe('paths', () => {
|
|
7
|
-
it('should handle recurring properties with paths', () => {
|
|
8
|
-
const addressSchema = z.object({
|
|
9
|
-
street: z.string(),
|
|
10
|
-
number: z.number(),
|
|
11
|
-
city: z.string(),
|
|
12
|
-
});
|
|
13
|
-
const someAddresses = z.object({
|
|
14
|
-
address1: addressSchema,
|
|
15
|
-
address2: addressSchema,
|
|
16
|
-
lotsOfAddresses: z.array(addressSchema),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const parsedSchema = zod3ToJsonSchema(someAddresses);
|
|
20
|
-
|
|
21
|
-
expect(parsedSchema).toStrictEqual({
|
|
22
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
23
|
-
type: 'object',
|
|
24
|
-
properties: {
|
|
25
|
-
address1: {
|
|
26
|
-
type: 'object',
|
|
27
|
-
properties: {
|
|
28
|
-
street: { type: 'string' },
|
|
29
|
-
number: { type: 'number' },
|
|
30
|
-
city: { type: 'string' },
|
|
31
|
-
},
|
|
32
|
-
additionalProperties: false,
|
|
33
|
-
required: ['street', 'number', 'city'],
|
|
34
|
-
},
|
|
35
|
-
address2: { $ref: '#/properties/address1' },
|
|
36
|
-
lotsOfAddresses: {
|
|
37
|
-
type: 'array',
|
|
38
|
-
items: { $ref: '#/properties/address1' },
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
additionalProperties: false,
|
|
42
|
-
required: ['address1', 'address2', 'lotsOfAddresses'],
|
|
43
|
-
} satisfies JSONSchema7);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('Should properly reference union participants', () => {
|
|
47
|
-
const participant = z.object({ str: z.string() });
|
|
48
|
-
|
|
49
|
-
const schema = z.object({
|
|
50
|
-
union: z.union([participant, z.string()]),
|
|
51
|
-
part: participant,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const parsedSchema = zod3ToJsonSchema(schema);
|
|
55
|
-
|
|
56
|
-
expect(parsedSchema).toStrictEqual({
|
|
57
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
58
|
-
type: 'object',
|
|
59
|
-
properties: {
|
|
60
|
-
union: {
|
|
61
|
-
anyOf: [
|
|
62
|
-
{
|
|
63
|
-
type: 'object',
|
|
64
|
-
properties: {
|
|
65
|
-
str: {
|
|
66
|
-
type: 'string',
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
additionalProperties: false,
|
|
70
|
-
required: ['str'],
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
type: 'string',
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
part: {
|
|
78
|
-
$ref: '#/properties/union/anyOf/0',
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
additionalProperties: false,
|
|
82
|
-
required: ['union', 'part'],
|
|
83
|
-
} satisfies JSONSchema7);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('Should be able to handle recursive schemas', () => {
|
|
87
|
-
type Category = {
|
|
88
|
-
name: string;
|
|
89
|
-
subcategories: Category[];
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
// cast to z.ZodSchema<Category>
|
|
93
|
-
// @ts-ignore
|
|
94
|
-
const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
|
|
95
|
-
z.object({
|
|
96
|
-
name: z.string(),
|
|
97
|
-
subcategories: z.array(categorySchema),
|
|
98
|
-
}),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
const parsedSchema = zod3ToJsonSchema(categorySchema);
|
|
102
|
-
|
|
103
|
-
expect(parsedSchema).toStrictEqual({
|
|
104
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
105
|
-
type: 'object',
|
|
106
|
-
properties: {
|
|
107
|
-
name: {
|
|
108
|
-
type: 'string',
|
|
109
|
-
},
|
|
110
|
-
subcategories: {
|
|
111
|
-
type: 'array',
|
|
112
|
-
items: {
|
|
113
|
-
$ref: '#',
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
required: ['name', 'subcategories'],
|
|
118
|
-
additionalProperties: false,
|
|
119
|
-
} satisfies JSONSchema7);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('Should be able to handle complex & nested recursive schemas', () => {
|
|
123
|
-
type Category = {
|
|
124
|
-
name: string;
|
|
125
|
-
inner: {
|
|
126
|
-
subcategories?: Record<string, Category> | null;
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// cast to z.ZodSchema<Category>
|
|
131
|
-
// @ts-ignore
|
|
132
|
-
const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
|
|
133
|
-
z.object({
|
|
134
|
-
name: z.string(),
|
|
135
|
-
inner: z.object({
|
|
136
|
-
subcategories: z.record(categorySchema).nullable().optional(),
|
|
137
|
-
}),
|
|
138
|
-
}),
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
const inObjectSchema = z.object({
|
|
142
|
-
category: categorySchema,
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const parsedSchema = zod3ToJsonSchema(inObjectSchema);
|
|
146
|
-
|
|
147
|
-
expect(parsedSchema).toStrictEqual({
|
|
148
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
149
|
-
type: 'object',
|
|
150
|
-
additionalProperties: false,
|
|
151
|
-
required: ['category'],
|
|
152
|
-
properties: {
|
|
153
|
-
category: {
|
|
154
|
-
type: 'object',
|
|
155
|
-
properties: {
|
|
156
|
-
name: {
|
|
157
|
-
type: 'string',
|
|
158
|
-
},
|
|
159
|
-
inner: {
|
|
160
|
-
type: 'object',
|
|
161
|
-
additionalProperties: false,
|
|
162
|
-
properties: {
|
|
163
|
-
subcategories: {
|
|
164
|
-
anyOf: [
|
|
165
|
-
{
|
|
166
|
-
type: 'object',
|
|
167
|
-
additionalProperties: {
|
|
168
|
-
$ref: '#/properties/category',
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
type: 'null',
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
required: ['name', 'inner'],
|
|
180
|
-
additionalProperties: false,
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
} satisfies JSONSchema7);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it('should work with relative references', () => {
|
|
187
|
-
const recurringSchema = z.string();
|
|
188
|
-
const objectSchema = z.object({
|
|
189
|
-
foo: recurringSchema,
|
|
190
|
-
bar: recurringSchema,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
194
|
-
$refStrategy: 'relative',
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
expect(jsonSchema).toStrictEqual({
|
|
198
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
199
|
-
type: 'object',
|
|
200
|
-
properties: {
|
|
201
|
-
foo: {
|
|
202
|
-
type: 'string',
|
|
203
|
-
},
|
|
204
|
-
bar: {
|
|
205
|
-
$ref: '1/foo',
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
required: ['foo', 'bar'],
|
|
209
|
-
additionalProperties: false,
|
|
210
|
-
} satisfies JSONSchema7);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('should be possible to override the base path', () => {
|
|
214
|
-
const recurringSchema = z.string();
|
|
215
|
-
const objectSchema = z.object({
|
|
216
|
-
foo: recurringSchema,
|
|
217
|
-
bar: recurringSchema,
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
221
|
-
basePath: ['#', 'lol', 'xD'],
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
expect(jsonSchema).toStrictEqual({
|
|
225
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
226
|
-
type: 'object',
|
|
227
|
-
properties: {
|
|
228
|
-
foo: {
|
|
229
|
-
type: 'string',
|
|
230
|
-
},
|
|
231
|
-
bar: {
|
|
232
|
-
$ref: '#/lol/xD/properties/foo',
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
required: ['foo', 'bar'],
|
|
236
|
-
additionalProperties: false,
|
|
237
|
-
} satisfies JSONSchema7);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('should be possible to override the base path with name', () => {
|
|
241
|
-
const recurringSchema = z.string();
|
|
242
|
-
const objectSchema = z.object({
|
|
243
|
-
foo: recurringSchema,
|
|
244
|
-
bar: recurringSchema,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
248
|
-
basePath: ['#', 'lol', 'xD'],
|
|
249
|
-
name: 'kex',
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
expect(jsonSchema).toStrictEqual({
|
|
253
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
254
|
-
$ref: '#/lol/xD/definitions/kex',
|
|
255
|
-
definitions: {
|
|
256
|
-
kex: {
|
|
257
|
-
type: 'object',
|
|
258
|
-
properties: {
|
|
259
|
-
foo: {
|
|
260
|
-
type: 'string',
|
|
261
|
-
},
|
|
262
|
-
bar: {
|
|
263
|
-
$ref: '#/lol/xD/definitions/kex/properties/foo',
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
required: ['foo', 'bar'],
|
|
267
|
-
additionalProperties: false,
|
|
268
|
-
},
|
|
269
|
-
},
|
|
270
|
-
} satisfies JSONSchema7);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('should be possible to opt out of $ref building', () => {
|
|
274
|
-
const recurringSchema = z.string();
|
|
275
|
-
const objectSchema = z.object({
|
|
276
|
-
foo: recurringSchema,
|
|
277
|
-
bar: recurringSchema,
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
281
|
-
$refStrategy: 'none',
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
expect(jsonSchema).toStrictEqual({
|
|
285
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
286
|
-
type: 'object',
|
|
287
|
-
properties: {
|
|
288
|
-
foo: {
|
|
289
|
-
type: 'string',
|
|
290
|
-
},
|
|
291
|
-
bar: {
|
|
292
|
-
type: 'string',
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
required: ['foo', 'bar'],
|
|
296
|
-
additionalProperties: false,
|
|
297
|
-
} satisfies JSONSchema7);
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
it('When opting out of ref building and using recursive schemas, should warn and default to any', () => {
|
|
301
|
-
const was = console.warn;
|
|
302
|
-
let warning = '';
|
|
303
|
-
console.warn = (x: any) => (warning = x);
|
|
304
|
-
|
|
305
|
-
type Category = {
|
|
306
|
-
name: string;
|
|
307
|
-
subcategories: Category[];
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// cast to z.ZodSchema<Category>
|
|
311
|
-
// @ts-ignore
|
|
312
|
-
const categorySchema: z.ZodSchema<Category> = z.lazy(() =>
|
|
313
|
-
z.object({
|
|
314
|
-
name: z.string(),
|
|
315
|
-
subcategories: z.array(categorySchema),
|
|
316
|
-
}),
|
|
317
|
-
);
|
|
318
|
-
|
|
319
|
-
const parsedSchema = zod3ToJsonSchema(categorySchema, {
|
|
320
|
-
$refStrategy: 'none',
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
expect(parsedSchema).toStrictEqual({
|
|
324
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
325
|
-
type: 'object',
|
|
326
|
-
properties: {
|
|
327
|
-
name: {
|
|
328
|
-
type: 'string',
|
|
329
|
-
},
|
|
330
|
-
subcategories: {
|
|
331
|
-
type: 'array',
|
|
332
|
-
items: {},
|
|
333
|
-
},
|
|
334
|
-
},
|
|
335
|
-
required: ['name', 'subcategories'],
|
|
336
|
-
additionalProperties: false,
|
|
337
|
-
} satisfies JSONSchema7);
|
|
338
|
-
|
|
339
|
-
expect(warning).toBe(
|
|
340
|
-
'Recursive reference detected at #/properties/subcategories/items! Defaulting to any',
|
|
341
|
-
);
|
|
342
|
-
|
|
343
|
-
console.warn = was;
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it('should be possible to override get proper references even when picking optional definitions path $defs', () => {
|
|
347
|
-
const recurringSchema = z.string();
|
|
348
|
-
const objectSchema = z.object({
|
|
349
|
-
foo: recurringSchema,
|
|
350
|
-
bar: recurringSchema,
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
354
|
-
name: 'hello',
|
|
355
|
-
definitionPath: '$defs',
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
expect(jsonSchema).toStrictEqual({
|
|
359
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
360
|
-
$ref: '#/$defs/hello',
|
|
361
|
-
$defs: {
|
|
362
|
-
hello: {
|
|
363
|
-
type: 'object',
|
|
364
|
-
properties: {
|
|
365
|
-
foo: {
|
|
366
|
-
type: 'string',
|
|
367
|
-
},
|
|
368
|
-
bar: {
|
|
369
|
-
$ref: '#/$defs/hello/properties/foo',
|
|
370
|
-
},
|
|
371
|
-
},
|
|
372
|
-
required: ['foo', 'bar'],
|
|
373
|
-
additionalProperties: false,
|
|
374
|
-
},
|
|
375
|
-
},
|
|
376
|
-
} satisfies JSONSchema7);
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('should be possible to override get proper references even when picking optional definitions path definitions', () => {
|
|
380
|
-
const recurringSchema = z.string();
|
|
381
|
-
const objectSchema = z.object({
|
|
382
|
-
foo: recurringSchema,
|
|
383
|
-
bar: recurringSchema,
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, {
|
|
387
|
-
name: 'hello',
|
|
388
|
-
definitionPath: 'definitions',
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
expect(jsonSchema).toStrictEqual({
|
|
392
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
393
|
-
$ref: '#/definitions/hello',
|
|
394
|
-
definitions: {
|
|
395
|
-
hello: {
|
|
396
|
-
type: 'object',
|
|
397
|
-
properties: {
|
|
398
|
-
foo: {
|
|
399
|
-
type: 'string',
|
|
400
|
-
},
|
|
401
|
-
bar: {
|
|
402
|
-
$ref: '#/definitions/hello/properties/foo',
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
required: ['foo', 'bar'],
|
|
406
|
-
additionalProperties: false,
|
|
407
|
-
},
|
|
408
|
-
},
|
|
409
|
-
} satisfies JSONSchema7);
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
it('should preserve correct $ref when overriding name with string', () => {
|
|
413
|
-
const recurringSchema = z.string();
|
|
414
|
-
const objectSchema = z.object({
|
|
415
|
-
foo: recurringSchema,
|
|
416
|
-
bar: recurringSchema,
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, 'hello');
|
|
420
|
-
|
|
421
|
-
expect(jsonSchema).toStrictEqual({
|
|
422
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
423
|
-
$ref: '#/definitions/hello',
|
|
424
|
-
definitions: {
|
|
425
|
-
hello: {
|
|
426
|
-
type: 'object',
|
|
427
|
-
properties: {
|
|
428
|
-
foo: {
|
|
429
|
-
type: 'string',
|
|
430
|
-
},
|
|
431
|
-
bar: {
|
|
432
|
-
$ref: '#/definitions/hello/properties/foo',
|
|
433
|
-
},
|
|
434
|
-
},
|
|
435
|
-
required: ['foo', 'bar'],
|
|
436
|
-
additionalProperties: false,
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
} satisfies JSONSchema7);
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
it('should preserve correct $ref when overriding name with object property', () => {
|
|
443
|
-
const recurringSchema = z.string();
|
|
444
|
-
const objectSchema = z.object({
|
|
445
|
-
foo: recurringSchema,
|
|
446
|
-
bar: recurringSchema,
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
const jsonSchema = zod3ToJsonSchema(objectSchema, { name: 'hello' });
|
|
450
|
-
|
|
451
|
-
expect(jsonSchema).toStrictEqual({
|
|
452
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
453
|
-
$ref: '#/definitions/hello',
|
|
454
|
-
definitions: {
|
|
455
|
-
hello: {
|
|
456
|
-
type: 'object',
|
|
457
|
-
properties: {
|
|
458
|
-
foo: {
|
|
459
|
-
type: 'string',
|
|
460
|
-
},
|
|
461
|
-
bar: {
|
|
462
|
-
$ref: '#/definitions/hello/properties/foo',
|
|
463
|
-
},
|
|
464
|
-
},
|
|
465
|
-
required: ['foo', 'bar'],
|
|
466
|
-
additionalProperties: false,
|
|
467
|
-
},
|
|
468
|
-
},
|
|
469
|
-
} satisfies JSONSchema7);
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('should be possible to preload a single definition', () => {
|
|
473
|
-
const myRecurringSchema = z.string();
|
|
474
|
-
const myObjectSchema = z.object({
|
|
475
|
-
a: myRecurringSchema,
|
|
476
|
-
b: myRecurringSchema,
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
480
|
-
definitions: { myRecurringSchema },
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
expect(myJsonSchema).toStrictEqual({
|
|
484
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
485
|
-
type: 'object',
|
|
486
|
-
required: ['a', 'b'],
|
|
487
|
-
properties: {
|
|
488
|
-
a: {
|
|
489
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
490
|
-
},
|
|
491
|
-
b: {
|
|
492
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
493
|
-
},
|
|
494
|
-
},
|
|
495
|
-
additionalProperties: false,
|
|
496
|
-
definitions: {
|
|
497
|
-
myRecurringSchema: {
|
|
498
|
-
type: 'string',
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
} satisfies JSONSchema7);
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
it('should be possible to preload multiple definitions', () => {
|
|
505
|
-
const myRecurringSchema = z.string();
|
|
506
|
-
const mySecondRecurringSchema = z.object({
|
|
507
|
-
x: myRecurringSchema,
|
|
508
|
-
});
|
|
509
|
-
const myObjectSchema = z.object({
|
|
510
|
-
a: myRecurringSchema,
|
|
511
|
-
b: mySecondRecurringSchema,
|
|
512
|
-
c: mySecondRecurringSchema,
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
516
|
-
definitions: { myRecurringSchema, mySecondRecurringSchema },
|
|
517
|
-
});
|
|
518
|
-
|
|
519
|
-
expect(myJsonSchema).toStrictEqual({
|
|
520
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
521
|
-
type: 'object',
|
|
522
|
-
required: ['a', 'b', 'c'],
|
|
523
|
-
properties: {
|
|
524
|
-
a: {
|
|
525
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
526
|
-
},
|
|
527
|
-
b: {
|
|
528
|
-
$ref: '#/definitions/mySecondRecurringSchema',
|
|
529
|
-
},
|
|
530
|
-
c: {
|
|
531
|
-
$ref: '#/definitions/mySecondRecurringSchema',
|
|
532
|
-
},
|
|
533
|
-
},
|
|
534
|
-
additionalProperties: false,
|
|
535
|
-
definitions: {
|
|
536
|
-
myRecurringSchema: {
|
|
537
|
-
type: 'string',
|
|
538
|
-
},
|
|
539
|
-
mySecondRecurringSchema: {
|
|
540
|
-
type: 'object',
|
|
541
|
-
required: ['x'],
|
|
542
|
-
properties: {
|
|
543
|
-
x: {
|
|
544
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
545
|
-
},
|
|
546
|
-
},
|
|
547
|
-
additionalProperties: false,
|
|
548
|
-
},
|
|
549
|
-
},
|
|
550
|
-
} satisfies JSONSchema7);
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it('should be possible to preload multiple definitions and have a named schema', () => {
|
|
554
|
-
const myRecurringSchema = z.string();
|
|
555
|
-
const mySecondRecurringSchema = z.object({
|
|
556
|
-
x: myRecurringSchema,
|
|
557
|
-
});
|
|
558
|
-
const myObjectSchema = z.object({
|
|
559
|
-
a: myRecurringSchema,
|
|
560
|
-
b: mySecondRecurringSchema,
|
|
561
|
-
c: mySecondRecurringSchema,
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
565
|
-
definitions: { myRecurringSchema, mySecondRecurringSchema },
|
|
566
|
-
name: 'mySchemaName',
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
expect(myJsonSchema).toStrictEqual({
|
|
570
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
571
|
-
$ref: '#/definitions/mySchemaName',
|
|
572
|
-
definitions: {
|
|
573
|
-
mySchemaName: {
|
|
574
|
-
type: 'object',
|
|
575
|
-
required: ['a', 'b', 'c'],
|
|
576
|
-
properties: {
|
|
577
|
-
a: {
|
|
578
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
579
|
-
},
|
|
580
|
-
b: {
|
|
581
|
-
$ref: '#/definitions/mySecondRecurringSchema',
|
|
582
|
-
},
|
|
583
|
-
c: {
|
|
584
|
-
$ref: '#/definitions/mySecondRecurringSchema',
|
|
585
|
-
},
|
|
586
|
-
},
|
|
587
|
-
additionalProperties: false,
|
|
588
|
-
},
|
|
589
|
-
myRecurringSchema: {
|
|
590
|
-
type: 'string',
|
|
591
|
-
},
|
|
592
|
-
mySecondRecurringSchema: {
|
|
593
|
-
type: 'object',
|
|
594
|
-
required: ['x'],
|
|
595
|
-
properties: {
|
|
596
|
-
x: {
|
|
597
|
-
$ref: '#/definitions/myRecurringSchema',
|
|
598
|
-
},
|
|
599
|
-
},
|
|
600
|
-
additionalProperties: false,
|
|
601
|
-
},
|
|
602
|
-
},
|
|
603
|
-
} satisfies JSONSchema7);
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
it('should be possible to preload multiple definitions and have a named schema and set the definitions path', () => {
|
|
607
|
-
const myRecurringSchema = z.string();
|
|
608
|
-
const mySecondRecurringSchema = z.object({
|
|
609
|
-
x: myRecurringSchema,
|
|
610
|
-
});
|
|
611
|
-
const myObjectSchema = z.object({
|
|
612
|
-
a: myRecurringSchema,
|
|
613
|
-
b: mySecondRecurringSchema,
|
|
614
|
-
c: mySecondRecurringSchema,
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
618
|
-
definitions: { myRecurringSchema, mySecondRecurringSchema },
|
|
619
|
-
name: 'mySchemaName',
|
|
620
|
-
definitionPath: '$defs',
|
|
621
|
-
});
|
|
622
|
-
|
|
623
|
-
expect(myJsonSchema).toStrictEqual({
|
|
624
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
625
|
-
$ref: '#/$defs/mySchemaName',
|
|
626
|
-
$defs: {
|
|
627
|
-
mySchemaName: {
|
|
628
|
-
type: 'object',
|
|
629
|
-
required: ['a', 'b', 'c'],
|
|
630
|
-
properties: {
|
|
631
|
-
a: {
|
|
632
|
-
$ref: '#/$defs/myRecurringSchema',
|
|
633
|
-
},
|
|
634
|
-
b: {
|
|
635
|
-
$ref: '#/$defs/mySecondRecurringSchema',
|
|
636
|
-
},
|
|
637
|
-
c: {
|
|
638
|
-
$ref: '#/$defs/mySecondRecurringSchema',
|
|
639
|
-
},
|
|
640
|
-
},
|
|
641
|
-
additionalProperties: false,
|
|
642
|
-
},
|
|
643
|
-
myRecurringSchema: {
|
|
644
|
-
type: 'string',
|
|
645
|
-
},
|
|
646
|
-
mySecondRecurringSchema: {
|
|
647
|
-
type: 'object',
|
|
648
|
-
required: ['x'],
|
|
649
|
-
properties: {
|
|
650
|
-
x: {
|
|
651
|
-
$ref: '#/$defs/myRecurringSchema',
|
|
652
|
-
},
|
|
653
|
-
},
|
|
654
|
-
additionalProperties: false,
|
|
655
|
-
},
|
|
656
|
-
},
|
|
657
|
-
} satisfies JSONSchema7);
|
|
658
|
-
});
|
|
659
|
-
|
|
660
|
-
it('should be possible to preload a single definition with custom basePath', () => {
|
|
661
|
-
const myRecurringSchema = z.string();
|
|
662
|
-
const myObjectSchema = z.object({
|
|
663
|
-
a: myRecurringSchema,
|
|
664
|
-
b: myRecurringSchema,
|
|
665
|
-
});
|
|
666
|
-
|
|
667
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
668
|
-
definitions: { myRecurringSchema },
|
|
669
|
-
basePath: ['hello'],
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
expect(myJsonSchema).toStrictEqual({
|
|
673
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
674
|
-
type: 'object',
|
|
675
|
-
required: ['a', 'b'],
|
|
676
|
-
properties: {
|
|
677
|
-
a: {
|
|
678
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
679
|
-
},
|
|
680
|
-
b: {
|
|
681
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
682
|
-
},
|
|
683
|
-
},
|
|
684
|
-
additionalProperties: false,
|
|
685
|
-
definitions: {
|
|
686
|
-
myRecurringSchema: {
|
|
687
|
-
type: 'string',
|
|
688
|
-
},
|
|
689
|
-
},
|
|
690
|
-
} satisfies JSONSchema7);
|
|
691
|
-
});
|
|
692
|
-
|
|
693
|
-
it('should be possible to preload a single definition with custom basePath and name', () => {
|
|
694
|
-
const myRecurringSchema = z.string();
|
|
695
|
-
const myObjectSchema = z.object({
|
|
696
|
-
a: myRecurringSchema,
|
|
697
|
-
b: myRecurringSchema,
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
701
|
-
definitions: { myRecurringSchema },
|
|
702
|
-
basePath: ['hello'],
|
|
703
|
-
name: 'kex',
|
|
704
|
-
});
|
|
705
|
-
|
|
706
|
-
expect(myJsonSchema).toStrictEqual({
|
|
707
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
708
|
-
$ref: 'hello/definitions/kex',
|
|
709
|
-
definitions: {
|
|
710
|
-
kex: {
|
|
711
|
-
type: 'object',
|
|
712
|
-
required: ['a', 'b'],
|
|
713
|
-
properties: {
|
|
714
|
-
a: {
|
|
715
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
716
|
-
},
|
|
717
|
-
b: {
|
|
718
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
719
|
-
},
|
|
720
|
-
},
|
|
721
|
-
additionalProperties: false,
|
|
722
|
-
},
|
|
723
|
-
myRecurringSchema: {
|
|
724
|
-
type: 'string',
|
|
725
|
-
},
|
|
726
|
-
},
|
|
727
|
-
} satisfies JSONSchema7);
|
|
728
|
-
});
|
|
729
|
-
|
|
730
|
-
it('should be possible for a preloaded definition to circularly reference itself', () => {
|
|
731
|
-
const myRecurringSchema: any = z.object({
|
|
732
|
-
circular: z.lazy(() => myRecurringSchema),
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
const myObjectSchema = z.object({
|
|
736
|
-
a: myRecurringSchema,
|
|
737
|
-
b: myRecurringSchema,
|
|
738
|
-
});
|
|
739
|
-
|
|
740
|
-
const myJsonSchema = zod3ToJsonSchema(myObjectSchema, {
|
|
741
|
-
definitions: { myRecurringSchema },
|
|
742
|
-
basePath: ['hello'],
|
|
743
|
-
name: 'kex',
|
|
744
|
-
});
|
|
745
|
-
|
|
746
|
-
expect(myJsonSchema).toStrictEqual({
|
|
747
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
748
|
-
$ref: 'hello/definitions/kex',
|
|
749
|
-
definitions: {
|
|
750
|
-
kex: {
|
|
751
|
-
type: 'object',
|
|
752
|
-
required: ['a', 'b'],
|
|
753
|
-
properties: {
|
|
754
|
-
a: {
|
|
755
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
756
|
-
},
|
|
757
|
-
b: {
|
|
758
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
759
|
-
},
|
|
760
|
-
},
|
|
761
|
-
additionalProperties: false,
|
|
762
|
-
},
|
|
763
|
-
myRecurringSchema: {
|
|
764
|
-
type: 'object',
|
|
765
|
-
required: ['circular'],
|
|
766
|
-
properties: {
|
|
767
|
-
circular: {
|
|
768
|
-
$ref: 'hello/definitions/myRecurringSchema',
|
|
769
|
-
},
|
|
770
|
-
},
|
|
771
|
-
additionalProperties: false,
|
|
772
|
-
},
|
|
773
|
-
},
|
|
774
|
-
} satisfies JSONSchema7);
|
|
775
|
-
});
|
|
776
|
-
|
|
777
|
-
it('should handle the user example', () => {
|
|
778
|
-
interface User {
|
|
779
|
-
id: string;
|
|
780
|
-
headUser?: User;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
const userSchema: z.ZodType<User> = z.lazy(() =>
|
|
784
|
-
z.object({
|
|
785
|
-
id: z.string(),
|
|
786
|
-
headUser: userSchema.optional(),
|
|
787
|
-
}),
|
|
788
|
-
);
|
|
789
|
-
|
|
790
|
-
const schema = z.object({ user: userSchema });
|
|
791
|
-
|
|
792
|
-
expect(
|
|
793
|
-
zod3ToJsonSchema(schema, {
|
|
794
|
-
definitions: { userSchema },
|
|
795
|
-
}),
|
|
796
|
-
).toStrictEqual({
|
|
797
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
798
|
-
type: 'object',
|
|
799
|
-
properties: {
|
|
800
|
-
user: {
|
|
801
|
-
$ref: '#/definitions/userSchema',
|
|
802
|
-
},
|
|
803
|
-
},
|
|
804
|
-
required: ['user'],
|
|
805
|
-
additionalProperties: false,
|
|
806
|
-
definitions: {
|
|
807
|
-
userSchema: {
|
|
808
|
-
type: 'object',
|
|
809
|
-
properties: {
|
|
810
|
-
id: {
|
|
811
|
-
type: 'string',
|
|
812
|
-
},
|
|
813
|
-
headUser: {
|
|
814
|
-
$ref: '#/definitions/userSchema',
|
|
815
|
-
},
|
|
816
|
-
},
|
|
817
|
-
required: ['id'],
|
|
818
|
-
additionalProperties: false,
|
|
819
|
-
},
|
|
820
|
-
},
|
|
821
|
-
} satisfies JSONSchema7);
|
|
822
|
-
});
|
|
823
|
-
|
|
824
|
-
it('should handle mutual recursion', () => {
|
|
825
|
-
const leafSchema = z.object({
|
|
826
|
-
prop: z.string(),
|
|
827
|
-
});
|
|
828
|
-
|
|
829
|
-
let nodeChildSchema: z.ZodType;
|
|
830
|
-
|
|
831
|
-
const nodeSchema = z.object({
|
|
832
|
-
children: z.lazy(() => z.array(nodeChildSchema)),
|
|
833
|
-
});
|
|
834
|
-
|
|
835
|
-
nodeChildSchema = z.union([leafSchema, nodeSchema]);
|
|
836
|
-
|
|
837
|
-
const treeSchema = z.object({
|
|
838
|
-
nodes: nodeSchema,
|
|
839
|
-
});
|
|
840
|
-
|
|
841
|
-
expect(
|
|
842
|
-
zod3ToJsonSchema(treeSchema, {
|
|
843
|
-
name: 'Tree',
|
|
844
|
-
definitions: {
|
|
845
|
-
Leaf: leafSchema,
|
|
846
|
-
NodeChild: nodeChildSchema,
|
|
847
|
-
Node: nodeSchema,
|
|
848
|
-
},
|
|
849
|
-
}),
|
|
850
|
-
).toStrictEqual({
|
|
851
|
-
$ref: '#/definitions/Tree',
|
|
852
|
-
definitions: {
|
|
853
|
-
Leaf: {
|
|
854
|
-
type: 'object',
|
|
855
|
-
properties: {
|
|
856
|
-
prop: {
|
|
857
|
-
type: 'string',
|
|
858
|
-
},
|
|
859
|
-
},
|
|
860
|
-
required: ['prop'],
|
|
861
|
-
additionalProperties: false,
|
|
862
|
-
},
|
|
863
|
-
Node: {
|
|
864
|
-
type: 'object',
|
|
865
|
-
properties: {
|
|
866
|
-
children: {
|
|
867
|
-
type: 'array',
|
|
868
|
-
items: {
|
|
869
|
-
$ref: '#/definitions/NodeChild',
|
|
870
|
-
},
|
|
871
|
-
},
|
|
872
|
-
},
|
|
873
|
-
required: ['children'],
|
|
874
|
-
additionalProperties: false,
|
|
875
|
-
},
|
|
876
|
-
NodeChild: {
|
|
877
|
-
anyOf: [
|
|
878
|
-
{
|
|
879
|
-
$ref: '#/definitions/Leaf',
|
|
880
|
-
},
|
|
881
|
-
{
|
|
882
|
-
$ref: '#/definitions/Node',
|
|
883
|
-
},
|
|
884
|
-
],
|
|
885
|
-
},
|
|
886
|
-
Tree: {
|
|
887
|
-
type: 'object',
|
|
888
|
-
properties: {
|
|
889
|
-
nodes: {
|
|
890
|
-
$ref: '#/definitions/Node',
|
|
891
|
-
},
|
|
892
|
-
},
|
|
893
|
-
required: ['nodes'],
|
|
894
|
-
additionalProperties: false,
|
|
895
|
-
},
|
|
896
|
-
},
|
|
897
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
898
|
-
} satisfies JSONSchema7);
|
|
899
|
-
});
|
|
900
|
-
|
|
901
|
-
it('should not fail when definition is lazy', () => {
|
|
902
|
-
const lazyString = z.lazy(() => z.string());
|
|
903
|
-
|
|
904
|
-
const lazyObject = z.lazy(() => z.object({ lazyProp: lazyString }));
|
|
905
|
-
|
|
906
|
-
const jsonSchema = zod3ToJsonSchema(lazyObject, {
|
|
907
|
-
definitions: { lazyString },
|
|
908
|
-
});
|
|
909
|
-
|
|
910
|
-
expect(jsonSchema).toStrictEqual({
|
|
911
|
-
type: 'object',
|
|
912
|
-
properties: { lazyProp: { $ref: '#/definitions/lazyString' } },
|
|
913
|
-
required: ['lazyProp'],
|
|
914
|
-
additionalProperties: false,
|
|
915
|
-
definitions: { lazyString: { type: 'string' } },
|
|
916
|
-
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
917
|
-
} satisfies JSONSchema7);
|
|
918
|
-
});
|
|
919
|
-
});
|