@orpc/zod 0.0.0-next.ae2f20c → 0.0.0-next.ae4860c

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.
@@ -2,24 +2,35 @@ import { Context } from '@orpc/server';
2
2
  import { StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
3
3
  import { AnySchema } from '@orpc/contract';
4
4
  import { JSONSchema, SchemaConvertOptions, ConditionalSchemaConverter } from '@orpc/openapi';
5
- import { Interceptor, ThrowableError, Promisable } from '@orpc/shared';
6
- import * as _zod_core from '@zod/core';
7
- import { $ZodType, $input, $output } from '@zod/core';
5
+ import { Interceptor } from '@orpc/shared';
6
+ import * as zod_v4_core from 'zod/v4/core';
7
+ import { $ZodType, $input, $output } from 'zod/v4/core';
8
8
 
9
+ /**
10
+ * @deprecated Use [Smart Coercion Plugin](https://orpc.dev/docs/openapi/plugins/smart-coercion) instead.
11
+ */
9
12
  declare class experimental_ZodSmartCoercionPlugin<TContext extends Context> implements StandardHandlerPlugin<TContext> {
10
13
  #private;
11
14
  init(options: StandardHandlerOptions<TContext>): void;
12
15
  }
13
16
 
14
- interface experimental_ZodToJsonSchemaOptions {
17
+ interface ZodToJsonSchemaConverterOptions {
15
18
  /**
16
- * Max depth of lazy type, if it exceeds.
19
+ * Max depth of lazy type.
17
20
  *
18
- * Used anyJsonSchema (`{}`) when reach max depth
21
+ * Used anyJsonSchema (`{}`) when exceed max depth
19
22
  *
20
23
  * @default 2
21
24
  */
22
25
  maxLazyDepth?: number;
26
+ /**
27
+ * Max depth of nested types.
28
+ *
29
+ * Used anyJsonSchema (`{}`) when exceed max depth
30
+ *
31
+ * @default 10
32
+ */
33
+ maxStructureDepth?: number;
23
34
  /**
24
35
  * The schema to be used to represent the any | unknown type.
25
36
  *
@@ -46,18 +57,19 @@ interface experimental_ZodToJsonSchemaOptions {
46
57
  }, [
47
58
  required: boolean,
48
59
  jsonSchema: Exclude<JSONSchema, boolean>
49
- ], ThrowableError>[];
60
+ ]>[];
50
61
  }
51
- declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
62
+ declare class ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
52
63
  #private;
53
64
  private readonly maxLazyDepth;
65
+ private readonly maxStructureDepth;
54
66
  private readonly anyJsonSchema;
55
67
  private readonly unsupportedJsonSchema;
56
68
  private readonly undefinedJsonSchema;
57
69
  private readonly interceptors;
58
- constructor(options?: experimental_ZodToJsonSchemaOptions);
70
+ constructor(options?: ZodToJsonSchemaConverterOptions);
59
71
  condition(schema: AnySchema | undefined): boolean;
60
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: Exclude<JSONSchema, boolean>]>;
72
+ convert(schema: AnySchema | undefined, options: SchemaConvertOptions): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
61
73
  }
62
74
 
63
75
  /**
@@ -77,7 +89,7 @@ declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchema
77
89
  * })
78
90
  * ```
79
91
  */
80
- declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
92
+ declare const JSON_SCHEMA_REGISTRY: zod_v4_core.$ZodRegistry<{
81
93
  $anchor?: string;
82
94
  $comment?: string;
83
95
  $defs?: Record<string, JSONSchema>;
@@ -138,7 +150,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
138
150
  unevaluatedProperties?: JSONSchema;
139
151
  uniqueItems?: boolean;
140
152
  writeOnly?: boolean;
141
- }, _zod_core.$ZodType<unknown, unknown>>;
153
+ }, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
142
154
  /**
143
155
  * Zod registry for customizing generated JSON schema, only useful for .input
144
156
  *
@@ -156,7 +168,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
156
168
  * })
157
169
  * ```
158
170
  */
159
- declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
171
+ declare const JSON_SCHEMA_INPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
160
172
  $anchor?: string;
161
173
  $comment?: string;
162
174
  $defs?: Record<string, JSONSchema>;
@@ -217,7 +229,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
217
229
  unevaluatedProperties?: JSONSchema;
218
230
  uniqueItems?: boolean;
219
231
  writeOnly?: boolean;
220
- }, _zod_core.$ZodType<unknown, unknown>>;
232
+ }, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
221
233
  /**
222
234
  * Zod registry for customizing generated JSON schema, only useful for .input
223
235
  *
@@ -235,7 +247,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
235
247
  * })
236
248
  * ```
237
249
  */
