mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Update go dependencies (#3480)
* Bump golang.org/x/text from 0.3.7 to 0.3.8 Bumps [golang.org/x/text](https://github.com/golang/text) from 0.3.7 to 0.3.8. - [Release notes](https://github.com/golang/text/releases) - [Commits](https://github.com/golang/text/compare/v0.3.7...v0.3.8) --- updated-dependencies: - dependency-name: golang.org/x/text dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> * Update go dependencies * Update x/net --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
19
vendor/github.com/99designs/gqlgen/graphql/context_field.go
generated
vendored
19
vendor/github.com/99designs/gqlgen/graphql/context_field.go
generated
vendored
@@ -30,6 +30,25 @@ type FieldContext struct {
|
||||
IsMethod bool
|
||||
// IsResolver indicates if the field has a user-specified resolver
|
||||
IsResolver bool
|
||||
// Child allows getting a child FieldContext by its field collection description.
|
||||
// Note that, the returned child FieldContext represents the context as it was
|
||||
// before the execution of the field resolver. For example:
|
||||
//
|
||||
// srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (interface{}, error) {
|
||||
// fc := graphql.GetFieldContext(ctx)
|
||||
// op := graphql.GetOperationContext(ctx)
|
||||
// collected := graphql.CollectFields(opCtx, fc.Field.Selections, []string{"User"})
|
||||
//
|
||||
// child, err := fc.Child(ctx, collected[0])
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// fmt.Println("child context %q with args: %v", child.Field.Name, child.Args)
|
||||
//
|
||||
// return next(ctx)
|
||||
// })
|
||||
//
|
||||
Child func(context.Context, CollectedField) (*FieldContext, error)
|
||||
}
|
||||
|
||||
type FieldStats struct {
|
||||
|
||||
14
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
14
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
@@ -3,8 +3,10 @@ package graphql
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
// Deprecated: Please update all references to OperationContext instead
|
||||
@@ -15,6 +17,7 @@ type OperationContext struct {
|
||||
Variables map[string]interface{}
|
||||
OperationName string
|
||||
Doc *ast.QueryDocument
|
||||
Headers http.Header
|
||||
|
||||
Operation *ast.OperationDefinition
|
||||
DisableIntrospection bool
|
||||
@@ -104,9 +107,16 @@ func (c *OperationContext) Errorf(ctx context.Context, format string, args ...in
|
||||
AddErrorf(ctx, format, args...)
|
||||
}
|
||||
|
||||
// Error sends an error to the client, passing it through the formatter.
|
||||
// Deprecated: use graphql.AddError(ctx, err) instead
|
||||
// Error add error or multiple errors (if underlaying type is gqlerror.List) into the stack.
|
||||
// Then it will be sends to the client, passing it through the formatter.
|
||||
func (c *OperationContext) Error(ctx context.Context, err error) {
|
||||
if errList, ok := err.(gqlerror.List); ok {
|
||||
for _, e := range errList {
|
||||
AddError(ctx, e)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
AddError(ctx, err)
|
||||
}
|
||||
|
||||
|
||||
19
vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go
generated
vendored
19
vendor/github.com/99designs/gqlgen/graphql/errcode/codes.go
generated
vendored
@@ -23,18 +23,27 @@ var codeType = map[string]ErrorKind{
|
||||
ParseFailed: KindProtocol,
|
||||
}
|
||||
|
||||
// RegisterErrorType should be called by extensions that want to customize the http status codes for errors they return
|
||||
// RegisterErrorType should be called by extensions that want to customize the http status codes for
|
||||
// errors they return
|
||||
func RegisterErrorType(code string, kind ErrorKind) {
|
||||
codeType[code] = kind
|
||||
}
|
||||
|
||||
// Set the error code on a given graphql error extension
|
||||
func Set(err *gqlerror.Error, value string) {
|
||||
if err.Extensions == nil {
|
||||
err.Extensions = map[string]interface{}{}
|
||||
func Set(err error, value string) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
err.Extensions["code"] = value
|
||||
if gqlErr.Extensions == nil {
|
||||
gqlErr.Extensions = map[string]interface{}{}
|
||||
}
|
||||
|
||||
gqlErr.Extensions["code"] = value
|
||||
}
|
||||
|
||||
// get the kind of the first non User error, defaults to User if no errors have a custom extension
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/error.go
generated
vendored
@@ -26,7 +26,8 @@ func ErrorOnPath(ctx context.Context, err error) error {
|
||||
if gqlErr.Path == nil {
|
||||
gqlErr.Path = GetPath(ctx)
|
||||
}
|
||||
return gqlErr
|
||||
// Return the original error to avoid losing any attached annotation
|
||||
return err
|
||||
}
|
||||
return gqlerror.WrapPath(GetPath(ctx), err)
|
||||
}
|
||||
|
||||
5
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
5
vendor/github.com/99designs/gqlgen/graphql/executable_schema.go
generated
vendored
@@ -118,6 +118,11 @@ func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, o
|
||||
return &(*c)[i]
|
||||
}
|
||||
}
|
||||
for _, ifc := range cf.ObjectDefinition.Interfaces {
|
||||
if ifc == objectDefinition.Name {
|
||||
return &(*c)[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
57
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
57
vendor/github.com/99designs/gqlgen/graphql/executor/executor.go
generated
vendored
@@ -37,7 +37,10 @@ func New(es graphql.ExecutableSchema) *Executor {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) {
|
||||
func (e *Executor) CreateOperationContext(
|
||||
ctx context.Context,
|
||||
params *graphql.RawParams,
|
||||
) (*graphql.OperationContext, gqlerror.List) {
|
||||
rc := &graphql.OperationContext{
|
||||
DisableIntrospection: true,
|
||||
RecoverFunc: e.recoverFunc,
|
||||
@@ -58,6 +61,7 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
|
||||
rc.RawQuery = params.Query
|
||||
rc.OperationName = params.OperationName
|
||||
rc.Headers = params.Headers
|
||||
|
||||
var listErr gqlerror.List
|
||||
rc.Doc, listErr = e.parseQuery(ctx, &rc.Stats, params.Query)
|
||||
@@ -67,15 +71,21 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
|
||||
rc.Operation = rc.Doc.Operations.ForName(params.OperationName)
|
||||
if rc.Operation == nil {
|
||||
return rc, gqlerror.List{gqlerror.Errorf("operation %s not found", params.OperationName)}
|
||||
}
|
||||
|
||||
var err *gqlerror.Error
|
||||
rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables)
|
||||
if err != nil {
|
||||
err := gqlerror.Errorf("operation %s not found", params.OperationName)
|
||||
errcode.Set(err, errcode.ValidationFailed)
|
||||
return rc, gqlerror.List{err}
|
||||
}
|
||||
|
||||
var err error
|
||||
rc.Variables, err = validator.VariableValues(e.es.Schema(), rc.Operation, params.Variables)
|
||||
|
||||
if err != nil {
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if ok {
|
||||
errcode.Set(gqlErr, errcode.ValidationFailed)
|
||||
return rc, gqlerror.List{gqlErr}
|
||||
}
|
||||
}
|
||||
rc.Stats.Validation.End = graphql.Now()
|
||||
|
||||
for _, p := range e.ext.operationContextMutators {
|
||||
@@ -87,7 +97,10 @@ func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.R
|
||||
return rc, nil
|
||||
}
|
||||
|
||||
func (e *Executor) DispatchOperation(ctx context.Context, rc *graphql.OperationContext) (graphql.ResponseHandler, context.Context) {
|
||||
func (e *Executor) DispatchOperation(
|
||||
ctx context.Context,
|
||||
rc *graphql.OperationContext,
|
||||
) (graphql.ResponseHandler, context.Context) {
|
||||
ctx = graphql.WithOperationContext(ctx, rc)
|
||||
|
||||
var innerCtx context.Context
|
||||
@@ -130,7 +143,7 @@ func (e *Executor) DispatchError(ctx context.Context, list gqlerror.List) *graph
|
||||
|
||||
resp := e.ext.responseMiddleware(ctx, func(ctx context.Context) *graphql.Response {
|
||||
resp := &graphql.Response{
|
||||
Errors: list,
|
||||
Errors: graphql.GetErrors(ctx),
|
||||
}
|
||||
resp.Extensions = graphql.GetExtensions(ctx)
|
||||
return resp
|
||||
@@ -139,7 +152,7 @@ func (e *Executor) DispatchError(ctx context.Context, list gqlerror.List) *graph
|
||||
return resp
|
||||
}
|
||||
|
||||
func (e *Executor) PresentRecoveredError(ctx context.Context, err interface{}) *gqlerror.Error {
|
||||
func (e *Executor) PresentRecoveredError(ctx context.Context, err interface{}) error {
|
||||
return e.errorPresenter(ctx, e.recoverFunc(ctx, err))
|
||||
}
|
||||
|
||||
@@ -157,9 +170,14 @@ func (e *Executor) SetRecoverFunc(f graphql.RecoverFunc) {
|
||||
|
||||
// parseQuery decodes the incoming query and validates it, pulling from cache if present.
|
||||
//
|
||||
// NOTE: This should NOT look at variables, they will change per request. It should only parse and validate
|
||||
// NOTE: This should NOT look at variables, they will change per request. It should only parse and
|
||||
// validate
|
||||
// the raw query string.
|
||||
func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query string) (*ast.QueryDocument, gqlerror.List) {
|
||||
func (e *Executor) parseQuery(
|
||||
ctx context.Context,
|
||||
stats *graphql.Stats,
|
||||
query string,
|
||||
) (*ast.QueryDocument, gqlerror.List) {
|
||||
stats.Parsing.Start = graphql.Now()
|
||||
|
||||
if doc, ok := e.queryCache.Get(ctx, query); ok {
|
||||
@@ -172,12 +190,23 @@ func (e *Executor) parseQuery(ctx context.Context, stats *graphql.Stats, query s
|
||||
|
||||
doc, err := parser.ParseQuery(&ast.Source{Input: query})
|
||||
if err != nil {
|
||||
errcode.Set(err, errcode.ParseFailed)
|
||||
return nil, gqlerror.List{err}
|
||||
gqlErr, ok := err.(*gqlerror.Error)
|
||||
if ok {
|
||||
errcode.Set(gqlErr, errcode.ParseFailed)
|
||||
return nil, gqlerror.List{gqlErr}
|
||||
}
|
||||
}
|
||||
stats.Parsing.End = graphql.Now()
|
||||
|
||||
stats.Validation.Start = graphql.Now()
|
||||
|
||||
if len(doc.Operations) == 0 {
|
||||
err = gqlerror.Errorf("no operation provided")
|
||||
gqlErr, _ := err.(*gqlerror.Error)
|
||||
errcode.Set(err, errcode.ValidationFailed)
|
||||
return nil, gqlerror.List{gqlErr}
|
||||
}
|
||||
|
||||
listErr := validator.Validate(e.es.Schema(), doc)
|
||||
if len(listErr) != 0 {
|
||||
for _, e := range listErr {
|
||||
|
||||
17
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
17
vendor/github.com/99designs/gqlgen/graphql/handler.go
generated
vendored
@@ -27,6 +27,7 @@ type (
|
||||
OperationName string `json:"operationName"`
|
||||
Variables map[string]interface{} `json:"variables"`
|
||||
Extensions map[string]interface{} `json:"extensions"`
|
||||
Headers http.Header `json:"headers"`
|
||||
|
||||
ReadTime TraceTiming `json:"-"`
|
||||
}
|
||||
@@ -41,14 +42,14 @@ type (
|
||||
// Its important to understand the lifecycle of a graphql request and the terminology we use in gqlgen
|
||||
// before working with these
|
||||
//
|
||||
// +--- REQUEST POST /graphql --------------------------------------------+
|
||||
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
||||
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
||||
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
||||
// | +--------------------------------------------------------------------+ |
|
||||
// +------------------------------------------------------------------------+
|
||||
// +--- REQUEST POST /graphql --------------------------------------------+
|
||||
// | +- OPERATION query OpName { viewer { name } } -----------------------+ |
|
||||
// | | RESPONSE { "data": { "viewer": { "name": "bob" } } } | |
|
||||
// | +- OPERATION subscription OpName2 { chat { message } } --------------+ |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "hello" } } } | |
|
||||
// | | RESPONSE { "data": { "chat": { "message": "byee" } } } | |
|
||||
// | +--------------------------------------------------------------------+ |
|
||||
// +------------------------------------------------------------------------+
|
||||
HandlerExtension interface {
|
||||
// ExtensionName should be a CamelCase string version of the extension which may be shown in stats and logging.
|
||||
ExtensionName() string
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/graphql/handler/server.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/handler/server.go
generated
vendored
@@ -102,7 +102,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
err := s.exec.PresentRecoveredError(r.Context(), err)
|
||||
resp := &graphql.Response{Errors: []*gqlerror.Error{err}}
|
||||
gqlErr, _ := err.(*gqlerror.Error)
|
||||
resp := &graphql.Response{Errors: []*gqlerror.Error{gqlErr}}
|
||||
b, _ := json.Marshal(resp)
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
w.Write(b)
|
||||
|
||||
196
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go
generated
vendored
196
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_form.go
generated
vendored
@@ -3,11 +3,9 @@ package transport
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
@@ -64,133 +62,145 @@ func (f MultipartForm) Do(w http.ResponseWriter, r *http.Request, exec graphql.G
|
||||
return
|
||||
}
|
||||
r.Body = http.MaxBytesReader(w, r.Body, f.maxUploadSize())
|
||||
if err = r.ParseMultipartForm(f.maxMemory()); err != nil {
|
||||
defer r.Body.Close()
|
||||
|
||||
mr, err := r.MultipartReader()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if strings.Contains(err.Error(), "request body too large") {
|
||||
writeJsonError(w, "failed to parse multipart form, request body too large")
|
||||
return
|
||||
}
|
||||
writeJsonError(w, "failed to parse multipart form")
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
part, err := mr.NextPart()
|
||||
if err != nil || part.FormName() != "operations" {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "first part must be operations")
|
||||
return
|
||||
}
|
||||
|
||||
var params graphql.RawParams
|
||||
|
||||
if err = jsonDecode(strings.NewReader(r.Form.Get("operations")), ¶ms); err != nil {
|
||||
if err = jsonDecode(part, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "operations form field could not be decoded")
|
||||
return
|
||||
}
|
||||
|
||||
part, err = mr.NextPart()
|
||||
if err != nil || part.FormName() != "map" {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "second part must be map")
|
||||
return
|
||||
}
|
||||
|
||||
uploadsMap := map[string][]string{}
|
||||
if err = json.Unmarshal([]byte(r.Form.Get("map")), &uploadsMap); err != nil {
|
||||
if err = json.NewDecoder(part).Decode(&uploadsMap); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonError(w, "map form field could not be decoded")
|
||||
return
|
||||
}
|
||||
|
||||
var upload graphql.Upload
|
||||
for key, paths := range uploadsMap {
|
||||
for {
|
||||
part, err = mr.NextPart()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to parse part")
|
||||
return
|
||||
}
|
||||
|
||||
key := part.FormName()
|
||||
filename := part.FileName()
|
||||
contentType := part.Header.Get("Content-Type")
|
||||
|
||||
paths := uploadsMap[key]
|
||||
if len(paths) == 0 {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "invalid empty operations paths list for key %s", key)
|
||||
return
|
||||
}
|
||||
file, header, err := r.FormFile(key)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to get key %s from form", key)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
delete(uploadsMap, key)
|
||||
|
||||
if len(paths) == 1 {
|
||||
upload = graphql.Upload{
|
||||
File: file,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, paths[0]); err != nil {
|
||||
var upload graphql.Upload
|
||||
if r.ContentLength < f.maxMemory() {
|
||||
fileBytes, err := io.ReadAll(part)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
writeJsonErrorf(w, "failed to read file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
upload = graphql.Upload{
|
||||
File: &bytesReader{s: &fileBytes, i: 0},
|
||||
Size: int64(len(fileBytes)),
|
||||
Filename: filename,
|
||||
ContentType: contentType,
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if r.ContentLength < f.maxMemory() {
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to read file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
upload = graphql.Upload{
|
||||
File: &bytesReader{s: &fileBytes, i: 0, prevRune: -1},
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "gqlgen-")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to create temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpName := tmpFile.Name()
|
||||
defer func() {
|
||||
_ = os.Remove(tmpName)
|
||||
}()
|
||||
_, err = io.Copy(tmpFile, file)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
writeJsonErrorf(w, "failed to copy to temp file and close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
writeJsonErrorf(w, "failed to copy to temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpFile, err := os.CreateTemp(os.TempDir(), "gqlgen-")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to create temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
tmpName := tmpFile.Name()
|
||||
defer func() {
|
||||
_ = os.Remove(tmpName)
|
||||
}()
|
||||
fileSize, err := io.Copy(tmpFile, part)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to close temp file for key %s", key)
|
||||
writeJsonErrorf(w, "failed to copy to temp file and close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
pathTmpFile, err := os.Open(tmpName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to open temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
defer pathTmpFile.Close()
|
||||
upload = graphql.Upload{
|
||||
File: pathTmpFile,
|
||||
Size: header.Size,
|
||||
Filename: header.Filename,
|
||||
ContentType: header.Header.Get("Content-Type"),
|
||||
}
|
||||
writeJsonErrorf(w, "failed to copy to temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
if err := tmpFile.Close(); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to close temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
for _, path := range paths {
|
||||
pathTmpFile, err := os.Open(tmpName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to open temp file for key %s", key)
|
||||
return
|
||||
}
|
||||
defer pathTmpFile.Close()
|
||||
upload = graphql.Upload{
|
||||
File: pathTmpFile,
|
||||
Size: fileSize,
|
||||
Filename: filename,
|
||||
ContentType: contentType,
|
||||
}
|
||||
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
if err := params.AddUpload(upload, key, path); err != nil {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonGraphqlError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key := range uploadsMap {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
writeJsonErrorf(w, "failed to get key %s from form", key)
|
||||
return
|
||||
}
|
||||
|
||||
params.Headers = r.Header
|
||||
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
|
||||
24
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
24
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_get.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
@@ -27,15 +28,22 @@ func (h GET) Supports(r *http.Request) bool {
|
||||
}
|
||||
|
||||
func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
query, err := url.ParseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
writeJsonError(w, err.Error())
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
raw := &graphql.RawParams{
|
||||
Query: r.URL.Query().Get("query"),
|
||||
OperationName: r.URL.Query().Get("operationName"),
|
||||
Query: query.Get("query"),
|
||||
OperationName: query.Get("operationName"),
|
||||
Headers: r.Header,
|
||||
}
|
||||
raw.ReadTime.Start = graphql.Now()
|
||||
|
||||
if variables := r.URL.Query().Get("variables"); variables != "" {
|
||||
if variables := query.Get("variables"); variables != "" {
|
||||
if err := jsonDecode(strings.NewReader(variables), &raw.Variables); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
writeJsonError(w, "variables could not be decoded")
|
||||
@@ -43,7 +51,7 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut
|
||||
}
|
||||
}
|
||||
|
||||
if extensions := r.URL.Query().Get("extensions"); extensions != "" {
|
||||
if extensions := query.Get("extensions"); extensions != "" {
|
||||
if err := jsonDecode(strings.NewReader(extensions), &raw.Extensions); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
writeJsonError(w, "extensions could not be decoded")
|
||||
@@ -53,10 +61,10 @@ func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecut
|
||||
|
||||
raw.ReadTime.End = graphql.Now()
|
||||
|
||||
rc, err := exec.CreateOperationContext(r.Context(), raw)
|
||||
if err != nil {
|
||||
w.WriteHeader(statusFor(err))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err)
|
||||
rc, gqlError := exec.CreateOperationContext(r.Context(), raw)
|
||||
if gqlError != nil {
|
||||
w.WriteHeader(statusFor(gqlError))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), gqlError)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
63
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
63
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
@@ -1,8 +1,14 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
@@ -26,28 +32,59 @@ func (h POST) Supports(r *http.Request) bool {
|
||||
return r.Method == "POST" && mediaType == "application/json"
|
||||
}
|
||||
|
||||
func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
var params *graphql.RawParams
|
||||
start := graphql.Now()
|
||||
if err := jsonDecode(r.Body, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
writeJsonErrorf(w, "json body could not be decoded: "+err.Error())
|
||||
return
|
||||
func getRequestBody(r *http.Request) (string, error) {
|
||||
if r == nil || r.Body == nil {
|
||||
return "", nil
|
||||
}
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to get Request Body %w", err)
|
||||
}
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
rc, err := exec.CreateOperationContext(r.Context(), params)
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(statusFor(err))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err)
|
||||
gqlErr := gqlerror.Errorf("could not get json request body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("could not get json request body: %+v", err.Error())
|
||||
writeJson(w, resp)
|
||||
}
|
||||
|
||||
bodyReader := io.NopCloser(strings.NewReader(bodyString))
|
||||
if err = jsonDecode(bodyReader, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
gqlErr := gqlerror.Errorf(
|
||||
"json request body could not be decoded: %+v body:%s",
|
||||
err,
|
||||
bodyString,
|
||||
)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("decoding error: %+v body:%s", err.Error(), bodyString)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
responses, ctx := exec.DispatchOperation(r.Context(), rc)
|
||||
|
||||
rc, OpErr := exec.CreateOperationContext(ctx, params)
|
||||
if OpErr != nil {
|
||||
w.WriteHeader(statusFor(OpErr))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
var responses graphql.ResponseHandler
|
||||
responses, ctx = exec.DispatchOperation(ctx, rc)
|
||||
writeJson(w, responses(ctx))
|
||||
}
|
||||
|
||||
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go
generated
vendored
15
vendor/github.com/99designs/gqlgen/graphql/handler/transport/options.go
generated
vendored
@@ -2,12 +2,16 @@ package transport
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
// Options responds to http OPTIONS and HEAD requests
|
||||
type Options struct{}
|
||||
type Options struct {
|
||||
// AllowedMethods is a list of allowed HTTP methods.
|
||||
AllowedMethods []string
|
||||
}
|
||||
|
||||
var _ graphql.Transport = Options{}
|
||||
|
||||
@@ -18,9 +22,16 @@ func (o Options) Supports(r *http.Request) bool {
|
||||
func (o Options) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
switch r.Method {
|
||||
case http.MethodOptions:
|
||||
w.Header().Set("Allow", "OPTIONS, GET, POST")
|
||||
w.Header().Set("Allow", o.allowedMethods())
|
||||
w.WriteHeader(http.StatusOK)
|
||||
case http.MethodHead:
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func (o Options) allowedMethods() string {
|
||||
if len(o.AllowedMethods) == 0 {
|
||||
return "OPTIONS, GET, POST"
|
||||
}
|
||||
return strings.Join(o.AllowedMethods, ", ")
|
||||
}
|
||||
|
||||
28
vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go
generated
vendored
28
vendor/github.com/99designs/gqlgen/graphql/handler/transport/reader.go
generated
vendored
@@ -6,9 +6,8 @@ import (
|
||||
)
|
||||
|
||||
type bytesReader struct {
|
||||
s *[]byte
|
||||
i int64 // current reading index
|
||||
prevRune int // index of previous rune; or < 0
|
||||
s *[]byte
|
||||
i int64 // current reading index
|
||||
}
|
||||
|
||||
func (r *bytesReader) Read(b []byte) (n int, err error) {
|
||||
@@ -18,8 +17,29 @@ func (r *bytesReader) Read(b []byte) (n int, err error) {
|
||||
if r.i >= int64(len(*r.s)) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
r.prevRune = -1
|
||||
n = copy(b, (*r.s)[r.i:])
|
||||
r.i += int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (r *bytesReader) Seek(offset int64, whence int) (int64, error) {
|
||||
if r.s == nil {
|
||||
return 0, errors.New("byte slice pointer is nil")
|
||||
}
|
||||
var abs int64
|
||||
switch whence {
|
||||
case io.SeekStart:
|
||||
abs = offset
|
||||
case io.SeekCurrent:
|
||||
abs = r.i + offset
|
||||
case io.SeekEnd:
|
||||
abs = int64(len(*r.s)) + offset
|
||||
default:
|
||||
return 0, errors.New("invalid whence")
|
||||
}
|
||||
if abs < 0 {
|
||||
return 0, errors.New("negative position")
|
||||
}
|
||||
r.i = abs
|
||||
return abs, nil
|
||||
}
|
||||
|
||||
110
vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go
generated
vendored
Normal file
110
vendor/github.com/99designs/gqlgen/graphql/handler/transport/sse.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"mime"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
|
||||
"github.com/99designs/gqlgen/graphql"
|
||||
)
|
||||
|
||||
type SSE struct{}
|
||||
|
||||
var _ graphql.Transport = SSE{}
|
||||
|
||||
func (t SSE) Supports(r *http.Request) bool {
|
||||
if !strings.Contains(r.Header.Get("Accept"), "text/event-stream") {
|
||||
return false
|
||||
}
|
||||
mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return r.Method == http.MethodPost && mediaType == "application/json"
|
||||
}
|
||||
|
||||
func (t SSE) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
|
||||
ctx := r.Context()
|
||||
flusher, ok := w.(http.Flusher)
|
||||
if !ok {
|
||||
SendErrorf(w, http.StatusInternalServerError, "streaming unsupported")
|
||||
return
|
||||
}
|
||||
defer flusher.Flush()
|
||||
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
params := &graphql.RawParams{}
|
||||
start := graphql.Now()
|
||||
params.Headers = r.Header
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
}
|
||||
|
||||
bodyString, err := getRequestBody(r)
|
||||
if err != nil {
|
||||
gqlErr := gqlerror.Errorf("could not get json request body: %+v", err)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("could not get json request body: %+v", err.Error())
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
bodyReader := io.NopCloser(strings.NewReader(bodyString))
|
||||
if err = jsonDecode(bodyReader, ¶ms); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
gqlErr := gqlerror.Errorf(
|
||||
"json request body could not be decoded: %+v body:%s",
|
||||
err,
|
||||
bodyString,
|
||||
)
|
||||
resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
|
||||
log.Printf("decoding error: %+v body:%s", err.Error(), bodyString)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
rc, OpErr := exec.CreateOperationContext(ctx, params)
|
||||
if OpErr != nil {
|
||||
w.WriteHeader(statusFor(OpErr))
|
||||
resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
|
||||
writeJson(w, resp)
|
||||
return
|
||||
}
|
||||
|
||||
ctx = graphql.WithOperationContext(ctx, rc)
|
||||
|
||||
w.Header().Set("Content-Type", "text/event-stream")
|
||||
fmt.Fprint(w, ":\n\n")
|
||||
flusher.Flush()
|
||||
|
||||
responses, ctx := exec.DispatchOperation(ctx, rc)
|
||||
|
||||
for {
|
||||
response := responses(ctx)
|
||||
if response == nil {
|
||||
break
|
||||
}
|
||||
writeJsonWithSSE(w, response)
|
||||
flusher.Flush()
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "event: complete\n\n")
|
||||
}
|
||||
|
||||
func writeJsonWithSSE(w io.Writer, response *graphql.Response) {
|
||||
b, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintf(w, "event: next\ndata: %s\n\n", b)
|
||||
}
|
||||
43
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
43
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
@@ -49,7 +49,24 @@ type (
|
||||
|
||||
var errReadTimeout = errors.New("read timeout")
|
||||
|
||||
var _ graphql.Transport = Websocket{}
|
||||
type WebsocketError struct {
|
||||
Err error
|
||||
|
||||
// IsReadError flags whether the error occurred on read or write to the websocket
|
||||
IsReadError bool
|
||||
}
|
||||
|
||||
func (e WebsocketError) Error() string {
|
||||
if e.IsReadError {
|
||||
return fmt.Sprintf("websocket read: %v", e.Err)
|
||||
}
|
||||
return fmt.Sprintf("websocket write: %v", e.Err)
|
||||
}
|
||||
|
||||
var (
|
||||
_ graphql.Transport = Websocket{}
|
||||
_ error = WebsocketError{}
|
||||
)
|
||||
|
||||
func (t Websocket) Supports(r *http.Request) bool {
|
||||
return r.Header.Get("Upgrade") != ""
|
||||
@@ -94,9 +111,12 @@ func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.Graph
|
||||
conn.run()
|
||||
}
|
||||
|
||||
func (c *wsConnection) handlePossibleError(err error) {
|
||||
func (c *wsConnection) handlePossibleError(err error, isReadError bool) {
|
||||
if c.ErrorFunc != nil && err != nil {
|
||||
c.ErrorFunc(c.ctx, err)
|
||||
c.ErrorFunc(c.ctx, WebsocketError{
|
||||
Err: err,
|
||||
IsReadError: isReadError,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +201,7 @@ func (c *wsConnection) init() bool {
|
||||
|
||||
func (c *wsConnection) write(msg *message) {
|
||||
c.mu.Lock()
|
||||
c.handlePossibleError(c.me.Send(msg))
|
||||
c.handlePossibleError(c.me.Send(msg), false)
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
@@ -227,7 +247,7 @@ func (c *wsConnection) run() {
|
||||
if err != nil {
|
||||
// If the connection got closed by us, don't report the error
|
||||
if !errors.Is(err, net.ErrClosed) {
|
||||
c.handlePossibleError(err)
|
||||
c.handlePossibleError(err, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -330,6 +350,7 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
c.mu.Unlock()
|
||||
|
||||
go func() {
|
||||
ctx = withSubscriptionErrorContext(ctx)
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err := rc.Recover(ctx, r)
|
||||
@@ -342,7 +363,11 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
}
|
||||
c.sendError(msg.id, gqlerr)
|
||||
}
|
||||
c.complete(msg.id)
|
||||
if errs := getSubscriptionError(ctx); len(errs) != 0 {
|
||||
c.sendError(msg.id, errs...)
|
||||
} else {
|
||||
c.complete(msg.id)
|
||||
}
|
||||
c.mu.Lock()
|
||||
delete(c.active, msg.id)
|
||||
c.mu.Unlock()
|
||||
@@ -358,12 +383,8 @@ func (c *wsConnection) subscribe(start time.Time, msg *message) {
|
||||
|
||||
c.sendResponse(msg.id, response)
|
||||
}
|
||||
c.complete(msg.id)
|
||||
|
||||
c.mu.Lock()
|
||||
delete(c.active, msg.id)
|
||||
c.mu.Unlock()
|
||||
cancel()
|
||||
// complete and context cancel comes from the defer
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md
|
||||
// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md
|
||||
const (
|
||||
graphqltransportwsSubprotocol = "graphql-transport-ws"
|
||||
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_graphqlws.go
generated
vendored
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md
|
||||
// https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md
|
||||
const (
|
||||
graphqlwsSubprotocol = "graphql-ws"
|
||||
|
||||
|
||||
69
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go
generated
vendored
Normal file
69
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket_resolver_error.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||
)
|
||||
|
||||
// A private key for context that only this package can access. This is important
|
||||
// to prevent collisions between different context uses
|
||||
var wsSubscriptionErrorCtxKey = &wsSubscriptionErrorContextKey{"subscription-error"}
|
||||
|
||||
type wsSubscriptionErrorContextKey struct {
|
||||
name string
|
||||
}
|
||||
|
||||
type subscriptionError struct {
|
||||
errs []*gqlerror.Error
|
||||
}
|
||||
|
||||
// AddSubscriptionError is used to let websocket return an error message after subscription resolver returns a channel.
|
||||
// for example:
|
||||
//
|
||||
// func (r *subscriptionResolver) Method(ctx context.Context) (<-chan *model.Message, error) {
|
||||
// ch := make(chan *model.Message)
|
||||
// go func() {
|
||||
// defer func() {
|
||||
// close(ch)
|
||||
// }
|
||||
// // some kind of block processing (e.g.: gRPC client streaming)
|
||||
// stream, err := gRPCClientStreamRequest(ctx)
|
||||
// if err != nil {
|
||||
// transport.AddSubscriptionError(ctx, err)
|
||||
// return // must return and close channel so websocket can send error back
|
||||
// }
|
||||
// for {
|
||||
// m, err := stream.Recv()
|
||||
// if err == io.EOF {
|
||||
// return
|
||||
// }
|
||||
// if err != nil {
|
||||
// transport.AddSubscriptionError(ctx, err)
|
||||
// return // must return and close channel so websocket can send error back
|
||||
// }
|
||||
// ch <- m
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// return ch, nil
|
||||
// }
|
||||
//
|
||||
// see https://github.com/99designs/gqlgen/pull/2506 for more details
|
||||
func AddSubscriptionError(ctx context.Context, err *gqlerror.Error) {
|
||||
subscriptionErrStruct := getSubscriptionErrorStruct(ctx)
|
||||
subscriptionErrStruct.errs = append(subscriptionErrStruct.errs, err)
|
||||
}
|
||||
|
||||
func withSubscriptionErrorContext(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, wsSubscriptionErrorCtxKey, &subscriptionError{})
|
||||
}
|
||||
|
||||
func getSubscriptionErrorStruct(ctx context.Context) *subscriptionError {
|
||||
v, _ := ctx.Value(wsSubscriptionErrorCtxKey).(*subscriptionError)
|
||||
return v
|
||||
}
|
||||
|
||||
func getSubscriptionError(ctx context.Context) []*gqlerror.Error {
|
||||
return getSubscriptionErrorStruct(ctx).errs
|
||||
}
|
||||
55
vendor/github.com/99designs/gqlgen/graphql/input.go
generated
vendored
Normal file
55
vendor/github.com/99designs/gqlgen/graphql/input.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
const unmarshalInputCtx key = "unmarshal_input_context"
|
||||
|
||||
// BuildUnmarshalerMap returns a map of unmarshal functions of the ExecutableContext
|
||||
// to use with the WithUnmarshalerMap function.
|
||||
func BuildUnmarshalerMap(unmarshaler ...interface{}) map[reflect.Type]reflect.Value {
|
||||
maps := make(map[reflect.Type]reflect.Value)
|
||||
for _, v := range unmarshaler {
|
||||
ft := reflect.TypeOf(v)
|
||||
if ft.Kind() == reflect.Func {
|
||||
maps[ft.Out(0)] = reflect.ValueOf(v)
|
||||
}
|
||||
}
|
||||
|
||||
return maps
|
||||
}
|
||||
|
||||
// WithUnmarshalerMap returns a new context with a map from input types to their unmarshaler functions.
|
||||
func WithUnmarshalerMap(ctx context.Context, maps map[reflect.Type]reflect.Value) context.Context {
|
||||
return context.WithValue(ctx, unmarshalInputCtx, maps)
|
||||
}
|
||||
|
||||
// UnmarshalInputFromContext allows unmarshaling input object from a context.
|
||||
func UnmarshalInputFromContext(ctx context.Context, raw, v interface{}) error {
|
||||
m, ok := ctx.Value(unmarshalInputCtx).(map[reflect.Type]reflect.Value)
|
||||
if m == nil || !ok {
|
||||
return errors.New("graphql: the input context is empty")
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.Kind() != reflect.Ptr || rv.IsNil() {
|
||||
return errors.New("graphql: input must be a non-nil pointer")
|
||||
}
|
||||
if fn, ok := m[rv.Elem().Type()]; ok {
|
||||
res := fn.Call([]reflect.Value{
|
||||
reflect.ValueOf(ctx),
|
||||
reflect.ValueOf(raw),
|
||||
})
|
||||
if err := res[1].Interface(); err != nil {
|
||||
return err.(error)
|
||||
}
|
||||
|
||||
rv.Elem().Set(res[0])
|
||||
return nil
|
||||
}
|
||||
|
||||
return errors.New("graphql: no unmarshal function found")
|
||||
}
|
||||
84
vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go
generated
vendored
Normal file
84
vendor/github.com/99designs/gqlgen/graphql/playground/altair_playground.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
package playground
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var altairPage = template.Must(template.New("altair").Parse(`<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<base href="https://cdn.jsdelivr.net/npm/altair-static@{{.version}}/build/dist/">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link href="styles.css" rel="stylesheet" crossorigin="anonymous" integrity="{{.cssSRI}}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root>
|
||||
<style>
|
||||
.loading-screen {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<div class="loading-screen styled">
|
||||
<div class="loading-screen-inner">
|
||||
<div class="loading-screen-logo-container">
|
||||
<img src="assets/img/logo_350.svg" alt="Altair">
|
||||
</div>
|
||||
<div class="loading-screen-loading-indicator">
|
||||
<span class="loading-indicator-dot"></span>
|
||||
<span class="loading-indicator-dot"></span>
|
||||
<span class="loading-indicator-dot"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</app-root>
|
||||
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.mainSRI}}" src="main.js"></script>
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.polyfillsSRI}}" src="polyfills.js"></script>
|
||||
<script rel="preload" as="script" type="text/javascript" crossorigin="anonymous" integrity="{{.runtimeSRI}}" src="runtime.js"></script>
|
||||
|
||||
<script>
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
var altairOptions = {
|
||||
endpointURL: url,
|
||||
subscriptionsEndpoint: subscriptionUrl,
|
||||
};
|
||||
window.addEventListener("load", function() {
|
||||
AltairGraphQL.init(altairOptions);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>`))
|
||||
|
||||
// AltairHandler responsible for setting up the altair playground
|
||||
func AltairHandler(title, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
err := altairPage.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "5.0.5",
|
||||
"cssSRI": "sha256-kZ35e5mdMYN5ALEbnsrA2CLn85Oe4hBodfsih9BqNxs=",
|
||||
"mainSRI": "sha256-nWdVTcGTlBDV1L04UQnqod+AJedzBCnKHv6Ct65liHE=",
|
||||
"polyfillsSRI": "sha256-1aVEg2sROcCQ/RxU3AlcPaRZhZdIWA92q2M+mdd/R4c=",
|
||||
"runtimeSRI": "sha256-cK2XhXqQr0WS1Z5eKNdac0rJxTD6miC3ubd+aEVMQDk=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
90
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
90
vendor/github.com/99designs/gqlgen/graphql/playground/playground.go
generated
vendored
@@ -3,22 +3,26 @@ package playground
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{.title}}</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
|
||||
integrity="{{.cssSRI}}"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
</head>
|
||||
<body style="margin: 0;">
|
||||
<div id="graphiql" style="height: 100vh;"></div>
|
||||
<meta charset="utf-8">
|
||||
<title>{{.title}}</title>
|
||||
<style>
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#graphiql {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js"
|
||||
integrity="{{.reactSRI}}"
|
||||
@@ -29,6 +33,16 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
integrity="{{.reactDOMSRI}}"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.css"
|
||||
integrity="{{.cssSRI}}"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="graphiql">Loading...</div>
|
||||
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/graphiql@{{.version}}/graphiql.min.js"
|
||||
integrity="{{.jsSRI}}"
|
||||
@@ -36,15 +50,20 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
></script>
|
||||
|
||||
<script>
|
||||
const url = location.protocol + '//' + location.host + '{{.endpoint}}';
|
||||
{{- if .endpointIsAbsolute}}
|
||||
const url = {{.endpoint}};
|
||||
const subscriptionUrl = {{.subscriptionEndpoint}};
|
||||
{{- else}}
|
||||
const url = location.protocol + '//' + location.host + {{.endpoint}};
|
||||
const wsProto = location.protocol == 'https:' ? 'wss:' : 'ws:';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + '{{.endpoint}}';
|
||||
const subscriptionUrl = wsProto + '//' + location.host + {{.endpoint}};
|
||||
{{- end}}
|
||||
|
||||
const fetcher = GraphiQL.createFetcher({ url, subscriptionUrl });
|
||||
ReactDOM.render(
|
||||
React.createElement(GraphiQL, {
|
||||
fetcher: fetcher,
|
||||
headerEditorEnabled: true,
|
||||
isHeadersEditorEnabled: true,
|
||||
shouldPersistHeaders: true
|
||||
}),
|
||||
document.getElementById('graphiql'),
|
||||
@@ -54,20 +73,47 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
|
||||
</html>
|
||||
`))
|
||||
|
||||
// Handler responsible for setting up the playground
|
||||
func Handler(title string, endpoint string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "text/html")
|
||||
err := page.Execute(w, map[string]string{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"version": "1.5.16",
|
||||
"cssSRI": "sha256-HADQowUuFum02+Ckkv5Yu5ygRoLllHZqg0TFZXY7NHI=",
|
||||
"jsSRI": "sha256-uHp12yvpXC4PC9+6JmITxKuLYwjlW9crq9ywPE5Rxco=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
w.Header().Add("Content-Type", "text/html; charset=UTF-8")
|
||||
err := page.Execute(w, map[string]interface{}{
|
||||
"title": title,
|
||||
"endpoint": endpoint,
|
||||
"endpointIsAbsolute": endpointHasScheme(endpoint),
|
||||
"subscriptionEndpoint": getSubscriptionEndpoint(endpoint),
|
||||
"version": "2.0.7",
|
||||
"cssSRI": "sha256-gQryfbGYeYFxnJYnfPStPYFt0+uv8RP8Dm++eh00G9c=",
|
||||
"jsSRI": "sha256-qQ6pw7LwTLC+GfzN+cJsYXfVWRKH9O5o7+5H96gTJhQ=",
|
||||
"reactSRI": "sha256-Ipu/TQ50iCCVZBUsZyNJfxrDk0E2yhaEIz0vqI+kFG8=",
|
||||
"reactDOMSRI": "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0=",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endpointHasScheme checks if the endpoint has a scheme.
|
||||
func endpointHasScheme(endpoint string) bool {
|
||||
u, err := url.Parse(endpoint)
|
||||
return err == nil && u.Scheme != ""
|
||||
}
|
||||
|
||||
// getSubscriptionEndpoint returns the subscription endpoint for the given
|
||||
// endpoint if it is parsable as a URL, or an empty string.
|
||||
func getSubscriptionEndpoint(endpoint string) string {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch u.Scheme {
|
||||
case "https":
|
||||
u.Scheme = "wss"
|
||||
default:
|
||||
u.Scheme = "ws"
|
||||
}
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
4
vendor/github.com/99designs/gqlgen/graphql/stats.go
generated
vendored
4
vendor/github.com/99designs/gqlgen/graphql/stats.go
generated
vendored
@@ -12,7 +12,7 @@ type Stats struct {
|
||||
Parsing TraceTiming
|
||||
Validation TraceTiming
|
||||
|
||||
// Stats collected by handler extensions. Dont use directly, the extension should provide a type safe way to
|
||||
// Stats collected by handler extensions. Don't use directly, the extension should provide a type safe way to
|
||||
// access this.
|
||||
extension map[string]interface{}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ var ctxTraceStart key = "trace_start"
|
||||
|
||||
// StartOperationTrace captures the current time and stores it in context. This will eventually be added to request
|
||||
// context but we want to grab it as soon as possible. For transports that can only handle a single graphql query
|
||||
// per http requests you dont need to call this at all, the server will do it for you. For transports that handle
|
||||
// per http requests you don't need to call this at all, the server will do it for you. For transports that handle
|
||||
// multiple (eg batching, subscriptions) this should be called before decoding each request.
|
||||
func StartOperationTrace(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, ctxTraceStart, Now())
|
||||
|
||||
5
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
5
vendor/github.com/99designs/gqlgen/graphql/string.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
@@ -55,7 +56,9 @@ func UnmarshalString(v interface{}) (string, error) {
|
||||
case int64:
|
||||
return strconv.FormatInt(v, 10), nil
|
||||
case float64:
|
||||
return fmt.Sprintf("%f", v), nil
|
||||
return strconv.FormatFloat(v, 'f', -1, 64), nil
|
||||
case json.Number:
|
||||
return string(v), nil
|
||||
case bool:
|
||||
if v {
|
||||
return "true", nil
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/upload.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/upload.go
generated
vendored
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
type Upload struct {
|
||||
File io.Reader
|
||||
File io.ReadSeeker
|
||||
Filename string
|
||||
Size int64
|
||||
ContentType string
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/version.go
generated
vendored
@@ -1,3 +1,3 @@
|
||||
package graphql
|
||||
|
||||
const Version = "v0.17.2"
|
||||
const Version = "v0.17.24"
|
||||
|
||||
Reference in New Issue
Block a user