@@ -25,6 +25,10 @@ const OpenTracingTagTrivial = "graphql.trivial"
25
25
const OpenTracingTagArgsPrefix = "graphql.args."
26
26
const OpenTracingTagError = "graphql.error"
27
27
28
+ type contextKey string
29
+
30
+ const GRAPHQL_FIELDS contextKey = "GRAPHQL_FIELD"
31
+
28
32
type Exec struct {
29
33
queryExec iExec
30
34
mutationExec iExec
@@ -494,12 +498,14 @@ func (e *objectExec) execSelectionSet(ctx context.Context, r *request, selSet *q
494
498
495
499
switch sel := sel .(type ) {
496
500
case * query.Field :
501
+ var namedFields []string
497
502
if skipByDirective (r , sel .Directives ) {
498
503
continue
499
504
}
500
505
506
+ namedFields = resolveFieldNames ("" , namedFields , sel .SelSet , r .doc )
501
507
execSel (func () {
502
- e .execField (ctx , r , sel , resolver , addResult )
508
+ e .execField (context . WithValue ( ctx , GRAPHQL_FIELDS , namedFields ) , r , sel , resolver , addResult )
503
509
})
504
510
505
511
case * query.FragmentSpread :
@@ -533,6 +539,32 @@ func (e *objectExec) execSelectionSet(ctx context.Context, r *request, selSet *q
533
539
wg .Wait ()
534
540
}
535
541
542
+ func resolveFieldNames (prefix string , namedFields []string , selSet * query.SelectionSet , doc * query.Document ) []string {
543
+ if selSet != nil {
544
+ for _ , selectionField := range selSet .Selections {
545
+ switch selectionField := selectionField .(type ) {
546
+ case * query.Field :
547
+ if selectionField .SelSet != nil {
548
+ namedFields = resolveFieldNames (selectionField .Name + "." , namedFields , selectionField .SelSet , doc )
549
+ } else {
550
+ namedFields = append (namedFields , prefix + selectionField .Name )
551
+ }
552
+ case * query.FragmentSpread :
553
+ frag , ok := doc .Fragments [selectionField .Name ]
554
+ if ! ok {
555
+ panic (fmt .Errorf ("fragment %q not found" , selectionField .Name )) // TODO proper error handling
556
+ }
557
+ namedFields = resolveFieldNames (prefix , namedFields , frag .SelSet , doc )
558
+ case * query.InlineFragment :
559
+ namedFields = resolveFieldNames (prefix , namedFields , selectionField .SelSet , doc )
560
+ default :
561
+ panic ("invalid type" )
562
+ }
563
+ }
564
+ }
565
+ return namedFields
566
+ }
567
+
536
568
func (e * objectExec ) execField (ctx context.Context , r * request , f * query.Field , resolver reflect.Value , addResult addResultFn ) {
537
569
switch f .Name {
538
570
case "__typename" :
0 commit comments