@orpc/zod 0.0.0-next.fa8d145 → 0.0.0-next.fc23c8d
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 +5 -7
- package/dist/index.d.mts +15 -6
- package/dist/index.d.ts +15 -6
- package/dist/index.mjs +44 -27
- package/dist/zod4/index.d.mts +17 -8
- package/dist/zod4/index.d.ts +17 -8
- package/dist/zod4/index.mjs +97 -89
- package/package.json +6 -6
package/README.md
CHANGED
@@ -30,7 +30,7 @@
|
|
30
30
|
- **🔗 End-to-End Type Safety**: Ensure type-safe inputs, outputs, and errors from client to server.
|
31
31
|
- **📘 First-Class OpenAPI**: Built-in support that fully adheres to the OpenAPI standard.
|
32
32
|
- **📝 Contract-First Development**: Optionally define your API contract before implementation.
|
33
|
-
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte), Pinia Colada, and more.
|
33
|
+
- **⚙️ Framework Integrations**: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), Pinia Colada, and more.
|
34
34
|
- **🚀 Server Actions**: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
|
35
35
|
- **🔠 Standard Schema Support**: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
|
36
36
|
- **🗃️ Native Types**: Supports native types like Date, File, Blob, BigInt, URL, and more.
|
@@ -49,14 +49,12 @@ 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/
|
52
|
+
- [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Generate OpenAPI specs and handle OpenAPI requests.
|
53
|
+
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Deeply integrate oRPC with [NestJS](https://nestjs.com/).
|
53
54
|
- [@orpc/react](https://www.npmjs.com/package/@orpc/react): Utilities for integrating oRPC with React and React Server Actions.
|
54
|
-
- [@orpc/
|
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).
|
56
|
-
- [@orpc/solid-query](https://www.npmjs.com/package/@orpc/solid-query): Integration with [Solid Query](https://tanstack.com/query/latest/docs/framework/solid/overview).
|
57
|
-
- [@orpc/svelte-query](https://www.npmjs.com/package/@orpc/svelte-query): Integration with [Svelte Query](https://tanstack.com/query/latest/docs/framework/svelte/overview).
|
55
|
+
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): [TanStack Query](https://tanstack.com/query/latest) integration.
|
58
56
|
- [@orpc/vue-colada](https://www.npmjs.com/package/@orpc/vue-colada): Integration with [Pinia Colada](https://pinia-colada.esm.dev/).
|
59
|
-
- [@orpc/
|
57
|
+
- [@orpc/hey-api](https://www.npmjs.com/package/@orpc/hey-api): [Hey API](https://heyapi.dev/) integration.
|
60
58
|
- [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): More schemas that [Zod](https://zod.dev/) doesn't support yet.
|
61
59
|
- [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): OpenAPI spec generation from [Valibot](https://valibot.dev/).
|
62
60
|
- [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): OpenAPI spec generation from [ArkType](https://arktype.io/).
|
package/dist/index.d.mts
CHANGED
@@ -40,34 +40,43 @@ declare class ZodSmartCoercionPlugin<TContext extends Context> implements Standa
|
|
40
40
|
|
41
41
|
interface ZodToJsonSchemaOptions {
|
42
42
|
/**
|
43
|
-
* Max depth of lazy type
|
43
|
+
* Max depth of lazy type
|
44
44
|
*
|
45
|
-
* Used `{}` when
|
45
|
+
* Used `{}` when exceed max depth
|
46
46
|
*
|
47
47
|
* @default 3
|
48
48
|
*/
|
49
49
|
maxLazyDepth?: number;
|
50
50
|
/**
|
51
|
-
*
|
51
|
+
* Max depth of nested types
|
52
52
|
*
|
53
|
-
*
|
53
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
54
|
+
*
|
55
|
+
* @default 10
|
54
56
|
*/
|
55
|
-
|
57
|
+
maxStructureDepth?: number;
|
56
58
|
/**
|
57
59
|
* The schema to be used to represent the any | unknown type.
|
58
60
|
*
|
59
61
|
* @default { }
|
60
62
|
*/
|
61
63
|
anyJsonSchema?: Exclude<JSONSchema, boolean>;
|
64
|
+
/**
|
65
|
+
* The schema to be used when the Zod schema is unsupported.
|
66
|
+
*
|
67
|
+
* @default { not: {} }
|
68
|
+
*/
|
69
|
+
unsupportedJsonSchema?: Exclude<JSONSchema, boolean>;
|
62
70
|
}
|
63
71
|
declare class ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
|
64
72
|
#private;
|
65
73
|
private readonly maxLazyDepth;
|
74
|
+
private readonly maxStructureDepth;
|
66
75
|
private readonly unsupportedJsonSchema;
|
67
76
|
private readonly anyJsonSchema;
|
68
77
|
constructor(options?: ZodToJsonSchemaOptions);
|
69
78
|
condition(schema: AnySchema | undefined): boolean;
|
70
|
-
convert(schema: AnySchema | undefined, options: SchemaConvertOptions, lazyDepth?: number, isHandledCustomJSONSchema?: boolean, isHandledZodDescription?: boolean): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
79
|
+
convert(schema: AnySchema | undefined, options: SchemaConvertOptions, lazyDepth?: number, isHandledCustomJSONSchema?: boolean, isHandledZodDescription?: boolean, structureDepth?: number): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
71
80
|
}
|
72
81
|
|
73
82
|
declare const oz: {
|
package/dist/index.d.ts
CHANGED
@@ -40,34 +40,43 @@ declare class ZodSmartCoercionPlugin<TContext extends Context> implements Standa
|
|
40
40
|
|
41
41
|
interface ZodToJsonSchemaOptions {
|
42
42
|
/**
|
43
|
-
* Max depth of lazy type
|
43
|
+
* Max depth of lazy type
|
44
44
|
*
|
45
|
-
* Used `{}` when
|
45
|
+
* Used `{}` when exceed max depth
|
46
46
|
*
|
47
47
|
* @default 3
|
48
48
|
*/
|
49
49
|
maxLazyDepth?: number;
|
50
50
|
/**
|
51
|
-
*
|
51
|
+
* Max depth of nested types
|
52
52
|
*
|
53
|
-
*
|
53
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
54
|
+
*
|
55
|
+
* @default 10
|
54
56
|
*/
|
55
|
-
|
57
|
+
maxStructureDepth?: number;
|
56
58
|
/**
|
57
59
|
* The schema to be used to represent the any | unknown type.
|
58
60
|
*
|
59
61
|
* @default { }
|
60
62
|
*/
|
61
63
|
anyJsonSchema?: Exclude<JSONSchema, boolean>;
|
64
|
+
/**
|
65
|
+
* The schema to be used when the Zod schema is unsupported.
|
66
|
+
*
|
67
|
+
* @default { not: {} }
|
68
|
+
*/
|
69
|
+
unsupportedJsonSchema?: Exclude<JSONSchema, boolean>;
|
62
70
|
}
|
63
71
|
declare class ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
|
64
72
|
#private;
|
65
73
|
private readonly maxLazyDepth;
|
74
|
+
private readonly maxStructureDepth;
|
66
75
|
private readonly unsupportedJsonSchema;
|
67
76
|
private readonly anyJsonSchema;
|
68
77
|
constructor(options?: ZodToJsonSchemaOptions);
|
69
78
|
condition(schema: AnySchema | undefined): boolean;
|
70
|
-
convert(schema: AnySchema | undefined, options: SchemaConvertOptions, lazyDepth?: number, isHandledCustomJSONSchema?: boolean, isHandledZodDescription?: boolean): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
79
|
+
convert(schema: AnySchema | undefined, options: SchemaConvertOptions, lazyDepth?: number, isHandledCustomJSONSchema?: boolean, isHandledZodDescription?: boolean, structureDepth?: number): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
71
80
|
}
|
72
81
|
|
73
82
|
declare const oz: {
|
package/dist/index.mjs
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { custom, ZodFirstPartyTypeKind } from 'zod';
|
2
2
|
import wcmatch from 'wildcard-match';
|
3
|
-
import { isObject, guard } from '@orpc/shared';
|
3
|
+
import { isObject, guard, toArray } from '@orpc/shared';
|
4
4
|
import { JSONSchemaFormat } from '@orpc/openapi';
|
5
5
|
import escapeStringRegexp from 'escape-string-regexp';
|
6
6
|
|
@@ -390,25 +390,39 @@ function safeToDate(value) {
|
|
390
390
|
|
391
391
|
class ZodToJsonSchemaConverter {
|
392
392
|
maxLazyDepth;
|
393
|
+
maxStructureDepth;
|
393
394
|
unsupportedJsonSchema;
|
394
395
|
anyJsonSchema;
|
395
396
|
constructor(options = {}) {
|
396
397
|
this.maxLazyDepth = options.maxLazyDepth ?? 3;
|
398
|
+
this.maxStructureDepth = options.maxStructureDepth ?? 10;
|
397
399
|
this.unsupportedJsonSchema = options.unsupportedJsonSchema ?? { not: {} };
|
398
400
|
this.anyJsonSchema = options.anyJsonSchema ?? {};
|
399
401
|
}
|
400
402
|
condition(schema) {
|
401
403
|
return schema !== void 0 && schema["~standard"].vendor === "zod";
|
402
404
|
}
|
403
|
-
convert(schema, options, lazyDepth = 0, isHandledCustomJSONSchema = false, isHandledZodDescription = false) {
|
405
|
+
convert(schema, options, lazyDepth = 0, isHandledCustomJSONSchema = false, isHandledZodDescription = false, structureDepth = 0) {
|
404
406
|
const def = schema._def;
|
407
|
+
if (structureDepth > this.maxStructureDepth) {
|
408
|
+
return [false, this.anyJsonSchema];
|
409
|
+
}
|
410
|
+
if (!options.minStructureDepthForRef || options.minStructureDepthForRef <= structureDepth) {
|
411
|
+
const components = toArray(options.components);
|
412
|
+
for (const component of components) {
|
413
|
+
if (component.schema === schema && component.allowedStrategies.includes(options.strategy)) {
|
414
|
+
return [component.required, { $ref: component.ref }];
|
415
|
+
}
|
416
|
+
}
|
417
|
+
}
|
405
418
|
if (!isHandledZodDescription && "description" in def && typeof def.description === "string") {
|
406
419
|
const [required, json] = this.convert(
|
407
420
|
schema,
|
408
421
|
options,
|
409
422
|
lazyDepth,
|
410
423
|
isHandledCustomJSONSchema,
|
411
|
-
true
|
424
|
+
true,
|
425
|
+
structureDepth
|
412
426
|
);
|
413
427
|
return [required, { ...json, description: def.description }];
|
414
428
|
}
|
@@ -420,7 +434,8 @@ class ZodToJsonSchemaConverter {
|
|
420
434
|
options,
|
421
435
|
lazyDepth,
|
422
436
|
true,
|
423
|
-
isHandledZodDescription
|
437
|
+
isHandledZodDescription,
|
438
|
+
structureDepth
|
424
439
|
);
|
425
440
|
return [required, { ...json, ...customJSONSchema }];
|
426
441
|
}
|
@@ -591,7 +606,7 @@ class ZodToJsonSchemaConverter {
|
|
591
606
|
const schema_ = schema;
|
592
607
|
const def2 = schema_._def;
|
593
608
|
const json = { type: "array" };
|
594
|
-
const [itemRequired, itemJson] = this.convert(def2.type, options, lazyDepth, false, false);
|
609
|
+
const [itemRequired, itemJson] = this.convert(def2.type, options, lazyDepth, false, false, structureDepth + 1);
|
595
610
|
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
596
611
|
if (def2.exactLength) {
|
597
612
|
json.maxItems = def2.exactLength.value;
|
@@ -610,7 +625,7 @@ class ZodToJsonSchemaConverter {
|
|
610
625
|
const prefixItems = [];
|
611
626
|
const json = { type: "array" };
|
612
627
|
for (const item of schema_._def.items) {
|
613
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false);
|
628
|
+
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth + 1);
|
614
629
|
prefixItems.push(
|
615
630
|
this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy)
|
616
631
|
);
|
@@ -619,7 +634,7 @@ class ZodToJsonSchemaConverter {
|
|
619
634
|
json.prefixItems = prefixItems;
|
620
635
|
}
|
621
636
|
if (schema_._def.rest) {
|
622
|
-
const [itemRequired, itemJson] = this.convert(schema_._def.rest, options, lazyDepth, false, false);
|
637
|
+
const [itemRequired, itemJson] = this.convert(schema_._def.rest, options, lazyDepth, false, false, structureDepth + 1);
|
623
638
|
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
624
639
|
}
|
625
640
|
return [true, json];
|
@@ -630,7 +645,7 @@ class ZodToJsonSchemaConverter {
|
|
630
645
|
const properties = {};
|
631
646
|
const required = [];
|
632
647
|
for (const [key, value] of Object.entries(schema_.shape)) {
|
633
|
-
const [itemRequired, itemJson] = this.convert(value, options, lazyDepth, false, false);
|
648
|
+
const [itemRequired, itemJson] = this.convert(value, options, lazyDepth, false, false, structureDepth + 1);
|
634
649
|
properties[key] = itemJson;
|
635
650
|
if (itemRequired) {
|
636
651
|
required.push(key);
|
@@ -648,7 +663,7 @@ class ZodToJsonSchemaConverter {
|
|
648
663
|
json.additionalProperties = false;
|
649
664
|
}
|
650
665
|
} else {
|
651
|
-
const [_, addJson] = this.convert(schema_._def.catchall, options, lazyDepth, false, false);
|
666
|
+
const [_, addJson] = this.convert(schema_._def.catchall, options, lazyDepth, false, false, structureDepth + 1);
|
652
667
|
json.additionalProperties = addJson;
|
653
668
|
}
|
654
669
|
return [true, json];
|
@@ -656,25 +671,25 @@ class ZodToJsonSchemaConverter {
|
|
656
671
|
case ZodFirstPartyTypeKind.ZodRecord: {
|
657
672
|
const schema_ = schema;
|
658
673
|
const json = { type: "object" };
|
659
|
-
const [__, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false);
|
674
|
+
const [__, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false, structureDepth + 1);
|
660
675
|
if (Object.entries(keyJson).some(([k, v]) => k !== "type" || v !== "string")) {
|
661
676
|
json.propertyNames = keyJson;
|
662
677
|
}
|
663
|
-
const [_, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false);
|
678
|
+
const [_, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
664
679
|
json.additionalProperties = itemJson;
|
665
680
|
return [true, json];
|
666
681
|
}
|
667
682
|
case ZodFirstPartyTypeKind.ZodSet: {
|
668
683
|
const schema_ = schema;
|
669
684
|
const json = { type: "array", uniqueItems: true };
|
670
|
-
const [itemRequired, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false);
|
685
|
+
const [itemRequired, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
671
686
|
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
672
687
|
return [true, json];
|
673
688
|
}
|
674
689
|
case ZodFirstPartyTypeKind.ZodMap: {
|
675
690
|
const schema_ = schema;
|
676
|
-
const [keyRequired, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false);
|
677
|
-
const [valueRequired, valueJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false);
|
691
|
+
const [keyRequired, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false, structureDepth + 1);
|
692
|
+
const [valueRequired, valueJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
678
693
|
return [true, {
|
679
694
|
type: "array",
|
680
695
|
items: {
|
@@ -694,7 +709,7 @@ class ZodToJsonSchemaConverter {
|
|
694
709
|
const anyOf = [];
|
695
710
|
let required = true;
|
696
711
|
for (const item of schema_._def.options) {
|
697
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false);
|
712
|
+
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth);
|
698
713
|
if (!itemRequired) {
|
699
714
|
required = false;
|
700
715
|
if (itemJson !== this.unsupportedJsonSchema) {
|
@@ -714,7 +729,7 @@ class ZodToJsonSchemaConverter {
|
|
714
729
|
const allOf = [];
|
715
730
|
let required = false;
|
716
731
|
for (const item of [schema_._def.left, schema_._def.right]) {
|
717
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false);
|
732
|
+
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth);
|
718
733
|
allOf.push(itemJson);
|
719
734
|
if (itemRequired) {
|
720
735
|
required = true;
|
@@ -723,25 +738,26 @@ class ZodToJsonSchemaConverter {
|
|
723
738
|
return [required, { allOf }];
|
724
739
|
}
|
725
740
|
case ZodFirstPartyTypeKind.ZodLazy: {
|
726
|
-
|
741
|
+
const currentLazyDepth = lazyDepth + 1;
|
742
|
+
if (currentLazyDepth > this.maxLazyDepth) {
|
727
743
|
return [false, this.anyJsonSchema];
|
728
744
|
}
|
729
745
|
const schema_ = schema;
|
730
|
-
return this.convert(schema_._def.getter(), options,
|
746
|
+
return this.convert(schema_._def.getter(), options, currentLazyDepth, false, false, structureDepth);
|
731
747
|
}
|
732
748
|
case ZodFirstPartyTypeKind.ZodOptional: {
|
733
749
|
const schema_ = schema;
|
734
|
-
const [_, inner] = this.convert(schema_._def.innerType, options, lazyDepth, false, false);
|
750
|
+
const [_, inner] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
735
751
|
return [false, inner];
|
736
752
|
}
|
737
753
|
case ZodFirstPartyTypeKind.ZodReadonly: {
|
738
754
|
const schema_ = schema;
|
739
|
-
const [required, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false);
|
755
|
+
const [required, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
740
756
|
return [required, { ...json, readOnly: true }];
|
741
757
|
}
|
742
758
|
case ZodFirstPartyTypeKind.ZodDefault: {
|
743
759
|
const schema_ = schema;
|
744
|
-
const [_, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false);
|
760
|
+
const [_, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
745
761
|
return [false, { default: schema_._def.defaultValue(), ...json }];
|
746
762
|
}
|
747
763
|
case ZodFirstPartyTypeKind.ZodEffects: {
|
@@ -749,15 +765,15 @@ class ZodToJsonSchemaConverter {
|
|
749
765
|
if (schema_._def.effect.type === "transform" && options.strategy === "output") {
|
750
766
|
return [false, this.anyJsonSchema];
|
751
767
|
}
|
752
|
-
return this.convert(schema_._def.schema, options, lazyDepth, false, false);
|
768
|
+
return this.convert(schema_._def.schema, options, lazyDepth, false, false, structureDepth);
|
753
769
|
}
|
754
770
|
case ZodFirstPartyTypeKind.ZodCatch: {
|
755
771
|
const schema_ = schema;
|
756
|
-
return this.convert(schema_._def.innerType, options, lazyDepth, false, false);
|
772
|
+
return this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
757
773
|
}
|
758
774
|
case ZodFirstPartyTypeKind.ZodBranded: {
|
759
775
|
const schema_ = schema;
|
760
|
-
return this.convert(schema_._def.type, options, lazyDepth, false, false);
|
776
|
+
return this.convert(schema_._def.type, options, lazyDepth, false, false, structureDepth);
|
761
777
|
}
|
762
778
|
case ZodFirstPartyTypeKind.ZodPipeline: {
|
763
779
|
const schema_ = schema;
|
@@ -766,13 +782,14 @@ class ZodToJsonSchemaConverter {
|
|
766
782
|
options,
|
767
783
|
lazyDepth,
|
768
784
|
false,
|
769
|
-
false
|
785
|
+
false,
|
786
|
+
structureDepth
|
770
787
|
);
|
771
788
|
}
|
772
789
|
case ZodFirstPartyTypeKind.ZodNullable: {
|
773
790
|
const schema_ = schema;
|
774
|
-
const [required, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false);
|
775
|
-
return [required, { anyOf: [{ type: "null" }
|
791
|
+
const [required, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
792
|
+
return [required, { anyOf: [json, { type: "null" }] }];
|
776
793
|
}
|
777
794
|
}
|
778
795
|
return [true, this.unsupportedJsonSchema];
|
package/dist/zod4/index.d.mts
CHANGED
@@ -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
|
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
|
|
@@ -13,13 +13,21 @@ declare class experimental_ZodSmartCoercionPlugin<TContext extends Context> impl
|
|
13
13
|
|
14
14
|
interface experimental_ZodToJsonSchemaOptions {
|
15
15
|
/**
|
16
|
-
* Max depth of lazy type
|
16
|
+
* Max depth of lazy type.
|
17
17
|
*
|
18
|
-
* Used anyJsonSchema (`{}`) when
|
18
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
19
19
|
*
|
20
20
|
* @default 2
|
21
21
|
*/
|
22
22
|
maxLazyDepth?: number;
|
23
|
+
/**
|
24
|
+
* Max depth of nested types.
|
25
|
+
*
|
26
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
27
|
+
*
|
28
|
+
* @default 10
|
29
|
+
*/
|
30
|
+
maxStructureDepth?: number;
|
23
31
|
/**
|
24
32
|
* The schema to be used to represent the any | unknown type.
|
25
33
|
*
|
@@ -46,18 +54,19 @@ interface experimental_ZodToJsonSchemaOptions {
|
|
46
54
|
}, [
|
47
55
|
required: boolean,
|
48
56
|
jsonSchema: Exclude<JSONSchema, boolean>
|
49
|
-
]
|
57
|
+
]>[];
|
50
58
|
}
|
51
59
|
declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
|
52
60
|
#private;
|
53
61
|
private readonly maxLazyDepth;
|
62
|
+
private readonly maxStructureDepth;
|
54
63
|
private readonly anyJsonSchema;
|
55
64
|
private readonly unsupportedJsonSchema;
|
56
65
|
private readonly undefinedJsonSchema;
|
57
66
|
private readonly interceptors;
|
58
67
|
constructor(options?: experimental_ZodToJsonSchemaOptions);
|
59
68
|
condition(schema: AnySchema | undefined): boolean;
|
60
|
-
convert(schema: AnySchema | undefined, options: SchemaConvertOptions):
|
69
|
+
convert(schema: AnySchema | undefined, options: SchemaConvertOptions): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
61
70
|
}
|
62
71
|
|
63
72
|
/**
|
@@ -138,7 +147,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: zod_v4_core.$ZodRegistry<{
|
|
138
147
|
unevaluatedProperties?: JSONSchema;
|
139
148
|
uniqueItems?: boolean;
|
140
149
|
writeOnly?: boolean;
|
141
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
150
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
142
151
|
/**
|
143
152
|
* Zod registry for customizing generated JSON schema, only useful for .input
|
144
153
|
*
|
@@ -217,7 +226,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: zod_v4_core.$ZodRegistry<
|
|
217
226
|
unevaluatedProperties?: JSONSchema;
|
218
227
|
uniqueItems?: boolean;
|
219
228
|
writeOnly?: boolean;
|
220
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
229
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
221
230
|
/**
|
222
231
|
* Zod registry for customizing generated JSON schema, only useful for .input
|
223
232
|
*
|
@@ -296,7 +305,7 @@ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: zod_v4_core.$ZodRegistry
|
|
296
305
|
unevaluatedProperties?: JSONSchema;
|
297
306
|
uniqueItems?: boolean;
|
298
307
|
writeOnly?: boolean;
|
299
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
308
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
300
309
|
|
301
310
|
export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
|
302
311
|
export type { experimental_ZodToJsonSchemaOptions };
|
package/dist/zod4/index.d.ts
CHANGED
@@ -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
|
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
|
|
@@ -13,13 +13,21 @@ declare class experimental_ZodSmartCoercionPlugin<TContext extends Context> impl
|
|
13
13
|
|
14
14
|
interface experimental_ZodToJsonSchemaOptions {
|
15
15
|
/**
|
16
|
-
* Max depth of lazy type
|
16
|
+
* Max depth of lazy type.
|
17
17
|
*
|
18
|
-
* Used anyJsonSchema (`{}`) when
|
18
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
19
19
|
*
|
20
20
|
* @default 2
|
21
21
|
*/
|
22
22
|
maxLazyDepth?: number;
|
23
|
+
/**
|
24
|
+
* Max depth of nested types.
|
25
|
+
*
|
26
|
+
* Used anyJsonSchema (`{}`) when exceed max depth
|
27
|
+
*
|
28
|
+
* @default 10
|
29
|
+
*/
|
30
|
+
maxStructureDepth?: number;
|
23
31
|
/**
|
24
32
|
* The schema to be used to represent the any | unknown type.
|
25
33
|
*
|
@@ -46,18 +54,19 @@ interface experimental_ZodToJsonSchemaOptions {
|
|
46
54
|
}, [
|
47
55
|
required: boolean,
|
48
56
|
jsonSchema: Exclude<JSONSchema, boolean>
|
49
|
-
]
|
57
|
+
]>[];
|
50
58
|
}
|
51
59
|
declare class experimental_ZodToJsonSchemaConverter implements ConditionalSchemaConverter {
|
52
60
|
#private;
|
53
61
|
private readonly maxLazyDepth;
|
62
|
+
private readonly maxStructureDepth;
|
54
63
|
private readonly anyJsonSchema;
|
55
64
|
private readonly unsupportedJsonSchema;
|
56
65
|
private readonly undefinedJsonSchema;
|
57
66
|
private readonly interceptors;
|
58
67
|
constructor(options?: experimental_ZodToJsonSchemaOptions);
|
59
68
|
condition(schema: AnySchema | undefined): boolean;
|
60
|
-
convert(schema: AnySchema | undefined, options: SchemaConvertOptions):
|
69
|
+
convert(schema: AnySchema | undefined, options: SchemaConvertOptions): [required: boolean, jsonSchema: Exclude<JSONSchema, boolean>];
|
61
70
|
}
|
62
71
|
|
63
72
|
/**
|
@@ -138,7 +147,7 @@ declare const experimental_JSON_SCHEMA_REGISTRY: zod_v4_core.$ZodRegistry<{
|
|
138
147
|
unevaluatedProperties?: JSONSchema;
|
139
148
|
uniqueItems?: boolean;
|
140
149
|
writeOnly?: boolean;
|
141
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
150
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
142
151
|
/**
|
143
152
|
* Zod registry for customizing generated JSON schema, only useful for .input
|
144
153
|
*
|
@@ -217,7 +226,7 @@ declare const experimental_JSON_SCHEMA_INPUT_REGISTRY: zod_v4_core.$ZodRegistry<
|
|
217
226
|
unevaluatedProperties?: JSONSchema;
|
218
227
|
uniqueItems?: boolean;
|
219
228
|
writeOnly?: boolean;
|
220
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
229
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
221
230
|
/**
|
222
231
|
* Zod registry for customizing generated JSON schema, only useful for .input
|
223
232
|
*
|
@@ -296,7 +305,7 @@ declare const experimental_JSON_SCHEMA_OUTPUT_REGISTRY: zod_v4_core.$ZodRegistry
|
|
296
305
|
unevaluatedProperties?: JSONSchema;
|
297
306
|
uniqueItems?: boolean;
|
298
307
|
writeOnly?: boolean;
|
299
|
-
}, zod_v4_core.$ZodType<unknown, unknown
|
308
|
+
}, zod_v4_core.$ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>>>;
|
300
309
|
|
301
310
|
export { experimental_JSON_SCHEMA_INPUT_REGISTRY, experimental_JSON_SCHEMA_OUTPUT_REGISTRY, experimental_JSON_SCHEMA_REGISTRY, experimental_ZodSmartCoercionPlugin, experimental_ZodToJsonSchemaConverter };
|
302
311
|
export type { experimental_ZodToJsonSchemaOptions };
|
package/dist/zod4/index.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { isObject, guard, intercept } from '@orpc/shared';
|
1
|
+
import { isObject, guard, intercept, toArray } from '@orpc/shared';
|
2
2
|
import { JSONSchemaFormat, JSONSchemaContentEncoding } from '@orpc/openapi';
|
3
3
|
import { registry, globalRegistry } from 'zod/v4/core';
|
4
4
|
|
@@ -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.
|
170
|
-
|
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();
|
@@ -287,12 +274,14 @@ const experimental_JSON_SCHEMA_OUTPUT_REGISTRY = registry();
|
|
287
274
|
|
288
275
|
class experimental_ZodToJsonSchemaConverter {
|
289
276
|
maxLazyDepth;
|
277
|
+
maxStructureDepth;
|
290
278
|
anyJsonSchema;
|
291
279
|
unsupportedJsonSchema;
|
292
280
|
undefinedJsonSchema;
|
293
281
|
interceptors;
|
294
282
|
constructor(options = {}) {
|
295
283
|
this.maxLazyDepth = options.maxLazyDepth ?? 2;
|
284
|
+
this.maxStructureDepth = options.maxStructureDepth ?? 10;
|
296
285
|
this.anyJsonSchema = options.anyJsonSchema ?? {};
|
297
286
|
this.unsupportedJsonSchema = options.unsupportedJsonSchema ?? { not: {} };
|
298
287
|
this.undefinedJsonSchema = options.undefinedJsonSchema ?? { not: {} };
|
@@ -302,17 +291,28 @@ class experimental_ZodToJsonSchemaConverter {
|
|
302
291
|
return schema !== void 0 && schema["~standard"].vendor === "zod";
|
303
292
|
}
|
304
293
|
convert(schema, options) {
|
305
|
-
return this.#convert(schema, options, 0);
|
294
|
+
return this.#convert(schema, options, 0, 0);
|
306
295
|
}
|
307
|
-
#convert(schema, options, lazyDepth, isHandledCustomJSONSchema = false) {
|
296
|
+
#convert(schema, options, lazyDepth, structureDepth, isHandledCustomJSONSchema = false) {
|
308
297
|
return intercept(
|
309
298
|
this.interceptors,
|
310
299
|
{ schema, options, lazyDepth, isHandledCustomJSONSchema },
|
311
|
-
|
300
|
+
({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
|
301
|
+
if (structureDepth > this.maxStructureDepth) {
|
302
|
+
return [false, this.anyJsonSchema];
|
303
|
+
}
|
304
|
+
if (!options2.minStructureDepthForRef || options2.minStructureDepthForRef <= structureDepth) {
|
305
|
+
const components = toArray(options2.components);
|
306
|
+
for (const component of components) {
|
307
|
+
if (component.schema === schema2 && component.allowedStrategies.includes(options2.strategy)) {
|
308
|
+
return [component.required, { $ref: component.ref }];
|
309
|
+
}
|
310
|
+
}
|
311
|
+
}
|
312
312
|
if (!isHandledCustomJSONSchema2) {
|
313
313
|
const customJSONSchema = this.#getCustomJsonSchema(schema2, options2);
|
314
314
|
if (customJSONSchema) {
|
315
|
-
const [required, json] =
|
315
|
+
const [required, json] = this.#convert(schema2, options2, lazyDepth2, structureDepth, true);
|
316
316
|
return [required, { ...json, ...customJSONSchema }];
|
317
317
|
}
|
318
318
|
}
|
@@ -320,21 +320,28 @@ class experimental_ZodToJsonSchemaConverter {
|
|
320
320
|
case "string": {
|
321
321
|
const string = schema2;
|
322
322
|
const json = { type: "string" };
|
323
|
-
const { minimum, maximum, format,
|
324
|
-
if (minimum
|
323
|
+
const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
|
324
|
+
if (typeof minimum === "number") {
|
325
325
|
json.minLength = minimum;
|
326
326
|
}
|
327
|
-
if (maximum
|
327
|
+
if (typeof maximum === "number") {
|
328
328
|
json.maxLength = maximum;
|
329
329
|
}
|
330
|
-
if (contentEncoding
|
330
|
+
if (typeof contentEncoding === "string") {
|
331
331
|
json.contentEncoding = this.#handleContentEncoding(contentEncoding);
|
332
332
|
}
|
333
|
-
if (format
|
333
|
+
if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
|
334
334
|
json.format = this.#handleStringFormat(format);
|
335
335
|
}
|
336
|
-
if (
|
337
|
-
|
336
|
+
if (patterns instanceof Set && json.contentEncoding === void 0 && json.format === void 0) {
|
337
|
+
for (const pattern of patterns) {
|
338
|
+
if (json.pattern === void 0) {
|
339
|
+
json.pattern = pattern.source;
|
340
|
+
} else {
|
341
|
+
json.allOf ??= [];
|
342
|
+
json.allOf.push({ pattern: pattern.source });
|
343
|
+
}
|
344
|
+
}
|
338
345
|
}
|
339
346
|
if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
|
340
347
|
json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
|
@@ -344,25 +351,23 @@ class experimental_ZodToJsonSchemaConverter {
|
|
344
351
|
case "number": {
|
345
352
|
const number = schema2;
|
346
353
|
const json = { type: "number" };
|
347
|
-
const { minimum, maximum, format, multipleOf,
|
348
|
-
if (format?.includes("int")) {
|
354
|
+
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = number._zod.bag;
|
355
|
+
if (typeof format === "string" && format?.includes("int")) {
|
349
356
|
json.type = "integer";
|
350
357
|
}
|
351
|
-
if (minimum
|
352
|
-
|
353
|
-
json.minimum = minimum;
|
354
|
-
} else {
|
355
|
-
json.exclusiveMinimum = minimum;
|
356
|
-
}
|
358
|
+
if (typeof minimum === "number") {
|
359
|
+
json.minimum = minimum;
|
357
360
|
}
|
358
|
-
if (maximum
|
359
|
-
|
360
|
-
json.maximum = maximum;
|
361
|
-
} else {
|
362
|
-
json.exclusiveMaximum = maximum;
|
363
|
-
}
|
361
|
+
if (typeof maximum === "number") {
|
362
|
+
json.maximum = maximum;
|
364
363
|
}
|
365
|
-
if (
|
364
|
+
if (typeof exclusiveMinimum === "number") {
|
365
|
+
json.exclusiveMinimum = exclusiveMinimum;
|
366
|
+
}
|
367
|
+
if (typeof exclusiveMaximum === "number") {
|
368
|
+
json.exclusiveMaximum = exclusiveMaximum;
|
369
|
+
}
|
370
|
+
if (typeof multipleOf === "number") {
|
366
371
|
json.multipleOf = multipleOf;
|
367
372
|
}
|
368
373
|
return [true, json];
|
@@ -395,21 +400,21 @@ class experimental_ZodToJsonSchemaConverter {
|
|
395
400
|
case "array": {
|
396
401
|
const array = schema2;
|
397
402
|
const json = { type: "array" };
|
398
|
-
const { minimum, maximum } = array._zod.
|
399
|
-
if (minimum
|
403
|
+
const { minimum, maximum } = array._zod.bag;
|
404
|
+
if (typeof minimum === "number") {
|
400
405
|
json.minItems = minimum;
|
401
406
|
}
|
402
|
-
if (maximum
|
407
|
+
if (typeof maximum === "number") {
|
403
408
|
json.maxItems = maximum;
|
404
409
|
}
|
405
|
-
json.items = this.#handleArrayItemJsonSchema(
|
410
|
+
json.items = this.#handleArrayItemJsonSchema(this.#convert(array._zod.def.element, options2, lazyDepth2, structureDepth + 1), options2);
|
406
411
|
return [true, json];
|
407
412
|
}
|
408
413
|
case "object": {
|
409
414
|
const object = schema2;
|
410
415
|
const json = { type: "object" };
|
411
416
|
for (const [key, value] of Object.entries(object._zod.def.shape)) {
|
412
|
-
const [itemRequired, itemJson] =
|
417
|
+
const [itemRequired, itemJson] = this.#convert(value, options2, lazyDepth2, structureDepth + 1);
|
413
418
|
json.properties ??= {};
|
414
419
|
json.properties[key] = itemJson;
|
415
420
|
if (itemRequired) {
|
@@ -421,7 +426,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
421
426
|
if (object._zod.def.catchall._zod.def.type === "never") {
|
422
427
|
json.additionalProperties = false;
|
423
428
|
} else {
|
424
|
-
const [_, addJson] =
|
429
|
+
const [_, addJson] = this.#convert(object._zod.def.catchall, options2, lazyDepth2, structureDepth + 1);
|
425
430
|
json.additionalProperties = addJson;
|
426
431
|
}
|
427
432
|
}
|
@@ -432,7 +437,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
432
437
|
const anyOf = [];
|
433
438
|
let required = true;
|
434
439
|
for (const item of union._zod.def.options) {
|
435
|
-
const [itemRequired, itemJson] =
|
440
|
+
const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth);
|
436
441
|
if (!itemRequired) {
|
437
442
|
required = false;
|
438
443
|
}
|
@@ -453,7 +458,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
453
458
|
const json = { allOf: [] };
|
454
459
|
let required = false;
|
455
460
|
for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
|
456
|
-
const [itemRequired, itemJson] =
|
461
|
+
const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth);
|
457
462
|
json.allOf.push(itemJson);
|
458
463
|
if (itemRequired) {
|
459
464
|
required = true;
|
@@ -465,16 +470,16 @@ class experimental_ZodToJsonSchemaConverter {
|
|
465
470
|
const tuple = schema2;
|
466
471
|
const json = { type: "array", prefixItems: [] };
|
467
472
|
for (const item of tuple._zod.def.items) {
|
468
|
-
json.prefixItems.push(this.#handleArrayItemJsonSchema(
|
473
|
+
json.prefixItems.push(this.#handleArrayItemJsonSchema(this.#convert(item, options2, lazyDepth2, structureDepth + 1), options2));
|
469
474
|
}
|
470
475
|
if (tuple._zod.def.rest) {
|
471
|
-
json.items = this.#handleArrayItemJsonSchema(
|
476
|
+
json.items = this.#handleArrayItemJsonSchema(this.#convert(tuple._zod.def.rest, options2, lazyDepth2, structureDepth + 1), options2);
|
472
477
|
}
|
473
|
-
const { minimum, maximum } = tuple._zod.
|
474
|
-
if (minimum
|
478
|
+
const { minimum, maximum } = tuple._zod.bag;
|
479
|
+
if (typeof minimum === "number") {
|
475
480
|
json.minItems = minimum;
|
476
481
|
}
|
477
|
-
if (maximum
|
482
|
+
if (typeof maximum === "number") {
|
478
483
|
json.maxItems = maximum;
|
479
484
|
}
|
480
485
|
return [true, json];
|
@@ -482,8 +487,8 @@ class experimental_ZodToJsonSchemaConverter {
|
|
482
487
|
case "record": {
|
483
488
|
const record = schema2;
|
484
489
|
const json = { type: "object" };
|
485
|
-
json.propertyNames =
|
486
|
-
json.additionalProperties =
|
490
|
+
json.propertyNames = this.#convert(record._zod.def.keyType, options2, lazyDepth2, structureDepth + 1)[1];
|
491
|
+
json.additionalProperties = this.#convert(record._zod.def.valueType, options2, lazyDepth2, structureDepth + 1)[1];
|
487
492
|
return [true, json];
|
488
493
|
}
|
489
494
|
case "map": {
|
@@ -493,8 +498,8 @@ class experimental_ZodToJsonSchemaConverter {
|
|
493
498
|
items: {
|
494
499
|
type: "array",
|
495
500
|
prefixItems: [
|
496
|
-
this.#handleArrayItemJsonSchema(
|
497
|
-
this.#handleArrayItemJsonSchema(
|
501
|
+
this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.keyType, options2, lazyDepth2, structureDepth + 1), options2),
|
502
|
+
this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2)
|
498
503
|
],
|
499
504
|
maxItems: 2,
|
500
505
|
minItems: 2
|
@@ -506,7 +511,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
506
511
|
return [true, {
|
507
512
|
type: "array",
|
508
513
|
uniqueItems: true,
|
509
|
-
items: this.#handleArrayItemJsonSchema(
|
514
|
+
items: this.#handleArrayItemJsonSchema(this.#convert(set._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2)
|
510
515
|
}];
|
511
516
|
}
|
512
517
|
case "enum": {
|
@@ -530,12 +535,14 @@ class experimental_ZodToJsonSchemaConverter {
|
|
530
535
|
case "file": {
|
531
536
|
const file = schema2;
|
532
537
|
const oneOf = [];
|
533
|
-
const { mime } = file._zod.
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
538
|
+
const { mime } = file._zod.bag;
|
539
|
+
if (mime === void 0 || Array.isArray(mime) && mime.every((m) => typeof m === "string")) {
|
540
|
+
for (const type of mime ?? ["*/*"]) {
|
541
|
+
oneOf.push({
|
542
|
+
type: "string",
|
543
|
+
contentMediaType: type
|
544
|
+
});
|
545
|
+
}
|
539
546
|
}
|
540
547
|
return [true, oneOf.length === 1 ? oneOf[0] : { anyOf: oneOf }];
|
541
548
|
}
|
@@ -544,12 +551,12 @@ class experimental_ZodToJsonSchemaConverter {
|
|
544
551
|
}
|
545
552
|
case "nullable": {
|
546
553
|
const nullable = schema2;
|
547
|
-
const [required, json] =
|
554
|
+
const [required, json] = this.#convert(nullable._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
548
555
|
return [required, { anyOf: [json, { type: "null" }] }];
|
549
556
|
}
|
550
557
|
case "nonoptional": {
|
551
558
|
const nonoptional = schema2;
|
552
|
-
const [, json] =
|
559
|
+
const [, json] = this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
553
560
|
return [true, json];
|
554
561
|
}
|
555
562
|
case "success": {
|
@@ -558,7 +565,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
558
565
|
case "default":
|
559
566
|
case "prefault": {
|
560
567
|
const default_ = schema2;
|
561
|
-
const [, json] =
|
568
|
+
const [, json] = this.#convert(default_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
562
569
|
return [false, {
|
563
570
|
...json,
|
564
571
|
default: default_._zod.def.defaultValue
|
@@ -566,18 +573,18 @@ class experimental_ZodToJsonSchemaConverter {
|
|
566
573
|
}
|
567
574
|
case "catch": {
|
568
575
|
const catch_ = schema2;
|
569
|
-
return
|
576
|
+
return this.#convert(catch_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
570
577
|
}
|
571
578
|
case "nan": {
|
572
579
|
return [true, options2.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
|
573
580
|
}
|
574
581
|
case "pipe": {
|
575
582
|
const pipe = schema2;
|
576
|
-
return
|
583
|
+
return this.#convert(options2.strategy === "input" ? pipe._zod.def.in : pipe._zod.def.out, options2, lazyDepth2, structureDepth);
|
577
584
|
}
|
578
585
|
case "readonly": {
|
579
586
|
const readonly_ = schema2;
|
580
|
-
const [required, json] =
|
587
|
+
const [required, json] = this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
581
588
|
return [required, { ...json, readOnly: true }];
|
582
589
|
}
|
583
590
|
case "template_literal": {
|
@@ -589,15 +596,16 @@ class experimental_ZodToJsonSchemaConverter {
|
|
589
596
|
}
|
590
597
|
case "optional": {
|
591
598
|
const optional = schema2;
|
592
|
-
const [, json] =
|
599
|
+
const [, json] = this.#convert(optional._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
593
600
|
return [false, json];
|
594
601
|
}
|
595
602
|
case "lazy": {
|
596
603
|
const lazy = schema2;
|
597
|
-
|
604
|
+
const currentLazyDepth = lazyDepth2 + 1;
|
605
|
+
if (currentLazyDepth > this.maxLazyDepth) {
|
598
606
|
return [false, this.anyJsonSchema];
|
599
607
|
}
|
600
|
-
return
|
608
|
+
return this.#convert(lazy._zod.def.getter(), options2, currentLazyDepth, structureDepth);
|
601
609
|
}
|
602
610
|
default: {
|
603
611
|
schema2._zod.def.type;
|
@@ -621,7 +629,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
621
629
|
if (global) {
|
622
630
|
return {
|
623
631
|
description: global.description,
|
624
|
-
examples: global.examples
|
632
|
+
examples: Array.isArray(global.examples) ? global.examples : void 0
|
625
633
|
};
|
626
634
|
}
|
627
635
|
}
|
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.
|
4
|
+
"version": "0.0.0-next.fc23c8d",
|
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/contract": "0.0.0-next.
|
34
|
-
"@orpc/server": "0.0.0-next.
|
33
|
+
"@orpc/contract": "0.0.0-next.fc23c8d",
|
34
|
+
"@orpc/server": "0.0.0-next.fc23c8d"
|
35
35
|
},
|
36
36
|
"dependencies": {
|
37
37
|
"escape-string-regexp": "^5.0.0",
|
38
38
|
"wildcard-match": "^5.1.3",
|
39
|
-
"@orpc/
|
40
|
-
"@orpc/
|
39
|
+
"@orpc/shared": "0.0.0-next.fc23c8d",
|
40
|
+
"@orpc/openapi": "0.0.0-next.fc23c8d"
|
41
41
|
},
|
42
42
|
"devDependencies": {
|
43
|
-
"zod": "3.25.
|
43
|
+
"zod": "^3.25.67",
|
44
44
|
"zod-to-json-schema": "^3.24.5"
|
45
45
|
},
|
46
46
|
"scripts": {
|