Skip to content

Commit a30764a

Browse files
committed
support union types for zod generator
1 parent 8109f45 commit a30764a

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/zod/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
InputObjectTypeDefinitionNode,
99
ObjectTypeDefinitionNode,
1010
EnumTypeDefinitionNode,
11+
UnionTypeDefinitionNode,
1112
FieldDefinitionNode,
1213
} from 'graphql';
1314
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
@@ -100,6 +101,18 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
100101
.withName(`${enumname}Schema`)
101102
.withContent(`z.nativeEnum(${enumname})`).string;
102103
},
104+
UnionTypeDefinition: (node: UnionTypeDefinitionNode) => {
105+
const unionName = tsVisitor.convertName(node.name.value);
106+
const unionElements = node.types?.map(t => `${t.name.value}Schema()`).join(', ');
107+
108+
const result = new DeclarationBlock({})
109+
.export()
110+
.asKind('function')
111+
.withName(`${unionName}Schema()`)
112+
.withBlock(indent(`return z.union([${unionElements}])`));
113+
114+
return result.string;
115+
},
103116
};
104117
};
105118

tests/zod.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,37 @@ describe('zod', () => {
636636
expect(result.content).not.toContain(wantNotContain);
637637
}
638638
});
639+
640+
it('generate union types', async () => {
641+
const schema = buildSchema(/* GraphQL */ `
642+
type Square {
643+
size: Int
644+
}
645+
type Circle {
646+
radius: Int
647+
}
648+
union Shape = Circle | Square
649+
`);
650+
651+
const result = await plugin(
652+
schema,
653+
[],
654+
{
655+
schema: 'zod',
656+
withObjectType: true,
657+
},
658+
{}
659+
);
660+
661+
const wantContains = [
662+
// Shape Schema
663+
'export function ShapeSchema() {',
664+
'z.union([CircleSchema(), SquareSchema()])',
665+
];
666+
for (const wantContain of wantContains) {
667+
expect(result.content).toContain(wantContain);
668+
}
669+
});
639670
});
640671

641672
it('properly generates custom directive values', async () => {

0 commit comments

Comments
 (0)