Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var FieldsOnCorrectTypeRule = Rule{ Name: "FieldsOnCorrectType", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncFieldsOnCorrectType(observers, addError, false) }, }
View Source
var FieldsOnCorrectTypeRuleWithoutSuggestions = Rule{ Name: "FieldsOnCorrectTypeWithoutSuggestions", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncFieldsOnCorrectType(observers, addError, true) }, }
View Source
var FragmentsOnCompositeTypesRule = Rule{ Name: "FragmentsOnCompositeTypes", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) { fragmentType := walker.Schema.Types[inlineFragment.TypeCondition] if fragmentType == nil || fragmentType.IsCompositeType() { return } message := fmt.Sprintf(`Fragment cannot condition on non composite type "%s".`, inlineFragment.TypeCondition) addError( Message("%s", message), At(inlineFragment.Position), ) }) observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { if fragment.Definition == nil || fragment.TypeCondition == "" || fragment.Definition.IsCompositeType() { return } message := fmt.Sprintf(`Fragment "%s" cannot condition on non composite type "%s".`, fragment.Name, fragment.TypeCondition) addError( Message("%s", message), At(fragment.Position), ) }) }, }
View Source
var KnownArgumentNamesRule = Rule{ Name: "KnownArgumentNames", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncKnownArgumentNames(observers, addError, false) }, }
View Source
var KnownArgumentNamesRuleWithoutSuggestions = Rule{ Name: "KnownArgumentNamesWithoutSuggestions", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncKnownArgumentNames(observers, addError, true) }, }
View Source
var KnownDirectivesRule = Rule{ Name: "KnownDirectives", RuleFunc: func(observers *Events, addError AddErrFunc) { type mayNotBeUsedDirective struct { Name string Line int Column int } seen := map[mayNotBeUsedDirective]bool{} observers.OnDirective(func(walker *Walker, directive *ast.Directive) { if directive.Definition == nil { addError( Message(`Unknown directive "@%s".`, directive.Name), At(directive.Position), ) return } for _, loc := range directive.Definition.Locations { if loc == directive.Location { return } } tmp := mayNotBeUsedDirective{ Name: directive.Name, Line: directive.Position.Line, Column: directive.Position.Column, } if !seen[tmp] { addError( Message(`Directive "@%s" may not be used on %s.`, directive.Name, directive.Location), At(directive.Position), ) seen[tmp] = true } }) }, }
View Source
var KnownFragmentNamesRule = Rule{ Name: "KnownFragmentNames", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) { if fragmentSpread.Definition == nil { addError( Message(`Unknown fragment "%s".`, fragmentSpread.Name), At(fragmentSpread.Position), ) } }) }, }
View Source
var KnownRootTypeRule = Rule{ Name: "KnownRootType", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { var def *ast.Definition switch operation.Operation { case ast.Query, "": def = walker.Schema.Query case ast.Mutation: def = walker.Schema.Mutation case ast.Subscription: def = walker.Schema.Subscription default: panic(fmt.Sprintf(`got unknown operation type "%s"`, operation.Operation)) } if def == nil { addError( Message(`Schema does not support operation type "%s"`, operation.Operation), At(operation.Position)) } }) }, }
View Source
var KnownTypeNamesRule = Rule{ Name: "KnownTypeNames", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncKnownTypeNames(observers, addError, false) }, }
View Source
var KnownTypeNamesRuleWithoutSuggestions = Rule{ Name: "KnownTypeNamesWithoutSuggestions", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncKnownTypeNames(observers, addError, true) }, }
View Source
var LoneAnonymousOperationRule = Rule{ Name: "LoneAnonymousOperation", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { if operation.Name == "" && len(walker.Document.Operations) > 1 { addError( Message(`This anonymous operation must be the only defined operation.`), At(operation.Position), ) } }) }, }
View Source
var NoFragmentCyclesRule = Rule{ Name: "NoFragmentCycles", RuleFunc: func(observers *Events, addError AddErrFunc) { visitedFrags := make(map[string]bool) observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { var spreadPath []*ast.FragmentSpread spreadPathIndexByName := make(map[string]int) var recursive func(fragment *ast.FragmentDefinition) recursive = func(fragment *ast.FragmentDefinition) { if visitedFrags[fragment.Name] { return } visitedFrags[fragment.Name] = true spreadNodes := getFragmentSpreads(fragment.SelectionSet) if len(spreadNodes) == 0 { return } spreadPathIndexByName[fragment.Name] = len(spreadPath) for _, spreadNode := range spreadNodes { spreadName := spreadNode.Name cycleIndex, ok := spreadPathIndexByName[spreadName] spreadPath = append(spreadPath, spreadNode) if !ok { spreadFragment := walker.Document.Fragments.ForName(spreadName) if spreadFragment != nil { recursive(spreadFragment) } } else { cyclePath := spreadPath[cycleIndex : len(spreadPath)-1] var fragmentNames []string for _, fs := range cyclePath { fragmentNames = append(fragmentNames, fmt.Sprintf(`"%s"`, fs.Name)) } var via string if len(fragmentNames) != 0 { via = fmt.Sprintf(" via %s", strings.Join(fragmentNames, ", ")) } addError( Message(`Cannot spread fragment "%s" within itself%s.`, spreadName, via), At(spreadNode.Position), ) } spreadPath = spreadPath[:len(spreadPath)-1] } delete(spreadPathIndexByName, fragment.Name) } recursive(fragment) }) }, }
View Source
var NoUndefinedVariablesRule = Rule{ Name: "NoUndefinedVariables", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnValue(func(walker *Walker, value *ast.Value) { if walker.CurrentOperation == nil || value.Kind != ast.Variable || value.VariableDefinition != nil { return } if walker.CurrentOperation.Name != "" { addError( Message(`Variable "%s" is not defined by operation "%s".`, value, walker.CurrentOperation.Name), At(value.Position), ) } else { addError( Message(`Variable "%s" is not defined.`, value), At(value.Position), ) } }) }, }
View Source
var NoUnusedFragmentsRule = Rule{ Name: "NoUnusedFragments", RuleFunc: func(observers *Events, addError AddErrFunc) { inFragmentDefinition := false fragmentNameUsed := make(map[string]bool) observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) { if !inFragmentDefinition { fragmentNameUsed[fragmentSpread.Name] = true } }) observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { inFragmentDefinition = true if !fragmentNameUsed[fragment.Name] { addError( Message(`Fragment "%s" is never used.`, fragment.Name), At(fragment.Position), ) } }) }, }
View Source
var NoUnusedVariablesRule = Rule{ Name: "NoUnusedVariables", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { for _, varDef := range operation.VariableDefinitions { if varDef.Used { continue } if operation.Name != "" { addError( Message(`Variable "$%s" is never used in operation "%s".`, varDef.Variable, operation.Name), At(varDef.Position), ) } else { addError( Message(`Variable "$%s" is never used.`, varDef.Variable), At(varDef.Position), ) } } }) }, }
View Source
var OverlappingFieldsCanBeMergedRule = Rule{ Name: "OverlappingFieldsCanBeMerged", RuleFunc: func(observers *Events, addError AddErrFunc) { m := &overlappingFieldsCanBeMergedManager{ comparedFragmentPairs: pairSet{data: make(map[string]map[string]bool)}, } observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { m.walker = walker conflicts := m.findConflictsWithinSelectionSet(operation.SelectionSet) for _, conflict := range conflicts { conflict.addFieldsConflictMessage(addError) } }) observers.OnField(func(walker *Walker, field *ast.Field) { if walker.CurrentOperation == nil { return } m.walker = walker conflicts := m.findConflictsWithinSelectionSet(field.SelectionSet) for _, conflict := range conflicts { conflict.addFieldsConflictMessage(addError) } }) observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) { m.walker = walker conflicts := m.findConflictsWithinSelectionSet(inlineFragment.SelectionSet) for _, conflict := range conflicts { conflict.addFieldsConflictMessage(addError) } }) observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { m.walker = walker conflicts := m.findConflictsWithinSelectionSet(fragment.SelectionSet) for _, conflict := range conflicts { conflict.addFieldsConflictMessage(addError) } }) }, }
View Source
var PossibleFragmentSpreadsRule = Rule{ Name: "PossibleFragmentSpreads", RuleFunc: func(observers *Events, addError AddErrFunc) { validate := func(walker *Walker, parentDef *ast.Definition, fragmentName string, emitError func()) { if parentDef == nil { return } var parentDefs []*ast.Definition switch parentDef.Kind { case ast.Object: parentDefs = []*ast.Definition{parentDef} case ast.Interface, ast.Union: parentDefs = walker.Schema.GetPossibleTypes(parentDef) default: return } fragmentDefType := walker.Schema.Types[fragmentName] if fragmentDefType == nil { return } if !fragmentDefType.IsCompositeType() { return } fragmentDefs := walker.Schema.GetPossibleTypes(fragmentDefType) for _, fragmentDef := range fragmentDefs { for _, parentDef := range parentDefs { if parentDef.Name == fragmentDef.Name { return } } } emitError() } observers.OnInlineFragment(func(walker *Walker, inlineFragment *ast.InlineFragment) { validate(walker, inlineFragment.ObjectDefinition, inlineFragment.TypeCondition, func() { addError( Message(`Fragment cannot be spread here as objects of type "%s" can never be of type "%s".`, inlineFragment.ObjectDefinition.Name, inlineFragment.TypeCondition), At(inlineFragment.Position), ) }) }) observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) { if fragmentSpread.Definition == nil { return } validate(walker, fragmentSpread.ObjectDefinition, fragmentSpread.Definition.TypeCondition, func() { addError( 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), At(fragmentSpread.Position), ) }) }) }, }
View Source
var ProvidedRequiredArgumentsRule = Rule{ Name: "ProvidedRequiredArguments", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnField(func(walker *Walker, field *ast.Field) { if field.Definition == nil { return } argDef: for _, argDef := range field.Definition.Arguments { if !argDef.Type.NonNull { continue } if argDef.DefaultValue != nil { continue } for _, arg := range field.Arguments { if arg.Name == argDef.Name { continue argDef } } addError( Message(`Field "%s" argument "%s" of type "%s" is required, but it was not provided.`, field.Name, argDef.Name, argDef.Type.String()), At(field.Position), ) } }) observers.OnDirective(func(walker *Walker, directive *ast.Directive) { if directive.Definition == nil { return } argDef: for _, argDef := range directive.Definition.Arguments { if !argDef.Type.NonNull { continue } if argDef.DefaultValue != nil { continue } for _, arg := range directive.Arguments { if arg.Name == argDef.Name { continue argDef } } addError( Message(`Directive "@%s" argument "%s" of type "%s" is required, but it was not provided.`, directive.Definition.Name, argDef.Name, argDef.Type.String()), At(directive.Position), ) } }) }, }
View Source
var ScalarLeafsRule = Rule{ Name: "ScalarLeafs", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnField(func(walker *Walker, field *ast.Field) { if field.Definition == nil { return } fieldType := walker.Schema.Types[field.Definition.Type.Name()] if fieldType == nil { return } if fieldType.IsLeafType() && len(field.SelectionSet) > 0 { addError( Message(`Field "%s" must not have a selection since type "%s" has no subfields.`, field.Name, fieldType.Name), At(field.Position), ) } if !fieldType.IsLeafType() && len(field.SelectionSet) == 0 { addError( Message(`Field "%s" of type "%s" must have a selection of subfields.`, field.Name, field.Definition.Type.String()), Suggestf(`"%s { ... }"`, field.Name), At(field.Position), ) } }) }, }
View Source
var SingleFieldSubscriptionsRule = Rule{ Name: "SingleFieldSubscriptions", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { if walker.Schema.Subscription == nil || operation.Operation != ast.Subscription { return } fields := retrieveTopFieldNames(operation.SelectionSet) name := "Anonymous Subscription" if operation.Name != "" { name = `Subscription ` + strconv.Quote(operation.Name) } if len(fields) > 1 { addError( Message(`%s must select only one top level field.`, name), At(fields[1].position), ) } for _, field := range fields { if strings.HasPrefix(field.name, "__") { addError( Message(`%s must not select an introspection top level field.`, name), At(field.position), ) } } }) }, }
View Source
var UniqueArgumentNamesRule = Rule{ Name: "UniqueArgumentNames", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnField(func(walker *Walker, field *ast.Field) { checkUniqueArgs(field.Arguments, addError) }) observers.OnDirective(func(walker *Walker, directive *ast.Directive) { checkUniqueArgs(directive.Arguments, addError) }) }, }
View Source
var UniqueDirectivesPerLocationRule = Rule{ Name: "UniqueDirectivesPerLocation", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnDirectiveList(func(walker *Walker, directives []*ast.Directive) { seen := map[string]bool{} for _, dir := range directives { if dir.Name != "repeatable" && seen[dir.Name] { addError( Message(`The directive "@%s" can only be used once at this location.`, dir.Name), At(dir.Position), ) } seen[dir.Name] = true } }) }, }
View Source
var UniqueFragmentNamesRule = Rule{ Name: "UniqueFragmentNames", RuleFunc: func(observers *Events, addError AddErrFunc) { seenFragments := map[string]bool{} observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) { if seenFragments[fragment.Name] { addError( Message(`There can be only one fragment named "%s".`, fragment.Name), At(fragment.Position), ) } seenFragments[fragment.Name] = true }) }, }
View Source
var UniqueInputFieldNamesRule = Rule{ Name: "UniqueInputFieldNames", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnValue(func(walker *Walker, value *ast.Value) { if value.Kind != ast.ObjectValue { return } seen := map[string]bool{} for _, field := range value.Children { if seen[field.Name] { addError( Message(`There can be only one input field named "%s".`, field.Name), At(field.Position), ) } seen[field.Name] = true } }) }, }
View Source
var UniqueOperationNamesRule = Rule{ Name: "UniqueOperationNames", RuleFunc: func(observers *Events, addError AddErrFunc) { seen := map[string]bool{} observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { if seen[operation.Name] { addError( Message(`There can be only one operation named "%s".`, operation.Name), At(operation.Position), ) } seen[operation.Name] = true }) }, }
View Source
var UniqueVariableNamesRule = Rule{ Name: "UniqueVariableNames", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { seen := map[string]int{} for _, def := range operation.VariableDefinitions { if seen[def.Variable] == 1 { addError( Message(`There can be only one variable named "$%s".`, def.Variable), At(def.Position), ) } seen[def.Variable]++ } }) }, }
View Source
var ValuesOfCorrectTypeRule = Rule{ Name: "ValuesOfCorrectType", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncValuesOfCorrectType(observers, addError, false) }, }
View Source
var ValuesOfCorrectTypeRuleWithoutSuggestions = Rule{ Name: "ValuesOfCorrectTypeWithoutSuggestions", RuleFunc: func(observers *Events, addError AddErrFunc) { ruleFuncValuesOfCorrectType(observers, addError, true) }, }
View Source
var VariablesAreInputTypesRule = Rule{ Name: "VariablesAreInputTypes", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) { for _, def := range operation.VariableDefinitions { if def.Definition == nil { continue } if !def.Definition.IsInputType() { addError( Message( `Variable "$%s" cannot be non-input type "%s".`, def.Variable, def.Type.String(), ), At(def.Position), ) } } }) }, }
View Source
var VariablesInAllowedPositionRule = Rule{ Name: "VariablesInAllowedPosition", RuleFunc: func(observers *Events, addError AddErrFunc) { observers.OnValue(func(walker *Walker, value *ast.Value) { if value.Kind != ast.Variable || value.ExpectedType == nil || value.VariableDefinition == nil || walker.CurrentOperation == nil { return } tmp := *value.ExpectedType if value.VariableDefinition.DefaultValue != nil && value.VariableDefinition.DefaultValue.Kind != ast.NullValue { if value.ExpectedType.NonNull { tmp.NonNull = false } } if !value.VariableDefinition.Type.IsCompatible(&tmp) { addError( Message( `Variable "%s" of type "%s" used in position expecting type "%s".`, value, value.VariableDefinition.Type.String(), value.ExpectedType.String(), ), At(value.Position), ) } }) }, }
Functions ¶
This section is empty.
Types ¶
type ConflictMessage ¶
type ConflictMessage struct { Message string ResponseName string Names []string SubMessage []*ConflictMessage Position *ast.Position }
func (*ConflictMessage) String ¶
func (m *ConflictMessage) String(buf *bytes.Buffer)
Source Files ¶
- fields_on_correct_type.go
- fragments_on_composite_types.go
- known_argument_names.go
- known_directives.go
- known_fragment_names.go
- known_root_type.go
- known_type_names.go
- lone_anonymous_operation.go
- no_fragment_cycles.go
- no_undefined_variables.go
- no_unused_fragments.go
- no_unused_variables.go
- overlapping_fields_can_be_merged.go
- possible_fragment_spreads.go
- provided_required_arguments.go
- scalar_leafs.go
- single_field_subscriptions.go
- unique_argument_names.go
- unique_directives_per_location.go
- unique_fragment_names.go
- unique_input_field_names.go
- unique_operation_names.go
- unique_variable_names.go
- values_of_correct_type.go
- variables_are_input_types.go
- variables_in_allowed_position.go
Click to show internal directories.
Click to hide internal directories.