238
- declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
250
+ declare const JSON_SCHEMA_OUTPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
239
251
  $anchor?: string;
240
252
  $comment?: string;
241
253
  $defs?: Record<string, JSONSchema>;
@@ -296,7 +308,7 @@ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
296
308
  unevaluatedProperties?: JSONSchema;
297
309
  uniqueItems?: boolean;
298
310
  writeOnly?: boolean;
299
- }, _zod_core.$ZodType<unknown, unknown>>;
311
+ }, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
300
312
 
301
- export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
302
- export type { experimental_ZodToJsonSchemaOptions };
313
+ export { JSON_SCHEMA_INPUT_REGISTRY, JSON_SCHEMA_OUTPUT_REGISTRY, JSON_SCHEMA_REGISTRY, ZodToJsonSchemaConverter, experimental_ZodSmartCoercionPlugin };
314
+ export type { ZodToJsonSchemaConverterOptions };
@@ -1,13 +1,14 @@
1
- import { isObject, guard, intercept } from '@orpc/shared';
1
+ import { isObject, guard, intercept, toArray } from '@orpc/shared';
2
+ import { JsonSchemaXNativeType } from '@orpc/json-schema';
2
3
  import { JSONSchemaFormat, JSONSchemaContentEncoding } from '@orpc/openapi';
3
- import { registry, globalRegistry } from '@zod/core';
4
+ import { registry, globalRegistry } from 'zod/v4/core';
4
5
 
