aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/vektah/gqlparser/parser
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-09-14 12:40:31 +0200
committerMichael Muré <batolettre@gmail.com>2018-09-14 12:41:59 +0200
commitb478cd1bcb4756b20f7f4b15fcf81f23e1a60a02 (patch)
tree8ce232dcab3dd00708f8ba66c334472457e5980d /vendor/github.com/vektah/gqlparser/parser
parenta3fc9abb921f5ce7084d6ab7473442d0b72b1d78 (diff)
downloadgit-bug-b478cd1bcb4756b20f7f4b15fcf81f23e1a60a02.tar.gz
graphql: update gqlgen to 0.5.1
fix #6
Diffstat (limited to 'vendor/github.com/vektah/gqlparser/parser')
-rw-r--r--vendor/github.com/vektah/gqlparser/parser/parser.go112
-rw-r--r--vendor/github.com/vektah/gqlparser/parser/query.go334
-rw-r--r--vendor/github.com/vektah/gqlparser/parser/query_test.yml507
-rw-r--r--vendor/github.com/vektah/gqlparser/parser/schema.go503
-rw-r--r--vendor/github.com/vektah/gqlparser/parser/schema_test.yml505
5 files changed, 1961 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlparser/parser/parser.go b/vendor/github.com/vektah/gqlparser/parser/parser.go
new file mode 100644
index 00000000..f3648cb3
--- /dev/null
+++ b/vendor/github.com/vektah/gqlparser/parser/parser.go
@@ -0,0 +1,112 @@
+package parser
+
+import (
+ "strconv"
+
+ "github.com/vektah/gqlparser/ast"
+ "github.com/vektah/gqlparser/gqlerror"
+ "github.com/vektah/gqlparser/lexer"
+)
+
+type parser struct {
+ lexer lexer.Lexer
+ err *gqlerror.Error
+
+ peeked bool
+ peekToken lexer.Token
+ peekError *gqlerror.Error
+
+ prev lexer.Token
+}
+
+func (p *parser) peekPos() *ast.Position {
+ if p.err != nil {
+ return nil
+ }
+
+ peek := p.peek()
+ return &peek.Pos
+}
+
+func (p *parser) peek() lexer.Token {
+ if p.err != nil {
+ return p.prev
+ }
+
+ if !p.peeked {
+ p.peekToken, p.peekError = p.lexer.ReadToken()
+ p.peeked = true
+ }
+
+ return p.peekToken
+}
+
+func (p *parser) error(tok lexer.Token, format string, args ...interface{}) {
+ if p.err != nil {
+ return
+ }
+ p.err = gqlerror.ErrorLocf(tok.Pos.Src.Name, tok.Pos.Line, tok.Pos.Column, format, args...)
+}
+
+func (p *parser) next() lexer.Token {
+ if p.err != nil {
+ return p.prev
+ }
+ if p.peeked {
+ p.peeked = false
+ p.prev, p.err = p.peekToken, p.peekError
+ } else {
+ p.prev, p.err = p.lexer.ReadToken()
+ }
+ return p.prev
+}
+
+func (p *parser) expectKeyword(value string) lexer.Token {
+ tok := p.peek()
+ if tok.Kind == lexer.Name && tok.Value == value {
+ return p.next()
+ }
+
+ p.error(tok, "Expected %s, found %s", strconv.Quote(value), tok.String())
+ return tok
+}
+
+func (p *parser) expect(kind lexer.Type) lexer.Token {
+ tok := p.peek()
+ if tok.Kind == kind {
+ return p.next()
+ }
+
+ p.error(tok, "Expected %s, found %s", kind, tok.Kind.String())
+ return tok
+}
+
+func (p *parser) skip(kind lexer.Type) bool {
+ tok := p.peek()
+
+ if tok.Kind != kind {
+ return false
+ }
+ p.next()
+ return true
+}
+
+func (p *parser) unexpectedError() {
+ p.unexpectedToken(p.peek())
+}
+
+func (p *parser) unexpectedToken(tok lexer.Token) {
+ p.error(tok, "Unexpected %s", tok.String())
+}
+
+func (p *parser) many(start lexer.Type, end lexer.Type, cb func()) {
+ hasDef := p.skip(start)
+ if !hasDef {
+ return
+ }
+
+ for p.peek().Kind != end && p.err == nil {
+ cb()
+ }
+ p.next()
+}
diff --git a/vendor/github.com/vektah/gqlparser/parser/query.go b/vendor/github.com/vektah/gqlparser/parser/query.go
new file mode 100644
index 00000000..7fecb57f
--- /dev/null
+++ b/vendor/github.com/vektah/gqlparser/parser/query.go
@@ -0,0 +1,334 @@
+package parser
+
+import (
+ "github.com/vektah/gqlparser/gqlerror"
+ "github.com/vektah/gqlparser/lexer"
+
+ . "github.com/vektah/gqlparser/ast"
+)
+
+func ParseQuery(source *Source) (*QueryDocument, *gqlerror.Error) {
+ p := parser{
+ lexer: lexer.New(source),
+ }
+ return p.parseQueryDocument(), p.err
+}
+
+func (p *parser) parseQueryDocument() *QueryDocument {
+ var doc QueryDocument
+ for p.peek().Kind != lexer.EOF {
+ if p.err != nil {
+ return &doc
+ }
+ doc.Position = p.peekPos()
+ switch p.peek().Kind {
+ case lexer.Name:
+ switch p.peek().Value {
+ case "query", "mutation", "subscription":
+ doc.Operations = append(doc.Operations, p.parseOperationDefinition())
+ case "fragment":
+ doc.Fragments = append(doc.Fragments, p.parseFragmentDefinition())
+ default:
+ p.unexpectedError()
+ }
+ case lexer.BraceL:
+ doc.Operations = append(doc.Operations, p.parseOperationDefinition())
+ default:
+ p.unexpectedError()
+ }
+ }
+
+ return &doc
+}
+
+func (p *parser) parseOperationDefinition() *OperationDefinition {
+ if p.peek().Kind == lexer.BraceL {
+ return &OperationDefinition{
+ Position: p.peekPos(),
+ Operation: Query,
+ SelectionSet: p.parseSelectionSet(),
+ }
+ }
+
+ var od OperationDefinition
+ od.Position = p.peekPos()
+ od.Operation = p.parseOperationType()
+
+ if p.peek().Kind == lexer.Name {
+ od.Name = p.next().Value
+ }
+
+ od.VariableDefinitions = p.parseVariableDefinitions()
+ od.Directives = p.parseDirectives(false)
+ od.SelectionSet = p.parseSelectionSet()
+
+ return &od
+}
+
+func (p *parser) parseOperationType() Operation {
+ tok := p.next()
+ switch tok.Value {
+ case "query":
+ return Query
+ case "mutation":
+ return Mutation
+ case "subscription":
+ return Subscription
+ }
+ p.unexpectedToken(tok)
+ return ""
+}
+
+func (p *parser) parseVariableDefinitions() VariableDefinitionList {
+ var defs []*VariableDefinition
+ p.many(lexer.ParenL, lexer.ParenR, func() {
+ defs = append(defs, p.parseVariableDefinition())
+ })
+
+ return defs
+}
+
+func (p *parser) parseVariableDefinition() *VariableDefinition {
+ var def VariableDefinition
+ def.Position = p.peekPos()
+ def.Variable = p.parseVariable()
+
+ p.expect(lexer.Colon)
+
+ def.Type = p.parseTypeReference()
+
+ if p.skip(lexer.Equals) {
+ def.DefaultValue = p.parseValueLiteral(true)
+ }
+
+ return &def
+}
+
+func (p *parser) parseVariable() string {
+ p.expect(lexer.Dollar)
+ return p.parseName()
+}
+
+func (p *parser) parseSelectionSet() SelectionSet {
+ var selections []Selection
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ selections = append(selections, p.parseSelection())
+ })
+
+ return SelectionSet(selections)
+}
+
+func (p *parser) parseSelection() Selection {
+ if p.peek().Kind == lexer.Spread {
+ return p.parseFragment()
+ }
+ return p.parseField()
+}
+
+func (p *parser) parseField() *Field {
+ var field Field
+ field.Position = p.peekPos()
+ field.Alias = p.parseName()
+
+ if p.skip(lexer.Colon) {
+ field.Name = p.parseName()
+ } else {
+ field.Name = field.Alias
+ }
+
+ field.Arguments = p.parseArguments(false)
+ field.Directives = p.parseDirectives(false)
+ if p.peek().Kind == lexer.BraceL {
+ field.SelectionSet = p.parseSelectionSet()
+ }
+
+ return &field
+}
+
+func (p *parser) parseArguments(isConst bool) ArgumentList {
+ var arguments ArgumentList
+ p.many(lexer.ParenL, lexer.ParenR, func() {
+ arguments = append(arguments, p.parseArgument(isConst))
+ })
+
+ return arguments
+}
+
+func (p *parser) parseArgument(isConst bool) *Argument {
+ arg := Argument{}
+ arg.Position = p.peekPos()
+ arg.Name = p.parseName()
+ p.expect(lexer.Colon)
+
+ arg.Value = p.parseValueLiteral(isConst)
+ return &arg
+}
+
+func (p *parser) parseFragment() Selection {
+ p.expect(lexer.Spread)
+
+ if peek := p.peek(); peek.Kind == lexer.Name && peek.Value != "on" {
+ return &FragmentSpread{
+ Position: p.peekPos(),
+ Name: p.parseFragmentName(),
+ Directives: p.parseDirectives(false),
+ }
+ }
+
+ var def InlineFragment
+ def.Position = p.peekPos()
+ if p.peek().Value == "on" {
+ p.next() // "on"
+
+ def.TypeCondition = p.parseName()
+ }
+
+ def.Directives = p.parseDirectives(false)
+ def.SelectionSet = p.parseSelectionSet()
+ return &def
+}
+
+func (p *parser) parseFragmentDefinition() *FragmentDefinition {
+ var def FragmentDefinition
+ def.Position = p.peekPos()
+ p.expectKeyword("fragment")
+
+ def.Name = p.parseFragmentName()
+ def.VariableDefinition = p.parseVariableDefinitions()
+
+ p.expectKeyword("on")
+
+ def.TypeCondition = p.parseName()
+ def.Directives = p.parseDirectives(false)
+ def.SelectionSet = p.parseSelectionSet()
+ return &def
+}
+
+func (p *parser) parseFragmentName() string {
+ if p.peek().Value == "on" {
+ p.unexpectedError()
+ return ""
+ }
+
+ return p.parseName()
+}
+
+func (p *parser) parseValueLiteral(isConst bool) *Value {
+ token := p.peek()
+
+ var kind ValueKind
+ switch token.Kind {
+ case lexer.BracketL:
+ return p.parseList(isConst)
+ case lexer.BraceL:
+ return p.parseObject(isConst)
+ case lexer.Dollar:
+ if isConst {
+ p.unexpectedError()
+ return nil
+ }
+ return &Value{Position: &token.Pos, Raw: p.parseVariable(), Kind: Variable}
+ case lexer.Int:
+ kind = IntValue
+ case lexer.Float:
+ kind = FloatValue
+ case lexer.String:
+ kind = StringValue
+ case lexer.BlockString:
+ kind = BlockValue
+ case lexer.Name:
+ switch token.Value {
+ case "true", "false":
+ kind = BooleanValue
+ case "null":
+ kind = NullValue
+ default:
+ kind = EnumValue
+ }
+ default:
+ p.unexpectedError()
+ return nil
+ }
+
+ p.next()
+
+ return &Value{Position: &token.Pos, Raw: token.Value, Kind: kind}
+}
+
+func (p *parser) parseList(isConst bool) *Value {
+ var values ChildValueList
+ pos := p.peekPos()
+ p.many(lexer.BracketL, lexer.BracketR, func() {
+ values = append(values, &ChildValue{Value: p.parseValueLiteral(isConst)})
+ })
+
+ return &Value{Children: values, Kind: ListValue, Position: pos}
+}
+
+func (p *parser) parseObject(isConst bool) *Value {
+ var fields ChildValueList
+ pos := p.peekPos()
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ fields = append(fields, p.parseObjectField(isConst))
+ })
+
+ return &Value{Children: fields, Kind: ObjectValue, Position: pos}
+}
+
+func (p *parser) parseObjectField(isConst bool) *ChildValue {
+ field := ChildValue{}
+ field.Position = p.peekPos()
+ field.Name = p.parseName()
+
+ p.expect(lexer.Colon)
+
+ field.Value = p.parseValueLiteral(isConst)
+ return &field
+}
+
+func (p *parser) parseDirectives(isConst bool) []*Directive {
+ var directives []*Directive
+
+ for p.peek().Kind == lexer.At {
+ if p.err != nil {
+ break
+ }
+ directives = append(directives, p.parseDirective(isConst))
+ }
+ return directives
+}
+
+func (p *parser) parseDirective(isConst bool) *Directive {
+ p.expect(lexer.At)
+
+ return &Directive{
+ Position: p.peekPos(),
+ Name: p.parseName(),
+ Arguments: p.parseArguments(isConst),
+ }
+}
+
+func (p *parser) parseTypeReference() *Type {
+ var typ Type
+
+ if p.skip(lexer.BracketL) {
+ typ.Position = p.peekPos()
+ typ.Elem = p.parseTypeReference()
+ p.expect(lexer.BracketR)
+ } else {
+ typ.Position = p.peekPos()
+ typ.NamedType = p.parseName()
+ }
+
+ if p.skip(lexer.Bang) {
+ typ.Position = p.peekPos()
+ typ.NonNull = true
+ }
+ return &typ
+}
+
+func (p *parser) parseName() string {
+ token := p.expect(lexer.Name)
+
+ return token.Value
+}
diff --git a/vendor/github.com/vektah/gqlparser/parser/query_test.yml b/vendor/github.com/vektah/gqlparser/parser/query_test.yml
new file mode 100644
index 00000000..f392eb8e
--- /dev/null
+++ b/vendor/github.com/vektah/gqlparser/parser/query_test.yml
@@ -0,0 +1,507 @@
+parser provides useful errors:
+ - name: unclosed paren
+ input: '{'
+ error:
+ message: "Expected Name, found <EOF>"
+ locations: [{line: 1, column: 2}]
+
+ - name: missing on in fragment
+ input: |
+ { ...MissingOn }
+ fragment MissingOn Type
+ error:
+ message: 'Expected "on", found Name "Type"'
+ locations: [{ line: 2, column: 20 }]
+
+ - name: missing name after alias
+ input: '{ field: {} }'
+ error:
+ message: "Expected Name, found {"
+ locations: [{ line: 1, column: 10 }]
+
+ - name: not an operation
+ input: 'notanoperation Foo { field }'
+ error:
+ message: 'Unexpected Name "notanoperation"'
+ locations: [{ line: 1, column: 1 }]
+
+ - name: a wild splat appears
+ input: '...'
+ error:
+ message: 'Unexpected ...'
+ locations: [{ line: 1, column: 1}]
+
+variables:
+ - name: are allowed in args
+ input: '{ field(complex: { a: { b: [ $var ] } }) }'
+
+ - name: are not allowed in default args
+ input: 'query Foo($x: Complex = { a: { b: [ $var ] } }) { field }'
+ error:
+ message: 'Unexpected $'
+ locations: [{ line: 1, column: 37 }]
+
+fragments:
+ - name: can not be named 'on'
+ input: 'fragment on on on { on }'
+ error:
+ message: 'Unexpected Name "on"'
+ locations: [{ line: 1, column: 10 }]
+
+ - name: can not spread fragments called 'on'
+ input: '{ ...on }'
+ error:
+ message: 'Expected Name, found }'
+ locations: [{ line: 1, column: 9 }]
+
+encoding:
+ - name: multibyte characters are supported
+ input: |
+ # This comment has a ਊ multi-byte character.
+ { field(arg: "Has a ਊ multi-byte character.") }
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "field"
+ Name: "field"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "arg"
+ Value: "Has a ਊ multi-byte character."
+
+keywords are allowed anywhere a name is:
+ - name: on
+ input: |
+ query on {
+ ... a
+ ... on on { field }
+ }
+ fragment a on Type {
+ on(on: $on)
+ @on(on: on)
+ }
+
+ - name: subscription
+ input: |
+ query subscription {
+ ... subscription
+ ... on subscription { field }
+ }
+ fragment subscription on Type {
+ subscription(subscription: $subscription)
+ @subscription(subscription: subscription)
+ }
+
+ - name: true
+ input: |
+ query true {
+ ... true
+ ... on true { field }
+ }
+ fragment true on Type {
+ true(true: $true)
+ @true(true: true)
+ }
+
+operations:
+ - name: anonymous mutation
+ input: 'mutation { mutationField }'
+
+ - name: named mutation
+ input: 'mutation Foo { mutationField }'
+
+ - name: anonymous subscription
+ input: 'subscription { subscriptionField }'
+
+ - name: named subscription
+ input: 'subscription Foo { subscriptionField }'
+
+
+ast:
+ - name: simple query
+ input: |
+ {
+ node(id: 4) {
+ id,
+ name
+ }
+ }
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "node"
+ Name: "node"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "id"
+ Value: 4
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <Field>
+ Alias: "name"
+ Name: "name"
+
+ - name: nameless query with no variables
+ input: |
+ query {
+ node {
+ id
+ }
+ }
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "node"
+ Name: "node"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+
+ - name: fragment defined variables
+ input: 'fragment a($v: Boolean = false) on t { f(v: $v) }'
+ ast: |
+ <QueryDocument>
+ Fragments: [FragmentDefinition]
+ - <FragmentDefinition>
+ Name: "a"
+ VariableDefinition: [VariableDefinition]
+ - <VariableDefinition>
+ Variable: "v"
+ Type: Boolean
+ DefaultValue: false
+ TypeCondition: "t"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "f"
+ Name: "f"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "v"
+ Value: $v
+
+
+values:
+ - name: null
+ input: '{ f(id: null) }'
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "f"
+ Name: "f"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "id"
+ Value: null
+
+ - name: strings
+ input: '{ f(long: """long""", short: "short") } '
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "f"
+ Name: "f"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "long"
+ Value: "long"
+ - <Argument>
+ Name: "short"
+ Value: "short"
+
+ - name: list
+ input: '{ f(id: [1,2]) }'
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "f"
+ Name: "f"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "id"
+ Value: [1,2]
+
+types:
+ - name: common types
+ input: 'query ($string: String, $int: Int, $arr: [Arr], $notnull: [Arr!]!) { f }'
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ VariableDefinitions: [VariableDefinition]
+ - <VariableDefinition>
+ Variable: "string"
+ Type: String
+ - <VariableDefinition>
+ Variable: "int"
+ Type: Int
+ - <VariableDefinition>
+ Variable: "arr"
+ Type: [Arr]
+ - <VariableDefinition>
+ Variable: "notnull"
+ Type: [Arr!]!
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "f"
+ Name: "f"
+
+large queries:
+ - name: kitchen sink
+ input: |
+ # Copyright (c) 2015-present, Facebook, Inc.
+ #
+ # This source code is licensed under the MIT license found in the
+ # LICENSE file in the root directory of this source tree.
+
+ query queryName($foo: ComplexType, $site: Site = MOBILE) {
+ whoever123is: node(id: [123, 456]) {
+ id ,
+ ... on User @defer {
+ field2 {
+ id ,
+ alias: field1(first:10, after:$foo,) @include(if: $foo) {
+ id,
+ ...frag
+ }
+ }
+ }
+ ... @skip(unless: $foo) {
+ id
+ }
+ ... {
+ id
+ }
+ }
+ }
+
+ mutation likeStory {
+ like(story: 123) @defer {
+ story {
+ id
+ }
+ }
+ }
+
+ subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
+ storyLikeSubscribe(input: $input) {
+ story {
+ likers {
+ count
+ }
+ likeSentence {
+ text
+ }
+ }
+ }
+ }
+
+ fragment frag on Friend {
+ foo(size: $size, bar: $b, obj: {key: "value", block: """
+ block string uses \"""
+ """})
+ }
+
+ {
+ unnamed(truthy: true, falsey: false, nullish: null),
+ query
+ }
+ ast: |
+ <QueryDocument>
+ Operations: [OperationDefinition]
+ - <OperationDefinition>
+ Operation: Operation("query")
+ Name: "queryName"
+ VariableDefinitions: [VariableDefinition]
+ - <VariableDefinition>
+ Variable: "foo"
+ Type: ComplexType
+ - <VariableDefinition>
+ Variable: "site"
+ Type: Site
+ DefaultValue: MOBILE
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "whoever123is"
+ Name: "node"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "id"
+ Value: [123,456]
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <InlineFragment>
+ TypeCondition: "User"
+ Directives: [Directive]
+ - <Directive>
+ Name: "defer"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "field2"
+ Name: "field2"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <Field>
+ Alias: "alias"
+ Name: "field1"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "first"
+ Value: 10
+ - <Argument>
+ Name: "after"
+ Value: $foo
+ Directives: [Directive]
+ - <Directive>
+ Name: "include"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "if"
+ Value: $foo
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <FragmentSpread>
+ Name: "frag"
+ - <InlineFragment>
+ Directives: [Directive]
+ - <Directive>
+ Name: "skip"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "unless"
+ Value: $foo
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <InlineFragment>
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <OperationDefinition>
+ Operation: Operation("mutation")
+ Name: "likeStory"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "like"
+ Name: "like"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "story"
+ Value: 123
+ Directives: [Directive]
+ - <Directive>
+ Name: "defer"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "story"
+ Name: "story"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "id"
+ Name: "id"
+ - <OperationDefinition>
+ Operation: Operation("subscription")
+ Name: "StoryLikeSubscription"
+ VariableDefinitions: [VariableDefinition]
+ - <VariableDefinition>
+ Variable: "input"
+ Type: StoryLikeSubscribeInput
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "storyLikeSubscribe"
+ Name: "storyLikeSubscribe"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "input"
+ Value: $input
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "story"
+ Name: "story"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "likers"
+ Name: "likers"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "count"
+ Name: "count"
+ - <Field>
+ Alias: "likeSentence"
+ Name: "likeSentence"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "text"
+ Name: "text"
+ - <OperationDefinition>
+ Operation: Operation("query")
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "unnamed"
+ Name: "unnamed"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "truthy"
+ Value: true
+ - <Argument>
+ Name: "falsey"
+ Value: false
+ - <Argument>
+ Name: "nullish"
+ Value: null
+ - <Field>
+ Alias: "query"
+ Name: "query"
+ Fragments: [FragmentDefinition]
+ - <FragmentDefinition>
+ Name: "frag"
+ TypeCondition: "Friend"
+ SelectionSet: [Selection]
+ - <Field>
+ Alias: "foo"
+ Name: "foo"
+ Arguments: [Argument]
+ - <Argument>
+ Name: "size"
+ Value: $size
+ - <Argument>
+ Name: "bar"
+ Value: $b
+ - <Argument>
+ Name: "obj"
+ Value: {"key":"value","block":"block string uses \"\"\""}
diff --git a/vendor/github.com/vektah/gqlparser/parser/schema.go b/vendor/github.com/vektah/gqlparser/parser/schema.go
new file mode 100644
index 00000000..f409f1f4
--- /dev/null
+++ b/vendor/github.com/vektah/gqlparser/parser/schema.go
@@ -0,0 +1,503 @@
+package parser
+
+import (
+ . "github.com/vektah/gqlparser/ast"
+ "github.com/vektah/gqlparser/gqlerror"
+ "github.com/vektah/gqlparser/lexer"
+)
+
+func ParseSchema(source *Source) (*SchemaDocument, *gqlerror.Error) {
+ p := parser{
+ lexer: lexer.New(source),
+ }
+ return p.parseSchemaDocument(), p.err
+}
+
+func (p *parser) parseSchemaDocument() *SchemaDocument {
+ var doc SchemaDocument
+ doc.Position = p.peekPos()
+ for p.peek().Kind != lexer.EOF {
+ if p.err != nil {
+ return nil
+ }
+
+ var description string
+ if p.peek().Kind == lexer.BlockString || p.peek().Kind == lexer.String {
+ description = p.parseDescription()
+ }
+
+ if p.peek().Kind != lexer.Name {
+ p.unexpectedError()
+ break
+ }
+
+ switch p.peek().Value {
+ case "scalar", "type", "interface", "union", "enum", "input":
+ doc.Definitions = append(doc.Definitions, p.parseTypeSystemDefinition(description))
+ case "schema":
+ doc.Schema = append(doc.Schema, p.parseSchemaDefinition(description))
+ case "directive":
+ doc.Directives = append(doc.Directives, p.parseDirectiveDefinition(description))
+ case "extend":
+ if description != "" {
+ p.unexpectedToken(p.prev)
+ }
+ p.parseTypeSystemExtension(&doc)
+ default:
+ p.unexpectedError()
+ return nil
+ }
+ }
+
+ return &doc
+}
+
+func (p *parser) parseDescription() string {
+ token := p.peek()
+
+ if token.Kind != lexer.BlockString && token.Kind != lexer.String {
+ return ""
+ }
+
+ return p.next().Value
+}
+
+func (p *parser) parseTypeSystemDefinition(description string) *Definition {
+ tok := p.peek()
+ if tok.Kind != lexer.Name {
+ p.unexpectedError()
+ return nil
+ }
+
+ switch tok.Value {
+ case "scalar":
+ return p.parseScalarTypeDefinition(description)
+ case "type":
+ return p.parseObjectTypeDefinition(description)
+ case "interface":
+ return p.parseInterfaceTypeDefinition(description)
+ case "union":
+ return p.parseUnionTypeDefinition(description)
+ case "enum":
+ return p.parseEnumTypeDefinition(description)
+ case "input":
+ return p.parseInputObjectTypeDefinition(description)
+ default:
+ p.unexpectedError()
+ return nil
+ }
+}
+
+func (p *parser) parseSchemaDefinition(description string) *SchemaDefinition {
+ p.expectKeyword("schema")
+
+ def := SchemaDefinition{Description: description}
+ def.Position = p.peekPos()
+ def.Description = description
+ def.Directives = p.parseDirectives(true)
+
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ def.OperationTypes = append(def.OperationTypes, p.parseOperationTypeDefinition())
+ })
+ return &def
+}
+
+func (p *parser) parseOperationTypeDefinition() *OperationTypeDefinition {
+ var op OperationTypeDefinition
+ op.Position = p.peekPos()
+ op.Operation = p.parseOperationType()
+ p.expect(lexer.Colon)
+ op.Type = p.parseName()
+ return &op
+}
+
+func (p *parser) parseScalarTypeDefinition(description string) *Definition {
+ p.expectKeyword("scalar")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Scalar
+ def.Description = description
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ return &def
+}
+
+func (p *parser) parseObjectTypeDefinition(description string) *Definition {
+ p.expectKeyword("type")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Object
+ def.Description = description
+ def.Name = p.parseName()
+ def.Interfaces = p.parseImplementsInterfaces()
+ def.Directives = p.parseDirectives(true)
+ def.Fields = p.parseFieldsDefinition()
+ return &def
+}
+
+func (p *parser) parseImplementsInterfaces() []string {
+ var types []string
+ if p.peek().Value == "implements" {
+ p.next()
+ // optional leading ampersand
+ p.skip(lexer.Amp)
+
+ types = append(types, p.parseName())
+ for p.skip(lexer.Amp) && p.err == nil {
+ types = append(types, p.parseName())
+ }
+ }
+ return types
+}
+
+func (p *parser) parseFieldsDefinition() FieldList {
+ var defs FieldList
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ defs = append(defs, p.parseFieldDefinition())
+ })
+ return defs
+}
+
+func (p *parser) parseFieldDefinition() *FieldDefinition {
+ var def FieldDefinition
+ def.Position = p.peekPos()
+ def.Description = p.parseDescription()
+ def.Name = p.parseName()
+ def.Arguments = p.parseArgumentDefs()
+ p.expect(lexer.Colon)
+ def.Type = p.parseTypeReference()
+ def.Directives = p.parseDirectives(true)
+
+ return &def
+}
+
+func (p *parser) parseArgumentDefs() ArgumentDefinitionList {
+ var args ArgumentDefinitionList
+ p.many(lexer.ParenL, lexer.ParenR, func() {
+ args = append(args, p.parseArgumentDef())
+ })
+ return args
+}
+
+func (p *parser) parseArgumentDef() *ArgumentDefinition {
+ var def ArgumentDefinition
+ def.Position = p.peekPos()
+ def.Description = p.parseDescription()
+ def.Name = p.parseName()
+ p.expect(lexer.Colon)
+ def.Type = p.parseTypeReference()
+ if p.skip(lexer.Equals) {
+ def.DefaultValue = p.parseValueLiteral(true)
+ }
+ def.Directives = p.parseDirectives(true)
+ return &def
+}
+
+func (p *parser) parseInputValueDef() *FieldDefinition {
+ var def FieldDefinition
+ def.Position = p.peekPos()
+ def.Description = p.parseDescription()
+ def.Name = p.parseName()
+ p.expect(lexer.Colon)
+ def.Type = p.parseTypeReference()
+ if p.skip(lexer.Equals) {
+ def.DefaultValue = p.parseValueLiteral(true)
+ }
+ def.Directives = p.parseDirectives(true)
+ return &def
+}
+
+func (p *parser) parseInterfaceTypeDefinition(description string) *Definition {
+ p.expectKeyword("interface")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Interface
+ def.Description = description
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.Fields = p.parseFieldsDefinition()
+ return &def
+}
+
+func (p *parser) parseUnionTypeDefinition(description string) *Definition {
+ p.expectKeyword("union")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Union
+ def.Description = description
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.Types = p.parseUnionMemberTypes()
+ return &def
+}
+
+func (p *parser) parseUnionMemberTypes() []string {
+ var types []string
+ if p.skip(lexer.Equals) {
+ // optional leading pipe
+ p.skip(lexer.Pipe)
+
+ types = append(types, p.parseName())
+ for p.skip(lexer.Pipe) && p.err == nil {
+ types = append(types, p.parseName())
+ }
+ }
+ return types
+}
+
+func (p *parser) parseEnumTypeDefinition(description string) *Definition {
+ p.expectKeyword("enum")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Enum
+ def.Description = description
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.EnumValues = p.parseEnumValuesDefinition()
+ return &def
+}
+
+func (p *parser) parseEnumValuesDefinition() EnumValueList {
+ var values EnumValueList
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ values = append(values, p.parseEnumValueDefinition())
+ })
+ return values
+}
+
+func (p *parser) parseEnumValueDefinition() *EnumValueDefinition {
+ return &EnumValueDefinition{
+ Position: p.peekPos(),
+ Description: p.parseDescription(),
+ Name: p.parseName(),
+ Directives: p.parseDirectives(true),
+ }
+}
+
+func (p *parser) parseInputObjectTypeDefinition(description string) *Definition {
+ p.expectKeyword("input")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = InputObject
+ def.Description = description
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.Fields = p.parseInputFieldsDefinition()
+ return &def
+}
+
+func (p *parser) parseInputFieldsDefinition() FieldList {
+ var values FieldList
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ values = append(values, p.parseInputValueDef())
+ })
+ return values
+}
+
+func (p *parser) parseTypeSystemExtension(doc *SchemaDocument) {
+ p.expectKeyword("extend")
+
+ switch p.peek().Value {
+ case "schema":
+ doc.SchemaExtension = append(doc.SchemaExtension, p.parseSchemaExtension())
+ case "scalar":
+ doc.Extensions = append(doc.Extensions, p.parseScalarTypeExtension())
+ case "type":
+ doc.Extensions = append(doc.Extensions, p.parseObjectTypeExtension())
+ case "interface":
+ doc.Extensions = append(doc.Extensions, p.parseInterfaceTypeExtension())
+ case "union":
+ doc.Extensions = append(doc.Extensions, p.parseUnionTypeExtension())
+ case "enum":
+ doc.Extensions = append(doc.Extensions, p.parseEnumTypeExtension())
+ case "input":
+ doc.Extensions = append(doc.Extensions, p.parseInputObjectTypeExtension())
+ default:
+ p.unexpectedError()
+ }
+}
+
+func (p *parser) parseSchemaExtension() *SchemaDefinition {
+ p.expectKeyword("schema")
+
+ var def SchemaDefinition
+ def.Position = p.peekPos()
+ def.Directives = p.parseDirectives(true)
+ p.many(lexer.BraceL, lexer.BraceR, func() {
+ def.OperationTypes = append(def.OperationTypes, p.parseOperationTypeDefinition())
+ })
+ if len(def.Directives) == 0 && len(def.OperationTypes) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseScalarTypeExtension() *Definition {
+ p.expectKeyword("scalar")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Scalar
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ if len(def.Directives) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseObjectTypeExtension() *Definition {
+ p.expectKeyword("type")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Object
+ def.Name = p.parseName()
+ def.Interfaces = p.parseImplementsInterfaces()
+ def.Directives = p.parseDirectives(true)
+ def.Fields = p.parseFieldsDefinition()
+ if len(def.Interfaces) == 0 && len(def.Directives) == 0 && len(def.Fields) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseInterfaceTypeExtension() *Definition {
+ p.expectKeyword("interface")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Interface
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.Fields = p.parseFieldsDefinition()
+ if len(def.Directives) == 0 && len(def.Fields) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseUnionTypeExtension() *Definition {
+ p.expectKeyword("union")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Union
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.Types = p.parseUnionMemberTypes()
+
+ if len(def.Directives) == 0 && len(def.Types) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseEnumTypeExtension() *Definition {
+ p.expectKeyword("enum")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = Enum
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(true)
+ def.EnumValues = p.parseEnumValuesDefinition()
+ if len(def.Directives) == 0 && len(def.EnumValues) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseInputObjectTypeExtension() *Definition {
+ p.expectKeyword("input")
+
+ var def Definition
+ def.Position = p.peekPos()
+ def.Kind = InputObject
+ def.Name = p.parseName()
+ def.Directives = p.parseDirectives(false)
+ def.Fields = p.parseInputFieldsDefinition()
+ if len(def.Directives) == 0 && len(def.Fields) == 0 {
+ p.unexpectedError()
+ }
+ return &def
+}
+
+func (p *parser) parseDirectiveDefinition(description string) *DirectiveDefinition {
+ p.expectKeyword("directive")
+ p.expect(lexer.At)
+
+ var def DirectiveDefinition
+ def.Position = p.peekPos()
+ def.Description = description
+ def.Name = p.parseName()
+ def.Arguments = p.parseArgumentDefs()
+
+ p.expectKeyword("on")
+ def.Locations = p.parseDirectiveLocations()
+ return &def
+}
+
+func (p *parser) parseDirectiveLocations() []DirectiveLocation {
+ p.skip(lexer.Pipe)
+
+ locations := []DirectiveLocation{p.parseDirectiveLocation()}
+
+ for p.skip(lexer.Pipe) && p.err == nil {
+ locations = append(locations, p.parseDirectiveLocation())
+ }
+
+ return locations
+}
+
+func (p *parser) parseDirectiveLocation() DirectiveLocation {
+ name := p.expect(lexer.Name)
+
+ switch name.Value {
+ case `QUERY`:
+ return LocationQuery
+ case `MUTATION`:
+ return LocationMutation
+ case `SUBSCRIPTION`:
+ return LocationSubscription
+ case `FIELD`:
+ return LocationField
+ case `FRAGMENT_DEFINITION`:
+ return LocationFragmentDefinition
+ case `FRAGMENT_SPREAD`:
+ return LocationFragmentSpread
+ case `INLINE_FRAGMENT`:
+ return LocationInlineFragment
+ case `SCHEMA`:
+ return LocationSchema
+ case `SCALAR`:
+ return LocationScalar
+ case `OBJECT`:
+ return LocationObject
+ case `FIELD_DEFINITION`:
+ return LocationFieldDefinition
+ case `ARGUMENT_DEFINITION`:
+ return LocationArgumentDefinition
+ case `INTERFACE`:
+ return LocationInterface
+ case `UNION`:
+ return LocationUnion
+ case `ENUM`:
+ return LocationEnum
+ case `ENUM_VALUE`:
+ return LocationEnumValue
+ case `INPUT_OBJECT`:
+ return LocationInputObject
+ case `INPUT_FIELD_DEFINITION`:
+ return LocationInputFieldDefinition
+ }
+
+ p.unexpectedToken(name)
+ return ""
+}
diff --git a/vendor/github.com/vektah/gqlparser/parser/schema_test.yml b/vendor/github.com/vektah/gqlparser/parser/schema_test.yml
new file mode 100644
index 00000000..c65239a5
--- /dev/null
+++ b/vendor/github.com/vektah/gqlparser/parser/schema_test.yml
@@ -0,0 +1,505 @@
+object types:
+ - name: simple
+ input: |
+ type Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+
+ - name: with description
+ input: |
+ "Description"
+ type Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Description: "Description"
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+
+ - name: with block description
+ input: |
+ """
+ Description
+ """
+ # Even with comments between them
+ type Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Description: "Description"
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+ - name: with field arg
+ input: |
+ type Hello {
+ world(flag: Boolean): String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Arguments: [ArgumentDefinition]
+ - <ArgumentDefinition>
+ Name: "flag"
+ Type: Boolean
+ Type: String
+
+ - name: with field arg and default value
+ input: |
+ type Hello {
+ world(flag: Boolean = true): String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Arguments: [ArgumentDefinition]
+ - <ArgumentDefinition>
+ Name: "flag"
+ DefaultValue: true
+ Type: Boolean
+ Type: String
+
+ - name: with field list arg
+ input: |
+ type Hello {
+ world(things: [String]): String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Arguments: [ArgumentDefinition]
+ - <ArgumentDefinition>
+ Name: "things"
+ Type: [String]
+ Type: String
+
+ - name: with two args
+ input: |
+ type Hello {
+ world(argOne: Boolean, argTwo: Int): String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Arguments: [ArgumentDefinition]
+ - <ArgumentDefinition>
+ Name: "argOne"
+ Type: Boolean
+ - <ArgumentDefinition>
+ Name: "argTwo"
+ Type: Int
+ Type: String
+
+type extensions:
+ - name: Object extension
+ input: |
+ extend type Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Extensions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+
+ - name: without any fields
+ input: "extend type Hello implements Greeting"
+ ast: |
+ <SchemaDocument>
+ Extensions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "Greeting"
+
+ - name: without fields twice
+ input: |
+ extend type Hello implements Greeting
+ extend type Hello implements SecondGreeting
+ ast: |
+ <SchemaDocument>
+ Extensions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "Greeting"
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "SecondGreeting"
+
+ - name: without anything errors
+ input: "extend type Hello"
+ error:
+ message: "Unexpected <EOF>"
+ locations: [{ line: 1, column: 18 }]
+
+ - name: can have descriptions # hmm, this might not be spec compliant...
+ input: |
+ "Description"
+ extend type Hello {
+ world: String
+ }
+ error:
+ message: 'Unexpected String "Description"'
+ locations: [{ line: 1, column: 2 }]
+
+ - name: can not have descriptions on types
+ input: |
+ extend "Description" type Hello {
+ world: String
+ }
+ error:
+ message: Unexpected String "Description"
+ locations: [{ line: 1, column: 9 }]
+
+schema definition:
+ - name: simple
+ input: |
+ schema {
+ query: Query
+ }
+ ast: |
+ <SchemaDocument>
+ Schema: [SchemaDefinition]
+ - <SchemaDefinition>
+ OperationTypes: [OperationTypeDefinition]
+ - <OperationTypeDefinition>
+ Operation: Operation("query")
+ Type: "Query"
+
+schema extensions:
+ - name: simple
+ input: |
+ extend schema {
+ mutation: Mutation
+ }
+ ast: |
+ <SchemaDocument>
+ SchemaExtension: [SchemaDefinition]
+ - <SchemaDefinition>
+ OperationTypes: [OperationTypeDefinition]
+ - <OperationTypeDefinition>
+ Operation: Operation("mutation")
+ Type: "Mutation"
+
+ - name: directive only
+ input: "extend schema @directive"
+ ast: |
+ <SchemaDocument>
+ SchemaExtension: [SchemaDefinition]
+ - <SchemaDefinition>
+ Directives: [Directive]
+ - <Directive>
+ Name: "directive"
+
+ - name: without anything errors
+ input: "extend schema"
+ error:
+ message: "Unexpected <EOF>"
+ locations: [{ line: 1, column: 14}]
+
+type extensions:
+ - name: all can have directives
+ input: |
+ extend scalar Foo @deprecated
+ extend type Foo @deprecated
+ extend interface Foo @deprecated
+ extend union Foo @deprecated
+ extend enum Foo @deprecated
+ extend input Foo @deprecated
+ ast: |
+ <SchemaDocument>
+ Extensions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("SCALAR")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+ - <Definition>
+ Kind: DefinitionKind("INTERFACE")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+ - <Definition>
+ Kind: DefinitionKind("UNION")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+ - <Definition>
+ Kind: DefinitionKind("ENUM")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+ - <Definition>
+ Kind: DefinitionKind("INPUT_OBJECT")
+ Name: "Foo"
+ Directives: [Directive]
+ - <Directive>
+ Name: "deprecated"
+
+
+inheritance:
+ - name: single
+ input: "type Hello implements World { field: String }"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "World"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "field"
+ Type: String
+
+ - name: multi
+ input: "type Hello implements Wo & rld { field: String }"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "Wo"
+ - "rld"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "field"
+ Type: String
+
+ - name: multi with leading amp
+ input: "type Hello implements & Wo & rld { field: String }"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("OBJECT")
+ Name: "Hello"
+ Interfaces: [string]
+ - "Wo"
+ - "rld"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "field"
+ Type: String
+
+enums:
+ - name: single value
+ input: "enum Hello { WORLD }"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("ENUM")
+ Name: "Hello"
+ EnumValues: [EnumValueDefinition]
+ - <EnumValueDefinition>
+ Name: "WORLD"
+
+ - name: double value
+ input: "enum Hello { WO, RLD }"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("ENUM")
+ Name: "Hello"
+ EnumValues: [EnumValueDefinition]
+ - <EnumValueDefinition>
+ Name: "WO"
+ - <EnumValueDefinition>
+ Name: "RLD"
+
+interface:
+ - name: simple
+ input: |
+ interface Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("INTERFACE")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+
+unions:
+ - name: simple
+ input: "union Hello = World"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("UNION")
+ Name: "Hello"
+ Types: [string]
+ - "World"
+
+ - name: with two types
+ input: "union Hello = Wo | Rld"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("UNION")
+ Name: "Hello"
+ Types: [string]
+ - "Wo"
+ - "Rld"
+
+ - name: with leading pipe
+ input: "union Hello = | Wo | Rld"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("UNION")
+ Name: "Hello"
+ Types: [string]
+ - "Wo"
+ - "Rld"
+
+ - name: cant be empty
+ input: "union Hello = || Wo | Rld"
+ error:
+ message: "Expected Name, found |"
+ locations: [{ line: 1, column: 16 }]
+
+ - name: cant double pipe
+ input: "union Hello = Wo || Rld"
+ error:
+ message: "Expected Name, found |"
+ locations: [{ line: 1, column: 19 }]
+
+ - name: cant have trailing pipe
+ input: "union Hello = | Wo | Rld |"
+ error:
+ message: "Expected Name, found <EOF>"
+ locations: [{ line: 1, column: 27 }]
+
+scalar:
+ - name: simple
+ input: "scalar Hello"
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("SCALAR")
+ Name: "Hello"
+
+input object:
+ - name: simple
+ input: |
+ input Hello {
+ world: String
+ }
+ ast: |
+ <SchemaDocument>
+ Definitions: [Definition]
+ - <Definition>
+ Kind: DefinitionKind("INPUT_OBJECT")
+ Name: "Hello"
+ Fields: [FieldDefinition]
+ - <FieldDefinition>
+ Name: "world"
+ Type: String
+
+ - name: can not have args
+ input: |
+ input Hello {
+ world(foo: Int): String
+ }
+ error:
+ message: "Expected :, found ("
+ locations: [{ line: 2, column: 8 }]
+
+directives:
+ - name: simple
+ input: directive @foo on FIELD
+ ast: |
+ <SchemaDocument>
+ Directives: [DirectiveDefinition]
+ - <DirectiveDefinition>
+ Name: "foo"
+ Locations: [DirectiveLocation]
+ - DirectiveLocation("FIELD")
+
+ - name: invalid location
+ input: "directive @foo on FIELD | INCORRECT_LOCATION"
+ error:
+ message: 'Unexpected Name "INCORRECT_LOCATION"'
+ locations: [{ line: 1, column: 27 }]
+