Skip to content

Commit 3ed4ebb

Browse files
committed
feat: support unions exporting
as const
1 parent 7f078b0 commit 3ed4ebb

File tree

6 files changed

+197
-40
lines changed

6 files changed

+197
-40
lines changed

src/myzod/index.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
2-
import { ValidationSchemaPluginConfig } from '../config';
1+
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
32
import {
4-
InputValueDefinitionNode,
5-
NameNode,
6-
TypeNode,
3+
EnumTypeDefinitionNode,
4+
FieldDefinitionNode,
75
GraphQLSchema,
86
InputObjectTypeDefinitionNode,
7+
InputValueDefinitionNode,
8+
NameNode,
99
ObjectTypeDefinitionNode,
10-
EnumTypeDefinitionNode,
11-
FieldDefinitionNode,
10+
TypeNode,
1211
UnionTypeDefinitionNode,
1312
} from 'graphql';
14-
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15-
import { Visitor } from '../visitor';
13+
import { ValidationSchemaPluginConfig } from '../config';
1614
import { buildApi, formatDirectiveConfig } from '../directive';
1715
import { SchemaVisitor } from '../types';
16+
import { Visitor } from '../visitor';
17+
import { ObjectTypeDefinitionBuilder, isInput, isListType, isNamedType, isNonNullType } from './../graphql';
1818

1919
const importZod = `import * as myzod from 'myzod'`;
2020
const anySchema = `definedNonNullAnySchema`;
@@ -144,16 +144,32 @@ export const MyZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSche
144144
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
145145
return `${element}Schema`;
146146
}
147-
return `${element}Schema()`;
147+
switch (config.validationSchemaExportType) {
148+
case 'const':
149+
return `${element}Schema`;
150+
case 'function':
151+
default:
152+
return `${element}Schema()`;
153+
}
148154
})
149155
.join(', ');
150156
const unionElementsCount = node.types?.length ?? 0;
151157

152158
const union =
153159
unionElementsCount > 1 ? indent(`return myzod.union([${unionElements}])`) : indent(`return ${unionElements}`);
154160

155-
return new DeclarationBlock({}).export().asKind('function').withName(`${unionName}Schema()`).withBlock(union)
156-
.string;
161+
switch (config.validationSchemaExportType) {
162+
case 'const':
163+
return new DeclarationBlock({}).export().asKind('const').withName(`${unionName}Schema`).withBlock(union)
164+
.string;
165+
case 'function':
166+
default:
167+
return new DeclarationBlock({})
168+
.export()
169+
.asKind('function')
170+
.withName(`${unionName}Schema()`)
171+
.withBlock(union).string;
172+
}
157173
},
158174
},
159175
};

src/yup/index.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
2-
import { ValidationSchemaPluginConfig } from '../config';
1+
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
32
import {
4-
InputValueDefinitionNode,
5-
NameNode,
6-
TypeNode,
3+
EnumTypeDefinitionNode,
4+
FieldDefinitionNode,
75
GraphQLSchema,
86
InputObjectTypeDefinitionNode,
9-
EnumTypeDefinitionNode,
7+
InputValueDefinitionNode,
8+
NameNode,
109
ObjectTypeDefinitionNode,
11-
FieldDefinitionNode,
10+
TypeNode,
1211
UnionTypeDefinitionNode,
1312
} from 'graphql';
14-
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15-
import { Visitor } from '../visitor';
13+
import { ValidationSchemaPluginConfig } from '../config';
1614
import { buildApi, formatDirectiveConfig } from '../directive';
1715
import { SchemaVisitor } from '../types';
16+
import { Visitor } from '../visitor';
17+
import { ObjectTypeDefinitionBuilder, isInput, isListType, isNamedType, isNonNullType } from './../graphql';
1818

1919
const importYup = `import * as yup from 'yup'`;
2020

@@ -178,16 +178,32 @@ export const YupSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
178178
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
179179
return `${element}Schema`;
180180
}
181-
return `${element}Schema()`;
181+
switch (config.validationSchemaExportType) {
182+
case 'const':
183+
return `${element}Schema`;
184+
case 'function':
185+
default:
186+
return `${element}Schema()`;
187+
}
182188
})
183189
.join(', ');
184190
const union = indent(`return union<${unionName}>(${unionElements})`);
185191

186-
return new DeclarationBlock({})
187-
.export()
188-
.asKind('function')
189-
.withName(`${unionName}Schema(): yup.MixedSchema<${unionName}>`)
190-
.withBlock(union).string;
192+
switch (config.validationSchemaExportType) {
193+
case 'const':
194+
return new DeclarationBlock({})
195+
.export()
196+
.asKind('const')
197+
.withName(`${unionName}Schema: yup.MixedSchema<${unionName}>`)
198+
.withBlock(union).string;
199+
case 'function':
200+
default:
201+
return new DeclarationBlock({})
202+
.export()
203+
.asKind('function')
204+
.withName(`${unionName}Schema(): yup.MixedSchema<${unionName}>`)
205+
.withBlock(union).string;
206+
}
191207
},
192208
},
193209
// ScalarTypeDefinition: (node) => {

src/zod/index.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { isInput, isNonNullType, isListType, isNamedType, ObjectTypeDefinitionBuilder } from './../graphql';
2-
import { ValidationSchemaPluginConfig } from '../config';
1+
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
32
import {
4-
InputValueDefinitionNode,
5-
NameNode,
6-
TypeNode,
3+
EnumTypeDefinitionNode,
4+
FieldDefinitionNode,
75
GraphQLSchema,
86
InputObjectTypeDefinitionNode,
7+
InputValueDefinitionNode,
8+
NameNode,
99
ObjectTypeDefinitionNode,
10-
EnumTypeDefinitionNode,
10+
TypeNode,
1111
UnionTypeDefinitionNode,
12-
FieldDefinitionNode,
1312
} from 'graphql';
14-
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15-
import { Visitor } from '../visitor';
13+
import { ValidationSchemaPluginConfig } from '../config';
1614
import { buildApi, formatDirectiveConfig } from '../directive';
1715
import { SchemaVisitor } from '../types';
16+
import { Visitor } from '../visitor';
17+
import { ObjectTypeDefinitionBuilder, isInput, isListType, isNamedType, isNonNullType } from './../graphql';
1818

