diff options
Diffstat (limited to 'vendor/github.com/vektah/gqlgen/graphql')
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/bool.go | 30 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/context.go | 145 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/defer.go | 30 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/error.go | 46 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/exec.go | 118 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/float.go | 26 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/id.go | 33 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/int.go | 26 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/jsonw.go | 83 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/map.go | 24 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/oneshot.go | 14 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/recovery.go | 19 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/response.go | 18 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/string.go | 63 | ||||
-rw-r--r-- | vendor/github.com/vektah/gqlgen/graphql/time.go | 21 |
15 files changed, 696 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlgen/graphql/bool.go b/vendor/github.com/vektah/gqlgen/graphql/bool.go new file mode 100644 index 00000000..7053bbca --- /dev/null +++ b/vendor/github.com/vektah/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/vektah/gqlgen/graphql/context.go b/vendor/github.com/vektah/gqlgen/graphql/context.go new file mode 100644 index 00000000..8f544100 --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/context.go @@ -0,0 +1,145 @@ +package graphql + +import ( + "context" + "fmt" + "sync" + + "github.com/vektah/gqlgen/neelance/query" +) + +type Resolver func(ctx context.Context) (res interface{}, err error) +type ResolverMiddleware 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 *query.Document + // ErrorPresenter will be used to generate the error + // message from errors given to Error(). + ErrorPresenter ErrorPresenterFunc + Recover RecoverFunc + ResolverMiddleware ResolverMiddleware + RequestMiddleware RequestMiddleware + + errorsMu sync.Mutex + Errors []*Error +} + +func DefaultResolverMiddleware(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 *query.Document, query string, variables map[string]interface{}) *RequestContext { + return &RequestContext{ + Doc: doc, + RawQuery: query, + Variables: variables, + ResolverMiddleware: DefaultResolverMiddleware, + 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 { + // 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 path of fields to get to this resolver + Path []interface{} +} + +func (r *ResolverContext) PushField(alias string) { + r.Path = append(r.Path, alias) +} + +func (r *ResolverContext) PushIndex(index int) { + r.Path = append(r.Path, index) +} + +func (r *ResolverContext) Pop() { + r.Path = r.Path[0 : len(r.Path)-1] +} + +func GetResolverContext(ctx context.Context) *ResolverContext { + val := ctx.Value(resolver) + if val == nil { + return nil + } + + return val.(*ResolverContext) +} + +func WithResolverContext(ctx context.Context, rc *ResolverContext) context.Context { + parent := GetResolverContext(ctx) + rc.Path = nil + if parent != nil { + rc.Path = append(rc.Path, parent.Path...) + } + if rc.Field.Alias != "" { + rc.PushField(rc.Field.Alias) + } + return context.WithValue(ctx, resolver, rc) +} + +// This is just a convenient wrapper method for CollectFields +func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField { + reqctx := GetRequestContext(ctx) + resctx := GetResolverContext(ctx) + return CollectFields(reqctx.Doc, resctx.Field.Selections, satisfies, reqctx.Variables) +} + +// 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)) +} + +// 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/vektah/gqlgen/graphql/defer.go b/vendor/github.com/vektah/gqlgen/graphql/defer.go new file mode 100644 index 00000000..79346a84 --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/defer.go @@ -0,0 +1,30 @@ +package graphql + +import ( + "io" + "sync" +) + +// Defer will begin executing the given function and immediately return a result that will block until the function completes +func Defer(f func() Marshaler) Marshaler { + var deferred deferred + deferred.mu.Lock() + + go func() { + deferred.result = f() + deferred.mu.Unlock() + }() + + return &deferred +} + +type deferred struct { + result Marshaler + mu sync.Mutex +} + +func (d *deferred) MarshalGQL(w io.Writer) { + d.mu.Lock() + d.result.MarshalGQL(w) + d.mu.Unlock() +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/error.go b/vendor/github.com/vektah/gqlgen/graphql/error.go new file mode 100644 index 00000000..15e65fab --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/error.go @@ -0,0 +1,46 @@ +package graphql + +import ( + "context" +) + +// Error is the standard graphql error type described in https://facebook.github.io/graphql/draft/#sec-Errors +type Error struct { + Message string `json:"message"` + Path []interface{} `json:"path,omitempty"` + Locations []ErrorLocation `json:"locations,omitempty"` + Extensions map[string]interface{} `json:"extensions,omitempty"` +} + +func (e *Error) Error() string { + return e.Message +} + +type ErrorLocation struct { + Line int `json:"line,omitempty"` + Column int `json:"column,omitempty"` +} + +type ErrorPresenterFunc func(context.Context, error) *Error + +type ExtendedError interface { + Extensions() map[string]interface{} +} + +func DefaultErrorPresenter(ctx context.Context, err error) *Error { + if gqlerr, ok := err.(*Error); ok { + gqlerr.Path = GetResolverContext(ctx).Path + return gqlerr + } + + var extensions map[string]interface{} + if ee, ok := err.(ExtendedError); ok { + extensions = ee.Extensions() + } + + return &Error{ + Message: err.Error(), + Path: GetResolverContext(ctx).Path, + Extensions: extensions, + } +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/exec.go b/vendor/github.com/vektah/gqlgen/graphql/exec.go new file mode 100644 index 00000000..2c034888 --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/exec.go @@ -0,0 +1,118 @@ +package graphql + +import ( + "context" + "fmt" + + "github.com/vektah/gqlgen/neelance/common" + "github.com/vektah/gqlgen/neelance/query" + "github.com/vektah/gqlgen/neelance/schema" +) + +type ExecutableSchema interface { + Schema() *schema.Schema + + Query(ctx context.Context, op *query.Operation) *Response + Mutation(ctx context.Context, op *query.Operation) *Response + Subscription(ctx context.Context, op *query.Operation) func() *Response +} + +func CollectFields(doc *query.Document, selSet []query.Selection, satisfies []string, variables map[string]interface{}) []CollectedField { + return collectFields(doc, selSet, satisfies, variables, map[string]bool{}) +} + +func collectFields(doc *query.Document, selSet []query.Selection, satisfies []string, variables map[string]interface{}, visited map[string]bool) []CollectedField { + var groupedFields []CollectedField + + for _, sel := range selSet { + switch sel := sel.(type) { + case *query.Field: + f := getOrCreateField(&groupedFields, sel.Alias.Name, func() CollectedField { + f := CollectedField{ + Alias: sel.Alias.Name, + Name: sel.Name.Name, + } + if len(sel.Arguments) > 0 { + f.Args = map[string]interface{}{} + for _, arg := range sel.Arguments { + if variable, ok := arg.Value.(*common.Variable); ok { + if val, ok := variables[variable.Name]; ok { + f.Args[arg.Name.Name] = val + } + } else { + f.Args[arg.Name.Name] = arg.Value.Value(variables) + } + } + } + return f + }) + + f.Selections = append(f.Selections, sel.Selections...) + case *query.InlineFragment: + if !instanceOf(sel.On.Ident.Name, satisfies) { + continue + } + + for _, childField := range collectFields(doc, sel.Selections, satisfies, variables, visited) { + f := getOrCreateField(&groupedFields, childField.Name, func() CollectedField { return childField }) + f.Selections = append(f.Selections, childField.Selections...) + } + + case *query.FragmentSpread: + fragmentName := sel.Name.Name + if _, seen := visited[fragmentName]; seen { + continue + } + visited[fragmentName] = true + + fragment := doc.Fragments.Get(fragmentName) + if fragment == nil { + // should never happen, validator has already run + panic(fmt.Errorf("missing fragment %s", fragmentName)) + } + + if !instanceOf(fragment.On.Ident.Name, satisfies) { + continue + } + + for _, childField := range collectFields(doc, fragment.Selections, satisfies, variables, 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 { + Alias string + Name string + Args map[string]interface{} + Selections []query.Selection +} + +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] +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/float.go b/vendor/github.com/vektah/gqlgen/graphql/float.go new file mode 100644 index 00000000..c08b490a --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/float.go @@ -0,0 +1,26 @@ +package graphql + +import ( + "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 float64: + return v, nil + default: + return 0, fmt.Errorf("%T is not an float", v) + } +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/id.go b/vendor/github.com/vektah/gqlgen/graphql/id.go new file mode 100644 index 00000000..7958670c --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/id.go @@ -0,0 +1,33 @@ +package graphql + +import ( + "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 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/vektah/gqlgen/graphql/int.go b/vendor/github.com/vektah/gqlgen/graphql/int.go new file mode 100644 index 00000000..b63b4c2a --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/int.go @@ -0,0 +1,26 @@ +package graphql + +import ( + "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 float64: + return int(v), nil + default: + return 0, fmt.Errorf("%T is not an int", v) + } +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/jsonw.go b/vendor/github.com/vektah/gqlgen/graphql/jsonw.go new file mode 100644 index 00000000..ef9e69c7 --- /dev/null +++ b/vendor/github.com/vektah/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) +} + +func lit(b []byte) Marshaler { + return WriterFunc(func(w io.Writer) { + w.Write(b) + }) +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/map.go b/vendor/github.com/vektah/gqlgen/graphql/map.go new file mode 100644 index 00000000..1e91d1d9 --- /dev/null +++ b/vendor/github.com/vektah/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/vektah/gqlgen/graphql/oneshot.go b/vendor/github.com/vektah/gqlgen/graphql/oneshot.go new file mode 100644 index 00000000..dd31f5ba --- /dev/null +++ b/vendor/github.com/vektah/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/vektah/gqlgen/graphql/recovery.go b/vendor/github.com/vektah/gqlgen/graphql/recovery.go new file mode 100644 index 00000000..3aa032dc --- /dev/null +++ b/vendor/github.com/vektah/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/vektah/gqlgen/graphql/response.go b/vendor/github.com/vektah/gqlgen/graphql/response.go new file mode 100644 index 00000000..c0dc1c23 --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/graphql/response.go @@ -0,0 +1,18 @@ +package graphql + +import ( + "context" + "encoding/json" + "fmt" +) + +type Response struct { + Data json.RawMessage `json:"data"` + Errors []*Error `json:"errors,omitempty"` +} + +func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response { + return &Response{ + Errors: []*Error{{Message: fmt.Sprintf(messagef, args...)}}, + } +} diff --git a/vendor/github.com/vektah/gqlgen/graphql/string.go b/vendor/github.com/vektah/gqlgen/graphql/string.go new file mode 100644 index 00000000..d5fb3294 --- /dev/null +++ b/vendor/github.com/vektah/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/vektah/gqlgen/graphql/time.go b/vendor/github.com/vektah/gqlgen/graphql/time.go new file mode 100644 index 00000000..4f448560 --- /dev/null +++ b/vendor/github.com/vektah/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") +} |