@orpc/zod 1.2.0 → 1.4.0

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 CHANGED
@@ -49,6 +49,7 @@ You can find the full documentation [here](https://orpc.unnoq.com).
49
49
  - [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Build your API contract.
50
50
  - [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build your API or implement API contract.
51
51
  - [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume your API on the client with type-safety.
52
+ - [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with NestJS.
52
53
  - [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
53
54
  - [@orpc/react-query](https://www.npmjs.com/package/@orpc/react-query): Integration with [React Query](https://tanstack.com/query/latest/docs/framework/react/overview).
54
55
  - [@orpc/vue-query](https://www.npmjs.com/package/@orpc/vue-query): Integration with [Vue Query](https://tanstack.com/query/latest/docs/framework/vue/overview).
@@ -2,9 +2,9 @@ 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
9
  declare class experimental_ZodSmartCoercionPlugin<TContext extends Context> implements StandardHandlerPlugin<TContext> {
10
10
  #private;
@@ -46,7 +46,7 @@ interface experimental_ZodToJsonSchemaOptions {
46
46
  }, [
47
47
  required: boolean,
48
48
  jsonSchema: Exclude<JSONSchema, boolean>
49
- ], ThrowableError>[];
49
+ ]>[];
50
50
  }
51
51
  declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
52
52
  #private;
@@ -57,7 +57,7 @@ declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchema
57
57
  private readonly interceptors;
58
58
  constructor(options?: experimental_ZodToJsonSchemaOptions);
59
59
  condition(schema: AnySchema | undefined): boolean;
60
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: Exclude<JSONSchema, boolean>]>;
60
+ convert(schema: AnySchema | undefined, options: SchemaConvertOptions): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
61
61
  }
62
62
 
63
63
  /**
@@ -77,7 +77,7 @@ declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchema
77
77
  * })
78
78
  * ```
79
79
  */
80
- declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
80
+ declare const experimental_JSON_SCHEMA_REGISTRY: zod_v4_core.$ZodRegistry<{
81
81
  $anchor?: string;
82
82
  $comment?: string;
83
83
  $defs?: Record<string, JSONSchema>;
@@ -138,7 +138,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
138
138
  unevaluatedProperties?: JSONSchema;
139
139
  uniqueItems?: boolean;
140
140
  writeOnly?: boolean;
141
- }, _zod_core.$ZodType<unknown, unknown>>;
141
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
142
142
  /**
143
143
  * Zod registry for customizing generated JSON schema, only useful for .input
144
144
  *
@@ -156,7 +156,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
156
156
  * })
157
157
  * ```
158
158
  */
159
- declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
159
+ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
160
160
  $anchor?: string;
161
161
  $comment?: string;
162
162
  $defs?: Record<string, JSONSchema>;
@@ -217,7 +217,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
217
217
  unevaluatedProperties?: JSONSchema;
218
218
  uniqueItems?: boolean;
219
219
  writeOnly?: boolean;
220
- }, _zod_core.$ZodType<unknown, unknown>>;
220
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
221
221
  /**
222
222
  * Zod registry for customizing generated JSON schema, only useful for .input
223
223
  *
@@ -235,7 +235,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
235
235
  * })
236
236
  * ```
237
237
  */
238
- declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
238
+ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
239
239
  $anchor?: string;
240
240
  $comment?: string;
241
241
  $defs?: Record<string, JSONSchema>;
@@ -296,7 +296,7 @@ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
296
296
  unevaluatedProperties?: JSONSchema;
297
297
  uniqueItems?: boolean;
298
298
  writeOnly?: boolean;
299
- }, _zod_core.$ZodType<unknown, unknown>>;
299
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
300
300
 
301
301
  export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
302
302
  export type { experimental_ZodToJsonSchemaOptions };
@@ -2,9 +2,9 @@ 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
9
  declare class experimental_ZodSmartCoercionPlugin<TContext extends Context> implements StandardHandlerPlugin<TContext> {
10
10
  #private;
@@ -46,7 +46,7 @@ interface experimental_ZodToJsonSchemaOptions {
46
46
  }, [
47
47
  required: boolean,
48
48
  jsonSchema: Exclude<JSONSchema, boolean>
49
- ], ThrowableError>[];
49
+ ]>[];
50
50
  }
51
51
  declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
52
52
  #private;
@@ -57,7 +57,7 @@ declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchema
57
57
  private readonly interceptors;
58
58
  constructor(options?: experimental_ZodToJsonSchemaOptions);
59
59
  condition(schema: AnySchema | undefined): boolean;
60
- convert(schema: AnySchema | undefined, options: SchemaConvertOptions): Promisable<[required: boolean, jsonSchema: Exclude<JSONSchema, boolean>]>;
60
+ convert(schema: AnySchema | undefined, options: SchemaConvertOptions): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
61
61
  }
62
62
 
63
63
  /**
@@ -77,7 +77,7 @@ declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchema
77
77
  * })
78
78
  * ```
79
79
  */
80
- declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
80
+ declare const experimental_JSON_SCHEMA_REGISTRY: zod_v4_core.$ZodRegistry<{
81
81
  $anchor?: string;
82
82
  $comment?: string;
83
83
  $defs?: Record<string, JSONSchema>;
@@ -138,7 +138,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
138
138
  unevaluatedProperties?: JSONSchema;
139
139
  uniqueItems?: boolean;
140
140
  writeOnly?: boolean;
141
- }, _zod_core.$ZodType<unknown, unknown>>;
141
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
142
142
  /**
143
143
  * Zod registry for customizing generated JSON schema, only useful for .input
144
144
  *
@@ -156,7 +156,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: _zod_core.$ZodRegistry<{
156
156
  * })
157
157
  * ```
158
158
  */
159
- declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
159
+ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
160
160
  $anchor?: string;
161
161
  $comment?: string;
162
162
  $defs?: Record<string, JSONSchema>;
@@ -217,7 +217,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
217
217
  unevaluatedProperties?: JSONSchema;
218
218
  uniqueItems?: boolean;
219
219
  writeOnly?: boolean;
220
- }, _zod_core.$ZodType<unknown, unknown>>;
220
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
221
221
  /**
222
222
  * Zod registry for customizing generated JSON schema, only useful for .input
223
223
  *
@@ -235,7 +235,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: _zod_core.$ZodRegistry<{
235
235
  * })
236
236
  * ```
237
237
  */
