Skip to content

Commit

Permalink
validator: make rules exported and allow custom set of rules for Vali…
Browse files Browse the repository at this point in the history
…date (#320)

* validator: make rules exported and allow custom set of rules be passed to the Validate

* use format string as a first argument to Message()

---------

Co-authored-by: Kirill Grigorev <[email protected]>
  • Loading branch information
kgrigorev and Kirill Grigorev authored Sep 26, 2024
1 parent ed10d5c commit 068eddf
Show file tree
Hide file tree
Showing 30 changed files with 298 additions and 124 deletions.
3 changes: 2 additions & 1 deletion validator/imported_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import (
"testing"

"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"

"github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/gqlerror"
"gopkg.in/yaml.v2"
)

type Spec struct {
Expand Down
17 changes: 11 additions & 6 deletions validator/rules/fields_on_correct_type.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"fmt"
Expand All @@ -11,8 +11,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("FieldsOnCorrectType", func(observers *Events, addError AddErrFunc) {
var FieldsOnCorrectTypeRule = Rule{
Name: "FieldsOnCorrectType",
RuleFunc: func(observers *Events, addError AddErrFunc) {
observers.OnField(func(walker *Walker, field *ast.Field) {
if field.ObjectDefinition == nil || field.Definition != nil {
return
Expand All @@ -27,14 +28,18 @@ func init() {
}

addError(
Message(message),
Message("%s", message),
At(field.Position),
)
})
})
},
}

func init() {
AddRule(FieldsOnCorrectTypeRule.Name, FieldsOnCorrectTypeRule.RuleFunc)
}

// Go through all of the implementations of type, as well as the interfaces
// Go through all the implementations of type, as well as the interfaces
// that they implement. If any of those types include the provided field,
// suggest them, sorted by how often the type is referenced, starting
// with Interfaces.
Expand Down
17 changes: 11 additions & 6 deletions validator/rules/fragments_on_composite_types.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"fmt"
Expand All @@ -9,8 +9,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("FragmentsOnCompositeTypes", func(observers *Events, addError AddErrFunc) {
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() {
Expand All @@ -20,7 +21,7 @@ func init() {
message := fmt.Sprintf(`Fragment cannot condition on non composite type "%s".`, inlineFragment.TypeCondition)

addError(
Message(message),
Message("%s", message),
At(inlineFragment.Position),
)
})
Expand All @@ -33,9 +34,13 @@ func init() {
message := fmt.Sprintf(`Fragment "%s" cannot condition on non composite type "%s".`, fragment.Name, fragment.TypeCondition)

addError(
Message(message),
Message("%s", message),
At(fragment.Position),
)
})
})
},
}

func init() {
AddRule(FragmentsOnCompositeTypesRule.Name, FragmentsOnCompositeTypesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/known_argument_names.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownArgumentNames", func(observers *Events, addError AddErrFunc) {
var KnownArgumentNamesRule = Rule{
Name: "KnownArgumentNames",
RuleFunc: func(observers *Events, addError AddErrFunc) {
// A GraphQL field is only valid if all supplied arguments are defined by that field.
observers.OnField(func(walker *Walker, field *ast.Field) {
if field.Definition == nil || field.ObjectDefinition == nil {
Expand Down Expand Up @@ -55,5 +56,9 @@ func init() {
)
}
})
})
},
}

func init() {
AddRule(KnownArgumentNamesRule.Name, KnownArgumentNamesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/known_directives.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownDirectives", func(observers *Events, addError AddErrFunc) {
var KnownDirectivesRule = Rule{
Name: "KnownDirectives",
RuleFunc: func(observers *Events, addError AddErrFunc) {
type mayNotBeUsedDirective struct {
Name string
Line int
Expand Down Expand Up @@ -45,5 +46,9 @@ func init() {
seen[tmp] = true
}
})
})
},
}

