aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/vektah/gqlparser/validator/schema.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vektah/gqlparser/validator/schema.go')
-rw-r--r--vendor/github.com/vektah/gqlparser/validator/schema.go94
1 files changed, 79 insertions, 15 deletions
diff --git a/vendor/github.com/vektah/gqlparser/validator/schema.go b/vendor/github.com/vektah/gqlparser/validator/schema.go
index 8fa18d7e..57d2022e 100644
--- a/vendor/github.com/vektah/gqlparser/validator/schema.go
+++ b/vendor/github.com/vektah/gqlparser/validator/schema.go
@@ -4,6 +4,7 @@ package validator
import (
"strconv"
+ "strings"
. "github.com/vektah/gqlparser/ast"
"github.com/vektah/gqlparser/gqlerror"
@@ -11,20 +12,19 @@ import (
)
func LoadSchema(inputs ...*Source) (*Schema, *gqlerror.Error) {
- ast := &SchemaDocument{}
- for _, input := range inputs {
- inputAst, err := parser.ParseSchema(input)
- if err != nil {
- return nil, err
- }
-
- ast.Merge(inputAst)
+ ast, err := parser.ParseSchemas(inputs...)
+ if err != nil {
+ return nil, err
}
+ return ValidateSchemaDocument(ast)
+}
+func ValidateSchemaDocument(ast *SchemaDocument) (*Schema, *gqlerror.Error) {
schema := Schema{
Types: map[string]*Definition{},
Directives: map[string]*DirectiveDefinition{},
PossibleTypes: map[string][]*Definition{},
+ Implements: map[string][]*Definition{},
}
for i, def := range ast.Definitions {
@@ -32,13 +32,6 @@ func LoadSchema(inputs ...*Source) (*Schema, *gqlerror.Error) {
return nil, gqlerror.ErrorPosf(def.Position, "Cannot redeclare type %s.", def.Name)
}
schema.Types[def.Name] = ast.Definitions[i]
-
- if def.Kind != Interface {
- for _, intf := range def.Interfaces {
- schema.AddPossibleType(intf, ast.Definitions[i])
- }
- schema.AddPossibleType(def.Name, ast.Definitions[i])
- }
}
for _, ext := range ast.Extensions {
@@ -58,6 +51,22 @@ func LoadSchema(inputs ...*Source) (*Schema, *gqlerror.Error) {
def.EnumValues = append(def.EnumValues, ext.EnumValues...)
}
+ for _, def := range ast.Definitions {
+ switch def.Kind {
+ case Union:
+ for _, t := range def.Types {
+ schema.AddPossibleType(def.Name, schema.Types[t])
+ schema.AddImplements(t, def)
+ }
+ case InputObject, Object:
+ for _, intf := range def.Interfaces {
+ schema.AddPossibleType(intf, def)
+ schema.AddImplements(def.Name, schema.Types[intf])
+ }
+ schema.AddPossibleType(def.Name, def)
+ }
+ }
+
for i, dir := range ast.Directives {
if schema.Directives[dir.Name] != nil {
return nil, gqlerror.ErrorPosf(dir.Position, "Cannot redeclare directive %s.", dir.Name)
@@ -150,11 +159,20 @@ func LoadSchema(inputs ...*Source) (*Schema, *gqlerror.Error) {
}
func validateDirective(schema *Schema, def *DirectiveDefinition) *gqlerror.Error {
+ if err := validateName(def.Position, def.Name); err != nil {
+ // now, GraphQL spec doesn't have reserved directive name
+ return err
+ }
+
return validateArgs(schema, def.Arguments, def)
}
func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error {
for _, field := range def.Fields {
+ if err := validateName(field.Position, field.Name); err != nil {
+ // now, GraphQL spec doesn't have reserved field name
+ return err
+ }
if err := validateTypeRef(schema, field.Type); err != nil {
return err
}
@@ -176,6 +194,37 @@ func validateDefinition(schema *Schema, def *Definition) *gqlerror.Error {
}
}
+ switch def.Kind {
+ case Object, Interface:
+ if len(def.Fields) == 0 {
+ return gqlerror.ErrorPosf(def.Position, "%s must define one or more fields.", def.Kind)
+ }
+ case Enum:
+ if len(def.EnumValues) == 0 {
+ return gqlerror.ErrorPosf(def.Position, "%s must define one or more unique enum values.", def.Kind)
+ }
+ case InputObject:
+ if len(def.Fields) == 0 {
+ return gqlerror.ErrorPosf(def.Position, "%s must define one or more input fields.", def.Kind)
+ }
+ }
+
+ for idx, field1 := range def.Fields {
+ for _, field2 := range def.Fields[idx+1:] {
+ if field1.Name == field2.Name {
+ return gqlerror.ErrorPosf(field2.Position, "Field %s.%s can only be defined once.", def.Name, field2.Name)
+ }
+ }
+ }
+
+ if !def.BuiltIn {
+ // GraphQL spec has reserved type names a lot!
+ err := validateName(def.Position, def.Name)
+ if err != nil {
+ return err
+ }
+ }
+
return validateDirectives(schema, def.Directives, nil)
}
@@ -188,6 +237,10 @@ func validateTypeRef(schema *Schema, typ *Type) *gqlerror.Error {
func validateArgs(schema *Schema, args ArgumentDefinitionList, currentDirective *DirectiveDefinition) *gqlerror.Error {
for _, arg := range args {
+ if err := validateName(arg.Position, arg.Name); err != nil {
+ // now, GraphQL spec doesn't have reserved argument name
+ return err
+ }
if err := validateTypeRef(schema, arg.Type); err != nil {
return err
}
@@ -200,6 +253,10 @@ func validateArgs(schema *Schema, args ArgumentDefinitionList, currentDirective
func validateDirectives(schema *Schema, dirs DirectiveList, currentDirective *DirectiveDefinition) *gqlerror.Error {
for _, dir := range dirs {
+ if err := validateName(dir.Position, dir.Name); err != nil {
+ // now, GraphQL spec doesn't have reserved directive name
+ return err
+ }
if currentDirective != nil && dir.Name == currentDirective.Name {
return gqlerror.ErrorPosf(dir.Position, "Directive %s cannot refer to itself.", currentDirective.Name)
}
@@ -210,3 +267,10 @@ func validateDirectives(schema *Schema, dirs DirectiveList, currentDirective *Di
}
return nil
}
+
+func validateName(pos *Position, name string) *gqlerror.Error {
+ if strings.HasPrefix(name, "__") {
+ return gqlerror.ErrorPosf(pos, `Name "%s" must not begin with "__", which is reserved by GraphQL introspection.`, name)
+ }
+ return nil
+}