aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs/gqlgen/graphql
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/graphql')
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/bool.go30
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/context.go178
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/error.go31
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/exec.go135
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/float.go31
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/id.go36
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/int.go29
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go58
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/query.go104
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go68
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/type.go174
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/jsonw.go83
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/map.go24
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/oneshot.go14
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/recovery.go19
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/response.go20
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/string.go63
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/time.go21
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/version.go3
19 files changed, 1121 insertions, 0 deletions
diff --git a/vendor/github.com/99designs/gqlgen/graphql/bool.go b/vendor/github.com/99designs/gqlgen/graphql/bool.go
new file mode 100644
index 00000000..7053bbca
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/bool.go
@@ -0,0 +1,30 @@
+package graphql
+
+import (
+ "fmt"
+ "io"
+ "strings"
+)
+
+func MarshalBoolean(b bool) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ if b {
+ w.Write(trueLit)
+ } else {
+ w.Write(falseLit)
+ }
+ })
+}
+
+func UnmarshalBoolean(v interface{}) (bool, error) {
+ switch v := v.(type) {
+ case string:
+ return "true" == strings.ToLower(v), nil
+ case int:
+ return v != 0, nil
+ case bool:
+ return v, nil
+ default:
+ return false, fmt.Errorf("%T is not a bool", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/context.go b/vendor/github.com/99designs/gqlgen/graphql/context.go
new file mode 100644
index 00000000..6baee83c
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/context.go
@@ -0,0 +1,178 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+ "sync"
+
+ "github.com/vektah/gqlparser/ast"
+ "github.com/vektah/gqlparser/gqlerror"
+)
+
+type Resolver func(ctx context.Context) (res interface{}, err error)
+type FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error)
+type RequestMiddleware func(ctx context.Context, next func(ctx context.Context) []byte) []byte
+
+type RequestContext struct {
+ RawQuery string
+ Variables map[string]interface{}
+ Doc *ast.QueryDocument
+ // ErrorPresenter will be used to generate the error
+ // message from errors given to Error().
+ ErrorPresenter ErrorPresenterFunc
+ Recover RecoverFunc
+ ResolverMiddleware FieldMiddleware
+ DirectiveMiddleware FieldMiddleware
+ RequestMiddleware RequestMiddleware
+
+ errorsMu sync.Mutex
+ Errors gqlerror.List
+}
+
+func DefaultResolverMiddleware(ctx context.Context, next Resolver) (res interface{}, err error) {
+ return next(ctx)
+}
+
+func DefaultDirectiveMiddleware(ctx context.Context, next Resolver) (res interface{}, err error) {
+ return next(ctx)
+}
+
+func DefaultRequestMiddleware(ctx context.Context, next func(ctx context.Context) []byte) []byte {
+ return next(ctx)
+}
+
+func NewRequestContext(doc *ast.QueryDocument, query string, variables map[string]interface{}) *RequestContext {
+ return &RequestContext{
+ Doc: doc,
+ RawQuery: query,
+ Variables: variables,
+ ResolverMiddleware: DefaultResolverMiddleware,
+ DirectiveMiddleware: DefaultDirectiveMiddleware,
+ RequestMiddleware: DefaultRequestMiddleware,
+ Recover: DefaultRecover,
+ ErrorPresenter: DefaultErrorPresenter,
+ }
+}
+
+type key string
+
+const (
+ request key = "request_context"
+ resolver key = "resolver_context"
+)
+
+func GetRequestContext(ctx context.Context) *RequestContext {
+ val := ctx.Value(request)
+ if val == nil {
+ return nil
+ }
+
+ return val.(*RequestContext)
+}
+
+func WithRequestContext(ctx context.Context, rc *RequestContext) context.Context {
+ return context.WithValue(ctx, request, rc)
+}
+
+type ResolverContext struct {
+ Parent *ResolverContext
+ // The name of the type this field belongs to
+ Object string
+ // These are the args after processing, they can be mutated in middleware to change what the resolver will get.
+ Args map[string]interface{}
+ // The raw field
+ Field CollectedField
+ // The index of array in path.
+ Index *int
+ // The result object of resolver
+ Result interface{}
+}
+
+func (r *ResolverContext) Path() []interface{} {
+ var path []interface{}
+ for it := r; it != nil; it = it.Parent {
+ if it.Index != nil {
+ path = append(path, *it.Index)
+ } else if it.Field.Field != nil {
+ path = append(path, it.Field.Alias)
+ }
+ }
+
+ // because we are walking up the chain, all the elements are backwards, do an inplace flip.
+ for i := len(path)/2 - 1; i >= 0; i-- {
+ opp := len(path) - 1 - i
+ path[i], path[opp] = path[opp], path[i]
+ }
+
+ return path
+}
+
+func GetResolverContext(ctx context.Context) *ResolverContext {
+ val, _ := ctx.Value(resolver).(*ResolverContext)
+ return val
+}
+
+func WithResolverContext(ctx context.Context, rc *ResolverContext) context.Context {
+ rc.Parent = GetResolverContext(ctx)
+ return context.WithValue(ctx, resolver, rc)
+}
+
+// This is just a convenient wrapper method for CollectFields
+func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField {
+ resctx := GetResolverContext(ctx)
+ return CollectFields(ctx, resctx.Field.Selections, satisfies)
+}
+
+// Errorf sends an error string to the client, passing it through the formatter.
+func (c *RequestContext) Errorf(ctx context.Context, format string, args ...interface{}) {
+ c.errorsMu.Lock()
+ defer c.errorsMu.Unlock()
+
+ c.Errors = append(c.Errors, c.ErrorPresenter(ctx, fmt.Errorf(format, args...)))
+}
+
+// Error sends an error to the client, passing it through the formatter.
+func (c *RequestContext) Error(ctx context.Context, err error) {
+ c.errorsMu.Lock()
+ defer c.errorsMu.Unlock()
+
+ c.Errors = append(c.Errors, c.ErrorPresenter(ctx, err))
+}
+
+// HasError returns true if the current field has already errored
+func (c *RequestContext) HasError(rctx *ResolverContext) bool {
+ c.errorsMu.Lock()
+ defer c.errorsMu.Unlock()
+ path := rctx.Path()
+
+ for _, err := range c.Errors {
+ if equalPath(err.Path, path) {
+ return true
+ }
+ }
+ return false
+}
+
+func equalPath(a []interface{}, b []interface{}) bool {
+ if len(a) != len(b) {
+ return false
+ }
+
+ for i := 0; i < len(a); i++ {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+// AddError is a convenience method for adding an error to the current response
+func AddError(ctx context.Context, err error) {
+ GetRequestContext(ctx).Error(ctx, err)
+}
+
+// AddErrorf is a convenience method for adding an error to the current response
+func AddErrorf(ctx context.Context, format string, args ...interface{}) {
+ GetRequestContext(ctx).Errorf(ctx, format, args...)
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/error.go b/vendor/github.com/99designs/gqlgen/graphql/error.go
new file mode 100644
index 00000000..7f161a43
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/error.go
@@ -0,0 +1,31 @@
+package graphql
+
+import (
+ "context"
+
+ "github.com/vektah/gqlparser/gqlerror"
+)
+
+type ErrorPresenterFunc func(context.Context, error) *gqlerror.Error
+
+type ExtendedError interface {
+ Extensions() map[string]interface{}
+}
+
+func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error {
+ if gqlerr, ok := err.(*gqlerror.Error); ok {
+ gqlerr.Path = GetResolverContext(ctx).Path()
+ return gqlerr
+ }
+
+ var extensions map[string]interface{}
+ if ee, ok := err.(ExtendedError); ok {
+ extensions = ee.Extensions()
+ }
+
+ return &gqlerror.Error{
+ Message: err.Error(),
+ Path: GetResolverContext(ctx).Path(),
+ Extensions: extensions,
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/exec.go b/vendor/github.com/99designs/gqlgen/graphql/exec.go
new file mode 100644
index 00000000..9beb3149
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/exec.go
@@ -0,0 +1,135 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/vektah/gqlparser/ast"
+)
+
+type ExecutableSchema interface {
+ Schema() *ast.Schema
+
+ Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{}) (int, bool)
+ Query(ctx context.Context, op *ast.OperationDefinition) *Response
+ Mutation(ctx context.Context, op *ast.OperationDefinition) *Response
+ Subscription(ctx context.Context, op *ast.OperationDefinition) func() *Response
+}
+
+func CollectFields(ctx context.Context, selSet ast.SelectionSet, satisfies []string) []CollectedField {
+ return collectFields(GetRequestContext(ctx), selSet, satisfies, map[string]bool{})
+}
+
+func collectFields(reqCtx *RequestContext, selSet ast.SelectionSet, satisfies []string, visited map[string]bool) []CollectedField {
+ var groupedFields []CollectedField
+
+ for _, sel := range selSet {
+ switch sel := sel.(type) {
+ case *ast.Field:
+ if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
+ continue
+ }
+ f := getOrCreateField(&groupedFields, sel.Alias, func() CollectedField {
+ return CollectedField{Field: sel}
+ })
+
+ f.Selections = append(f.Selections, sel.SelectionSet...)
+ case *ast.InlineFragment:
+ if !shouldIncludeNode(sel.Directives, reqCtx.Variables) || !instanceOf(sel.TypeCondition, satisfies) {
+ continue
+ }
+ for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) {
+ f := getOrCreateField(&groupedFields, childField.Name, func() CollectedField { return childField })
+ f.Selections = append(f.Selections, childField.Selections...)
+ }
+
+ case *ast.FragmentSpread:
+ if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
+ continue
+ }
+ fragmentName := sel.Name
+ if _, seen := visited[fragmentName]; seen {
+ continue
+ }
+ visited[fragmentName] = true
+
+ fragment := reqCtx.Doc.Fragments.ForName(fragmentName)
+ if fragment == nil {
+ // should never happen, validator has already run
+ panic(fmt.Errorf("missing fragment %s", fragmentName))
+ }
+
+ if !instanceOf(fragment.TypeCondition, satisfies) {
+ continue
+ }
+
+ for _, childField := range collectFields(reqCtx, fragment.SelectionSet, satisfies, visited) {
+ f := getOrCreateField(&groupedFields, childField.Name, func() CollectedField { return childField })
+ f.Selections = append(f.Selections, childField.Selections...)
+ }
+
+ default:
+ panic(fmt.Errorf("unsupported %T", sel))
+ }
+ }
+
+ return groupedFields
+}
+
+type CollectedField struct {
+ *ast.Field
+
+ Selections ast.SelectionSet
+}
+
+func instanceOf(val string, satisfies []string) bool {
+ for _, s := range satisfies {
+ if val == s {
+ return true
+ }
+ }
+ return false
+}
+
+func getOrCreateField(c *[]CollectedField, name string, creator func() CollectedField) *CollectedField {
+ for i, cf := range *c {
+ if cf.Alias == name {
+ return &(*c)[i]
+ }
+ }
+
+ f := creator()
+
+ *c = append(*c, f)
+ return &(*c)[len(*c)-1]
+}
+
+func shouldIncludeNode(directives ast.DirectiveList, variables map[string]interface{}) bool {
+ skip, include := false, true
+
+ if d := directives.ForName("skip"); d != nil {
+ skip = resolveIfArgument(d, variables)
+ }
+
+ if d := directives.ForName("include"); d != nil {
+ include = resolveIfArgument(d, variables)
+ }
+
+ return !skip && include
+}
+
+func resolveIfArgument(d *ast.Directive, variables map[string]interface{}) bool {
+ arg := d.Arguments.ForName("if")
+ if arg == nil {
+ panic(fmt.Sprintf("%s: argument 'if' not defined", d.Name))
+ }
+ value, err := arg.Value.Value(variables)
+ if err != nil {
+ panic(err)
+ }
+ ret, ok := value.(bool)
+ if !ok {
+ panic(fmt.Sprintf("%s: argument 'if' is not a boolean", d.Name))
+ }
+ return ret
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/float.go b/vendor/github.com/99designs/gqlgen/graphql/float.go
new file mode 100644
index 00000000..d204335c
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/float.go
@@ -0,0 +1,31 @@
+package graphql
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+func MarshalFloat(f float64) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, fmt.Sprintf("%f", f))
+ })
+}
+
+func UnmarshalFloat(v interface{}) (float64, error) {
+ switch v := v.(type) {
+ case string:
+ return strconv.ParseFloat(v, 64)
+ case int:
+ return float64(v), nil
+ case int64:
+ return float64(v), nil
+ case float64:
+ return v, nil
+ case json.Number:
+ return strconv.ParseFloat(string(v), 64)
+ default:
+ return 0, fmt.Errorf("%T is not an float", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go
new file mode 100644
index 00000000..a5a7960f
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/id.go
@@ -0,0 +1,36 @@
+package graphql
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+func MarshalID(s string) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, strconv.Quote(s))
+ })
+}
+func UnmarshalID(v interface{}) (string, error) {
+ switch v := v.(type) {
+ case string:
+ return v, nil
+ case json.Number:
+ return string(v), nil
+ case int:
+ return strconv.Itoa(v), nil
+ case float64:
+ return fmt.Sprintf("%f", v), nil
+ case bool:
+ if v {
+ return "true", nil
+ } else {
+ return "false", nil
+ }
+ case nil:
+ return "null", nil
+ default:
+ return "", fmt.Errorf("%T is not a string", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/int.go b/vendor/github.com/99designs/gqlgen/graphql/int.go
new file mode 100644
index 00000000..ff87574c
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/int.go
@@ -0,0 +1,29 @@
+package graphql
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "strconv"
+)
+
+func MarshalInt(i int) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, strconv.Itoa(i))
+ })
+}
+
+func UnmarshalInt(v interface{}) (int, error) {
+ switch v := v.(type) {
+ case string:
+ return strconv.Atoi(v)
+ case int:
+ return v, nil
+ case int64:
+ return int(v), nil
+ case json.Number:
+ return strconv.Atoi(string(v))
+ default:
+ return 0, fmt.Errorf("%T is not an int", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
new file mode 100644
index 00000000..baff882e
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
@@ -0,0 +1,58 @@
+// introspection implements the spec defined in https://github.com/facebook/graphql/blob/master/spec/Section%204%20--%20Introspection.md#schema-introspection
+package introspection
+
+import "github.com/vektah/gqlparser/ast"
+
+type (
+ Directive struct {
+ Name string
+ Description string
+ Locations []string
+ Args []InputValue
+ }
+
+ EnumValue struct {
+ Name string
+ Description string
+ IsDeprecated bool
+ DeprecationReason string
+ }
+
+ Field struct {
+ Name string
+ Description string
+ Type *Type
+ Args []InputValue
+ IsDeprecated bool
+ DeprecationReason string
+ }
+
+ InputValue struct {
+ Name string
+ Description string
+ DefaultValue *string
+ Type *Type
+ }
+)
+
+func WrapSchema(schema *ast.Schema) *Schema {
+ return &Schema{schema: schema}
+}
+
+func isDeprecated(directives ast.DirectiveList) bool {
+ return directives.ForName("deprecated") != nil
+}
+
+func deprecationReason(directives ast.DirectiveList) string {
+ deprecation := directives.ForName("deprecated")
+ if deprecation == nil {
+ return ""
+ }
+
+ reason := deprecation.Arguments.ForName("reason")
+ if reason == nil {
+ return ""
+ }
+
+ return reason.Value.Raw
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go
new file mode 100644
index 00000000..b1e4fbc6
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/query.go
@@ -0,0 +1,104 @@
+package introspection
+
+// Query is the query generated by graphiql to determine type information
+const Query = `
+query IntrospectionQuery {
+ __schema {
+ queryType {
+ name
+ }
+ mutationType {
+ name
+ }
+ subscriptionType {
+ name
+ }
+ types {
+ ...FullType
+ }
+ directives {
+ name
+ description
+ locations
+ args {
+ ...InputValue
+ }
+ }
+ }
+}
+
+fragment FullType on __Type {
+ kind
+ name
+ description
+ fields(includeDeprecated: true) {
+ name
+ description
+ args {
+ ...InputValue
+ }
+ type {
+ ...TypeRef
+ }
+ isDeprecated
+ deprecationReason
+ }
+ inputFields {
+ ...InputValue
+ }
+ interfaces {
+ ...TypeRef
+ }
+ enumValues(includeDeprecated: true) {
+ name
+ description
+ isDeprecated
+ deprecationReason
+ }
+ possibleTypes {
+ ...TypeRef
+ }
+}
+
+fragment InputValue on __InputValue {
+ name
+ description
+ type {
+ ...TypeRef
+ }
+ defaultValue
+}
+
+fragment TypeRef on __Type {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ ofType {
+ kind
+ name
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+`
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go
new file mode 100644
index 00000000..b5d2c482
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/schema.go
@@ -0,0 +1,68 @@
+package introspection
+
+import (
+ "strings"
+
+ "github.com/vektah/gqlparser/ast"
+)
+
+type Schema struct {
+ schema *ast.Schema
+}
+
+func (s *Schema) Types() []Type {
+ var types []Type
+ for _, typ := range s.schema.Types {
+ if strings.HasPrefix(typ.Name, "__") {
+ continue
+ }
+ types = append(types, *WrapTypeFromDef(s.schema, typ))
+ }
+ return types
+}
+
+func (s *Schema) QueryType() *Type {
+ return WrapTypeFromDef(s.schema, s.schema.Query)
+}
+
+func (s *Schema) MutationType() *Type {
+ return WrapTypeFromDef(s.schema, s.schema.Mutation)
+}
+
+func (s *Schema) SubscriptionType() *Type {
+ return WrapTypeFromDef(s.schema, s.schema.Subscription)
+}
+
+func (s *Schema) Directives() []Directive {
+ var res []Directive
+
+ for _, d := range s.schema.Directives {
+ res = append(res, s.directiveFromDef(d))
+ }
+
+ return res
+}
+
+func (s *Schema) directiveFromDef(d *ast.DirectiveDefinition) Directive {
+ var locs []string
+ for _, loc := range d.Locations {
+ locs = append(locs, string(loc))
+ }
+
+ var args []InputValue
+ for _, arg := range d.Arguments {
+ args = append(args, InputValue{
+ Name: arg.Name,
+ Description: arg.Description,
+ DefaultValue: defaultValue(arg.DefaultValue),
+ Type: WrapTypeFromType(s.schema, arg.Type),
+ })
+ }
+
+ return Directive{
+ Name: d.Name,
+ Description: d.Description,
+ Locations: locs,
+ Args: args,
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
new file mode 100644
index 00000000..dce144e0
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
@@ -0,0 +1,174 @@
+package introspection
+
+import (
+ "strings"
+
+ "github.com/vektah/gqlparser/ast"
+)
+
+type Type struct {
+ schema *ast.Schema
+ def *ast.Definition
+ typ *ast.Type
+}
+
+func WrapTypeFromDef(s *ast.Schema, def *ast.Definition) *Type {
+ if def == nil {
+ return nil
+ }
+ return &Type{schema: s, def: def}
+}
+
+func WrapTypeFromType(s *ast.Schema, typ *ast.Type) *Type {
+ if typ == nil {
+ return nil
+ }
+
+ if !typ.NonNull && typ.NamedType != "" {
+ return &Type{schema: s, def: s.Types[typ.NamedType]}
+ }
+ return &Type{schema: s, typ: typ}
+}
+
+func (t *Type) Kind() string {
+ if t.typ != nil {
+ if t.typ.NonNull {
+ return "NON_NULL"
+ }
+
+ if t.typ.Elem != nil {
+ return "LIST"
+ }
+ } else {
+ return string(t.def.Kind)
+ }
+
+ panic("UNKNOWN")
+}
+
+func (t *Type) Name() *string {
+ if t.def == nil {
+ return nil
+ }
+ return &t.def.Name
+}
+
+func (t *Type) Description() string {
+ if t.def == nil {
+ return ""
+ }
+ return t.def.Description
+}
+
+func (t *Type) Fields(includeDeprecated bool) []Field {
+ if t.def == nil || (t.def.Kind != ast.Object && t.def.Kind != ast.Interface) {
+ return nil
+ }
+ var fields []Field
+ for _, f := range t.def.Fields {
+ if strings.HasPrefix(f.Name, "__") {
+ continue
+ }
+
+ var args []InputValue
+ for _, arg := range f.Arguments {
+ args = append(args, InputValue{
+ Type: WrapTypeFromType(t.schema, arg.Type),
+ Name: arg.Name,
+ Description: arg.Description,
+ DefaultValue: defaultValue(arg.DefaultValue),
+ })
+ }
+
+ fields = append(fields, Field{
+ Name: f.Name,
+ Description: f.Description,
+ Args: args,
+ Type: WrapTypeFromType(t.schema, f.Type),
+ IsDeprecated: isDeprecated(f.Directives),
+ DeprecationReason: deprecationReason(f.Directives),
+ })
+ }
+ return fields
+}
+
+func (t *Type) InputFields() []InputValue {
+ if t.def == nil || t.def.Kind != ast.InputObject {
+ return nil
+ }
+
+ var res []InputValue
+ for _, f := range t.def.Fields {
+ res = append(res, InputValue{
+ Name: f.Name,
+ Description: f.Description,
+ Type: WrapTypeFromType(t.schema, f.Type),
+ DefaultValue: defaultValue(f.DefaultValue),
+ })
+ }
+ return res
+}
+
+func defaultValue(value *ast.Value) *string {
+ if value == nil {
+ return nil
+ }
+ val := value.String()
+ return &val
+}
+
+func (t *Type) Interfaces() []Type {
+ if t.def == nil || t.def.Kind != ast.Object {
+ return nil
+ }
+
+ var res []Type
+ for _, intf := range t.def.Interfaces {
+ res = append(res, *WrapTypeFromDef(t.schema, t.schema.Types[intf]))
+ }
+
+ return res
+}
+
+func (t *Type) PossibleTypes() []Type {
+ if t.def == nil || (t.def.Kind != ast.Interface && t.def.Kind != ast.Union) {
+ return nil
+ }
+
+ var res []Type
+ for _, pt := range t.schema.GetPossibleTypes(t.def) {
+ res = append(res, *WrapTypeFromDef(t.schema, pt))
+ }
+ return res
+}
+
+func (t *Type) EnumValues(includeDeprecated bool) []EnumValue {
+ if t.def == nil || t.def.Kind != ast.Enum {
+ return nil
+ }
+
+ var res []EnumValue
+ for _, val := range t.def.EnumValues {
+ res = append(res, EnumValue{
+ Name: val.Name,
+ Description: val.Description,
+ IsDeprecated: isDeprecated(val.Directives),
+ DeprecationReason: deprecationReason(val.Directives),
+ })
+ }
+ return res
+}
+
+func (t *Type) OfType() *Type {
+ if t.typ == nil {
+ return nil
+ }
+ if t.typ.NonNull {
+ // fake non null nodes
+ cpy := *t.typ
+ cpy.NonNull = false
+
+ return WrapTypeFromType(t.schema, &cpy)
+ }
+ return WrapTypeFromType(t.schema, t.typ.Elem)
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go
new file mode 100644
index 00000000..c112444a
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go
@@ -0,0 +1,83 @@
+package graphql
+
+import (
+ "io"
+ "strconv"
+)
+
+var nullLit = []byte(`null`)
+var trueLit = []byte(`true`)
+var falseLit = []byte(`false`)
+var openBrace = []byte(`{`)
+var closeBrace = []byte(`}`)
+var openBracket = []byte(`[`)
+var closeBracket = []byte(`]`)
+var colon = []byte(`:`)
+var comma = []byte(`,`)
+
+var Null = &lit{nullLit}
+var True = &lit{trueLit}
+var False = &lit{falseLit}
+
+type Marshaler interface {
+ MarshalGQL(w io.Writer)
+}
+
+type Unmarshaler interface {
+ UnmarshalGQL(v interface{}) error
+}
+
+type OrderedMap struct {
+ Keys []string
+ Values []Marshaler
+}
+
+type WriterFunc func(writer io.Writer)
+
+func (f WriterFunc) MarshalGQL(w io.Writer) {
+ f(w)
+}
+
+func NewOrderedMap(len int) *OrderedMap {
+ return &OrderedMap{
+ Keys: make([]string, len),
+ Values: make([]Marshaler, len),
+ }
+}
+
+func (m *OrderedMap) Add(key string, value Marshaler) {
+ m.Keys = append(m.Keys, key)
+ m.Values = append(m.Values, value)
+}
+
+func (m *OrderedMap) MarshalGQL(writer io.Writer) {
+ writer.Write(openBrace)
+ for i, key := range m.Keys {
+ if i != 0 {
+ writer.Write(comma)
+ }
+ io.WriteString(writer, strconv.Quote(key))
+ writer.Write(colon)
+ m.Values[i].MarshalGQL(writer)
+ }
+ writer.Write(closeBrace)
+}
+
+type Array []Marshaler
+
+func (a Array) MarshalGQL(writer io.Writer) {
+ writer.Write(openBracket)
+ for i, val := range a {
+ if i != 0 {
+ writer.Write(comma)
+ }
+ val.MarshalGQL(writer)
+ }
+ writer.Write(closeBracket)
+}
+
+type lit struct{ b []byte }
+
+func (l lit) MarshalGQL(w io.Writer) {
+ w.Write(l.b)
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/map.go b/vendor/github.com/99designs/gqlgen/graphql/map.go
new file mode 100644
index 00000000..1e91d1d9
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/map.go
@@ -0,0 +1,24 @@
+package graphql
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+)
+
+func MarshalMap(val map[string]interface{}) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ err := json.NewEncoder(w).Encode(val)
+ if err != nil {
+ panic(err)
+ }
+ })
+}
+
+func UnmarshalMap(v interface{}) (map[string]interface{}, error) {
+ if m, ok := v.(map[string]interface{}); ok {
+ return m, nil
+ }
+
+ return nil, fmt.Errorf("%T is not a map", v)
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/oneshot.go b/vendor/github.com/99designs/gqlgen/graphql/oneshot.go
new file mode 100644
index 00000000..dd31f5ba
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/oneshot.go
@@ -0,0 +1,14 @@
+package graphql
+
+func OneShot(resp *Response) func() *Response {
+ var oneshot bool
+
+ return func() *Response {
+ if oneshot {
+ return nil
+ }
+ oneshot = true
+
+ return resp
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/recovery.go b/vendor/github.com/99designs/gqlgen/graphql/recovery.go
new file mode 100644
index 00000000..3aa032dc
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/recovery.go
@@ -0,0 +1,19 @@
+package graphql
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "runtime/debug"
+)
+
+type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error)
+
+func DefaultRecover(ctx context.Context, err interface{}) error {
+ fmt.Fprintln(os.Stderr, err)
+ fmt.Fprintln(os.Stderr)
+ debug.PrintStack()
+
+ return errors.New("internal system error")
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/response.go b/vendor/github.com/99designs/gqlgen/graphql/response.go
new file mode 100644
index 00000000..18664dca
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/response.go
@@ -0,0 +1,20 @@
+package graphql
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+
+ "github.com/vektah/gqlparser/gqlerror"
+)
+
+type Response struct {
+ Data json.RawMessage `json:"data"`
+ Errors gqlerror.List `json:"errors,omitempty"`
+}
+
+func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response {
+ return &Response{
+ Errors: gqlerror.List{{Message: fmt.Sprintf(messagef, args...)}},
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/string.go b/vendor/github.com/99designs/gqlgen/graphql/string.go
new file mode 100644
index 00000000..d5fb3294
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/string.go
@@ -0,0 +1,63 @@
+package graphql
+
+import (
+ "fmt"
+ "io"
+ "strconv"
+)
+
+const encodeHex = "0123456789ABCDEF"
+
+func MarshalString(s string) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ start := 0
+ io.WriteString(w, `"`)
+
+ for i, c := range s {
+ if c < 0x20 || c == '\\' || c == '"' {
+ io.WriteString(w, s[start:i])
+
+ switch c {
+ case '\t':
+ io.WriteString(w, `\t`)
+ case '\r':
+ io.WriteString(w, `\r`)
+ case '\n':
+ io.WriteString(w, `\n`)
+ case '\\':
+ io.WriteString(w, `\\`)
+ case '"':
+ io.WriteString(w, `\"`)
+ default:
+ io.WriteString(w, `\u00`)
+ w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
+ }
+
+ start = i + 1
+ }
+ }
+
+ io.WriteString(w, s[start:])
+ io.WriteString(w, `"`)
+ })
+}
+func UnmarshalString(v interface{}) (string, error) {
+ switch v := v.(type) {
+ case string:
+ return v, nil
+ case int:
+ return strconv.Itoa(v), nil
+ case float64:
+ return fmt.Sprintf("%f", v), nil
+ case bool:
+ if v {
+ return "true", nil
+ } else {
+ return "false", nil
+ }
+ case nil:
+ return "null", nil
+ default:
+ return "", fmt.Errorf("%T is not a string", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/time.go b/vendor/github.com/99designs/gqlgen/graphql/time.go
new file mode 100644
index 00000000..4f448560
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/time.go
@@ -0,0 +1,21 @@
+package graphql
+
+import (
+ "errors"
+ "io"
+ "strconv"
+ "time"
+)
+
+func MarshalTime(t time.Time) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, strconv.Quote(t.Format(time.RFC3339)))
+ })
+}
+
+func UnmarshalTime(v interface{}) (time.Time, error) {
+ if tmpStr, ok := v.(string); ok {
+ return time.Parse(time.RFC3339, tmpStr)
+ }
+ return time.Time{}, errors.New("time should be RFC3339 formatted string")
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go
new file mode 100644
index 00000000..38d3720b
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/version.go
@@ -0,0 +1,3 @@
+package graphql
+
+const Version = "v0.5.1"