@@ -169,6 +169,12 @@ export class GenerateFragments {
169
169
return line ;
170
170
}
171
171
172
+ private fragmentType = {
173
+ DEFAULT : "" ,
174
+ NO_RELATIONS : "NoNesting" ,
175
+ DEEP : "DeepNesting" ,
176
+ } ;
177
+
172
178
private makeFragments ( schemaContents : string , generator : string ) {
173
179
const document : DocumentNode = parse ( schemaContents , { noLocation : true } ) ;
174
180
const ast : GraphQLSchema = buildASTSchema ( document ) ;
@@ -199,9 +205,10 @@ export class GenerateFragments {
199
205
: 1
200
206
) ;
201
207
208
+
202
209
// console.log(typeNames)
203
210
204
- const definitions = typeNames . map ( typeName => {
211
+ const standardFragments = typeNames . map ( typeName => {
205
212
const type : any = ast . getType ( typeName ) ;
206
213
const { name } = type ;
207
214
@@ -220,16 +227,36 @@ export class GenerateFragments {
220
227
221
228
} ) ;
222
229
223
- const noRelations = typeNames . map ( typeName => {
230
+ const noRelationsFragments = typeNames . map ( typeName => {
224
231
const type : any = ast . getType ( typeName ) ;
225
232
const { name } = type ;
226
233
227
234
const fields : GraphQLFieldMap < any , any > = type . getFields ( ) ;
228
235
return {
229
236
name,
230
- fragment : `fragment ${ name } NoRelation on ${ name } {
237
+ fragment : `fragment ${ name } ${ this . fragmentType . NO_RELATIONS } on ${ name } {
231
238
${ Object . keys ( fields ) . map ( field => {
232
- return this . printField ( field , fields [ field ] , ast , true ) ;
239
+ return this . printField ( field , fields [ field ] , ast , this . fragmentType . NO_RELATIONS ) ;
240
+ } )
241
+ // Some fields should not be printed, ie. fields with relations.
242
+ // Remove those from the output by returning null from printField.
243
+ . filter ( field => field != null )
244
+ . join ( this . indentedLine ( 1 ) ) }
245
+ }
246
+ `
247
+ } ;
248
+
249
+ } ) ;
250
+ const deepFragments = typeNames . map ( typeName => {
251
+ const type : any = ast . getType ( typeName ) ;
252
+ const { name } = type ;
253
+
254
+ const fields : GraphQLFieldMap < any , any > = type . getFields ( ) ;
255
+ return {
256
+ name,
257
+ fragment : `fragment ${ name } ${ this . fragmentType . DEEP } on ${ name } {
258
+ ${ Object . keys ( fields ) . map ( field => {
259
+ return this . printField ( field , fields [ field ] , ast , this . fragmentType . DEEP ) ;
233
260
} )
234
261
// Some fields should not be printed, ie. fields with relations.
235
262
// Remove those from the output by returning null from printField.
@@ -244,38 +271,62 @@ export class GenerateFragments {
244
271
if ( generator === 'js' ) {
245
272
return `// THIS FILE HAS BEEN AUTO-GENERATED BY "graphql-cli-generate-fragments"
246
273
// DO NOT EDIT THIS FILE DIRECTLY
247
- ${ definitions
274
+ ${ standardFragments
248
275
. map (
249
276
( { name, fragment } ) => `
250
277
export const ${ name } Fragment = \`${ fragment } \`
251
278
` ,
252
279
)
253
280
. join ( "" ) }
254
- ${ noRelations
281
+ ${ noRelationsFragments
255
282
. map (
256
283
( { name, fragment } ) => `
257
- export const ${ name } NoRelationFragment = \`${ fragment } \`
284
+ export const ${ name } ${ this . fragmentType . NO_RELATIONS } Fragment = \`${ fragment } \`
258
285
` ,
259
286
)
260
287
. join ( "" ) }
288
+ ${ deepFragments
289
+ . map (
290
+ ( { name, fragment } ) => `
291
+ export const ${ name } ${ this . fragmentType . DEEP } Fragment = \`${ fragment } \`
292
+ ` ,
293
+ )
294
+ . join ( "" ) }
261
295
` ;
262
296
}
263
297
return `# THIS FILE HAS BEEN AUTO-GENERATED BY "graphql-cli-generate-fragments"
264
298
# DO NOT EDIT THIS FILE DIRECTLY
265
299
266
- ${ definitions
300
+ # Standard Fragments
301
+ # Nested fragments will spread one layer deep
302
+
303
+ ${ standardFragments
267
304
. map ( ( { name, fragment } ) => `
268
305
${ fragment } `)
269
306
. join ( "" ) }
270
- ${ noRelations
307
+
308
+ # No Relational objects
309
+ # No nested fragments
310
+
311
+ ${ noRelationsFragments
312
+ . map ( ( { name, fragment } ) => `
313
+ ${ fragment } `)
314
+ . join ( "" ) }
315
+
316
+ # Deeply nested Fragments
317
+ # Will include n nested fragments
318
+ # If there is a recursive relation you will receive a
319
+ # "Cannot spread fragment within itself" error when using
320
+
321
+ ${ deepFragments
271
322
. map ( ( { name, fragment } ) => `
272
323
${ fragment } `)
273
324
. join ( "" ) }
274
325
`
275
326
276
327
}
277
328
278
- private printField ( fieldName , field , ast : GraphQLSchema , noRelation = false , indent = 1 ) {
329
+ private printField ( fieldName , field , ast : GraphQLSchema , fragmentType = this . fragmentType . DEFAULT , indent = 1 ) {
279
330
let constructorName =
280
331
field . type . constructor . name && field . type . constructor . name ;
281
332
if ( constructorName === "Object" )
@@ -315,7 +366,7 @@ ${fragment}`)
315
366
}
316
367
317
368
if ( constructorName === "GraphQLObjectType" ) {
318
- if ( noRelation ) return null
369
+ if ( fragmentType === this . fragmentType . NO_RELATIONS ) return null
319
370
let typeName = null ;
320
371
// if(field.name !== undefined)
321
372
typeName =
@@ -327,7 +378,7 @@ ${fragment}`)
327
378
" {" +
328
379
this . indentedLine ( indent + 1 ) +
329
380
"..." +
330
- `${ typeName } NoRelation ` +
381
+ `${ ( fragmentType === this . fragmentType . DEFAULT ) && typeName + this . fragmentType . NO_RELATIONS || typeName + this . fragmentType . DEFAULT } ` +
331
382
this . indentedLine ( indent ) +
332
383
"}"
333
384
) ;
0 commit comments