238
- declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
238
+ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: zod_v4_core.$ZodRegistry<{
239
239
  $anchor?: string;
240
240
  $comment?: string;
241
241
  $defs?: Record<string, JSONSchema>;
@@ -296,7 +296,7 @@ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: _zod_core.$ZodRegistry<{
296
296
  unevaluatedProperties?: JSONSchema;
297
297
  uniqueItems?: boolean;
298
298
  writeOnly?: boolean;
299
- }, _zod_core.$ZodType<unknown, unknown>>;
299
+ }, zod_v4_core.$ZodType<unknown, unknown>>;
300
300
 
301
301
  export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
302
302
  export type { experimental_ZodToJsonSchemaOptions };
@@ -1,6 +1,6 @@
1
1
  import { isObject, guard, intercept } from '@orpc/shared';
2
2
  import { JSONSchemaFormat, JSONSchemaContentEncoding } from '@orpc/openapi';
3
- import { registry, globalRegistry } from '@zod/core';
3
+ import { registry, globalRegistry } from 'zod/v4/core';
4
4
 
5
5
  class experimental_ZodSmartCoercionPlugin {
6
6
  init(options) {
@@ -100,8 +100,7 @@ class experimental_ZodSmartCoercionPlugin {
100
100
  }
101
101
  return value;
102
102
  }
103
- case "object":
104
- case "interface": {
103
+ case "object": {
105
104
  const object = schema;
106
105
  if (value === void 0) {
107
106
  return {};
@@ -165,9 +164,21 @@ class experimental_ZodSmartCoercionPlugin {
165
164
  return this.#coerce(union._zod.def.options[0], value);
166
165
  }
167
166
  if (isObject(value)) {
167
+ const discriminator = "discriminator" in union._zod.def && typeof union._zod.def.discriminator === "string" ? union._zod.def.discriminator : void 0;
168
168
  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);
169
+ if (!option._zod.propValues) {
170
+ continue;
171
+ }
172
+ if (discriminator !== void 0) {
173
+ if (option._zod.propValues[discriminator]?.has(value[discriminator])) {
174
+ return this.#coerce(option, value);
175
+ }
176
+ } else {
177
+ for (const key in option._zod.propValues) {
178
+ if (option._zod.propValues[key]?.has(value[key])) {
179
+ return this.#coerce(option, value);
180
+ }
181
+ }
171
182
  }
172
183
  }
173
184
  }
@@ -207,10 +218,17 @@ class experimental_ZodSmartCoercionPlugin {
207
218
  return this.#coerce(pipe._zod.def.in, value);
208
219
  }
209
220
  case "default":
210
- case "catch": {
221
+ case "prefault": {
211
222
  const default_ = schema;
223
+ if (value === void 0) {
224
+ return value;
225
+ }
212
226
  return this.#coerce(default_._zod.def.innerType, value);
213
227
  }
228
+ case "catch": {
229
+ const catch_ = schema;
230
+ return this.#coerce(catch_._zod.def.innerType, value);
231
+ }
214
232
  case "lazy": {
215
233
  const lazy = schema;
216
234
  if (value !== void 0) {
@@ -248,30 +266,6 @@ class experimental_ZodSmartCoercionPlugin {
248
266
  }
249
267
  return value;
250
268
  }
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
269
  }
276
270
 
277
271
  const experimental_JSON_SCHEMA_REGISTRY = registry();
@@ -301,11 +295,11 @@ class experimental_ZodToJsonSchemaConverter {
301
295
  return intercept(
302
296
  this.interceptors,
303
297
  { schema, options, lazyDepth, isHandledCustomJSONSchema },
304
- async ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
298
+ ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
305
299
  if (!isHandledCustomJSONSchema2) {
306
300
  const customJSONSchema = this.#getCustomJsonSchema(schema2, options2);
307
301
  if (customJSONSchema) {
308
- const [required, json] = await this.#convert(schema2, options2, lazyDepth2, true);
302
+ const [required, json] = this.#convert(schema2, options2, lazyDepth2, true);
309
303
  return [required, { ...json, ...customJSONSchema }];
310
304
  }
311
305
  }
@@ -313,21 +307,28 @@ class experimental_ZodToJsonSchemaConverter {
313
307
  case "string": {
314
308
  const string = schema2;
315
309
  const json = { type: "string" };
316
- const { minimum, maximum, format, pattern, contentEncoding } = string._zod.computed;
317
- if (minimum !== void 0) {
310
+ const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
311
+ if (typeof minimum === "number") {
318
312
  json.minLength = minimum;
319
313
  }
320
- if (maximum !== void 0) {
314
+ if (typeof maximum === "number") {
321
315
  json.maxLength = maximum;
322
316
  }
323
- if (contentEncoding !== void 0) {
317
+ if (typeof contentEncoding === "string") {
324
318
  json.contentEncoding = this.#handleContentEncoding(contentEncoding);
325
319
  }
326
- if (format !== void 0 && format !== "regex" && json.contentEncoding === void 0) {
320
+ if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
327
321
  json.format = this.#handleStringFormat(format);
328
322
  }
329
- if (pattern !== void 0 && json.contentEncoding === void 0 && json.format === void 0) {
330
- json.pattern = pattern.source;
323
+ if (patterns instanceof Set && json.contentEncoding === void 0 && json.format === void 0) {
324
+ for (const pattern of patterns) {
325
+ if (json.pattern === void 0) {
326
+ json.pattern = pattern.source;
327
+ } else {
328
+ json.allOf ??= [];
329
+ json.allOf.push({ pattern: pattern.source });
330
+ }
331
+ }
331
332
  }
332
333
  if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
333
334
  json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
@@ -337,25 +338,23 @@ class experimental_ZodToJsonSchemaConverter {
337
338
  case "number": {
338
339
  const number = schema2;
339
340
  const json = { type: "number" };
340
- const { minimum, maximum, format, multipleOf, inclusive } = number._zod.computed;
341
- if (format?.includes("int")) {
341
+ const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = number._zod.bag;
342
+ if (typeof format === "string" && format?.includes("int")) {
342
343
  json.type = "integer";
343
344
  }
344
- if (minimum !== void 0) {
345
- if (inclusive) {
346
- json.minimum = minimum;
347
- } else {
348
- json.exclusiveMinimum = minimum;
349
- }
345
+ if (typeof minimum === "number") {
346
+ json.minimum = minimum;
350
347
  }
351
- if (maximum !== void 0) {
352
- if (inclusive) {
353
- json.maximum = maximum;
354
- } else {
355
- json.exclusiveMaximum = maximum;
356
- }
348
+ if (typeof maximum === "number") {
349
+ json.maximum = maximum;
350
+ }
351
+ if (typeof exclusiveMinimum === "number") {
352
+ json.exclusiveMinimum = exclusiveMinimum;
357
353
  }
358
- if (multipleOf !== void 0) {
354
+ if (typeof exclusiveMaximum === "number") {
355
+ json.exclusiveMaximum = exclusiveMaximum;
356
+ }
357
+ if (typeof multipleOf === "number") {
359
358
  json.multipleOf = multipleOf;
360
359
  }
361
360
  return [true, json];
@@ -388,21 +387,21 @@ class experimental_ZodToJsonSchemaConverter {
388
387
  case "array": {
389
388
  const array = schema2;
390
389
  const json = { type: "array" };
391
- const { minimum, maximum } = array._zod.computed;
392
- if (minimum !== void 0) {
390
+ const { minimum, maximum } = array._zod.bag;
391
+ if (typeof minimum === "number") {
393
392
  json.minItems = minimum;
394
393
  }
395
- if (maximum !== void 0) {
394
+ if (typeof maximum === "number") {
396
395
  json.maxItems = maximum;
397
396
  }
398
- json.items = this.#handleArrayItemJsonSchema(await this.#convert(array._zod.def.element, options2, lazyDepth2), options2);
397
+ json.items = this.#handleArrayItemJsonSchema(this.#convert(array._zod.def.element, options2, lazyDepth2), options2);
399
398
  return [true, json];
400
399
  }
401
400
  case "object": {
402
401
  const object = schema2;
403
402
  const json = { type: "object" };
404
403
  for (const [key, value] of Object.entries(object._zod.def.shape)) {
405
- const [itemRequired, itemJson] = await this.#convert(value, options2, lazyDepth2);
404
+ const [itemRequired, itemJson] = this.#convert(value, options2, lazyDepth2);
406
405
  json.properties ??= {};
407
406
  json.properties[key] = itemJson;
408
407
  if (itemRequired) {
@@ -414,7 +413,7 @@ class experimental_ZodToJsonSchemaConverter {
414
413
  if (object._zod.def.catchall._zod.def.type === "never") {
415
414
  json.additionalProperties = false;
416
415
  } else {
417
- const [_, addJson] = await this.#convert(object._zod.def.catchall, options2, lazyDepth2);
416
+ const [_, addJson] = this.#convert(object._zod.def.catchall, options2, lazyDepth2);
418
417
  json.additionalProperties = addJson;
419
418
  }
420
419
  }
@@ -425,7 +424,7 @@ class experimental_ZodToJsonSchemaConverter {
425
424
  const anyOf = [];
426
425
  let required = true;
427
426
  for (const item of union._zod.def.options) {
428
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
427
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2);
429
428
  if (!itemRequired) {
430
429
  required = false;
431
430
  }
@@ -446,7 +445,7 @@ class experimental_ZodToJsonSchemaConverter {
446
445
  const json = { allOf: [] };
447
446
  let required = false;
448
447
  for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
449
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
448
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2);
450
449
  json.allOf.push(itemJson);
451
450
  if (itemRequired) {
452
451
  required = true;
@@ -458,16 +457,16 @@ class experimental_ZodToJsonSchemaConverter {
458
457
  const tuple = schema2;
459
458
  const json = { type: "array", prefixItems: [] };
460
459
  for (const item of tuple._zod.def.items) {
461
- json.prefixItems.push(this.#handleArrayItemJsonSchema(await this.#convert(item, options2, lazyDepth2), options2));
460
+ json.prefixItems.push(this.#handleArrayItemJsonSchema(this.#convert(item, options2, lazyDepth2), options2));
462
461
  }
463
462
  if (tuple._zod.def.rest) {
464
- json.items = this.#handleArrayItemJsonSchema(await this.#convert(tuple._zod.def.rest, options2, lazyDepth2), options2);
463
+ json.items = this.#handleArrayItemJsonSchema(this.#convert(tuple._zod.def.rest, options2, lazyDepth2), options2);
465
464
  }
466
- const { minimum, maximum } = tuple._zod.computed;
467
- if (minimum !== void 0) {
465
+ const { minimum, maximum } = tuple._zod.bag;
466
+ if (typeof minimum === "number") {
468
467
  json.minItems = minimum;
469
468
  }
470
- if (maximum !== void 0) {
469
+ if (typeof maximum === "number") {
471
470
  json.maxItems = maximum;
472
471
  }
473
472
  return [true, json];
@@ -475,8 +474,8 @@ class experimental_ZodToJsonSchemaConverter {
475
474
  case "record": {
476
475
  const record = schema2;
477
476
  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];
477
+ json.propertyNames = this.#convert(record._zod.def.keyType, options2, lazyDepth2)[1];
478
+ json.additionalProperties = this.#convert(record._zod.def.valueType, options2, lazyDepth2)[1];
480
479
  return [true, json];
481
480
  }
482
481
  case "map": {
@@ -486,8 +485,8 @@ class experimental_ZodToJsonSchemaConverter {
486
485
  items: {
487
486
  type: "array",
488
487
  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)
488
+ this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.keyType, options2, lazyDepth2), options2),
489
+ this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.valueType, options2, lazyDepth2), options2)
491
490
  ],
492
491
  maxItems: 2,
493
492
  minItems: 2
@@ -499,7 +498,7 @@ class experimental_ZodToJsonSchemaConverter {
499
498
  return [true, {
500
499
  type: "array",
501
500
  uniqueItems: true,
502
- items: this.#handleArrayItemJsonSchema(await this.#convert(set._zod.def.valueType, options2, lazyDepth2), options2)
501
+ items: this.#handleArrayItemJsonSchema(this.#convert(set._zod.def.valueType, options2, lazyDepth2), options2)
503
502
  }];
504
503
  }
505
504
  case "enum": {
@@ -523,12 +522,14 @@ class experimental_ZodToJsonSchemaConverter {
523
522
  case "file": {
524
523
  const file = schema2;
525
524
  const oneOf = [];
526
- const { mime } = file._zod.computed;
527
- for (const type of mime ?? ["*/*"]) {
528
- oneOf.push({
529
- type: "string",
530
- contentMediaType: type
531
- });
525
+ const { mime } = file._zod.bag;
526
+ if (mime === void 0 || Array.isArray(mime) && mime.every((m) => typeof m === "string")) {
527
+ for (const type of mime ?? ["*/*"]) {
528
+ oneOf.push({
529
+ type: "string",
530
+ contentMediaType: type
531
+ });
532
+ }
532
533
  }
533
534
  return [true, oneOf.length === 1 ? oneOf[0] : { anyOf: oneOf }];
534
535
  }
@@ -537,40 +538,40 @@ class experimental_ZodToJsonSchemaConverter {
537
538
  }
538
539
  case "nullable": {
539
540
  const nullable = schema2;
540
- const [required, json] = await this.#convert(nullable._zod.def.innerType, options2, lazyDepth2);
541
+ const [required, json] = this.#convert(nullable._zod.def.innerType, options2, lazyDepth2);
541
542
  return [required, { anyOf: [json, { type: "null" }] }];
542
543
  }
543
544
  case "nonoptional": {
544
545
  const nonoptional = schema2;
545
- const [, json] = await this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2);
546
+ const [, json] = this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2);
546
547
  return [true, json];
547
548
  }
548
549
  case "success": {
549
550
  return [true, { type: "boolean" }];
550
551
  }
551
- case "default": {
552
+ case "default":
553
+ case "prefault": {
552
554
  const default_ = schema2;
553
- const [, json] = await this.#convert(default_._zod.def.innerType, options2, lazyDepth2);
555
+ const [, json] = this.#convert(default_._zod.def.innerType, options2, lazyDepth2);
554
556
  return [false, {
555
557
  ...json,
556
- default: default_._zod.def.defaultValue()
558
+ default: default_._zod.def.defaultValue
557
559
  }];
558
560
  }
559
561
  case "catch": {
560
562
  const catch_ = schema2;
561
- const [, json] = await this.#convert(catch_._zod.def.innerType, options2, lazyDepth2);
562
- return [false, json];
563
+ return this.#convert(catch_._zod.def.innerType, options2, lazyDepth2);
563
564
  }
564
565
  case "nan": {
565
566
  return [true, options2.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
566
567
  }
567
568
  case "pipe": {
568
569
  const pipe = schema2;
569
- return await this.#convert(options2.strategy === "input" ? pipe._zod.def.in : pipe._zod.def.out, options2, lazyDepth2);
570
+ return this.#convert(options2.strategy === "input" ? pipe._zod.def.in : pipe._zod.def.out, options2, lazyDepth2);
570
571
  }
571
572
  case "readonly": {
572
573
  const readonly_ = schema2;
573
- const [required, json] = await this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2);
574
+ const [required, json] = this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2);
574
575
  return [required, { ...json, readOnly: true }];
575
576
  }
576
577
  case "template_literal": {
@@ -582,7 +583,7 @@ class experimental_ZodToJsonSchemaConverter {
582
583
  }
583
584
  case "optional": {
584
585
  const optional = schema2;
585
- const [, json] = await this.#convert(optional._zod.def.innerType, options2, lazyDepth2);
586
+ const [, json] = this.#convert(optional._zod.def.innerType, options2, lazyDepth2);
586
587
  return [false, json];
587
588
  }
588
589
  case "lazy": {
@@ -590,7 +591,7 @@ class experimental_ZodToJsonSchemaConverter {
590
591
  if (lazyDepth2 >= this.maxLazyDepth) {
591
592
  return [false, this.anyJsonSchema];
592
593
  }
593
- return await this.#convert(lazy._zod.def.getter(), options2, lazyDepth2 + 1);
594
+ return this.#convert(lazy._zod.def.getter(), options2, lazyDepth2 + 1);
594
595
  }
595
596
  default: {
596
597
  schema2._zod.def.type;
@@ -614,12 +615,12 @@ class experimental_ZodToJsonSchemaConverter {
614
615
  if (global) {
615
616
  return {
616
617
  description: global.description,
617
- examples: global.examples
618
+ examples: Array.isArray(global.examples) ? global.examples : void 0
618
619
  };
619
620
  }
620
621
  }
621
622
  #handleArrayItemJsonSchema([required, schema], options) {
622
- if (required || options.strategy === "input") {
623
+ if (required || options.strategy === "input" || schema.default !== void 0) {
623
624
  return schema;
624
625
  }
625
626
  if (schema === this.undefinedJsonSchema) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/zod",
3
3
  "type": "module",
4
- "version": "1.2.0",
4
+ "version": "1.4.0",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -29,31 +29,19 @@
29
29
  "dist"
30
30
  ],
31
31
  "peerDependencies": {
32
- "@zod/core": ">=0.11.4",
33
32
  "zod": ">=3.24.2",
34
- "@orpc/contract": "1.2.0",
35
- "@orpc/server": "1.2.0"
36
- },
37
- "peerDependenciesMeta": {
38
- "@zod/core": {
39
- "optional": true
40
- },
41
- "zod": {
42
- "optional": true
43
- }
33
+ "@orpc/contract": "1.4.0",
34
+ "@orpc/server": "1.4.0"
44
35
  },
45
36
  "dependencies": {
46
37
  "escape-string-regexp": "^5.0.0",
47
38
  "wildcard-match": "^5.1.3",
48
- "@orpc/openapi": "1.2.0",
49
- "@orpc/shared": "1.2.0"
39
+ "@orpc/openapi": "1.4.0",
40
+ "@orpc/shared": "1.4.0"
50
41
  },
51
42
  "devDependencies": {
52
- "@zod/core": "^0.11.4",
53
- "@zod/mini": "^4.0.0-beta.20250505T012514",
54
- "zod": "^3.24.2",
55
- "zod-to-json-schema": "^3.24.5",
56
- "zod4": "npm:zod@^4.0.0-beta.20250505T012514"
43
+ "zod": "^3.25.49",
44
+ "zod-to-json-schema": "^3.24.5"
57
45
  },
58
46
  "scripts": {
59
47
  "build": "unbuild",