@@ -24,6 +24,7 @@ import { Kind } from '../language/kinds';
24
24
25
25
import type {
26
26
DocumentNode ,
27
+ NameNode ,
27
28
TypeNode ,
28
29
NamedTypeNode ,
29
30
SchemaDefinitionNode ,
@@ -49,8 +50,9 @@ import type {
49
50
GraphQLType ,
50
51
GraphQLNamedType ,
51
52
GraphQLFieldConfig ,
53
+ GraphQLArgumentConfig ,
52
54
GraphQLEnumValueConfig ,
53
- GraphQLInputField ,
55
+ GraphQLInputFieldConfig ,
54
56
} from '../type/definition' ;
55
57
56
58
import {
@@ -256,17 +258,17 @@ export class ASTDefinitionBuilder {
256
258
return this . buildType ( typeNode ) ;
257
259
}
258
260
259
- buildDirective ( directiveNode : DirectiveDefinitionNode ) : GraphQLDirective {
261
+ buildDirective ( directive : DirectiveDefinitionNode ) : GraphQLDirective {
262
+ const locations = directive . locations . map (
263
+ ( { value } ) => ( ( value : any ) : DirectiveLocationEnum ) ,
264
+ ) ;
265
+
260
266
return new GraphQLDirective ( {
261
- name : directiveNode . name . value ,
262
- description : getDescription ( directiveNode , this . _options ) ,
263
- locations : directiveNode . locations . map (
264
- node => ( ( node . value : any ) : DirectiveLocationEnum ) ,
265
- ) ,
266
- args :
267
- directiveNode . arguments &&
268
- this . _makeInputValues ( directiveNode . arguments ) ,
269
- astNode : directiveNode ,
267
+ name : directive . name . value ,
268
+ description : getDescription ( directive , this . _options ) ,
269
+ locations,
270
+ args : keyByNameNode ( directive . arguments || [ ] , arg => this . buildArg ( arg ) ) ,
271
+ astNode : directive ,
270
272
} ) ;
271
273
}
272
274
@@ -277,19 +279,31 @@ export class ASTDefinitionBuilder {
277
279
// with validateSchema() will produce more actionable results.
278
280
type : ( this . _buildWrappedType ( field . type ) : any ) ,
279
281
description : getDescription ( field , this . _options ) ,
280
- args : field . arguments && this . _makeInputValues ( field . arguments ) ,
282
+ args : keyByNameNode ( field . arguments || [ ] , arg => this . buildArg ( arg ) ) ,
281
283
deprecationReason : getDeprecationReason ( field ) ,
282
284
astNode : field ,
283
285
} ;
284
286
}
285
287
286
- buildInputField ( value : InputValueDefinitionNode ) : GraphQLInputField {
288
+ buildArg ( value : InputValueDefinitionNode ) : GraphQLArgumentConfig {
289
+ // Note: While this could make assertions to get the correctly typed
290
+ // value, that would throw immediately while type system validation
291
+ // with validateSchema() will produce more actionable results.
292
+ const type : any = this . _buildWrappedType ( value . type ) ;
293
+ return {
294
+ type,
295
+ description : getDescription ( value , this . _options ) ,
296
+ defaultValue : valueFromAST ( value . defaultValue , type ) ,
297
+ astNode : value ,
298
+ } ;
299
+ }
300
+
301
+ buildInputField ( value : InputValueDefinitionNode ) : GraphQLInputFieldConfig {
287
302
// Note: While this could make assertions to get the correctly typed
288
303
// value, that would throw immediately while type system validation
289
304
// with validateSchema() will produce more actionable results.
290
305
const type : any = this . _buildWrappedType ( value . type ) ;
291
306
return {
292
- name : value . name . value ,
293
307
type,
294
308
description : getDescription ( value , this . _options ) ,
295
309
defaultValue : valueFromAST ( value . defaultValue , type ) ,
@@ -305,121 +319,127 @@ export class ASTDefinitionBuilder {
305
319
} ;
306
320
}
307
321
308
- _makeSchemaDef ( def : TypeDefinitionNode ) : GraphQLNamedType {
309
- switch ( def . kind ) {
322
+ _makeSchemaDef ( astNode : TypeDefinitionNode ) : GraphQLNamedType {
323
+ switch ( astNode . kind ) {
310
324
case Kind . OBJECT_TYPE_DEFINITION :
311
- return this . _makeTypeDef ( def ) ;
325
+ return this . _makeTypeDef ( astNode ) ;
312
326
case Kind . INTERFACE_TYPE_DEFINITION :
313
- return this . _makeInterfaceDef ( def ) ;
327
+ return this . _makeInterfaceDef ( astNode ) ;
314
328
case Kind . ENUM_TYPE_DEFINITION :
315
- return this . _makeEnumDef ( def ) ;
329
+ return this . _makeEnumDef ( astNode ) ;
316
330
case Kind . UNION_TYPE_DEFINITION :
317
- return this . _makeUnionDef ( def ) ;
331
+ return this . _makeUnionDef ( astNode ) ;
318
332
case Kind . SCALAR_TYPE_DEFINITION :
319
- return this . _makeScalarDef ( def ) ;
333
+ return this . _makeScalarDef ( astNode ) ;
320
334
case Kind . INPUT_OBJECT_TYPE_DEFINITION :
321
- return this . _makeInputObjectDef ( def ) ;
335
+ return this . _makeInputObjectDef ( astNode ) ;
322
336
default :
323
- throw new Error ( `Type kind "${ def . kind } " not supported.` ) ;
337
+ throw new Error ( `Type kind "${ astNode . kind } " not supported.` ) ;
324
338
}
325
339
}
326
340
327
- _makeTypeDef ( def : ObjectTypeDefinitionNode ) {
328
- const interfaces : ?$ReadOnlyArray < NamedTypeNode > = def.interfaces;
341
+ _makeTypeDef ( astNode : ObjectTypeDefinitionNode ) {
342
+ const interfaceNodes = astNode . interfaces ;
343
+ const fieldNodes = astNode . fields ;
344
+
345
+ // Note: While this could make assertions to get the correctly typed
346
+ // values below, that would throw immediately while type system
347
+ // validation with validateSchema() will produce more actionable results.
348
+ const interfaces =
349
+ interfaceNodes && interfaceNodes . length > 0
350
+ ? ( ) => interfaceNodes . map ( ref => ( this . buildType ( ref ) : any ) )
351
+ : [ ] ;
352
+
353
+ const fields =
354
+ fieldNodes && fieldNodes . length > 0
355
+ ? ( ) => keyByNameNode ( fieldNodes , field => this . buildField ( field ) )
356
+ : Object . create ( null ) ;
357
+
329
358
return new GraphQLObjectType ( {
330
- name : def . name . value ,
331
- description : getDescription ( def , this . _options ) ,
332
- fields : ( ) => this . _makeFieldDefMap ( def ) ,
333
- // Note: While this could make early assertions to get the correctly
334
- // typed values, that would throw immediately while type system
335
- // validation with validateSchema() will produce more actionable results.
336
- interfaces : interfaces
337
- ? ( ) => interfaces . map ( ref => ( this . buildType ( ref ) : any ) )
338
- : [ ] ,
339
- astNode : def ,
359
+ name : astNode . name . value ,
360
+ description : getDescription ( astNode , this . _options ) ,
361
+ interfaces,
362
+ fields,
363
+ astNode,
340
364
} ) ;
341
365
}
342
366
343
- _makeFieldDefMap (
344
- def : ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode ,
345
- ) {
346
- return def . fields
347
- ? keyValMap < _ , GraphQLFieldConfig < mixed , mixed >> (
348
- def . fields ,
349
- field => field . name . value ,
350
- field => this . buildField ( field ) ,
351
- )
352
- : { } ;
353
- }
367
+ _makeInterfaceDef ( astNode : InterfaceTypeDefinitionNode ) {
368
+ const fieldNodes = astNode . fields ;
354
369
355
- _makeInputValues(values: $ReadOnlyArray< InputValueDefinitionNode > ) {
356
- return keyValMap < _ , GraphQLInputField > (
357
- values ,
358
- value => value . name . value ,
359
- value => this . buildInputField ( value ) ,
360
- ) ;
361
- }
370
+ const fields =
371
+ fieldNodes && fieldNodes . length > 0
372
+ ? ( ) => keyByNameNode ( fieldNodes , field => this . buildField ( field ) )
373
+ : Object . create ( null ) ;
362
374
363
- _makeInterfaceDef ( def : InterfaceTypeDefinitionNode ) {
364
375
return new GraphQLInterfaceType ( {
365
- name : def . name . value ,
366
- description : getDescription ( def , this . _options ) ,
367
- fields : ( ) => this . _makeFieldDefMap ( def ) ,
368
- astNode : def ,
376
+ name : astNode . name . value ,
377
+ description : getDescription ( astNode , this . _options ) ,
378
+ fields,
379
+ astNode,
369
380
} ) ;
370
381
}
371
382
372
- _makeEnumDef ( def : EnumTypeDefinitionNode ) {
383
+ _makeEnumDef ( astNode : EnumTypeDefinitionNode ) {
384
+ const valueNodes = astNode . values || [ ] ;
385
+
373
386
return new GraphQLEnumType ( {
374
- name : def . name . value ,
375
- description : getDescription ( def , this . _options ) ,
376
- values : this . _makeValueDefMap ( def ) ,
377
- astNode : def ,
387
+ name : astNode . name . value ,
388
+ description : getDescription ( astNode , this . _options ) ,
389
+ values : keyByNameNode ( valueNodes , value => this . buildEnumValue ( value ) ) ,
390
+ astNode,
378
391
} ) ;
379
392
}
380
393
381
- _makeValueDefMap ( def : EnumTypeDefinitionNode ) {
382
- return def . values
383
- ? keyValMap < _, GraphQLEnumValueConfig> (
384
- def . values ,
385
- enumValue => enumValue . name . value ,
386
- enumValue => this . buildEnumValue ( enumValue ) ,
387
- )
388
- : { } ;
389
- }
394
+ _makeUnionDef ( astNode : UnionTypeDefinitionNode ) {
395
+ const typeNodes = astNode . types ;
396
+
397
+ // Note: While this could make assertions to get the correctly typed
398
+ // values below, that would throw immediately while type system
399
+ // validation with validateSchema() will produce more actionable results.
400
+ const types =
401
+ typeNodes && typeNodes . length > 0
402
+ ? ( ) => typeNodes . map ( ref => ( this . buildType ( ref ) : any ) )
403
+ : [ ] ;
390
404
391
- _makeUnionDef ( def : UnionTypeDefinitionNode ) {
392
- const types : ?$ReadOnlyArray < NamedTypeNode > = def . types ;
393
405
return new GraphQLUnionType ( {
394
- name : def . name . value ,
395
- description : getDescription ( def , this . _options ) ,
396
- // Note: While this could make assertions to get the correctly typed
397
- // values below, that would throw immediately while type system
398
- // validation with validateSchema() will produce more actionable results.
399
- types : types ? ( ) => types . map ( ref => ( this . buildType ( ref ) : any ) ) : [ ] ,
400
- astNode : def ,
406
+ name : astNode . name . value ,
407
+ description : getDescription ( astNode , this . _options ) ,
408
+ types,
409
+ astNode,
401
410
} ) ;
402
411
}
403
412
404
- _makeScalarDef ( def : ScalarTypeDefinitionNode ) {
413
+ _makeScalarDef ( astNode : ScalarTypeDefinitionNode ) {
405
414
return new GraphQLScalarType ( {
406
- name : def . name . value ,
407
- description : getDescription ( def , this . _options ) ,
408
- astNode : def ,
415
+ name : astNode . name . value ,
416
+ description : getDescription ( astNode , this . _options ) ,
417
+ astNode,
409
418
serialize : value => value ,
410
419
} ) ;
411
420
}
412
421
413
422
_makeInputObjectDef ( def : InputObjectTypeDefinitionNode ) {
423
+ const { fields } = def ;
424
+
414
425
return new GraphQLInputObjectType ( {
415
426
name : def . name . value ,
416
427
description : getDescription ( def , this . _options ) ,
417
- fields : ( ) => ( def . fields ? this . _makeInputValues ( def . fields ) : { } ) ,
428
+ fields : fields
429
+ ? ( ) => keyByNameNode ( fields , field => this . buildInputField ( field ) )
430
+ : Object . create ( null ) ,
418
431
astNode : def ,
419
432
} ) ;
420
433
}
421
434
}
422
435
436
+ function keyByNameNode < T : { + name : NameNode } , V > (
437
+ list : $ReadOnlyArray < T > ,
438
+ valFn : ( item : T ) = > V ,
439
+ ) : ObjMap < V > {
440
+ return keyValMap ( list , ( { name } ) => name . value , valFn ) ;
441
+ }
442
+
423
443
/**
424
444
* Given a field or enum value node, returns the string value for the
425
445
* deprecation reason.
0 commit comments