1919
const importZod = `import { z } from 'zod'`;
2020
const anySchema = `definedNonNullAnySchema`;
@@ -154,16 +154,32 @@ export const ZodSchemaVisitor = (schema: GraphQLSchema, config: ValidationSchema
154154
if (typ?.astNode?.kind === 'EnumTypeDefinition') {
155155
return `${element}Schema`;
156156
}
157-
return `${element}Schema()`;
157+
switch (config.validationSchemaExportType) {
158+
case 'const':
159+
return `${element}Schema`;
160+
case 'function':
161+
default:
162+
return `${element}Schema()`;
163+
}
158164
})
159165
.join(', ');
160166
const unionElementsCount = node.types.length ?? 0;
161167

162168
const union =
163169
unionElementsCount > 1 ? indent(`return z.union([${unionElements}])`) : indent(`return ${unionElements}`);
164170

165-
return new DeclarationBlock({}).export().asKind('function').withName(`${unionName}Schema()`).withBlock(union)
166-
.string;
171+
switch (config.validationSchemaExportType) {
172+
case 'const':
173+
return new DeclarationBlock({}).export().asKind('const').withName(`${unionName}Schema`).withBlock(union)
174+
.string;
175+
case 'function':
176+
default:
177+
return new DeclarationBlock({})
178+
.export()
179+
.asKind('function')
180+
.withName(`${unionName}Schema()`)
181+
.withBlock(union).string;
182+
}
167183
},
168184
},
169185
};

tests/myzod.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,43 @@ describe('myzod', () => {
733733
expect(result.content).toContain(wantContain);
734734
}
735735
});
736+
737+
it('generate union types with single element, export as const', async () => {
738+
const schema = buildSchema(/* GraphQL */ `
739+
type Square {
740+
size: Int
741+
}
742+
type Circle {
743+
radius: Int
744+
}
745+
union Shape = Circle | Square
746+
747+
type Geometry {
748+
shape: Shape
749+
}
750+
`);
751+
752+
const result = await plugin(
753+
schema,
754+
[],
755+
{
756+
schema: 'myzod',
757+
withObjectType: true,
758+
validationSchemaExportType: 'const',
759+
},
760+
{}
761+
);
762+
763+
const wantContains = [
764+
'export const GeometrySchema: myzod.Type<Geometry> = myzod.object({',
765+
"__typename: myzod.literal('Geometry').optional(),",
766+
'shape: ShapeSchema.optional().nullable()',
767+
'}',
768+
];
769+
for (const wantContain of wantContains) {
770+
expect(result.content).toContain(wantContain);
771+
}
772+
});
736773
});
737774

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

tests/yup.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,43 @@ describe('yup', () => {
647647
expect(result.content).toContain(wantContain);
648648
}
649649
});
650+
651+
it('generate union types with single element, export as const', async () => {
652+
const schema = buildSchema(/* GraphQL */ `
653+
type Square {
654+
size: Int
655+
}
656+
type Circle {
657+
radius: Int
658+
}
659+
union Shape = Circle | Square
660+
661+
type Geometry {
662+
shape: Shape
663+
}
664+
`);
665+
666+
const result = await plugin(
667+
schema,
668+
[],
669+
{
670+
schema: 'yup',
671+
withObjectType: true,
672+
validationSchemaExportType: 'const',
673+
},
674+
{}
675+
);
676+
677+
const wantContains = [
678+
'export const GeometrySchema: yup.ObjectSchema<Geometry> = yup.object({',
679+
"__typename: yup.string<'Geometry'>().optional(),",
680+
'shape: ShapeSchema.nullable().optional()',
681+
'})',
682+
];
683+
for (const wantContain of wantContains) {
684+
expect(result.content).toContain(wantContain);
685+
}
686+
});
650687
});
651688

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

tests/zod.spec.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { buildSchema } from 'graphql';
22
import { plugin } from '../src/index';
3-
import { ScalarsMap } from '@graphql-codegen/visitor-plugin-common';
43

54
describe('zod', () => {
65
test.each([
@@ -802,6 +801,42 @@ describe('zod', () => {
802801
expect(result.content).toContain(wantContain);
803802
}
804803
});
804+
805+
it('generate union types with single element, export as const', async () => {
806+
const schema = buildSchema(/* GraphQL */ `
807+
type Square {
808+
size: Int
809+
}
810+
type Circle {
811+
radius: Int
812+
}
813+
union Shape = Circle | Square
814+
815+
type Geometry {
816+
shape: Shape
817+
}
818+
`);
819+
820+
const result = await plugin(
821+
schema,
822+
[],
823+
{
824+
schema: 'zod',
825+
withObjectType: true,
826+
validationSchemaExportType: 'const',
827+
},
828+
{}
829+
);
830+
831+
const wantContains = [
832+
'export const GeometrySchema: z.ZodObject<Properties<Geometry>> = z.object({',
833+
"__typename: z.literal('Geometry').optional(),",
834+
'shape: ShapeSchema.nullish()',
835+
];
836+
for (const wantContain of wantContains) {
837+
expect(result.content).toContain(wantContain);
838+
}
839+
});
805840
});
806841

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

0 commit comments

Comments
 (0)