diff options
Diffstat (limited to 'vendor/github.com/vektah/gqlparser/validator/schema.go')
-rw-r--r-- | vendor/github.com/vektah/gqlparser/validator/schema.go | 276 |
1 files changed, 0 insertions, 276 deletions
diff --git a/vendor/github.com/vektah/gqlparser/validator/schema.go b/vendor/github.com/vektah/gqlparser/validator/schema.go deleted file mode 100644 index 57d2022e..00000000 --- a/vendor/github.com/vektah/gqlparser/validator/schema.go +++ /dev/null @@ -1,276 +0,0 @@ -//go:generate go run ./inliner/inliner.go - -package validator - -import ( - "strconv" - "strings" - - . "github.com/vektah/gqlparser/ast" - "github.com/vektah/gqlparser/gqlerror" - "github.com/vektah/gqlparser/parser" -) - -func LoadSchema(inputs ...*Source) (*Schema, *gqlerror.Error) { - 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 { - if schema.Types[def.Name] != nil { - return nil, gqlerror.ErrorPosf(def.Position, "Cannot redeclare type %s.", def.Name) - } - schema.Types[def.Name] = ast.Definitions[i] - } - - for _, ext := range ast.Extensions { - def := schema.Types[ext.Name] - if def == nil { - return nil, gqlerror.ErrorPosf(ext.Position, "Cannot extend type %s because it does not exist.", ext.Name) - } - - if def.Kind != ext.Kind { - return nil, gqlerror.ErrorPosf(ext.Position, "Cannot extend type %s because the base type is a %s, not %s.", ext.Name, def.Kind, ext.Kind) - } - - def.Directives = append(def.Directives, ext.Directives...) - def.Interfaces = append(def.Interfaces, ext.Interfaces...) - def.Fields = append(def.Fields, ext.Fields...) - def.Types = append(def.Types, ext.Types...) - 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) - } - schema.Directives[dir.Name] = ast.Directives[i] - } - - if len(ast.Schema) > 1 { - return nil, gqlerror.ErrorPosf(ast.Schema[1].Position, "Cannot have multiple schema entry points, consider schema extensions instead.") - } - - if len(ast.Schema) == 1 { - for _, entrypoint := range ast.Schema[0].OperationTypes { - def := schema.Types[entrypoint.Type] - if def == nil { - return nil, gqlerror.ErrorPosf(entrypoint.Position, "Schema root %s refers to a type %s that does not exist.", entrypoint.Operation, entrypoint.Type) - } - switch entrypoint.Operation { - case Query: - schema.Query = def - case Mutation: - schema.Mutation = def - case Subscription: - schema.Subscription = def - } - } - } - - for _, ext := range ast.SchemaExtension { - for _, entrypoint := range ext.OperationTypes { - def := schema.Types[entrypoint.Type] - if def == nil { - return nil, gqlerror.ErrorPosf(entrypoint.Position, "Schema root %s refers to a type %s that does not exist.", entrypoint.Operation, entrypoint.Type) - } - switch entrypoint.Operation { - case Query: - schema.Query = def - case Mutation: - schema.Mutation = def - case Subscription: - schema.Subscription = def - } - } - } - - for _, typ := range schema.Types { - err := validateDefinition(&schema, typ) - if err != nil { - return nil, err - } - } - - for _, dir := range schema.Directives { - err := validateDirective(&schema, dir) - if err != nil { - return nil, err - } - } - - if schema.Query == nil && schema.Types["Query"] != nil { - schema.Query = schema.Types["Query"] - } - - if schema.Mutation == nil && schema.Types["Mutation"] != nil { - schema.Mutation = schema.Types["Mutation"] - } - - if schema.Subscription == nil && schema.Types["Subscription"] != nil { - schema.Subscription = schema.Types["Subscription"] - } - - if schema.Query != nil { - schema.Query.Fields = append( - schema.Query.Fields, - &FieldDefinition{ - Name: "__schema", - Type: NonNullNamedType("__Schema", nil), - }, - &FieldDefinition{ - Name: "__type", - Type: NonNullNamedType("__Type", nil), - Arguments: ArgumentDefinitionList{ - {Name: "name", Type: NamedType("String", nil)}, - }, - }, - ) - } - - return &schema, nil -} - -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 - } - if err := validateArgs(schema, field.Arguments, nil); err != nil { - return err - } - if err := validateDirectives(schema, field.Directives, nil); err != nil { - return err - } - } - - for _, intf := range def.Interfaces { - intDef := schema.Types[intf] - if intDef == nil { - return gqlerror.ErrorPosf(def.Position, "Undefined type %s.", strconv.Quote(intf)) - } - if intDef.Kind != Interface { - return gqlerror.ErrorPosf(def.Position, "%s is a non interface type %s.", strconv.Quote(intf), intDef.Kind) - } - } - - 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) -} - -func validateTypeRef(schema *Schema, typ *Type) *gqlerror.Error { - if schema.Types[typ.Name()] == nil { - return gqlerror.ErrorPosf(typ.Position, "Undefined type %s.", typ.Name()) - } - return nil -} - -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 - } - if err := validateDirectives(schema, arg.Directives, currentDirective); err != nil { - return err - } - } - return nil -} - -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) - } - if schema.Directives[dir.Name] == nil { - return gqlerror.ErrorPosf(dir.Position, "Undefined directive %s.", dir.Name) - } - dir.Definition = schema.Directives[dir.Name] - } - 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 -} |