5
6
  class experimental_ZodSmartCoercionPlugin {
6
7
  init(options) {
7
8
  options.clientInterceptors ??= [];
8
9
  options.clientInterceptors.unshift((options2) => {
9
10
  const inputSchema = options2.procedure["~orpc"].inputSchema;
10
- if (!inputSchema || inputSchema["~standard"].vendor !== "zod") {
11
+ if (!inputSchema || inputSchema["~standard"].vendor !== "zod" || !("_zod" in inputSchema)) {
11
12
  return options2.next();
12
13
  }
13
14
  const coercedInput = this.#coerce(inputSchema, options2.input);
@@ -100,8 +101,7 @@ class experimental_ZodSmartCoercionPlugin {
100
101
  }
101
102
  return value;
102
103
  }
103
- case "object":
104
- case "interface": {
104
+ case "object": {
105
105
  const object = schema;
106
106
  if (value === void 0) {
107
107
  return {};
@@ -165,9 +165,21 @@ class experimental_ZodSmartCoercionPlugin {
165
165
  return this.#coerce(union._zod.def.options[0], value);
166
166
  }
167
167
  if (isObject(value)) {
168
+ const discriminator = "discriminator" in union._zod.def && typeof union._zod.def.discriminator === "string" ? union._zod.def.discriminator : void 0;
168
169
  for (const option of union._zod.def.options) {
169
- if (option._zod.disc && this.#matchDiscriminators(value, option._zod.disc)) {
170
- return this.#coerce(option, value);
170
+ if (!option._zod.propValues) {
171
+ continue;
172
+ }
173
+ if (discriminator !== void 0) {
174
+ if (option._zod.propValues[discriminator]?.has(value[discriminator])) {
175
+ return this.#coerce(option, value);
176
+ }
177
+ } else {
178
+ for (const key in option._zod.propValues) {
179
+ if (option._zod.propValues[key]?.has(value[key])) {
180
+ return this.#coerce(option, value);
181
+ }
182
+ }
171
183
  }
172
184
  }
173
185
  }
@@ -207,10 +219,17 @@ class experimental_ZodSmartCoercionPlugin {
207
219
  return this.#coerce(pipe._zod.def.in, value);
208
220
  }
209
221
  case "default":
210
- case "catch": {
222
+ case "prefault": {
211
223
  const default_ = schema;
224
+ if (value === void 0) {
225
+ return value;
226
+ }
212
227
  return this.#coerce(default_._zod.def.innerType, value);
213
228
  }
229
+ case "catch": {
230
+ const catch_ = schema;
231
+ return this.#coerce(catch_._zod.def.innerType, value);
232
+ }
214
233
  case "lazy": {
215
234
  const lazy = schema;
216
235
  if (value !== void 0) {
@@ -248,64 +267,53 @@ class experimental_ZodSmartCoercionPlugin {
248
267
  }
249
268
  return value;
250
269
  }
251
- /**
252
- * This function is inspired from Zod, because it's not exported
253
- * https://github.com/colinhacks/zod/blob/v4/packages/core/src/schemas.ts#L1903C1-L1921C2
254
- */
255
- #matchDiscriminators(input, discs) {
256
- for (const [key, value] of discs) {
257
- const data = input[key];
258
- if (value.values.size && !value.values.has(data)) {
259
- return false;
260
- }
261
- if (value.maps.length === 0) {
262
- continue;
263
- }
264
- if (!isObject(data)) {
265
- return false;
266
- }
267
- for (const m of value.maps) {
268
- if (!this.#matchDiscriminators(data, m)) {
269
- return false;
270
- }
271
- }
272
- }
273
- return true;
274
- }
275
270
  }
276
271
 
277
- const experimental_JSON_SCHEMA_REGISTRY = registry();
278
- const experimental_JSON_SCHEMA_INPUT_REGISTRY = registry();
279
- const experimental_JSON_SCHEMA_OUTPUT_REGISTRY = registry();
272
+ const JSON_SCHEMA_REGISTRY = registry();
273
+ const JSON_SCHEMA_INPUT_REGISTRY = registry();
274
+ const JSON_SCHEMA_OUTPUT_REGISTRY = registry();
280
275
 
281
- class experimental_ZodToJsonSchemaConverter {
276
+ class ZodToJsonSchemaConverter {
282
277
  maxLazyDepth;
278
+ maxStructureDepth;
283
279
  anyJsonSchema;
284
280
  unsupportedJsonSchema;
285
281
  undefinedJsonSchema;
286
282
  interceptors;
287
283
  constructor(options = {}) {
288
284
  this.maxLazyDepth = options.maxLazyDepth ?? 2;
285
+ this.maxStructureDepth = options.maxStructureDepth ?? 10;
289
286
  this.anyJsonSchema = options.anyJsonSchema ?? {};
290
287
  this.unsupportedJsonSchema = options.unsupportedJsonSchema ?? { not: {} };
291
288
  this.undefinedJsonSchema = options.undefinedJsonSchema ?? { not: {} };
292
289
  this.interceptors = options.interceptors ?? [];
293
290
  }
294
291
  condition(schema) {
295
- return schema !== void 0 && schema["~standard"].vendor === "zod";
292
+ return schema !== void 0 && schema["~standard"].vendor === "zod" && "_zod" in schema;
296
293
  }
297
294
  convert(schema, options) {
298
- return this.#convert(schema, options, 0);
295
+ return this.#convert(schema, options, 0, 0);
299
296
  }
300
- #convert(schema, options, lazyDepth, isHandledCustomJSONSchema = false) {
297
+ #convert(schema, options, lazyDepth, structureDepth, isHandledCustomJSONSchema = false) {
301
298
  return intercept(
302
299
  this.interceptors,
303
300
  { schema, options, lazyDepth, isHandledCustomJSONSchema },
304
- async ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
301
+ ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
302
+ if (structureDepth > this.maxStructureDepth) {
303
+ return [false, this.anyJsonSchema];
304
+ }
305
+ if (!options2.minStructureDepthForRef || options2.minStructureDepthForRef <= structureDepth) {
306
+ const components = toArray(options2.components);
307
+ for (const component of components) {
308
+ if (component.schema === schema2 && component.allowedStrategies.includes(options2.strategy)) {
309
+ return [component.required, { $ref: component.ref }];
310
+ }
311
+ }
312
+ }
305
313
  if (!isHandledCustomJSONSchema2) {
306
314
  const customJSONSchema = this.#getCustomJsonSchema(schema2, options2);
307
315
  if (customJSONSchema) {
308
- const [required, json] = await this.#convert(schema2, options2, lazyDepth2, true);
316
+ const [required, json] = this.#convert(schema2, options2, lazyDepth2, structureDepth, true);
309
317
  return [required, { ...json, ...customJSONSchema }];
310
318
  }
311
319
  }
@@ -313,21 +321,28 @@ class experimental_ZodToJsonSchemaConverter {
313
321
  case "string": {
314
322
  const string = schema2;
315
323
  const json = { type: "string" };
316
- const { minimum, maximum, format, pattern, contentEncoding } = string._zod.computed;
317
- if (minimum !== void 0) {
324
+ const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
325
+ if (typeof minimum === "number") {
318
326
  json.minLength = minimum;
319
327
  }
320
- if (maximum !== void 0) {
328
+ if (typeof maximum === "number") {
321
329
  json.maxLength = maximum;
322
330
  }
323
- if (contentEncoding !== void 0) {
331
+ if (typeof contentEncoding === "string") {
324
332
  json.contentEncoding = this.#handleContentEncoding(contentEncoding);
325
333
  }
326
- if (format !== void 0 && format !== "regex" && json.contentEncoding === void 0) {
334
+ if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
327
335
  json.format = this.#handleStringFormat(format);
328
336
  }
329
- if (pattern !== void 0 && json.contentEncoding === void 0 && json.format === void 0) {
330
- json.pattern = pattern.source;
337
+ if (patterns instanceof Set && json.contentEncoding === void 0 && json.format === void 0) {
338
+ for (const pattern of patterns) {
339
+ if (json.pattern === void 0) {
340
+ json.pattern = pattern.source;
341
+ } else {
342
+ json.allOf ??= [];
343
+ json.allOf.push({ pattern: pattern.source });
344
+ }
345
+ }
331
346
  }
332
347
  if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
333
348
  json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
@@ -337,25 +352,23 @@ class experimental_ZodToJsonSchemaConverter {
337
352
  case "number": {
338
353
  const number = schema2;
339
354
  const json = { type: "number" };
340
- const { minimum, maximum, format, multipleOf, inclusive } = number._zod.computed;
341
- if (format?.includes("int")) {
355
+ const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = number._zod.bag;
356
+ if (typeof format === "string" && format?.includes("int")) {
342
357
  json.type = "integer";
343
358
  }
344
- if (minimum !== void 0) {
345
- if (inclusive) {
346
- json.minimum = minimum;
347
- } else {
348
- json.exclusiveMinimum = minimum;
349
- }
359
+ if (typeof minimum === "number") {
360
+ json.minimum = minimum;
350
361
  }
351
- if (maximum !== void 0) {
352
- if (inclusive) {
353
- json.maximum = maximum;
354
- } else {
355
- json.exclusiveMaximum = maximum;
356
- }
362
+ if (typeof maximum === "number") {
363
+ json.maximum = maximum;
364
+ }
365
+ if (typeof exclusiveMinimum === "number") {
366
+ json.exclusiveMinimum = exclusiveMinimum;
357
367
  }
358
- if (multipleOf !== void 0) {
368
+ if (typeof exclusiveMaximum === "number") {
369
+ json.exclusiveMaximum = exclusiveMaximum;
370
+ }
371
+ if (typeof multipleOf === "number") {
359
372
  json.multipleOf = multipleOf;
360
373
  }
361
374
  return [true, json];
@@ -364,10 +377,18 @@ class experimental_ZodToJsonSchemaConverter {
364
377
  return [true, { type: "boolean" }];
365
378
  }
366
379
  case "bigint": {
367
- return [true, { type: "string", pattern: "^-?[0-9]+$" }];
380
+ return [true, {
381
+ "type": "string",
382
+ "pattern": "^-?[0-9]+$",
383
+ "x-native-type": JsonSchemaXNativeType.BigInt
384
+ }];
368
385
  }
369
386
  case "date": {
370
- return [true, { type: "string", format: JSONSchemaFormat.DateTime }];
387
+ return [true, {
388
+ "type": "string",
389
+ "format": JSONSchemaFormat.DateTime,
390
+ "x-native-type": JsonSchemaXNativeType.Date
391
+ }];
371
392
  }
372
393
  case "null": {
373
394
  return [true, { type: "null" }];
@@ -388,21 +409,21 @@ class experimental_ZodToJsonSchemaConverter {
388
409
  case "array": {
389
410
  const array = schema2;
390
411
  const json = { type: "array" };
391
- const { minimum, maximum } = array._zod.computed;
392
- if (minimum !== void 0) {
412
+ const { minimum, maximum } = array._zod.bag;
413
+ if (typeof minimum === "number") {
393
414
  json.minItems = minimum;
394
415
  }
395
- if (maximum !== void 0) {
416
+ if (typeof maximum === "number") {
396
417
  json.maxItems = maximum;
397
418
  }
398
- json.items = this.#handleArrayItemJsonSchema(await this.#convert(array._zod.def.element, options2, lazyDepth2), options2);
419
+ json.items = this.#handleArrayItemJsonSchema(this.#convert(array._zod.def.element, options2, lazyDepth2, structureDepth + 1), options2);
399
420
  return [true, json];
400
421
  }
401
422
  case "object": {
402
423
  const object = schema2;
403
424
  const json = { type: "object" };
404
425
  for (const [key, value] of Object.entries(object._zod.def.shape)) {
405
- const [itemRequired, itemJson] = await this.#convert(value, options2, lazyDepth2);
426
+ const [itemRequired, itemJson] = this.#convert(value, options2, lazyDepth2, structureDepth + 1);
406
427
  json.properties ??= {};
407
428
  json.properties[key] = itemJson;
408
429
  if (itemRequired) {
@@ -414,7 +435,7 @@ class experimental_ZodToJsonSchemaConverter {
414
435
  if (object._zod.def.catchall._zod.def.type === "never") {
415
436
  json.additionalProperties = false;
416
437
  } else {
417
- const [_, addJson] = await this.#convert(object._zod.def.catchall, options2, lazyDepth2);
438
+ const [_, addJson] = this.#convert(object._zod.def.catchall, options2, lazyDepth2, structureDepth + 1);
418
439
  json.additionalProperties = addJson;
419
440
  }
420
441
  }
@@ -425,7 +446,7 @@ class experimental_ZodToJsonSchemaConverter {
425
446
  const anyOf = [];
426
447
  let required = true;
427
448
  for (const item of union._zod.def.options) {
428
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
449
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth + 1);
429
450
  if (!itemRequired) {
430
451
  required = false;
431
452
  }
@@ -439,14 +460,14 @@ class experimental_ZodToJsonSchemaConverter {
439
460
  }
440
461
  }
441
462
  }
442
- return [required, anyOf.length === 1 ? anyOf[0] : { anyOf }];
463
+ return [required, { anyOf }];
443
464
  }
444
465
  case "intersection": {
445
466
  const intersection = schema2;
446
467
  const json = { allOf: [] };
447
468
  let required = false;
448
469
  for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
449
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
470
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth + 1);
450
471
  json.allOf.push(itemJson);
451
472
  if (itemRequired) {
452
473
  required = true;
@@ -458,16 +479,16 @@ class experimental_ZodToJsonSchemaConverter {
458
479
  const tuple = schema2;
459
480
  const json = { type: "array", prefixItems: [] };
460
481
  for (const item of tuple._zod.def.items) {
461
- json.prefixItems.push(this.#handleArrayItemJsonSchema(await this.#convert(item, options2, lazyDepth2), options2));
482
+ json.prefixItems.push(this.#handleArrayItemJsonSchema(this.#convert(item, options2, lazyDepth2, structureDepth + 1), options2));
462
483
  }
463
484
  if (tuple._zod.def.rest) {
464
- json.items = this.#handleArrayItemJsonSchema(await this.#convert(tuple._zod.def.rest, options2, lazyDepth2), options2);
485
+ json.items = this.#handleArrayItemJsonSchema(this.#convert(tuple._zod.def.rest, options2, lazyDepth2, structureDepth + 1), options2);
465
486
  }
466
- const { minimum, maximum } = tuple._zod.computed;
467
- if (minimum !== void 0) {
487
+ const { minimum, maximum } = tuple._zod.bag;
488
+ if (typeof minimum === "number") {
468
489
  json.minItems = minimum;
469
490
  }
470
- if (maximum !== void 0) {
491
+ if (typeof maximum === "number") {
471
492
  json.maxItems = maximum;
472
493
  }
473
494
  return [true, json];
@@ -475,31 +496,33 @@ class experimental_ZodToJsonSchemaConverter {
475
496
  case "record": {
476
497
  const record = schema2;
477
498
  const json = { type: "object" };
478
- json.propertyNames = (await this.#convert(record._zod.def.keyType, options2, lazyDepth2))[1];
479
- json.additionalProperties = (await this.#convert(record._zod.def.valueType, options2, lazyDepth2))[1];
499
+ json.propertyNames = this.#convert(record._zod.def.keyType, options2, lazyDepth2, structureDepth + 1)[1];
500
+ json.additionalProperties = this.#convert(record._zod.def.valueType, options2, lazyDepth2, structureDepth + 1)[1];
480
501
  return [true, json];
481
502
  }
482
503
  case "map": {
483
504
  const map = schema2;
484
505
  return [true, {
485
- type: "array",
486
- items: {
506
+ "type": "array",
507
+ "items": {
487
508
  type: "array",
488
509
  prefixItems: [
489
- this.#handleArrayItemJsonSchema(await this.#convert(map._zod.def.keyType, options2, lazyDepth2), options2),
490
- this.#handleArrayItemJsonSchema(await this.#convert(map._zod.def.valueType, options2, lazyDepth2), options2)
510
+ this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.keyType, options2, lazyDepth2, structureDepth + 1), options2),
511
+ this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2)
491
512
  ],
492
513
  maxItems: 2,
493
514
  minItems: 2
494
- }
515
+ },
516
+ "x-native-type": JsonSchemaXNativeType.Map
495
517
  }];
496
518
  }
497
519
  case "set": {
498
520
  const set = schema2;
499
521
  return [true, {
500
- type: "array",
501
- uniqueItems: true,
502
- items: this.#handleArrayItemJsonSchema(await this.#convert(set._zod.def.valueType, options2, lazyDepth2), options2)
522
+ "type": "array",
523
+ "uniqueItems": true,
524
+ "items": this.#handleArrayItemJsonSchema(this.#convert(set._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2),
525
+ "x-native-type": JsonSchemaXNativeType.Set
503
526
  }];
504
527
  }
505
528
  case "enum": {
@@ -523,12 +546,14 @@ class experimental_ZodToJsonSchemaConverter {
523
546
  case "file": {
524
547
  const file = schema2;
525
548
  const oneOf = [];
526
- const { mime } = file._zod.computed;
527
- for (const type of mime ?? ["*/*"]) {
528
- oneOf.push({
529
- type: "string",
530
- contentMediaType: type
531
- });
549
+ const { mime } = file._zod.bag;
550
+ if (mime === void 0 || Array.isArray(mime) && mime.every((m) => typeof m === "string")) {
551
+ for (const type of mime ?? ["*/*"]) {
552
+ oneOf.push({
553
+ type: "string",
554
+ contentMediaType: type
555
+ });
556
+ }
532
557
  }
533
558
  return [true, oneOf.length === 1 ? oneOf[0] : { anyOf: oneOf }];
534
559
  }
@@ -537,40 +562,46 @@ class experimental_ZodToJsonSchemaConverter {
537
562
  }
538
563
  case "nullable": {
539
564
  const nullable = schema2;
540
- const [required, json] = await this.#convert(nullable._zod.def.innerType, options2, lazyDepth2);
565
+ const [required, json] = this.#convert(nullable._zod.def.innerType, options2, lazyDepth2, structureDepth);
541
566
  return [required, { anyOf: [json, { type: "null" }] }];
542
567
  }
543
568
  case "nonoptional": {
544
569
  const nonoptional = schema2;
545
- const [, json] = await this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2);
570
+ const [, json] = this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2, structureDepth);
546
571
  return [true, json];
547
572
  }
548
573
  case "success": {
549
574
  return [true, { type: "boolean" }];
550
575
  }
551
- case "default": {
576
+ case "default":
577
+ case "prefault": {
552
578
  const default_ = schema2;
553
- const [, json] = await this.#convert(default_._zod.def.innerType, options2, lazyDepth2);
579
+ const [, json] = this.#convert(default_._zod.def.innerType, options2, lazyDepth2, structureDepth);
554
580
  return [false, {
555
581
  ...json,
556
- default: default_._zod.def.defaultValue()
582
+ default: default_._zod.def.defaultValue
557
583
  }];
558
584
  }
559
585
  case "catch": {
560
586
  const catch_ = schema2;
561
- const [, json] = await this.#convert(catch_._zod.def.innerType, options2, lazyDepth2);
562
- return [false, json];
587
+ return this.#convert(catch_._zod.def.innerType, options2, lazyDepth2, structureDepth);
563
588
  }
564
589
  case "nan": {
565
590
  return [true, options2.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
566
591
  }
567
592
  case "pipe": {
568
593
  const pipe = schema2;
569
- return await this.#convert(options2.strategy === "input" ? pipe._zod.def.in : pipe._zod.def.out, options2, lazyDepth2);
594
+ return this.#convert(
595
+ // prefer out schema when in schema is preprocess/transform
596
+ options2.strategy === "input" && pipe._zod.def.in._zod.def.type !== "transform" ? pipe._zod.def.in : pipe._zod.def.out,
597
+ options2,
598
+ lazyDepth2,
599
+ structureDepth
600
+ );
570
601
  }
571
602
  case "readonly": {
572
603
  const readonly_ = schema2;
573
- const [required, json] = await this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2);
604
+ const [required, json] = this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2, structureDepth);
574
605
  return [required, { ...json, readOnly: true }];
575
606
  }
576
607
  case "template_literal": {
@@ -582,15 +613,16 @@ class experimental_ZodToJsonSchemaConverter {
582
613
  }
583
614
  case "optional": {
584
615
  const optional = schema2;
585
- const [, json] = await this.#convert(optional._zod.def.innerType, options2, lazyDepth2);
616
+ const [, json] = this.#convert(optional._zod.def.innerType, options2, lazyDepth2, structureDepth);
586
617
  return [false, json];
587
618
  }
588
619
  case "lazy": {
589
620
  const lazy = schema2;
590
- if (lazyDepth2 >= this.maxLazyDepth) {
621
+ const currentLazyDepth = lazyDepth2 + 1;
622
+ if (currentLazyDepth > this.maxLazyDepth) {
591
623
  return [false, this.anyJsonSchema];
592
624
  }
593
- return await this.#convert(lazy._zod.def.getter(), options2, lazyDepth2 + 1);
625
+ return this.#convert(lazy._zod.def.getter(), options2, currentLazyDepth, structureDepth);
594
626
  }
595
627
  default: {
596
628
  schema2._zod.def.type;
@@ -601,25 +633,26 @@ class experimental_ZodToJsonSchemaConverter {
601
633
  );
602
634
  }
603
635
  #getCustomJsonSchema(schema, options) {
604
- if (options.strategy === "input" && experimental_JSON_SCHEMA_INPUT_REGISTRY.has(schema)) {
605
- return experimental_JSON_SCHEMA_INPUT_REGISTRY.get(schema);
636
+ if (options.strategy === "input" && JSON_SCHEMA_INPUT_REGISTRY.has(schema)) {
637
+ return JSON_SCHEMA_INPUT_REGISTRY.get(schema);
606
638
  }
607
- if (options.strategy === "output" && experimental_JSON_SCHEMA_OUTPUT_REGISTRY.has(schema)) {
608
- return experimental_JSON_SCHEMA_OUTPUT_REGISTRY.get(schema);
639
+ if (options.strategy === "output" && JSON_SCHEMA_OUTPUT_REGISTRY.has(schema)) {
640
+ return JSON_SCHEMA_OUTPUT_REGISTRY.get(schema);
609
641
  }
610
- if (experimental_JSON_SCHEMA_REGISTRY.has(schema)) {
611
- return experimental_JSON_SCHEMA_REGISTRY.get(schema);
642
+ if (JSON_SCHEMA_REGISTRY.has(schema)) {
643
+ return JSON_SCHEMA_REGISTRY.get(schema);
612
644
  }
613
645
  const global = globalRegistry.get(schema);
614
646
  if (global) {
615
647
  return {
648
+ title: global.title,
616
649
  description: global.description,
617
- examples: global.examples
650
+ examples: Array.isArray(global.examples) ? global.examples : void 0
618
651
  };
619
652
  }
620
653
  }
621
654
  #handleArrayItemJsonSchema([required, schema], options) {
622
- if (required || options.strategy === "input") {
655
+ if (required || options.strategy === "input" || schema.default !== void 0) {
623
656
  return schema;
624
657
  }
625
658
  if (schema === this.undefinedJsonSchema) {
@@ -650,4 +683,4 @@ class experimental_ZodToJsonSchemaConverter {
650
683
  }
651
684
  }
652
685
 
653
- export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
686
+ export { JSON_SCHEMA_INPUT_REGISTRY, JSON_SCHEMA_OUTPUT_REGISTRY, JSON_SCHEMA_REGISTRY, ZodToJsonSchemaConverter, experimental_ZodSmartCoercionPlugin };