@orpc/zod 0.0.0-next.a9447ff → 0.0.0-next.a9d0401

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,7 +2,7 @@ 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';
5
+ import { Interceptor } from '@orpc/shared';
6
6
  import * as zod_v4_core from 'zod/v4/core';
7
7
  import { $ZodType, $input, $output } from 'zod/v4/core';
8
8
 
@@ -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
  /**
@@ -2,7 +2,7 @@ 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';
5
+ import { Interceptor } from '@orpc/shared';
6
6
  import * as zod_v4_core from 'zod/v4/core';
7
7
  import { $ZodType, $input, $output } from 'zod/v4/core';
8
8
 
@@ -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
  /**
@@ -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
  }
@@ -255,30 +266,6 @@ class experimental_ZodSmartCoercionPlugin {
255
266
  }
256
267
  return value;
257
268
  }
258
- /**
259
- * This function is inspired from Zod, because it's not exported
260
- * https://github.com/colinhacks/zod/blob/v4/packages/core/src/schemas.ts#L1903C1-L1921C2
261
- */
262
- #matchDiscriminators(input, discs) {
263
- for (const [key, value] of discs) {
264
- const data = input[key];
265
- if (value.values.size && !value.values.has(data)) {
266
- return false;
267
- }
268
- if (value.maps.length === 0) {
269
- continue;
270
- }
271
- if (!isObject(data)) {
272
- return false;
273
- }
274
- for (const m of value.maps) {
275
- if (!this.#matchDiscriminators(data, m)) {
276
- return false;
277
- }
278
- }
279
- }
280
- return true;
281
- }
282
269
  }
283
270
 
284
271
  const experimental_JSON_SCHEMA_REGISTRY = registry();
