Skip to content

Commit 594f3a6

Browse files
author
Lubos ​
committed
fix(zod): support tuple types
1 parent 3d0aeb8 commit 594f3a6

File tree

8 files changed

+170
-49
lines changed

8 files changed

+170
-49
lines changed

.changeset/hot-wolves-wait.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(parser): filter orphans only when there are some operations

.changeset/spicy-wombats-allow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(zod): support tuple types

packages/openapi-ts-tests/test/__snapshots__/3.0.x/plugins/zod/default/zod.gen.ts

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,10 @@ export const zModelWithOneOfEnum = z.union([
818818
])
819819
}),
820820
z.object({
821-
content: z.unknown(),
821+
content: z.tuple([
822+
z.string().datetime(),
823+
z.string().datetime()
824+
]),
822825
foo: z.enum([
823826
'Corge'
824827
])
@@ -849,21 +852,70 @@ export const zModelWithNestedCompositionEnums = z.object({
849852
foo: zModelWithNestedArrayEnumsDataFoo.optional()
850853
});
851854

852-
export const zModelWithConstantSizeArray = z.unknown();
855+
export const zModelWithConstantSizeArray = z.tuple([
856+
z.number(),
857+
z.number()
858+
]);
853859

854-
export const zModelWithAnyOfConstantSizeArray = z.unknown();
860+
export const zModelWithAnyOfConstantSizeArray = z.tuple([
861+
z.union([
862+
z.number(),
863+
z.string()
864+
]),
865+
z.union([
866+
z.number(),
867+
z.string()
868+
]),
869+
z.union([
870+
z.number(),
871+
z.string()
872+
])
873+
]);
855874

856875
export const zModelWithPrefixItemsConstantSizeArray = z.array(z.union([
857876
zModelWithInteger,
858877
z.number(),
859878
z.string()
860879
]));
861880

862-
export const zModelWithAnyOfConstantSizeArrayNullable = z.unknown();
881+
export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([
882+
z.union([
883+
z.number(),
884+
z.null(),
885+
z.string()
886+
]),
887+
z.union([
888+
z.number(),
889+
z.null(),
890+
z.string()
891+
]),
892+
z.union([
893+
z.number(),
894+
z.null(),
895+
z.string()
896+
])
897+
]);
863898

864-
export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.unknown();
899+
/**
900+
* Model with restricted keyword name
901+
*/
902+
export const zImport = z.string();
903+
904+
export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([
905+
z.union([
906+
z.number(),
907+
zImport
908+
]),
909+
z.union([
910+
z.number(),
911+
zImport
912+
])
913+
]);
865914

866-
export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.unknown();
915+
export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([
916+
z.intersection(z.number(), z.string()),
917+
z.intersection(z.number(), z.string())
918+
]);
867919

868920
export const zModelWithNumericEnumUnion = z.object({
869921
value: z.unknown().optional()
@@ -912,11 +964,6 @@ export const zDeleteFooData = z.string();
912964
*/
913965
export const zDeleteFooData2 = z.string();
914966

915-
/**
916-
* Model with restricted keyword name
917-
*/
918-
export const zImport = z.string();
919-
920967
export const zSchemaWithFormRestrictedKeys = z.object({
921968
description: z.string().optional(),
922969
'x-enum-descriptions': z.string().optional(),

packages/openapi-ts-tests/test/__snapshots__/3.1.x/plugins/zod/default/zod.gen.ts

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,10 @@ export const zModelWithOneOfEnum = z.union([
815815
])
816816
}),
817817
z.object({
818-
content: z.unknown(),
818+
content: z.tuple([
819+
z.string().datetime(),
820+
z.string()
821+
]),
819822
foo: z.enum([
820823
'Corge'
821824
])
@@ -846,17 +849,73 @@ export const zModelWithNestedCompositionEnums = z.object({
846849
foo: zModelWithNestedArrayEnumsDataFoo.optional()
847850
});
848851

849-
export const zModelWithConstantSizeArray = z.unknown();
852+
export const zModelWithConstantSizeArray = z.tuple([
853+
z.number(),
854+
z.number()
855+
]);
856+
857+
export const zModelWithAnyOfConstantSizeArray = z.tuple([
858+
z.union([
859+
z.number(),
860+
z.string()
861+
]),
862+
z.union([
863+
z.number(),
864+
z.string()
865+
]),
866+
z.union([
867+
z.number(),
868+
z.string()
869+
])
870+
]);
850871

851-
export const zModelWithAnyOfConstantSizeArray = z.unknown();
872+
export const zModelWithPrefixItemsConstantSizeArray = z.tuple([
873+
zModelWithInteger,
874+
z.union([
875+
z.number(),
876+
z.string()
877+
]),
878+
z.string()
879+
]);
852880

853-
export const zModelWithPrefixItemsConstantSizeArray = z.unknown();
881+
export const zModelWithAnyOfConstantSizeArrayNullable = z.tuple([
882+
z.union([
883+
z.number(),
884+
z.null(),
885+
z.string()
886+
]),
887+
z.union([
888+
z.number(),
889+
z.null(),
890+
z.string()
891+
]),
892+
z.union([
893+
z.number(),
894+
z.null(),
895+
z.string()
896+
])
897+
]);
854898

855-
export const zModelWithAnyOfConstantSizeArrayNullable = z.unknown();
899+
/**
900+
* Model with restricted keyword name
901+
*/
902+
export const zImport = z.string();
856903

857-
export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.unknown();
904+
export const zModelWithAnyOfConstantSizeArrayWithNSizeAndOptions = z.tuple([
905+
z.union([
906+
z.number(),
907+
zImport
908+
]),
909+
z.union([
910+
z.number(),
911+
zImport
912+
])
913+
]);
858914

859-
export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.unknown();
915+
export const zModelWithAnyOfConstantSizeArrayAndIntersect = z.tuple([
916+
z.intersection(z.number(), z.string()),
917+
z.intersection(z.number(), z.string())
918+
]);
860919

861920
export const zModelWithNumericEnumUnion = z.object({
862921
value: z.unknown().optional()
@@ -905,11 +964,6 @@ export const zDeleteFooData = z.string();
905964
*/
906965
export const zDeleteFooData2 = z.string();
907966

908-
/**
909-
* Model with restricted keyword name
910-
*/
911-
export const zImport = z.string();
912-
913967
export const zSchemaWithFormRestrictedKeys = z.object({
914968
description: z.string().optional(),
915969
'x-enum-descriptions': z.string().optional(),

packages/openapi-ts-tests/test/openapi-ts.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ export default defineConfig(() => {
3131
},
3232
// orphans: false,
3333
// preserveOrder: true,
34+
// schemas: {
35+
// include: ['Foo'],
36+
// },
3437
// tags: {
3538
// exclude: ['bar'],
3639
// },
@@ -51,7 +54,7 @@ export default defineConfig(() => {
5154
// 'invalid',
5255
// 'servers-entry.yaml',
5356
// ),
54-
path: path.resolve(__dirname, 'spec', '3.1.x', 'validators.yaml'),
57+
path: path.resolve(__dirname, 'spec', '3.1.x', 'full.yaml'),
5558
// path: 'http://localhost:4000/',
5659
// path: 'https://get.heyapi.dev/',
5760
// path: 'https://get.heyapi.dev/hey-api/backend?branch=main&version=1.0.0',
@@ -150,7 +153,7 @@ export default defineConfig(() => {
150153
{
151154
// comments: false,
152155
// exportFromIndex: true,
153-
metadata: true,
156+
// metadata: true,
154157
name: 'zod',
155158
},
156159
],

packages/openapi-ts/src/openApi/shared/utils/filter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ export const createFilteredDependencies = ({
938938
schemas,
939939
});
940940

941-
if (!filters.orphans) {
941+
if (!filters.orphans && operations.size) {
942942
const { operationDependencies } = collectOperationDependencies({
943943
graph,
944944
operations,

packages/openapi-ts/src/plugins/zod/plugin.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,13 @@ const stringTypeToZodSchema = ({
609609

610610
const tupleTypeToZodSchema = ({
611611
context,
612+
plugin,
613+
result,
612614
schema,
613615
}: {
614616
context: IR.Context;
617+
plugin: Plugin.Instance<Config>;
618+
result: Result;
615619
schema: SchemaWithType<'tuple'>;
616620
}) => {
617621
if (schema.const && Array.isArray(schema.const)) {
@@ -638,30 +642,31 @@ const tupleTypeToZodSchema = ({
638642
return expression;
639643
}
640644

641-
// TODO: parser - handle tuple items
642-
// const itemTypes: Array<ts.TypeNode> = [];
643-
644-
// for (const item of schema.items ?? []) {
645-
// itemTypes.push(
646-
// schemaToType({
647-
// context,
648-
// namespace,
649-
// plugin,
650-
// schema: item,
651-
// }),
652-
// );
653-
// }
645+
const tupleElements: Array<ts.Expression> = [];
654646

655-
// return compiler.typeTupleNode({
656-
// types: itemTypes,
657-
// });
647+
for (const item of schema.items ?? []) {
648+
tupleElements.push(
649+
schemaToZodSchema({
650+
context,
651+
plugin,
652+
result,
653+
schema: item,
654+
}),
655+
);
656+
}
658657

659-
return unknownTypeToZodSchema({
660-
context,
661-
schema: {
662-
type: 'unknown',
663-
},
658+
const expression = compiler.callExpression({
659+
functionName: compiler.propertyAccessExpression({
660+
expression: zIdentifier,
661+
name: compiler.identifier({ text: 'tuple' }),
662+
}),
663+
parameters: [
664+
compiler.arrayLiteralExpression({
665+
elements: tupleElements,
666+
}),
667+
],
664668
});
669+
return expression;
665670
};
666671

667672
const undefinedTypeToZodSchema = ({
@@ -790,6 +795,8 @@ const schemaTypeToZodSchema = ({
790795
return {
791796
expression: tupleTypeToZodSchema({
792797
context,
798+
plugin,
799+
result,
793800
schema: schema as SchemaWithType<'tuple'>,
794801
}),
795802
};

packages/openapi-ts/src/types/input.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ export interface Filters {
140140
include?: ReadonlyArray<string>;
141141
};
142142
/**
143-
* Keep reusable components without any references in the output? By
144-
* default, we exclude orphaned resources.
143+
* Keep reusable components without any references from operations in the
144+
* output? By default, we exclude orphaned resources.
145145
*
146146
* @default false
147147
*/

0 commit comments

Comments
 (0)