Skip to content

Commit ec4dfb0

Browse files
authored
Merge pull request #828 from sutt0n/fix/name-parts
fix(enum): propagate namingConvention.transformUnderscore to convertNameParts
2 parents d8e91dc + db7e15e commit ec4dfb0

14 files changed

+256
-33
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,6 @@ type: `NamingConventionMap` default: `{ enumValues: "change-case-all#pascalCase"
215215

216216
Uses the full path of the enum type as the default value instead of the stringified value.
217217

218-
Note: This option has not been tested with `namingConvention.transformUnderscore` and `namingConvention.typeNames` options and may not work as expected.
219-
220218
Related: https://the-guild.dev/graphql/codegen/docs/config-reference/naming-convention#namingconvention
221219

222220
### `directives`

src/directive.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ConstArgumentNode, ConstDirectiveNode, ConstValueNode } from 'graphql';
2+
import { Kind, valueFromASTUntyped } from 'graphql';
23
import type { DirectiveConfig, DirectiveObjectArguments } from './config.js';
34

4-
import { Kind, valueFromASTUntyped } from 'graphql';
55
import { isConvertableRegexp } from './regexp.js';
66

77
export interface FormattedDirectiveConfig {

src/graphql.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import type {
55
GraphQLSchema,
66
InterfaceTypeDefinitionNode,
77
ListTypeNode,
8-
NamedTypeNode,
98
NameNode,
9+
NamedTypeNode,
1010
NonNullTypeNode,
1111
ObjectTypeDefinitionNode,
1212
TypeNode,

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { PluginFunction, Types } from '@graphql-codegen/plugin-helpers';
22
import type { GraphQLSchema } from 'graphql';
3+
import { transformSchemaAST } from '@graphql-codegen/schema-ast';
4+
import { buildSchema, printSchema, visit } from 'graphql';
35
import type { ValidationSchemaPluginConfig } from './config.js';
46
import type { SchemaVisitor } from './types.js';
57

6-
import { transformSchemaAST } from '@graphql-codegen/schema-ast';
7-
import { buildSchema, printSchema, visit } from 'graphql';
88
import { isGeneratedByIntrospection, topologicalSortAST } from './graphql.js';
99
import { MyZodSchemaVisitor } from './myzod/index.js';
1010
import { ValibotSchemaVisitor } from './valibot/index.js';

src/myzod/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ import type {
1010
TypeNode,
1111
UnionTypeDefinitionNode,
1212
} from 'graphql';
13-
import type { ValidationSchemaPluginConfig } from '../config.js';
14-
import type { Visitor } from '../visitor.js';
1513

1614
import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers';
17-
import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15+
import { DeclarationBlock, convertNameParts, indent } from '@graphql-codegen/visitor-plugin-common';
1816
import {
1917
Kind,
2018
} from 'graphql';
19+
import type { Visitor } from '../visitor.js';
20+
import type { ValidationSchemaPluginConfig } from '../config.js';
2121
import { buildApi, formatDirectiveConfig } from '../directive.js';
2222
import {
23-
escapeGraphQLCharacters,
2423
InterfaceTypeDefinitionBuilder,
24+
ObjectTypeDefinitionBuilder,
25+
escapeGraphQLCharacters,
2526
isInput,
2627
isListType,
2728
isNamedType,
2829
isNonNullType,
29-
ObjectTypeDefinitionBuilder,
3030
} from '../graphql.js';
3131
import { BaseSchemaVisitor } from '../schema_visitor.js';
3232

@@ -290,10 +290,10 @@ function generateFieldTypeMyZodSchema(config: ValidationSchemaPluginConfig, visi
290290

291291
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
292292
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
293-
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'));
293+
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'), config?.namingConvention?.transformUnderscore);
294294

295295
if (config.namingConvention?.enumValues)
296-
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues));
296+
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues), config?.namingConvention?.transformUnderscore);
297297

298298
appliedDirectivesGen = `${appliedDirectivesGen}.default(${visitor.convertName(type.name.value)}.${value})`;
299299
}

src/valibot/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ import type {
1010
TypeNode,
1111
UnionTypeDefinitionNode,
1212
} from 'graphql';
13+
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
1314
import type { ValidationSchemaPluginConfig } from '../config.js';
1415

1516
import type { Visitor } from '../visitor.js';
16-
import { DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
1717
import { buildApiForValibot, formatDirectiveConfig } from '../directive.js';
1818
import {
1919
InterfaceTypeDefinitionBuilder,
20+
ObjectTypeDefinitionBuilder,
2021
isInput,
2122
isListType,
2223
isNamedType,
2324
isNonNullType,
24-
ObjectTypeDefinitionBuilder,
2525
} from '../graphql.js';
2626
import { BaseSchemaVisitor } from '../schema_visitor.js';
2727

src/visitor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import type {
55
NameNode,
66
ObjectTypeDefinitionNode,
77
} from 'graphql';
8-
import type { ValidationSchemaPluginConfig } from './config.js';
98
import { TsVisitor } from '@graphql-codegen/typescript';
109

1110
import {
1211
specifiedScalarTypes,
1312
} from 'graphql';
13+
import type { ValidationSchemaPluginConfig } from './config.js';
1414

1515
export class Visitor extends TsVisitor {
1616
constructor(

src/yup/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ import type {
1010
TypeNode,
1111
UnionTypeDefinitionNode,
1212
} from 'graphql';
13-
import type { ValidationSchemaPluginConfig } from '../config.js';
14-
import type { Visitor } from '../visitor.js';
1513

1614
import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers';
17-
import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15+
import { DeclarationBlock, convertNameParts, indent } from '@graphql-codegen/visitor-plugin-common';
1816
import {
1917
Kind,
2018
} from 'graphql';
19+
import type { Visitor } from '../visitor.js';
20+
import type { ValidationSchemaPluginConfig } from '../config.js';
2121
import { buildApi, formatDirectiveConfig } from '../directive.js';
2222
import {
23-
escapeGraphQLCharacters,
2423
InterfaceTypeDefinitionBuilder,
24+
ObjectTypeDefinitionBuilder,
25+
escapeGraphQLCharacters,
2526
isInput,
2627
isListType,
2728
isNamedType,
2829
isNonNullType,
29-
ObjectTypeDefinitionBuilder,
3030
} from '../graphql.js';
3131
import { BaseSchemaVisitor } from '../schema_visitor.js';
3232

@@ -292,10 +292,10 @@ function shapeFields(fields: readonly (FieldDefinitionNode | InputValueDefinitio
292292

293293
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
294294
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
295-
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'));
295+
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'), config?.namingConvention?.transformUnderscore);
296296

297297
if (config.namingConvention?.enumValues)
298-
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues));
298+
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues), config?.namingConvention?.transformUnderscore);
299299

300300
fieldSchema = `${fieldSchema}.default(${visitor.convertName(field.name.value)}.${value})`;
301301
}

src/zod/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ import type {
1010
TypeNode,
1111
UnionTypeDefinitionNode,
1212
} from 'graphql';
13-
import type { ValidationSchemaPluginConfig } from '../config.js';
14-
import type { Visitor } from '../visitor.js';
1513

1614
import { resolveExternalModuleAndFn } from '@graphql-codegen/plugin-helpers';
17-
import { convertNameParts, DeclarationBlock, indent } from '@graphql-codegen/visitor-plugin-common';
15+
import { DeclarationBlock, convertNameParts, indent } from '@graphql-codegen/visitor-plugin-common';
1816
import {
1917
Kind,
2018
} from 'graphql';
19+
import type { Visitor } from '../visitor.js';
20+
import type { ValidationSchemaPluginConfig } from '../config.js';
2121
import { buildApi, formatDirectiveConfig } from '../directive.js';
2222
import {
23-
escapeGraphQLCharacters,
2423
InterfaceTypeDefinitionBuilder,
24+
ObjectTypeDefinitionBuilder,
25+
escapeGraphQLCharacters,
2526
isInput,
2627
isListType,
2728
isNamedType,
2829
isNonNullType,
29-
ObjectTypeDefinitionBuilder,
3030
} from '../graphql.js';
3131
import { BaseSchemaVisitor } from '../schema_visitor.js';
3232

@@ -306,10 +306,10 @@ function generateFieldTypeZodSchema(config: ValidationSchemaPluginConfig, visito
306306

307307
if (defaultValue?.kind === Kind.STRING || defaultValue?.kind === Kind.ENUM) {
308308
if (config.useEnumTypeAsDefaultValue && defaultValue?.kind !== Kind.STRING) {
309-
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'));
309+
let value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn('change-case-all#pascalCase'), config.namingConvention?.transformUnderscore);
310310

311311
if (config.namingConvention?.enumValues)
312-
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues));
312+
value = convertNameParts(defaultValue.value, resolveExternalModuleAndFn(config.namingConvention?.enumValues), config.namingConvention?.transformUnderscore);
313313

314314
appliedDirectivesGen = `${appliedDirectivesGen}.default(${type.name.value}.${value})`;
315315
}

tests/directive.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import type { ConstArgumentNode, ConstDirectiveNode, ConstValueNode, NameNode } from 'graphql';
2+
import { Kind, parseConstValue } from 'graphql';
23
import type { DirectiveConfig, DirectiveObjectArguments } from '../src/config';
34

45
import type {
56
FormattedDirectiveArguments,
67
FormattedDirectiveConfig,
78
FormattedDirectiveObjectArguments,
89
} from '../src/directive';
9-
import { Kind, parseConstValue } from 'graphql';
1010
import {
1111
buildApi,
1212
buildApiForValibot,

tests/graphql.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import type {
33
} from 'graphql';
44
import { Graph } from 'graphlib';
55
import {
6+
Kind,
67
buildClientSchema,
78
buildSchema,
89
introspectionFromSchema,
9-
Kind,
1010
parse,
1111
print,
1212
} from 'graphql';
1313
import dedent from 'ts-dedent';
1414

15-
import { escapeGraphQLCharacters, isGeneratedByIntrospection, ObjectTypeDefinitionBuilder, topologicalSortAST, topsort } from '../src/graphql';
15+
import { ObjectTypeDefinitionBuilder, escapeGraphQLCharacters, isGeneratedByIntrospection, topologicalSortAST, topsort } from '../src/graphql';
1616

1717
describe('graphql', () => {
1818
describe('objectTypeDefinitionBuilder', () => {

tests/myzod.spec.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,4 +1444,77 @@ describe('myzod', () => {
14441444
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
14451445
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
14461446
});
1447+
1448+
it('with default input values as enum types with underscores', async () => {
1449+
const schema = buildSchema(/* GraphQL */ `
1450+
enum PageType {
1451+
PUBLIC
1452+
BASIC_AUTH
1453+
}
1454+
input PageInput {
1455+
pageType: PageType! = BASIC_AUTH
1456+
greeting: String = "Hello"
1457+
score: Int = 100
1458+
ratio: Float = 0.5
1459+
isMember: Boolean = true
1460+
}
1461+
`);
1462+
const result = await plugin(
1463+
schema,
1464+
[],
1465+
{
1466+
schema: 'myzod',
1467+
importFrom: './types',
1468+
useEnumTypeAsDefaultValue: true,
1469+
},
1470+
{},
1471+
);
1472+
1473+
expect(result.content).toContain('export const PageTypeSchema = myzod.enum(PageType)');
1474+
expect(result.content).toContain('export function PageInputSchema(): myzod.Type<PageInput>');
1475+
1476+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.Basic_Auth)');
1477+
expect(result.content).toContain('greeting: myzod.string().default("Hello").optional().nullable()');
1478+
expect(result.content).toContain('score: myzod.number().default(100).optional().nullable()');
1479+
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
1480+
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
1481+
});
1482+
1483+
it('with default input values as enum types with no underscores', async () => {
1484+
const schema = buildSchema(/* GraphQL */ `
1485+
enum PageType {
1486+
PUBLIC
1487+
BASIC_AUTH
1488+
}
1489+
input PageInput {
1490+
pageType: PageType! = BASIC_AUTH
1491+
greeting: String = "Hello"
1492+
score: Int = 100
1493+
ratio: Float = 0.5
1494+
isMember: Boolean = true
1495+
}
1496+
`);
1497+
const result = await plugin(
1498+
schema,
1499+
[],
1500+
{
1501+
schema: 'myzod',
1502+
importFrom: './types',
1503+
useEnumTypeAsDefaultValue: true,
1504+
namingConvention: {
1505+
transformUnderscore: true,
1506+
},
1507+
},
1508+
{},
1509+
);
1510+
1511+
expect(result.content).toContain('export const PageTypeSchema = myzod.enum(PageType)');
1512+
expect(result.content).toContain('export function PageInputSchema(): myzod.Type<PageInput>');
1513+
1514+
expect(result.content).toContain('pageType: PageTypeSchema.default(PageType.BasicAuth)');
1515+
expect(result.content).toContain('greeting: myzod.string().default("Hello").optional().nullable()');
1516+
expect(result.content).toContain('score: myzod.number().default(100).optional().nullable()');
1517+
expect(result.content).toContain('ratio: myzod.number().default(0.5).optional().nullable()');
1518+
expect(result.content).toContain('isMember: myzod.boolean().default(true).optional().nullable()');
1519+
});
14471520
});

tests/yup.spec.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,4 +1470,81 @@ describe('yup', () => {
14701470
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
14711471
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
14721472
});
1473+
1474+
it('with default input values as enum types with underscores', async () => {
1475+
const schema = buildSchema(/* GraphQL */ `
1476+
enum PageType {
1477+
PUBLIC
1478+
BASIC_AUTH
1479+
}
1480+
input PageInput {
1481+
pageType: PageType! = BASIC_AUTH
1482+
greeting: String = "Hello"
1483+
score: Int = 100
1484+
ratio: Float = 0.5
1485+
isMember: Boolean = true
1486+
}
1487+
`);
1488+
const result = await plugin(
1489+
schema,
1490+
[],
1491+
{
1492+
schema: 'yup',
1493+
importFrom: './types',
1494+
useEnumTypeAsDefaultValue: true,
1495+
},
1496+
{},
1497+
);
1498+
1499+
expect(result.content).toContain(
1500+
'export const PageTypeSchema = yup.string<PageType>().oneOf(Object.values(PageType)).defined()',
1501+
);
1502+
expect(result.content).toContain('export function PageInputSchema(): yup.ObjectSchema<PageInput>');
1503+
1504+
expect(result.content).toContain('pageType: PageTypeSchema.nonNullable().default(PageType.Basic_Auth)');
1505+
expect(result.content).toContain('greeting: yup.string().defined().nullable().default("Hello").optional()');
1506+
expect(result.content).toContain('score: yup.number().defined().nullable().default(100).optional()');
1507+
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
1508+
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
1509+
});
1510+
1511+
it('with default input values as enum types with no underscores', async () => {
1512+
const schema = buildSchema(/* GraphQL */ `
1513+
enum PageType {
1514+
PUBLIC
1515+
BASIC_AUTH
1516+
}
1517+
input PageInput {
1518+
pageType: PageType! = BASIC_AUTH
1519+
greeting: String = "Hello"
1520+
score: Int = 100
1521+
ratio: Float = 0.5
1522+
isMember: Boolean = true
1523+
}
1524+
`);
1525+
const result = await plugin(
1526+
schema,
1527+
[],
1528+
{
1529+
schema: 'yup',
1530+
importFrom: './types',
1531+
useEnumTypeAsDefaultValue: true,
1532+
namingConvention: {
1533+
transformUnderscore: true,
1534+
},
1535+
},
1536+
{},
1537+
);
1538+
1539+
expect(result.content).toContain(
1540+
'export const PageTypeSchema = yup.string<PageType>().oneOf(Object.values(PageType)).defined()',
1541+
);
1542+
expect(result.content).toContain('export function PageInputSchema(): yup.ObjectSchema<PageInput>');
1543+
1544+
expect(result.content).toContain('pageType: PageTypeSchema.nonNullable().default(PageType.BasicAuth)');
1545+
expect(result.content).toContain('greeting: yup.string().defined().nullable().default("Hello").optional()');
1546+
expect(result.content).toContain('score: yup.number().defined().nullable().default(100).optional()');
1547+
expect(result.content).toContain('ratio: yup.number().defined().nullable().default(0.5).optional()');
1548+
expect(result.content).toContain('isMember: yup.boolean().defined().nullable().default(true).optional()');
1549+
});
14731550
});

0 commit comments

Comments
 (0)