Skip to content

Commit e9e4d78

Browse files
mdazyMatthieu Dazy
andauthored
Issue #16: default typename casing to pascalCase and add configuration option (#18)
* Default casing of typenames to pascalCase for consistency with the `typescript` plugin - **this is a breaking change** * Add configuration option `typenames` to allow customization of typenames casing * Add `keep` value for preserving original casing of both enum values and typenames. Users who rely on the current behavior can use it to avoid having to adjust their code * Adjust existing unit tests and add new ones * Update doc Co-authored-by: Matthieu Dazy <[email protected]>
1 parent dbb791e commit e9e4d78

File tree

6 files changed

+587
-96
lines changed

6 files changed

+587
-96
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ Adds `__typename` property to mock data
2020

2121
### enumValues (`string`, defaultValue: `pascal-case#pascalCase`)
2222

23-
Change the case of the enums. Accept `upper-case#upperCase` or `pascal-case#pascalCase`
23+
Changes the case of the enums. Accepts `upper-case#upperCase`, `pascal-case#pascalCase` or `keep`
24+
25+
### typenames (`string`, defaultValue: `pascal-case#pascalCase`)
26+
27+
Changes the case of the enums. Accepts `upper-case#upperCase`, `pascal-case#pascalCase` or `keep`
2428

2529
## Example of usage
2630

