@@ -20,10 +20,7 @@ import { locatedError } from '../error/locatedError';
20
20
import type {
21
21
DocumentNode ,
22
22
OperationDefinitionNode ,
23
- SelectionSetNode ,
24
23
FieldNode ,
25
- FragmentSpreadNode ,
26
- InlineFragmentNode ,
27
24
FragmentDefinitionNode ,
28
25
} from '../language/ast' ;
29
26
import { Kind } from '../language/kinds' ;
@@ -46,10 +43,6 @@ import {
46
43
TypeMetaFieldDef ,
47
44
TypeNameMetaFieldDef ,
48
45
} from '../type/introspection' ;
49
- import {
50
- GraphQLIncludeDirective ,
51
- GraphQLSkipDirective ,
52
- } from '../type/directives' ;
53
46
import {
54
47
isObjectType ,
55
48
isAbstractType ,
@@ -58,14 +51,10 @@ import {
58
51
isNonNullType ,
59
52
} from '../type/definition' ;
60
53
61
- import { typeFromAST } from '../utilities/typeFromAST' ;
62
54
import { getOperationRootType } from '../utilities/getOperationRootType' ;
63
55
64
- import {
65
- getVariableValues ,
66
- getArgumentValues ,
67
- getDirectiveValues ,
68
- } from './values' ;
56
+ import { getVariableValues , getArgumentValues } from './values' ;
57
+ import { collectFields } from './collectFields' ;
69
58
70
59
/**
71
60
* Terminology
@@ -336,7 +325,9 @@ function executeOperation(
336
325
) : PromiseOrValue < ObjMap < unknown > | null > {
337
326
const type = getOperationRootType ( exeContext . schema , operation ) ;
338
327
const fields = collectFields (
339
- exeContext ,
328
+ exeContext . schema ,
329
+ exeContext . fragments ,
330
+ exeContext . variableValues ,
340
331
type ,
341
332
operation . selectionSet ,
342
333
new Map ( ) ,
@@ -447,141 +438,6 @@ function executeFields(
447
438
return promiseForObject ( results ) ;
448
439
}
449
440
450
- /**
451
- * Given a selectionSet, adds all of the fields in that selection to
452
- * the passed in map of fields, and returns it at the end.
453
- *
454
- * CollectFields requires the "runtime type" of an object. For a field which
455
- * returns an Interface or Union type, the "runtime type" will be the actual
456
- * Object type returned by that field.
457
- *
458
- * @internal
459
- */
460
- export function collectFields (
461
- exeContext : ExecutionContext ,
462
- runtimeType : GraphQLObjectType ,
463
- selectionSet : SelectionSetNode ,
464
- fields : Map < string , Array < FieldNode > > ,
465
- visitedFragmentNames : Set < string > ,
466
- ) : Map < string , ReadonlyArray < FieldNode > > {
467
- for ( const selection of selectionSet . selections ) {
468
- switch ( selection . kind ) {
469
- case Kind . FIELD : {
470
- if ( ! shouldIncludeNode ( exeContext , selection ) ) {
471
- continue ;
472
- }
473
- const name = getFieldEntryKey ( selection ) ;
474
- const fieldList = fields . get ( name ) ;
475
- if ( fieldList !== undefined ) {
476
- fieldList . push ( selection ) ;
477
- } else {
478
- fields . set ( name , [ selection ] ) ;
479
- }
480
- break ;
481
- }
482
- case Kind . INLINE_FRAGMENT : {
483
- if (
484
- ! shouldIncludeNode ( exeContext , selection ) ||
485
- ! doesFragmentConditionMatch ( exeContext , selection , runtimeType )
486
- ) {
487
- continue ;
488
- }
489
- collectFields (
490
- exeContext ,
491
- runtimeType ,
492
- selection . selectionSet ,
493
- fields ,
494
- visitedFragmentNames ,
495
- ) ;
496
- break ;
497
- }
498
- case Kind . FRAGMENT_SPREAD : {
499
- const fragName = selection . name . value ;
500
- if (
501
- visitedFragmentNames . has ( fragName ) ||
502
- ! shouldIncludeNode ( exeContext , selection )
503
- ) {
504
- continue ;
505
- }
506
- visitedFragmentNames . add ( fragName ) ;
507
- const fragment = exeContext . fragments [ fragName ] ;
508
- if (
509
- ! fragment ||
510
- ! doesFragmentConditionMatch ( exeContext , fragment , runtimeType )
511
- ) {
512
- continue ;
513
- }
514
- collectFields (
515
- exeContext ,
516
- runtimeType ,
517
- fragment . selectionSet ,
518
- fields ,
519
- visitedFragmentNames ,
520
- ) ;
521
- break ;
522
- }
523
- }
524
- }
525
- return fields ;
526
- }
527
-
528
- /**
529
- * Determines if a field should be included based on the @include and @skip
530
- * directives, where @skip has higher precedence than @include.
531
- */
532
- function shouldIncludeNode (
533
- exeContext : ExecutionContext ,
534
- node : FragmentSpreadNode | FieldNode | InlineFragmentNode ,
535
- ) : boolean {
536
- const skip = getDirectiveValues (
537
- GraphQLSkipDirective ,
538
- node ,
539
- exeContext . variableValues ,
540
- ) ;
541
- if ( skip ?. if === true ) {
542
- return false ;
543
- }
544
-
545
- const include = getDirectiveValues (
546
- GraphQLIncludeDirective ,
547
- node ,
548
- exeContext . variableValues ,
549
- ) ;
550
- if ( include ?. if === false ) {
551
- return false ;
552
- }
553
- return true ;
554
- }
555
-
556
- /**
557
- * Determines if a fragment is applicable to the given type.
558
- */
559
- function doesFragmentConditionMatch (
560
- exeContext : ExecutionContext ,
561
- fragment : FragmentDefinitionNode | InlineFragmentNode ,
562
- type : GraphQLObjectType ,
563
- ) : boolean {
564
- const typeConditionNode = fragment . typeCondition ;
565
- if ( ! typeConditionNode ) {
566
- return true ;
567
- }
568
- const conditionalType = typeFromAST ( exeContext . schema , typeConditionNode ) ;
569
- if ( conditionalType === type ) {
570
- return true ;
571
- }
572
- if ( isAbstractType ( conditionalType ) ) {
573
- return exeContext . schema . isSubType ( conditionalType , type ) ;
574
- }
575
- return false ;
576
- }
577
-
578
- /**
579
- * Implements the logic to compute the key of a given field's entry
580
- */
581
- function getFieldEntryKey ( node : FieldNode ) : string {
582
- return node . alias ? node . alias . value : node . name . value ;
583
- }
584
-
585
441
/**
586
442
* Implements the "Executing field" section of the spec
587
443
* In particular, this function figures out the value that the field returns by
@@ -1081,7 +937,9 @@ function _collectSubfields(
1081
937
for ( const node of fieldNodes ) {
1082
938
if ( node . selectionSet ) {
1083
939
subFieldNodes = collectFields (
1084
- exeContext ,
940
+ exeContext . schema ,
941
+ exeContext . fragments ,
942
+ exeContext . variableValues ,
1085
943
returnType ,
1086
944
node . selectionSet ,
1087
945
subFieldNodes ,
0 commit comments