func init() {
AddRule(KnownDirectivesRule.Name, KnownDirectivesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/known_fragment_names.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownFragmentNames", func(observers *Events, addError AddErrFunc) {
var KnownFragmentNamesRule = Rule{
Name: "KnownFragmentNames",
RuleFunc: func(observers *Events, addError AddErrFunc) {
observers.OnFragmentSpread(func(walker *Walker, fragmentSpread *ast.FragmentSpread) {
if fragmentSpread.Definition == nil {
addError(
Expand All @@ -17,5 +18,9 @@ func init() {
)
}
})
})
},
}

func init() {
AddRule(KnownFragmentNamesRule.Name, KnownFragmentNamesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/known_root_type.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"fmt"
Expand All @@ -9,8 +9,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownRootType", func(observers *Events, addError AddErrFunc) {
var KnownRootTypeRule = Rule{
Name: "KnownRootType",
RuleFunc: func(observers *Events, addError AddErrFunc) {
// A query's root must be a valid type. Surprisingly, this isn't
// checked anywhere else!
observers.OnOperation(func(walker *Walker, operation *ast.OperationDefinition) {
Expand All @@ -33,5 +34,9 @@ func init() {
At(operation.Position))
}
})
})
},
}

func init() {
AddRule(KnownRootTypeRule.Name, KnownRootTypeRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/known_type_names.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("KnownTypeNames", func(observers *Events, addError AddErrFunc) {
var KnownTypeNamesRule = Rule{
Name: "KnownTypeNames",
RuleFunc: func(observers *Events, addError AddErrFunc) {
observers.OnVariable(func(walker *Walker, variable *ast.VariableDefinition) {
typeName := variable.Type.Name()
typdef := walker.Schema.Types[typeName]
Expand Down Expand Up @@ -57,5 +58,9 @@ func init() {
At(fragment.Position),
)
})
})
},
}

func init() {
AddRule(KnownTypeNamesRule.Name, KnownTypeNamesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/lone_anonymous_operation.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("LoneAnonymousOperation", func(observers *Events, addError AddErrFunc) {
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(
Expand All @@ -17,5 +18,9 @@ func init() {
)
}
})
})
},
}

func init() {
AddRule(LoneAnonymousOperationRule.Name, LoneAnonymousOperationRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/no_fragment_cycles.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"fmt"
Expand All @@ -10,8 +10,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("NoFragmentCycles", func(observers *Events, addError AddErrFunc) {
var NoFragmentCyclesRule = Rule{
Name: "NoFragmentCycles",
RuleFunc: func(observers *Events, addError AddErrFunc) {
visitedFrags := make(map[string]bool)

observers.OnFragment(func(walker *Walker, fragment *ast.FragmentDefinition) {
Expand Down Expand Up @@ -67,7 +68,11 @@ func init() {

recursive(fragment)
})
})
},
}

func init() {
AddRule(NoFragmentCyclesRule.Name, NoFragmentCyclesRule.RuleFunc)
}

func getFragmentSpreads(node ast.SelectionSet) []*ast.FragmentSpread {
Expand Down
13 changes: 9 additions & 4 deletions validator/rules/no_undefined_variables.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("NoUndefinedVariables", func(observers *Events, addError AddErrFunc) {
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
Expand All @@ -26,5 +27,9 @@ func init() {
)
}
})
})
},
}

func init() {
AddRule(NoUndefinedVariablesRule.Name, NoUndefinedVariablesRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/no_unused_fragments.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("NoUnusedFragments", func(observers *Events, addError AddErrFunc) {
var NoUnusedFragmentsRule = Rule{
Name: "NoUnusedFragments",
RuleFunc: func(observers *Events, addError AddErrFunc) {
inFragmentDefinition := false
fragmentNameUsed := make(map[string]bool)

Expand All @@ -27,5 +28,9 @@ func init() {
)
}
})
})
},
}

func init() {
AddRule(NoUnusedFragmentsRule.Name, NoUnusedFragmentsRule.RuleFunc)
}
13 changes: 9 additions & 4 deletions validator/rules/no_unused_variables.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package validator
package rules

import (
"github.com/vektah/gqlparser/v2/ast"
Expand All @@ -7,8 +7,9 @@ import (
. "github.com/vektah/gqlparser/v2/validator"
)

func init() {
AddRule("NoUnusedVariables", func(observers *Events, addError AddErrFunc) {
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 {
Expand All @@ -28,5 +29,9 @@ func init() {
}
}
})
})
},
}

func init() {
AddRule(NoUnusedVariablesRule.Name, NoUnusedVariablesRule.RuleFunc)
}
Loading

0 comments on commit 068eddf

Please sign in to comment.