Skip to content

Commit 1bf4597

Browse files
committed
fix(default-value): add flag to utilize generated enum types for default values
1 parent 5000320 commit 1bf4597

File tree

8 files changed

+4111
-5454
lines changed

8 files changed

+4111
-5454
lines changed

pnpm-lock.yaml

+3,963-5,448
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/config.ts

+16
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,22 @@ export interface ValidationSchemaPluginConfig extends TypeScriptPluginConfig {
210210
* ```
211211
*/
212212
validationSchemaExportType?: ValidationSchemaExportType
213+
/**
214+
* @description Uses the full path of the enum type as the default value instead of the stringified value.
215+
* @default false
216+
*
217+
* @exampleMarkdown
218+
* ```yml
219+
* generates:
220+
* path/to/file.ts:
221+
* plugins:
222+
* - typescript
223+
* - graphql-codegen-validation-schema
224+
* config:
225+
* useEnumTypeAsDefault: true
226+
* ```
227+
*/
228+
useEnumTypeAsDefaultValue?: boolean
213229
/**
214230
* @description Generates validation schema with more API based on directive schema.
215231
* @exampleMarkdown

src/myzod/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
import {
1515
Kind,
1616
} from 'graphql';
17+
import { pascalCase } from "change-case";
1718

1819
import type { ValidationSchemaPluginConfig } from '../config';
1920
import { buildApi, formatDirectiveConfig } from '../directive';
@@ -281,8 +282,13 @@ function generateFieldTypeMyZodSchema(config: ValidationSchemaPluginConfig, visi
281282
if (defaultValue?.kind === Kind.INT || defaultValue?.kind === Kind.FLOAT || defaultValue?.kind === Kind.BOOLEAN)
282283
appliedDirectivesGen = `${appliedDirectivesGen}.default(${defaultValue.value})`;
283284

284-
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM)
285-
appliedDirectivesGen = `${appliedDirectivesGen}.default("${defaultValue.value}")`;
285+
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
286+
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
287+
appliedDirectivesGen = `${appliedDirectivesGen}.default(${visitor.convertName(type.name.value)}.${pascalCase(defaultValue.value)})`;
288+
} else {
289+
appliedDirectivesGen = `${appliedDirectivesGen}.default("${defaultValue.value}")`;
290+
}
291+
}
286292
}
287293

288294
if (isNonNullType(parentType)) {

src/yup/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
import {
1515
Kind,
1616
} from 'graphql';
17+
import { pascalCase } from "change-case";
1718

1819
import type { ValidationSchemaPluginConfig } from '../config';
1920
import { buildApi, formatDirectiveConfig } from '../directive';
@@ -282,8 +283,13 @@ function shapeFields(fields: readonly (FieldDefinitionNode | InputValueDefinitio
282283
)
283284
fieldSchema = `${fieldSchema}.default(${defaultValue.value})`;
284285

285-
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM)
286-
fieldSchema = `${fieldSchema}.default("${defaultValue.value}")`;
286+
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
287+
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
288+
fieldSchema = `${fieldSchema}.default(${visitor.convertName(field.name.value)}.${pascalCase(defaultValue.value)})`;
289+
} else {
290+
fieldSchema = `${fieldSchema}.default("${defaultValue.value}")`;
291+
}
292+
}
287293
}
288294

289295
if (isNonNullType(field.type))

src/zod/index.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
import {
1515
Kind,
1616
} from 'graphql';
17+
import { pascalCase } from "change-case";
1718

1819
import type { ValidationSchemaPluginConfig } from '../config';
1920
import { buildApi, formatDirectiveConfig } from '../directive';
@@ -294,8 +295,13 @@ function generateFieldTypeZodSchema(config: ValidationSchemaPluginConfig, visito
294295
if (defaultValue?.kind === Kind.INT || defaultValue?.kind === Kind.FLOAT || defaultValue?.kind === Kind.BOOLEAN)
295296
appliedDirectivesGen = `${appliedDirectivesGen}.default(${defaultValue.value})`;
296297

297-
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM)
298-
appliedDirectivesGen = `${appliedDirectivesGen}.default("${defaultValue.value}")`;
298+
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
299+
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
300+
appliedDirectivesGen = `${appliedDirectivesGen}.default(${type.name.value}.${pascalCase(defaultValue.value)})`;
301+
} else {
302+
appliedDirectivesGen = `${appliedDirectivesGen}.default("${defaultValue.value}")`;
303+
}
304+
}
299305
}
300306

301307
if (isNonNullType(parentType)) {

tests/myzod.spec.ts

+35
Original file line numberDiff line numberDiff line change
@@ -1168,4 +1168,39 @@ describe('myzod', () => {
11681168
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
11691169
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
11701170
});
1171+
1172+
it('with default input values as enum types', async () => {
1173+
const schema = buildSchema(/* GraphQL */ `
1174+
enum PageType {
1175+
PUBLIC
1176+
BASIC_AUTH
1177+
}
1178+
input PageInput {
1179+
pageType: PageType! = PUBLIC
1180+
greeting: String = "Hello"
1181+
score: Int = 100
1182+
ratio: Float = 0.5
1183+
isMember: Boolean = true
1184+
}
1185+
`);
1186+
const result = await plugin(
1187+
schema,
1188+
[],
1189+
{
1190+
schema: 'myzod',
1191+
importFrom: './types',
1192+
useEnumTypeAsDefaultValue: true,
1193+
},
1194+
{},
1195+
);
1196+
1197+
expect(result.content).toContain('export const PageTypeSchema = myzod.enum(PageType)');
1198+
expect(result.content).toContain('export function PageInputSchema(): myzod.Type<PageInput>');
1199+
1200+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.Public)');
1201+
expect(result.content).toContain('greeting: myzod.string().default("Hello").optional().nullable()');
1202+
expect(result.content).toContain('score: myzod.number().default(100).optional().nullable()');
1203+
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
1204+
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
1205+
});
11711206
});

tests/yup.spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -1102,4 +1102,41 @@ describe('yup', () => {
11021102
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
11031103
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
11041104
});
1105+
1106+
it('with default input values as enum types', async () => {
1107+
const schema = buildSchema(/* GraphQL */ `
1108+
enum PageType {
1109+
PUBLIC
1110+
BASIC_AUTH
1111+
}
1112+
input PageInput {
1113+
pageType: PageType! = PUBLIC
1114+
greeting: String = "Hello"
1115+
score: Int = 100
1116+
ratio: Float = 0.5
1117+
isMember: Boolean = true
1118+
}
1119+
`);
1120+
const result = await plugin(
1121+
schema,
1122+
[],
1123+
{
1124+
schema: 'yup',
1125+
importFrom: './types',
1126+
useEnumTypeAsDefaultValue: true,
1127+
},
1128+
{},
1129+
);
1130+
1131+
expect(result.content).toContain(
1132+
'export const PageTypeSchema = yup.string<PageType>().oneOf(Object.values(PageType)).defined()',
1133+
);
1134+
expect(result.content).toContain('export function PageInputSchema(): yup.ObjectSchema<PageInput>');
1135+
1136+
expect(result.content).toContain('pageType: PageTypeSchema.nonNullable().default(PageType.Public)');
1137+
expect(result.content).toContain('greeting: yup.string().defined().nullable().default("Hello").optional()');
1138+
expect(result.content).toContain('score: yup.number().defined().nullable().default(100).optional()');
1139+
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
1140+
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
1141+
});
11051142
});

tests/zod.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,42 @@ describe('zod', () => {
399399
expect(result.content).toContain('export function SayISchema(): z.ZodObject<Properties<SayI>> {');
400400
});
401401

402+
it('with default input values as enum types', async () => {
403+
const schema = buildSchema(/* GraphQL */ `
404+
enum PageType {
405+
PUBLIC
406+
BASIC_AUTH
407+
}
408+
input PageInput {
409+
pageType: PageType! = PUBLIC
410+
greeting: String = "Hello"
411+
score: Int = 100
412+
ratio: Float = 0.5
413+
isMember: Boolean = true
414+
}
415+
`);
416+
const result = await plugin(
417+
schema,
418+
[],
419+
{
420+
schema: 'zod',
421+
importFrom: './types',
422+
useEnumTypeAsDefaultValue: true,
423+
},
424+
{
425+
},
426+
);
427+
428+
expect(result.content).toContain('export const PageTypeSchema = z.nativeEnum(PageType)');
429+
expect(result.content).toContain('export function PageInputSchema(): z.ZodObject<Properties<PageInput>>');
430+
431+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.Public)');
432+
expect(result.content).toContain('greeting: z.string().default("Hello").nullish()');
433+
expect(result.content).toContain('score: z.number().default(100).nullish()');
434+
expect(result.content).toContain('ratio: z.number().default(0.5).nullish()');
435+
expect(result.content).toContain('isMember: z.boolean().default(true).nullish()');
436+
});
437+
402438
it('with default input values', async () => {
403439
const schema = buildSchema(/* GraphQL */ `
404440
enum PageType {

0 commit comments

Comments
 (0)