@@ -8,17 +8,30 @@ import a from 'indefinite';
8
8
9
9
type NamingConvention = 'upper-case#upperCase' | 'pascal-case#pascalCase' | 'keep' ;
10
10
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 = '' ) => {
12
25
switch ( convention ) {
13
26
case 'upper-case#upperCase' :
14
- return upperCase ( value || '' ) ;
27
+ return ` ${ prefix } ${ upperCase ( value || '' ) } ` ;
15
28
case 'keep' :
16
- return value ;
29
+ return ` ${ prefix } ${ value } ` ;
17
30
case 'pascal-case#pascalCase' :
18
31
// fallthrough
19
32
default :
20
33
// default to pascal case in case of unknown values
21
- return pascalCase ( value || '' ) ;
34
+ return ` ${ prefix } ${ pascalCase ( value || '' ) } ` ;
22
35
}
23
36
} ;
24
37
@@ -68,24 +81,14 @@ const getScalarDefinition = (value: ScalarDefinition | ScalarGeneratorName): Sca
68
81
return value ;
69
82
} ;
70
83
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 ) {
83
86
return '' ;
84
87
}
85
88
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 ) ;
89
92
switch ( name ) {
90
93
case 'String' :
91
94
return `'${ casual . word } '` ;
@@ -98,29 +101,28 @@ const getNamedType = (
98
101
case 'Int' :
99
102
return casual . integer ( 0 , 9999 ) ;
100
103
default : {
101
- const foundType = types . find ( ( enumType : TypeItem ) => enumType . name === name ) ;
104
+ const foundType = opts . types . find ( ( enumType : TypeItem ) => enumType . name === name ) ;
102
105
if ( foundType ) {
103
106
switch ( foundType . type ) {
104
107
case 'enum' : {
105
108
// It's an enum
106
- const typenameConverter = createNameConverter ( typenamesConvention ) ;
109
+ const typenameConverter = createNameConverter ( opts . typenamesConvention ) ;
107
110
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
+ ) } `;
109
115
}
110
116
case 'union' :
111
117
// 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
+ } ) ;
122
122
case 'scalar' : {
123
- const customScalar = customScalars ? getScalarDefinition ( customScalars [ foundType . name ] ) : null ;
123
+ const customScalar = opts . customScalars
124
+ ? getScalarDefinition ( opts . customScalars [ foundType . name ] )
125
+ : null ;
124
126
// it's a scalar, let's use a string as a value if there is no custom
125
127
// mapping for this particular scalar
126
128
if ( ! customScalar || ! customScalar . generator ) {
@@ -158,67 +160,36 @@ const getNamedType = (
158
160
throw `foundType is unknown: ${ foundType . name } : ${ foundType . type } ` ;
159
161
}
160
162
}
161
- if ( terminateCircularRelationships ) {
163
+ if ( opts . terminateCircularRelationships ) {
162
164
return `relationshipsToOmit.has('${ name } ') ? {} as ${ name } : ${ toMockName (
163
165
name ,
164
166
casedName ,
165
- prefix ,
167
+ opts . prefix ,
166
168
) } ({}, relationshipsToOmit)`;
167
169
} else {
168
- return `${ toMockName ( name , casedName , prefix ) } ()` ;
170
+ return `${ toMockName ( name , casedName , opts . prefix ) } ()` ;
169
171
}
170
172
}
171
173
}
172
174
} ;
173
175
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 ) {
186
178
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
+ } ) ;
198
183
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
+ } ) ;
210
188
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
+ } ) ;
222
193
return `[${ value } ]` ;
223
194
}
224
195
}
@@ -233,7 +204,9 @@ const getMockString = (
233
204
prefix ,
234
205
typesPrefix = '' ,
235
206
) => {
236
- const casedName = createNameConverter ( typenamesConvention ) ( typeName ) ;
207
+ const typenameConverter = createNameConverter ( typenamesConvention ) ;
208
+ const casedName = typenameConverter ( typeName ) ;
209
+ const casedNameWithPrefix = typenameConverter ( typeName , typesPrefix ) ;
237
210
const typename = addTypename ? `\n __typename: '${ casedName } ',` : '' ;
238
211
const typenameReturnType = addTypename ? `{ __typename: '${ casedName } ' } & ` : '' ;
239
212
@@ -243,7 +216,7 @@ export const ${toMockName(
243
216
typeName ,
244
217
casedName ,
245
218
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 } => {
247
220
relationshipsToOmit.add('${ casedName } ');
248
221
return {${ typename }
249
222
${ fields }
@@ -255,14 +228,40 @@ export const ${toMockName(
255
228
typeName ,
256
229
casedName ,
257
230
prefix ,
258
- ) } = (overrides?: Partial<${ typesPrefix } ${ casedName } >): ${ typenameReturnType } ${ typesPrefix } ${ casedName } => {
231
+ ) } = (overrides?: Partial<${ casedNameWithPrefix } >): ${ typenameReturnType } ${ casedNameWithPrefix } => {
259
232
return {${ typename }
260
233
${ fields }
261
234
};
262
235
};` ;
263
236
}
264
237
} ;
265
238
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
+
266
265
type ScalarGeneratorName = keyof Casual . Casual | keyof Casual . functions | string ;
267
266
type ScalarDefinition = {
268
267
generator : ScalarGeneratorName ;
@@ -331,17 +330,18 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
331
330
return {
332
331
name : fieldName ,
333
332
mockFn : ( typeName : string ) => {
334
- const value = generateMockValue (
333
+ const value = generateMockValue ( {
335
334
typeName,
336
335
fieldName,
337
336
types,
338
337
typenamesConvention,
339
338
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
+ } ) ;
345
345
346
346
return ` ${ fieldName } : overrides && overrides.hasOwnProperty('${ fieldName } ') ? overrides.${ fieldName } ! : ${ value } ,` ;
347
347
} ,
@@ -356,17 +356,18 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
356
356
const mockFields = node . fields
357
357
? node . fields
358
358
. map ( ( field ) => {
359
- const value = generateMockValue (
360
- fieldName ,
361
- field . name . value ,
359
+ const value = generateMockValue ( {
360
+ typeName : fieldName ,
361
+ fieldName : field . name . value ,
362
362
types,
363
363
typenamesConvention,
364
364
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
+ } ) ;
370
371
371
372
return ` ${ field . name . value } : overrides && overrides.hasOwnProperty('${ field . name . value } ') ? overrides.${ field . name . value } ! : ${ value } ,` ;
372
373
} )
@@ -442,21 +443,20 @@ export const plugin: PluginFunction<TypescriptMocksPluginConfig> = (schema, docu
442
443
} ,
443
444
} ;
444
445
445
- const result : any = visit ( astNode , { leave : visitor } ) ;
446
+ const result = visit ( astNode , { leave : visitor } ) ;
446
447
const definitions = result . definitions . filter ( ( definition : any ) => ! ! definition ) ;
447
448
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
+ } ) ;
453
457
// List of function that will generate the mock.
454
458
// We generate it after having visited because we need to distinct types from enums
455
459
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
- : '' ;
460
460
461
461
return `${ typesFileImport } ${ mockFns . map ( ( mockFn : Function ) => mockFn ( ) ) . join ( '\n' ) }
462
462
` ;
0 commit comments