Skip to content

Commit e9210e8

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

File tree

8 files changed

+1426
-1749
lines changed

8 files changed

+1426
-1749
lines changed

pnpm-lock.yaml

+1,278-1,743
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';
@@ -283,8 +284,13 @@ function shapeFields(fields: readonly (FieldDefinitionNode | InputValueDefinitio
283284
fieldSchema = `${fieldSchema}.default(${defaultValue.value})`;
284285
}
285286

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

290296
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
@@ -1407,4 +1407,39 @@ describe('myzod', () => {
14071407
"
14081408
`)
14091409
});
1410+
1411+
it('with default input values as enum types', async () => {
1412+
const schema = buildSchema(/* GraphQL */ `
1413+
enum PageType {
1414+
PUBLIC
1415+
BASIC_AUTH
1416+
}
1417+
input PageInput {
1418+
pageType: PageType! = PUBLIC
1419+
greeting: String = "Hello"
1420+
score: Int = 100
1421+
ratio: Float = 0.5
1422+
isMember: Boolean = true
1423+
}
1424+
`);
1425+
const result = await plugin(
1426+
schema,
1427+
[],
1428+
{
1429+
schema: 'myzod',
1430+
importFrom: './types',
1431+
useEnumTypeAsDefaultValue: true,
1432+
},
1433+
{},
1434+
);
1435+
1436+
expect(result.content).toContain('export const PageTypeSchema = myzod.enum(PageType)');
1437+
expect(result.content).toContain('export function PageInputSchema(): myzod.Type<PageInput>');
1438+
1439+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.Public)');
1440+
expect(result.content).toContain('greeting: myzod.string().default("Hello").optional().nullable()');
1441+
expect(result.content).toContain('score: myzod.number().default(100).optional().nullable()');
1442+
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
1443+
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
1444+
});
14101445
});

tests/yup.spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -1431,4 +1431,41 @@ describe('yup', () => {
14311431
"
14321432
`)
14331433
});
1434+
1435+
it('with default input values as enum types', async () => {
1436+
const schema = buildSchema(/* GraphQL */ `
1437+
enum PageType {
1438+
PUBLIC
1439+
BASIC_AUTH
1440+
}
1441+
input PageInput {
1442+
pageType: PageType! = PUBLIC
1443+
greeting: String = "Hello"
1444+
score: Int = 100
1445+
ratio: Float = 0.5
1446+
isMember: Boolean = true
1447+
}
1448+
`);
1449+
const result = await plugin(
1450+
schema,
1451+
[],
1452+
{
1453+
schema: 'yup',
1454+
importFrom: './types',
1455+
useEnumTypeAsDefaultValue: true,
1456+
},
1457+
{},
1458+
);
1459+
1460+
expect(result.content).toContain(
1461+
'export const PageTypeSchema = yup.string<PageType>().oneOf(Object.values(PageType)).defined()',
1462+
);
1463+
expect(result.content).toContain('export function PageInputSchema(): yup.ObjectSchema<PageInput>');
1464+
1465+
expect(result.content).toContain('pageType: PageTypeSchema.nonNullable().default(PageType.Public)');
1466+
expect(result.content).toContain('greeting: yup.string().defined().nullable().default("Hello").optional()');
1467+
expect(result.content).toContain('score: yup.number().defined().nullable().default(100).optional()');
1468+
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
1469+
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
1470+
});
14341471
});

tests/zod.spec.ts

+36
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,42 @@ describe('zod', () => {
530530
`)
531531
});
532532

533+
it('with default input values as enum types', async () => {
534+
const schema = buildSchema(/* GraphQL */ `
535+
enum PageType {
536+
PUBLIC
537+
BASIC_AUTH
538+
}
539+
input PageInput {
540+
pageType: PageType! = PUBLIC
541+
greeting: String = "Hello"
542+
score: Int = 100
543+
ratio: Float = 0.5
544+
isMember: Boolean = true
545+
}
546+
`);
547+
const result = await plugin(
548+
schema,
549+
[],
550+
{
551+
schema: 'zod',
552+
importFrom: './types',
553+
useEnumTypeAsDefaultValue: true,
554+
},
555+
{
556+
},
557+
);
558+
559+
expect(result.content).toContain('export const PageTypeSchema = z.nativeEnum(PageType)');
560+
expect(result.content).toContain('export function PageInputSchema(): z.ZodObject<Properties<PageInput>>');
561+
562+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.Public)');
563+
expect(result.content).toContain('greeting: z.string().default("Hello").nullish()');
564+
expect(result.content).toContain('score: z.number().default(100).nullish()');
565+
expect(result.content).toContain('ratio: z.number().default(0.5).nullish()');
566+
expect(result.content).toContain('isMember: z.boolean().default(true).nullish()');
567+
});
568+
533569
it('with default input values', async () => {
534570
const schema = buildSchema(/* GraphQL */ `
535571
enum PageType {

0 commit comments

Comments
 (0)