@@ -38,6 +42,7 @@ generates:
3842
- 'graphql-codegen-typescript-mock-data':
3943
typesFile: '../generated-types.ts'
4044
enumValues: upper-case#upperCase
45+
typenames: keep
4146
```
4247
4348
## Example or generated code

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"lint-staged": "^10.1.1",
5252
"prettier": "^2.0.2",
5353
"prettier-config-landr": "^0.0.7",
54-
"ts-jest": "^25.3.1",
54+
"ts-jest": "^25.4.0",
5555
"typescript": "^3.8.3"
5656
},
5757
"sideEffects": false,

src/index.ts

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,29 @@ import { PluginFunction } from '@graphql-codegen/plugin-helpers';
44
import { pascalCase } from 'pascal-case';
55
import { upperCase } from 'upper-case';
66

7-
type EnumValuesTypes = 'upper-case#upperCase' | 'pascal-case#pascalCase';
7+
type NamingConvention = 'upper-case#upperCase' | 'pascal-case#pascalCase' | 'keep';
8+
9+
const createNameConverter = (convention: NamingConvention) => (value: string) => {
10+
switch (convention) {
11+
case 'upper-case#upperCase':
12+
return upperCase(value || '');
13+
case 'keep':
14+
return value;
15+
case 'pascal-case#pascalCase':
16+
// fallthrough
17+
default:
18+
// default to pascal case in case of unknown values
19+
return pascalCase(value || '');
20+
}
21+
};
822

923
const toMockName = (name: string) => {
1024
const isVowel = name.match(/^[AEIO]/);
1125
return isVowel ? `an${name}` : `a${name}`;
1226
};
1327

14-
const updateTextCase = (str: string, enumValues: EnumValuesTypes) => {
15-
const convert = (value: string) =>
16-
enumValues === 'upper-case#upperCase' ? upperCase(value || '') : pascalCase(value || '');
28+
const updateTextCase = (str: string, enumValuesConvention: NamingConvention) => {
29+
const convert = createNameConverter(enumValuesConvention);
1730

1831
if (str.charAt(0) === '_') {
1932
return str.replace(
@@ -44,7 +57,8 @@ const getNamedType = (
4457
typeName: string,
4558
fieldName: string,
4659
types: TypeItem[],
47-
enumValues: EnumValuesTypes,
60+
typenamesConvention: NamingConvention,
61+
enumValuesConvention: NamingConvention,
4862
namedType?: NamedTypeNode,
4963
): string | number | boolean => {
5064
if (!namedType) {
@@ -72,16 +86,18 @@ const getNamedType = (
7286
switch (foundType.type) {
7387
case 'enum': {
7488
// It's an enum
89+
const typenameConverter = createNameConverter(typenamesConvention);
7590
const value = foundType.values ? foundType.values[0] : '';
76-
return `${foundType.name}.${updateTextCase(value, enumValues)}`;
91+
return `${typenameConverter(foundType.name)}.${updateTextCase(value, enumValuesConvention)}`;
7792
}
7893
case 'union':
7994
// Return the first union type node.
8095
return getNamedType(
8196
typeName,
8297
fieldName,
8398
types,
84-
enumValues,
99+
typenamesConvention,
100+
enumValuesConvention,
85101
foundType.types && foundType.types[0],
86102
);
87103
default:
@@ -97,25 +113,53 @@ const generateMockValue = (
97113
typeName: string,
98114
fieldName: string,
99115
types: TypeItem[],
100-
enumValues: EnumValuesTypes,
116+
typenamesConvention: NamingConvention,
117+
enumValuesConvention: NamingConvention,
101118
currentType: TypeNode,
102119
): string | number | boolean => {
103120
switch (currentType.kind) {
104121
case 'NamedType':
105-
return getNamedType(typeName, fieldName, types, enumValues, currentType as NamedTypeNode);
122+
return getNamedType(
123+
typeName,
124+
fieldName,
125+
types,
126+
typenamesConvention,
127+
enumValuesConvention,
128+
currentType as NamedTypeNode,
129+
);
106130
case 'NonNullType':
107-
return generateMockValue(typeName, fieldName, types, enumValues, currentType.type);
131+
return generateMockValue(
132+
typeName,
133+
fieldName,
134+
types,
135+
typenamesConvention,
136+
enumValuesConvention,
137+
currentType.type,
138+
);
108139
case 'ListType': {
109-
const value = generateMockValue(typeName, fieldName, types, enumValues, currentType.type);
140+
const value = generateMockValue(
141+
typeName,
142+
fieldName,
143+
types,
144+
typenamesConvention,
145+
enumValuesConvention,
146+
currentType.type,
147+
);
110148
return `[${value}]`;
111149
}
112150
}
113151
};
114152

115-
const getMockString = (typeName: string, fields: string, addTypename = false) => {
116-
const typename = addTypename ? `\n __typename: '${typeName}',` : '';
153+
const getMockString = (
154+
typeName: string,
155+
fields: string,
156+
typenamesConvention: NamingConvention,
157+
addTypename = false,
158+
) => {
159+
const casedName = createNameConverter(typenamesConvention)(typeName);
160+
const typename = addTypename ? `\n __typename: '${casedName}',` : '';
117161
return `
118-
export const ${toMockName(typeName)} = (overrides?: Partial<${typeName}>): ${typeName} => {
162+
export const ${toMockName(casedName)} = (overrides?: Partial<${casedName}>): ${casedName} => {
119163
return {${typename}
120164
${fields}
121165
};
@@ -124,7 +168,8 @@ ${fields}
124168

125169
export interface TypescriptMocksPluginConfig {
126170
typesFile?: string;
127-
enumValues?: EnumValuesTypes;
171+
enumValues?: NamingConvention;
172+
typenames?: NamingConvention;
128173
addTypename?: boolean;
129174
}
130175

@@ -144,7 +189,8 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
144189
const printedSchema = printSchema(schema); // Returns a string representation of the schema
145190
const astNode = parse(printedSchema); // Transforms the string into ASTNode
146191

147-
const enumValues = config.enumValues || 'pascal-case#pascalCase';
192+
const enumValuesConvention = config.enumValues || 'pascal-case#pascalCase';
193+
const typenamesConvention = config.typenames || 'pascal-case#pascalCase';
148194
// List of types that are enums
149195
const types: TypeItem[] = [];
150196
const visitor: VisitorType = {
@@ -174,7 +220,14 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
174220
return {
175221
name: fieldName,
176222
mockFn: (typeName: string) => {
177-
const value = generateMockValue(typeName, fieldName, types, enumValues, node.type);
223+
const value = generateMockValue(
224+
typeName,
225+
fieldName,
226+
types,
227+
typenamesConvention,
228+
enumValuesConvention,
229+
node.type,
230+
);
178231

179232
return ` ${fieldName}: overrides && overrides.hasOwnProperty('${fieldName}') ? overrides.${fieldName}! : ${value},`;
180233
},
@@ -193,7 +246,8 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
193246
fieldName,
194247
field.name.value,
195248
types,
196-
enumValues,
249+
typenamesConvention,
250+
enumValuesConvention,
197251
field.type,
198252
);
199253

@@ -202,7 +256,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
202256
.join('\n')
203257
: '';
204258

205-
return getMockString(fieldName, mockFields, false);
259+
return getMockString(fieldName, mockFields, typenamesConvention, false);
206260
},
207261
};
208262
},
@@ -220,7 +274,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
220274
mockFn: () => {
221275
const mockFields = fields ? fields.map(({ mockFn }: any) => mockFn(typeName)).join('\n') : '';
222276

223-
return getMockString(typeName, mockFields, !!config.addTypename);
277+
return getMockString(typeName, mockFields, typenamesConvention, !!config.addTypename);
224278
},
225279
};
226280
},

0 commit comments

Comments
 (0)