Skip to content

Commit 9205bd4

Browse files
authored
feat: add typesTransformUnderscore config option (#61)
add `transformUnderscore` option which will remove `_` character in types. This is option is `true` by default to avoid breaking changes and is similar to [typescript plugin option `transformUnderscore` for `namingConvention`](https://www.graphql-code-generator.com/docs/plugins/typescript)
1 parent 0c16918 commit 9205bd4

File tree

4 files changed

+337
-20
lines changed

4 files changed

+337
-20
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ export const aUser = (overrides?: Partial<User>): User => {
125125
}
126126
```
127127
128+
### transformUnderscore (`boolean`, defaultValue: `true`)
129+
130+
When disabled, underscores will be retained for type names when the case is changed. It has no effect if `typenames` is set to `keep`.
131+
128132
## Example of usage
129133
130134
**codegen.yml**

src/index.ts

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,34 @@ type Options<T = TypeNode> = {
2020
enumsPrefix: string;
2121
currentType: T;
2222
customScalars?: ScalarMap;
23+
transformUnderscore: boolean;
24+
};
25+
26+
const convertName = (value: string, fn: (v: string) => string, transformUnderscore: boolean): string => {
27+
if (transformUnderscore) {
28+
return fn(value);
29+
}
30+
31+
return value
32+
.split('_')
33+
.map((s) => fn(s))
34+
.join('_');
2335
};
2436

2537
const createNameConverter =
26-
(convention: NamingConvention) =>
38+
(convention: NamingConvention, transformUnderscore: boolean) =>
2739
(value: string, prefix = '') => {
2840
switch (convention) {
29-
case 'upper-case#upperCase':
30-
return `${prefix}${upperCase(value || '')}`;
41+
case 'upper-case#upperCase': {
42+
return `${prefix}${convertName(value, (s) => upperCase(s || ''), transformUnderscore)}`;
43+
}
3144
case 'keep':
3245
return `${prefix}${value}`;
3346
case 'pascal-case#pascalCase':
3447
// fallthrough
3548
default:
3649
// default to pascal case in case of unknown values
37-
return `${prefix}${pascalCase(value || '')}`;
50+
return `${prefix}${convertName(value, (s) => pascalCase(s || ''), transformUnderscore)}`;
3851
}
3952
};
4053

@@ -46,8 +59,8 @@ const toMockName = (typedName: string, casedName: string, prefix?: string) => {
4659
return `${a(firstWord, { articleOnly: true })}${casedName}`;
4760
};
4861

49-
const updateTextCase = (str: string, enumValuesConvention: NamingConvention) => {
50-
const convert = createNameConverter(enumValuesConvention);
62+
const updateTextCase = (str: string, enumValuesConvention: NamingConvention, transformUnderscore: boolean) => {
63+
const convert = createNameConverter(enumValuesConvention, transformUnderscore);
5164

5265
if (str.charAt(0) === '_') {
5366
return str.replace(
@@ -91,7 +104,7 @@ const getNamedType = (opts: Options<NamedTypeNode>): string | number | boolean =
91104

92105
casual.seed(hashedString(opts.typeName + opts.fieldName));
93106
const name = opts.currentType.name.value;
94-
const casedName = createNameConverter(opts.typenamesConvention)(name);
107+
const casedName = createNameConverter(opts.typenamesConvention, opts.transformUnderscore)(name);
95108
switch (name) {
96109
case 'String':
97110
return `'${casual.word}'`;
@@ -109,11 +122,15 @@ const getNamedType = (opts: Options<NamedTypeNode>): string | number | boolean =
109122
switch (foundType.type) {
110123
case 'enum': {
111124
// It's an enum
112-
const typenameConverter = createNameConverter(opts.typenamesConvention);
125+
const typenameConverter = createNameConverter(
126+
opts.typenamesConvention,
127+
opts.transformUnderscore,
128+
);
113129
const value = foundType.values ? foundType.values[0] : '';
114130
return `${typenameConverter(foundType.name, opts.enumsPrefix)}.${updateTextCase(
115131
value,
116132
opts.enumValuesConvention,
133+
opts.transformUnderscore,
117134
)}`;
118135
}
119136
case 'union':
@@ -206,8 +223,9 @@ const getMockString = (
206223
addTypename = false,
207224
prefix,
208225
typesPrefix = '',
226+
transformUnderscore: boolean,
209227
) => {
210-
const typenameConverter = createNameConverter(typenamesConvention);
228+
const typenameConverter = createNameConverter(typenamesConvention, transformUnderscore);
211229
const casedName = typenameConverter(typeName);
212230
const casedNameWithPrefix = typenameConverter(typeName, typesPrefix);
213231
const typename = addTypename ? `\n __typename: '${casedName}',` : '';
@@ -246,15 +264,17 @@ const getImportTypes = ({
246264
typesFile,
247265
typesPrefix,
248266
enumsPrefix,
267+
transformUnderscore,
249268
}: {
250269
typenamesConvention: NamingConvention;
251270
definitions: any;
252271
types: TypeItem[];
253272
typesFile: string;
254273
typesPrefix: string;
255274
enumsPrefix: string;
275+
transformUnderscore: boolean;
256276
}) => {
257-
const typenameConverter = createNameConverter(typenamesConvention);
277+
const typenameConverter = createNameConverter(typenamesConvention, transformUnderscore);
258278
const typeImports = typesPrefix?.endsWith('.')
259279
? [typesPrefix.slice(0, -1)]
260280
: definitions
@@ -296,6 +316,7 @@ export interface TypescriptMocksPluginConfig {
296316
terminateCircularRelationships?: boolean;
297317
typesPrefix?: string;
298318
enumsPrefix?: string;
319+
transformUnderscore?: boolean;
299320
}
300321

301322
interface TypeItem {
@@ -316,6 +337,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
316337

317338
const enumValuesConvention = config.enumValues || 'pascal-case#pascalCase';
318339
const typenamesConvention = config.typenames || 'pascal-case#pascalCase';
340+
const transformUnderscore = config.transformUnderscore ?? true;
319341
// List of types that are enums
320342
const types: TypeItem[] = [];
321343
const visitor: VisitorType = {
@@ -357,6 +379,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
357379
enumsPrefix: config.enumsPrefix,
358380
currentType: node.type,
359381
customScalars: config.scalars,
382+
transformUnderscore,
360383
});
361384

362385
return ` ${fieldName}: overrides && overrides.hasOwnProperty('${fieldName}') ? overrides.${fieldName}! : ${value},`;
@@ -384,6 +407,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
384407
enumsPrefix: config.enumsPrefix,
385408
currentType: field.type,
386409
customScalars: config.scalars,
410+
transformUnderscore,
387411
});
388412

389413
return ` ${field.name.value}: overrides && overrides.hasOwnProperty('${field.name.value}') ? overrides.${field.name.value}! : ${value},`;
@@ -399,6 +423,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
399423
false,
400424
config.prefix,
401425
config.typesPrefix,
426+
transformUnderscore,
402427
);
403428
},
404429
};
@@ -421,6 +446,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
421446
!!config.addTypename,
422447
config.prefix,
423448
config.typesPrefix,
449+
transformUnderscore,
424450
);
425451
},
426452
};
@@ -441,6 +467,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
441467
!!config.addTypename,
442468
config.prefix,
443469
config.typesPrefix,
470+
transformUnderscore,
444471
);
445472
},
446473
};
@@ -467,6 +494,7 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
467494
typesFile,
468495
typesPrefix: config.typesPrefix,
469496
enumsPrefix: config.enumsPrefix,
497+
transformUnderscore: transformUnderscore,
470498
});
471499
// List of function that will generate the mock.
472500
// We generate it after having visited because we need to distinct types from enums

0 commit comments

Comments
 (0)