@@ -308,11 +295,11 @@ class experimental_ZodToJsonSchemaConverter {
308
295
  return intercept(
309
296
  this.interceptors,
310
297
  { schema, options, lazyDepth, isHandledCustomJSONSchema },
311
- async ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
298
+ ({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
312
299
  if (!isHandledCustomJSONSchema2) {
313
300
  const customJSONSchema = this.#getCustomJsonSchema(schema2, options2);
314
301
  if (customJSONSchema) {
315
- const [required, json] = await this.#convert(schema2, options2, lazyDepth2, true);
302
+ const [required, json] = this.#convert(schema2, options2, lazyDepth2, true);
316
303
  return [required, { ...json, ...customJSONSchema }];
317
304
  }
318
305
  }
@@ -320,7 +307,7 @@ class experimental_ZodToJsonSchemaConverter {
320
307
  case "string": {
321
308
  const string = schema2;
322
309
  const json = { type: "string" };
323
- const { minimum, maximum, format, pattern, contentEncoding } = string._zod.bag;
310
+ const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
324
311
  if (typeof minimum === "number") {
325
312
  json.minLength = minimum;
326
313
  }
@@ -333,8 +320,15 @@ class experimental_ZodToJsonSchemaConverter {
333
320
  if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
334
321
  json.format = this.#handleStringFormat(format);
335
322
  }
336
- if (pattern instanceof RegExp && json.contentEncoding === void 0 && json.format === void 0) {
337
- 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
+ }
338
332
  }
339
333
  if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
340
334
  json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
@@ -400,14 +394,14 @@ class experimental_ZodToJsonSchemaConverter {
400
394
  if (typeof maximum === "number") {
401
395
  json.maxItems = maximum;
402
396
  }
403
- 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);
404
398
  return [true, json];
405
399
  }
406
400
  case "object": {
407
401
  const object = schema2;
408
402
  const json = { type: "object" };
409
403
  for (const [key, value] of Object.entries(object._zod.def.shape)) {
410
- const [itemRequired, itemJson] = await this.#convert(value, options2, lazyDepth2);
404
+ const [itemRequired, itemJson] = this.#convert(value, options2, lazyDepth2);
411
405
  json.properties ??= {};
412
406
  json.properties[key] = itemJson;
413
407
  if (itemRequired) {
@@ -419,7 +413,7 @@ class experimental_ZodToJsonSchemaConverter {
419
413
  if (object._zod.def.catchall._zod.def.type === "never") {
420
414
  json.additionalProperties = false;
421
415
  } else {
422
- const [_, addJson] = await this.#convert(object._zod.def.catchall, options2, lazyDepth2);
416
+ const [_, addJson] = this.#convert(object._zod.def.catchall, options2, lazyDepth2);
423
417
  json.additionalProperties = addJson;
424
418
  }
425
419
  }
@@ -430,7 +424,7 @@ class experimental_ZodToJsonSchemaConverter {
430
424
  const anyOf = [];
431
425
  let required = true;
432
426
  for (const item of union._zod.def.options) {
433
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
427
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2);
434
428
  if (!itemRequired) {
435
429
  required = false;
436
430
  }
@@ -451,7 +445,7 @@ class experimental_ZodToJsonSchemaConverter {
451
445
  const json = { allOf: [] };
452
446
  let required = false;
453
447
  for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
454
- const [itemRequired, itemJson] = await this.#convert(item, options2, lazyDepth2);
448
+ const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2);
455
449
  json.allOf.push(itemJson);
456
450
  if (itemRequired) {
457
451
  required = true;
@@ -463,10 +457,10 @@ class experimental_ZodToJsonSchemaConverter {
463
457
  const tuple = schema2;
464
458
  const json = { type: "array", prefixItems: [] };
465
459
  for (const item of tuple._zod.def.items) {
466
- json.prefixItems.push(this.#handleArrayItemJsonSchema(await this.#convert(item, options2, lazyDepth2), options2));
460
+ json.prefixItems.push(this.#handleArrayItemJsonSchema(this.#convert(item, options2, lazyDepth2), options2));
467
461
  }
468
462
  if (tuple._zod.def.rest) {
469
- 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);
470
464
  }
471
465
  const { minimum, maximum } = tuple._zod.bag;
472
466
  if (typeof minimum === "number") {
@@ -480,8 +474,8 @@ class experimental_ZodToJsonSchemaConverter {
480
474
  case "record": {
481
475
  const record = schema2;
482
476
  const json = { type: "object" };
483
- json.propertyNames = (await this.#convert(record._zod.def.keyType, options2, lazyDepth2))[1];
484
- 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];
485
479
  return [true, json];
486
480
  }
487
481
  case "map": {
@@ -491,8 +485,8 @@ class experimental_ZodToJsonSchemaConverter {
491
485
  items: {
492
486
  type: "array",
493
487
  prefixItems: [
494
- this.#handleArrayItemJsonSchema(await this.#convert(map._zod.def.keyType, options2, lazyDepth2), options2),
495
- 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)
496
490
  ],
497
491
  maxItems: 2,
498
492
  minItems: 2
@@ -504,7 +498,7 @@ class experimental_ZodToJsonSchemaConverter {
504
498
  return [true, {
505
499
  type: "array",
506
500
  uniqueItems: true,
507
- 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)
508
502
  }];
509
503
  }
510
504
  case "enum": {
@@ -544,12 +538,12 @@ class experimental_ZodToJsonSchemaConverter {
544
538
  }
545
539
  case "nullable": {
546
540
  const nullable = schema2;
547
- const [required, json] = await this.#convert(nullable._zod.def.innerType, options2, lazyDepth2);
541
+ const [required, json] = this.#convert(nullable._zod.def.innerType, options2, lazyDepth2);
548
542
  return [required, { anyOf: [json, { type: "null" }] }];
549
543
  }
550
544
  case "nonoptional": {
551
545
  const nonoptional = schema2;
552
- const [, json] = await this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2);
546
+ const [, json] = this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2);
553
547
  return [true, json];
554
548
  }
555
549
  case "success": {
@@ -558,7 +552,7 @@ class experimental_ZodToJsonSchemaConverter {
558
552
  case "default":
559
553
  case "prefault": {
560
554
  const default_ = schema2;
561
- const [, json] = await this.#convert(default_._zod.def.innerType, options2, lazyDepth2);
555
+ const [, json] = this.#convert(default_._zod.def.innerType, options2, lazyDepth2);
562
556
  return [false, {
563
557
  ...json,
564
558
  default: default_._zod.def.defaultValue
@@ -566,18 +560,18 @@ class experimental_ZodToJsonSchemaConverter {
566
560
  }
567
561
  case "catch": {
568
562
  const catch_ = schema2;
569
- return await this.#convert(catch_._zod.def.innerType, options2, lazyDepth2);
563
+ return this.#convert(catch_._zod.def.innerType, options2, lazyDepth2);
570
564
  }
571
565
  case "nan": {
572
566
  return [true, options2.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
573
567
  }
574
568
  case "pipe": {
575
569
  const pipe = schema2;
576
- 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);
577
571
  }
578
572
  case "readonly": {
579
573
  const readonly_ = schema2;
580
- const [required, json] = await this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2);
574
+ const [required, json] = this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2);
581
575
  return [required, { ...json, readOnly: true }];
582
576
  }
583
577
  case "template_literal": {
@@ -589,7 +583,7 @@ class experimental_ZodToJsonSchemaConverter {
589
583
  }
590
584
  case "optional": {
591
585
  const optional = schema2;
592
- const [, json] = await this.#convert(optional._zod.def.innerType, options2, lazyDepth2);
586
+ const [, json] = this.#convert(optional._zod.def.innerType, options2, lazyDepth2);
593
587
  return [false, json];
594
588
  }
595
589
  case "lazy": {
@@ -597,7 +591,7 @@ class experimental_ZodToJsonSchemaConverter {
597
591
  if (lazyDepth2 >= this.maxLazyDepth) {
598
592
  return [false, this.anyJsonSchema];
599
593
  }
600
- return await this.#convert(lazy._zod.def.getter(), options2, lazyDepth2 + 1);
594
+ return this.#convert(lazy._zod.def.getter(), options2, lazyDepth2 + 1);
601
595
  }
602
596
  default: {
603
597
  schema2._zod.def.type;
@@ -621,7 +615,7 @@ class experimental_ZodToJsonSchemaConverter {
621
615
  if (global) {
622
616
  return {
623
617
  description: global.description,
624
- examples: global.examples
618
+ examples: Array.isArray(global.examples) ? global.examples : void 0
625
619
  };
626
620
  }
627
621
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/zod",
3
3
  "type": "module",
4
- "version": "0.0.0-next.a9447ff",
4
+ "version": "0.0.0-next.a9d0401",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.unnoq.com",
7
7
  "repository": {
@@ -30,17 +30,17 @@
30
30
  ],
31
31
  "peerDependencies": {
32
32
  "zod": ">=3.24.2",
33
- "@orpc/server": "0.0.0-next.a9447ff",
34
- "@orpc/contract": "0.0.0-next.a9447ff"
33
+ "@orpc/contract": "0.0.0-next.a9d0401",
34
+ "@orpc/server": "0.0.0-next.a9d0401"
35
35
  },
36
36
  "dependencies": {
37
37
  "escape-string-regexp": "^5.0.0",
38
38
  "wildcard-match": "^5.1.3",
39
- "@orpc/openapi": "0.0.0-next.a9447ff",
40
- "@orpc/shared": "0.0.0-next.a9447ff"
39
+ "@orpc/openapi": "0.0.0-next.a9d0401",
40
+ "@orpc/shared": "0.0.0-next.a9d0401"
41
41
  },
42
42
  "devDependencies": {
43
- "zod": "^3.25.7",
43
+ "zod": "^3.25.49",
44
44
  "zod-to-json-schema": "^3.24.5"
45
45
  },
46
46
  "scripts": {