@ai-sdk/provider-utils 4.0.8 → 4.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.js +29 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +29 -1
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +6 -2
  7. package/src/handle-fetch-error.ts +33 -0
  8. package/src/__snapshots__/schema.test.ts.snap +0 -346
  9. package/src/add-additional-properties-to-json-schema.test.ts +0 -289
  10. package/src/convert-async-iterator-to-readable-stream.test.ts +0 -78
  11. package/src/convert-image-model-file-to-data-uri.test.ts +0 -85
  12. package/src/convert-to-form-data.test.ts +0 -167
  13. package/src/create-tool-name-mapping.test.ts +0 -163
  14. package/src/delay.test.ts +0 -212
  15. package/src/delayed-promise.test.ts +0 -132
  16. package/src/download-blob.test.ts +0 -145
  17. package/src/generate-id.test.ts +0 -31
  18. package/src/get-from-api.test.ts +0 -199
  19. package/src/get-runtime-environment-user-agent.test.ts +0 -47
  20. package/src/inject-json-instruction.test.ts +0 -404
  21. package/src/is-url-supported.test.ts +0 -282
  22. package/src/media-type-to-extension.test.ts +0 -26
  23. package/src/normalize-headers.test.ts +0 -64
  24. package/src/parse-json.test.ts +0 -191
  25. package/src/remove-undefined-entries.test.ts +0 -57
  26. package/src/resolve.test.ts +0 -125
  27. package/src/response-handler.test.ts +0 -89
  28. package/src/schema.test-d.ts +0 -11
  29. package/src/schema.test.ts +0 -502
  30. package/src/secure-json-parse.test.ts +0 -59
  31. package/src/to-json-schema/zod3-to-json-schema/parse-def.test.ts +0 -224
  32. package/src/to-json-schema/zod3-to-json-schema/parsers/array.test.ts +0 -98
  33. package/src/to-json-schema/zod3-to-json-schema/parsers/bigint.test.ts +0 -51
  34. package/src/to-json-schema/zod3-to-json-schema/parsers/branded.test.ts +0 -16
  35. package/src/to-json-schema/zod3-to-json-schema/parsers/catch.test.ts +0 -15
  36. package/src/to-json-schema/zod3-to-json-schema/parsers/date.test.ts +0 -97
  37. package/src/to-json-schema/zod3-to-json-schema/parsers/default.test.ts +0 -54
  38. package/src/to-json-schema/zod3-to-json-schema/parsers/effects.test.ts +0 -41
  39. package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.test.ts +0 -92
  40. package/src/to-json-schema/zod3-to-json-schema/parsers/map.test.ts +0 -48
  41. package/src/to-json-schema/zod3-to-json-schema/parsers/native-enum.test.ts +0 -102
  42. package/src/to-json-schema/zod3-to-json-schema/parsers/nullable.test.ts +0 -67
  43. package/src/to-json-schema/zod3-to-json-schema/parsers/number.test.ts +0 -65
  44. package/src/to-json-schema/zod3-to-json-schema/parsers/object.test.ts +0 -149
  45. package/src/to-json-schema/zod3-to-json-schema/parsers/optional.test.ts +0 -147
  46. package/src/to-json-schema/zod3-to-json-schema/parsers/pipe.test.ts +0 -35
  47. package/src/to-json-schema/zod3-to-json-schema/parsers/promise.test.ts +0 -15
  48. package/src/to-json-schema/zod3-to-json-schema/parsers/readonly.test.ts +0 -20
  49. package/src/to-json-schema/zod3-to-json-schema/parsers/record.test.ts +0 -108
  50. package/src/to-json-schema/zod3-to-json-schema/parsers/set.test.ts +0 -20
  51. package/src/to-json-schema/zod3-to-json-schema/parsers/string.test.ts +0 -438
  52. package/src/to-json-schema/zod3-to-json-schema/parsers/tuple.test.ts +0 -33
  53. package/src/to-json-schema/zod3-to-json-schema/parsers/union.test.ts +0 -226
  54. package/src/to-json-schema/zod3-to-json-schema/refs.test.ts +0 -919
  55. package/src/to-json-schema/zod3-to-json-schema/zod3-to-json-schema.test.ts +0 -862
  56. package/src/types/tool.test-d.ts +0 -228
  57. package/src/validate-types.test.ts +0 -105
  58. 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
- });