Skip to content

Commit 130af3d

Browse files
authored
fix(typesPrefix): use typesPrefix in imports (#55)
When option typesFile was used, the import line was not using typesPrefix for types Also used objects in function parameters, as the current params were getting out of control
1 parent debc035 commit 130af3d

File tree

4 files changed

+235
-109
lines changed

4 files changed

+235
-109
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ declare namespace Api {
9999
}
100100
```
101101
102-
Setting the typesPrefix to `Api.` will create the following mock data
102+
Setting the `typesPrefix` to `Api.` will create the following mock data
103103
104104
```
105105
export const aUser = (overrides?: Partial<Api.User>): Api.User => {

src/index.ts

Lines changed: 108 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,30 @@ import a from 'indefinite';
88

99
type NamingConvention = 'upper-case#upperCase' | 'pascal-case#pascalCase' | 'keep';
1010

11-
const createNameConverter = (convention: NamingConvention) => (value: string) => {
11+
type Options<T = TypeNode> = {
12+
typeName: string;
13+
fieldName: string;
14+
types: TypeItem[];
15+
typenamesConvention: NamingConvention;
16+
enumValuesConvention: NamingConvention;
17+
terminateCircularRelationships: boolean;
18+
prefix: string | undefined;
19+
typesPrefix: string;
20+
currentType: T;
21+
customScalars?: ScalarMap;
22+
};
23+
24+
const createNameConverter = (convention: NamingConvention) => (value: string, prefix = '') => {
1225
switch (convention) {
1326
case 'upper-case#upperCase':
14-
return upperCase(value || '');
27+
return `${prefix}${upperCase(value || '')}`;
1528
case 'keep':
16-
return value;
29+
return `${prefix}${value}`;
1730
case 'pascal-case#pascalCase':
1831
// fallthrough
1932
default:
2033
// default to pascal case in case of unknown values
21-
return pascalCase(value || '');
34+
return `${prefix}${pascalCase(value || '')}`;
2235
}
2336
};
2437

@@ -68,24 +81,14 @@ const getScalarDefinition = (value: ScalarDefinition | ScalarGeneratorName): Sca
6881
return value;
6982
};
7083

71-
const getNamedType = (
72-
typeName: string,
73-
fieldName: string,
74-
types: TypeItem[],
75-
typenamesConvention: NamingConvention,
76-
enumValuesConvention: NamingConvention,
77-
terminateCircularRelationships: boolean,
78-
prefix?: string,
79-
namedType?: NamedTypeNode,
80-
customScalars?: ScalarMap,
81-
): string | number | boolean => {
82-
if (!namedType) {
84+
const getNamedType = (opts: Options<NamedTypeNode>): string | number | boolean => {
85+
if (!opts.currentType) {
8386
return '';
8487
}
8588

86-
casual.seed(hashedString(typeName + fieldName));
87-
const name = namedType.name.value;
88-
const casedName = createNameConverter(typenamesConvention)(name);
89+
casual.seed(hashedString(opts.typeName + opts.fieldName));
90+
const name = opts.currentType.name.value;
91+
const casedName = createNameConverter(opts.typenamesConvention)(name);
8992
switch (name) {
9093
case 'String':
9194
return `'${casual.word}'`;
@@ -98,29 +101,28 @@ const getNamedType = (
98101
case 'Int':
99102
return casual.integer(0, 9999);
100103
default: {
101-
const foundType = types.find((enumType: TypeItem) => enumType.name === name);
104+
const foundType = opts.types.find((enumType: TypeItem) => enumType.name === name);
102105
if (foundType) {
103106
switch (foundType.type) {
104107
case 'enum': {
105108
// It's an enum
106-
const typenameConverter = createNameConverter(typenamesConvention);
109+
const typenameConverter = createNameConverter(opts.typenamesConvention);
107110
const value = foundType.values ? foundType.values[0] : '';
108-
return `${typenameConverter(foundType.name)}.${updateTextCase(value, enumValuesConvention)}`;
111+
return `${typenameConverter(foundType.name)}.${updateTextCase(
112+
value,
113+
opts.enumValuesConvention,
114+
)}`;
109115
}
110116
case 'union':
111117
// Return the first union type node.
112-
return getNamedType(
113-
typeName,
114-
fieldName,
115-
types,
116-
typenamesConvention,
117-
enumValuesConvention,
118-
terminateCircularRelationships,
119-
prefix,
120-
foundType.types && foundType.types[0],
121-
);
118+
return getNamedType({
119+
...opts,
120+
currentType: foundType.types && foundType.types[0],
121+
});
122122
case 'scalar': {
123-
const customScalar = customScalars ? getScalarDefinition(customScalars[foundType.name]) : null;
123+
const customScalar = opts.customScalars
124+
? getScalarDefinition(opts.customScalars[foundType.name])
125+
: null;
124126
// it's a scalar, let's use a string as a value if there is no custom
125127
// mapping for this particular scalar
126128
if (!customScalar || !customScalar.generator) {
@@ -158,67 +160,36 @@ const getNamedType = (
158160
throw `foundType is unknown: ${foundType.name}: ${foundType.type}`;
159161
}
160162
}
161-
if (terminateCircularRelationships) {
163+
if (opts.terminateCircularRelationships) {
162164
return `relationshipsToOmit.has('${name}') ? {} as ${name} : ${toMockName(
163165
name,
164166
casedName,
165-
prefix,
167+
opts.prefix,
166168
)}({}, relationshipsToOmit)`;
167169
} else {
168-
return `${toMockName(name, casedName, prefix)}()`;
170+
return `${toMockName(name, casedName, opts.prefix)}()`;
169171
}
170172
}
171173
}
172174
};
173175

174-
const generateMockValue = (
175-
typeName: string,
176-
fieldName: string,
177-
types: TypeItem[],
178-
typenamesConvention: NamingConvention,
179-
enumValuesConvention: NamingConvention,
180-
terminateCircularRelationships: boolean,
181-
prefix: string | undefined,
182-
currentType: TypeNode,
183-
customScalars: ScalarMap,
184-
): string | number | boolean => {
185-
switch (currentType.kind) {
176+
const generateMockValue = (opts: Options): string | number | boolean => {
177+
switch (opts.currentType.kind) {
186178
case 'NamedType':
187-
return getNamedType(
188-
typeName,
189-
fieldName,
190-
types,
191-
typenamesConvention,
192-
enumValuesConvention,
193-
terminateCircularRelationships,
194-
prefix,
195-
currentType as NamedTypeNode,
196-
customScalars,
197-
);
179+
return getNamedType({
180+
...opts,
181+
currentType: opts.currentType as NamedTypeNode,
182+
});
198183
case 'NonNullType':
199-
return generateMockValue(
200-
typeName,
201-
fieldName,
202-
types,
203-
typenamesConvention,
204-
enumValuesConvention,
205-
terminateCircularRelationships,
206-
prefix,
207-
currentType.type,
208-
customScalars,
209-
);
184+
return generateMockValue({
185+
...opts,
186+
currentType: opts.currentType.type,
187+
});
210188
case 'ListType': {
211-
const value = generateMockValue(
212-
typeName,
213-
fieldName,
214-
types,
215-
typenamesConvention,
216-
enumValuesConvention,
217-
terminateCircularRelationships,
218-
prefix,
219-
currentType.type,
220-
customScalars,
221-
);
189+
const value = generateMockValue({
190+
...opts,
191+
currentType: opts.currentType.type,
192+
});
222193
return `[${value}]`;
223194
}
224195
}
@@ -233,7 +204,9 @@ const getMockString = (
233204
prefix,
234205
typesPrefix = '',
235206
) => {
236-
const casedName = createNameConverter(typenamesConvention)(typeName);
207+
const typenameConverter = createNameConverter(typenamesConvention);
208+
const casedName = typenameConverter(typeName);
209+
const casedNameWithPrefix = typenameConverter(typeName, typesPrefix);
237210
const typename = addTypename ? `\n __typename: '${casedName}',` : '';
238211
const typenameReturnType = addTypename ? `{ __typename: '${casedName}' } & ` : '';
239212

@@ -243,7 +216,7 @@ export const ${toMockName(
243216
typeName,
244217
casedName,
245218
prefix,
246-
)} = (overrides?: Partial<${typesPrefix}${casedName}>, relationshipsToOmit: Set<string> = new Set()): ${typenameReturnType}${typesPrefix}${casedName} => {
219+
)} = (overrides?: Partial<${casedNameWithPrefix}>, relationshipsToOmit: Set<string> = new Set()): ${typenameReturnType}${casedNameWithPrefix} => {
247220
relationshipsToOmit.add('${casedName}');
248221
return {${typename}
249222
${fields}
@@ -255,14 +228,40 @@ export const ${toMockName(
255228
typeName,
256229
casedName,
257230
prefix,
258-
)} = (overrides?: Partial<${typesPrefix}${casedName}>): ${typenameReturnType}${typesPrefix}${casedName} => {
231+
)} = (overrides?: Partial<${casedNameWithPrefix}>): ${typenameReturnType}${casedNameWithPrefix} => {
259232
return {${typename}
260233
${fields}
261234
};
262235
};`;
263236
}
264237
};
265238

239+
const getImportTypes = ({
240+
typenamesConvention,
241+
definitions,
242+
types,
243+
typesFile,
244+
typesPrefix,
245+
}: {
246+
typenamesConvention: NamingConvention;
247+
definitions: any;
248+
types: TypeItem[];
249+
typesFile: string;
250+
typesPrefix: string;
251+
}) => {
252+
const typenameConverter = createNameConverter(typenamesConvention);
253+
const enumTypes = types.filter(({ type }) => type === 'enum');
254+
const typeImports = definitions
255+
.filter(({ typeName }: { typeName: string }) => !!typeName)
256+
.map(({ typeName }: { typeName: string }) => typenameConverter(typeName, typesPrefix));
257+
258+
typeImports.push(...enumTypes.map(({ name }) => typenameConverter(name)));
259+
return typesFile
260+
? `/* eslint-disable @typescript-eslint/no-use-before-define,@typescript-eslint/no-unused-vars,no-prototype-builtins */
261+
import { ${typeImports.join(', ')} } from '${typesFile}';\n`
262+
: '';
263+
};
264+
266265
type ScalarGeneratorName = keyof Casual.Casual | keyof Casual.functions | string;
267266
type ScalarDefinition = {
268267
generator: ScalarGeneratorName;
@@ -331,17 +330,18 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
331330
return {
332331
name: fieldName,
333332
mockFn: (typeName: string) => {
334-
const value = generateMockValue(
333+
const value = generateMockValue({
335334
typeName,
336335
fieldName,
337336
types,
338337
typenamesConvention,
339338
enumValuesConvention,
340-
!!config.terminateCircularRelationships,
341-
config.prefix,
342-
node.type,
343-
config.scalars,
344-
);
339+
terminateCircularRelationships: !!config.terminateCircularRelationships,
340+
prefix: config.prefix,
341+
typesPrefix: config.typesPrefix,
342+
currentType: node.type,
343+
customScalars: config.scalars,
344+
});
345345

346346
return ` ${fieldName}: overrides && overrides.hasOwnProperty('${fieldName}') ? overrides.${fieldName}! : ${value},`;
347347
},
@@ -356,17 +356,18 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
356356
const mockFields = node.fields
357357
? node.fields
358358
.map((field) => {
359-
const value = generateMockValue(
360-
fieldName,
361-
field.name.value,
359+
const value = generateMockValue({
360+
typeName: fieldName,
361+
fieldName: field.name.value,
362362
types,
363363
typenamesConvention,
364364
enumValuesConvention,
365-
!!config.terminateCircularRelationships,
366-
config.prefix,
367-
field.type,
368-
config.scalars,
369-
);
365+
terminateCircularRelationships: !!config.terminateCircularRelationships,
366+
prefix: config.prefix,
367+
typesPrefix: config.typesPrefix,
368+
currentType: field.type,
369+
customScalars: config.scalars,
370+
});
370371

371372
return ` ${field.name.value}: overrides && overrides.hasOwnProperty('${field.name.value}') ? overrides.${field.name.value}! : ${value},`;
372373
})
@@ -442,21 +443,20 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
442443
},
443444
};
444445

445-
const result: any = visit(astNode, { leave: visitor });
446+
const result = visit(astNode, { leave: visitor });
446447
const definitions = result.definitions.filter((definition: any) => !!definition);
447448
const typesFile = config.typesFile ? config.typesFile.replace(/\.[\w]+$/, '') : null;
448-
const typenameConverter = createNameConverter(typenamesConvention);
449-
const typeImports = definitions
450-
.map(({ typeName }: { typeName: string }) => typenameConverter(typeName))
451-
.filter((typeName: string) => !!typeName);
452-
typeImports.push(...types.filter(({ type }) => type !== 'scalar').map(({ name }) => typenameConverter(name)));
449+
450+
const typesFileImport = getImportTypes({
451+
typenamesConvention,
452+
definitions,
453+
types,
454+
typesFile,
455+
typesPrefix: config.typesPrefix,
456+
});
453457
// List of function that will generate the mock.
454458
// We generate it after having visited because we need to distinct types from enums
455459
const mockFns = definitions.map(({ mockFn }: any) => mockFn).filter((mockFn: Function) => !!mockFn);
456-
const typesFileImport = typesFile
457-
? `/* eslint-disable @typescript-eslint/no-use-before-define,@typescript-eslint/no-unused-vars,no-prototype-builtins */
458-
import { ${typeImports.join(', ')} } from '${typesFile}';\n`
459-
: '';
460460

461461
return `${typesFileImport}${mockFns.map((mockFn: Function) => mockFn()).join('\n')}
462462
`;

0 commit comments

Comments
 (0)