...

Source file src/github.com/vektah/gqlparser/v2/validator/rules/possible_fragment_spreads.go

Documentation: github.com/vektah/gqlparser/v2/validator/rules

     1  package validator
     2  
     3  import (
     4  	"github.com/vektah/gqlparser/v2/ast"
     5  
     6  	//nolint:revive // Validator rules each use dot imports for convenience.
     7  	. "github.com/vektah/gqlparser/v2/validator"
     8  )
     9  
    10  func init() {
    11  	AddRule("PossibleFragmentSpreads", func(observers *Events, addError AddErrFunc) {
    12  
    13  		validate := func(walker *Walker, parentDef *ast.Definition, fragmentName string, emitError func()) {
    14  			if parentDef == nil {
    15  				return
    16  			}
    17  
    18  			var parentDefs []*ast.Definition
    19  			switch parentDef.Kind {
    20  			case ast.Object:
    21  				parentDefs = []*ast.Definition{parentDef}
    22  			case ast.Interface, ast.Union:
    23  				parentDefs = walker.Schema.GetPossibleTypes(parentDef)
    24  			default:
    25  				return
    26  			}
    27  
    28  			fragmentDefType := walker.Schema.Types[fragmentName]
    29  			if fragmentDefType == nil {
    30  				return
    31  			}
    32  			if !fragmentDefType.IsCompositeType() {
    33  				// checked by FragmentsOnCompositeTypes
    34  				return
    35  			}
    36  			fragmentDefs := walker.Schema.GetPossibleTypes(fragmentDefType)
    37  
    38  			for _, fragmentDef := range fragmentDefs {
    39  				for _, parentDef := range parentDefs {
    40  					if parentDef.Name == fragmentDef.Name {
    41  						return
    42  					}
    43  				}
    44  			}
    45  
    46  			emitError()
    47  		}
    48  
    49  		observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) {
    50  			validate(walker, inlineFragment.ObjectDefinition, inlineFragment.TypeCondition, func() {
    51  				addError(
    52  					Message(`Fragment cannot be spread here as objects of type "%s" can never be of type "%s".`, inlineFragment.ObjectDefinition.Name, inlineFragment.TypeCondition),
    53  					At(inlineFragment.Position),
    54  				)
    55  			})
    56  		})
    57  
    58  		observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) {
    59  			if fragmentSpread.Definition == nil {
    60  				return
    61  			}
    62  			validate(walker, fragmentSpread.ObjectDefinition, fragmentSpread.Definition.TypeCondition, func() {
    63  				addError(
    64  					Message(`Fragment "%s" cannot be spread here as objects of type "%s" can never be of type "%s".`, fragmentSpread.Name, fragmentSpread.ObjectDefinition.Name, fragmentSpread.Definition.TypeCondition),
    65  					At(fragmentSpread.Position),
    66  				)
    67  			})
    68  		})
    69  	})
    70  }
    71  

View as plain text