mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
Upgrade to go 1.19 and update dependencies (#3069)
* Update to go 1.19 * Update dependencies * Update cross-compile script * Add missing targets to cross-compile-all * Update cache action to remove warning
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 {
|
||||
|
||||
2
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
2
vendor/github.com/99designs/gqlgen/graphql/context_operation.go
generated
vendored
@@ -3,6 +3,7 @@ package graphql
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
)
|
||||
@@ -15,6 +16,7 @@ type OperationContext struct {
|
||||
Variables map[string]interface{}
|
||||
OperationName string
|
||||
Doc *ast.QueryDocument
|
||||
Headers http.Header
|
||||
|
||||
Operation *ast.OperationDefinition
|
||||
DisableIntrospection bool
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
3
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
3
vendor/github.com/99designs/gqlgen/graphql/handler/transport/http_post.go
generated
vendored
@@ -36,6 +36,9 @@ func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecu
|
||||
writeJsonErrorf(w, "json body could not be decoded: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
params.Headers = r.Header
|
||||
|
||||
params.ReadTime = graphql.TraceTiming{
|
||||
Start: start,
|
||||
End: graphql.Now(),
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
36
vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
generated
vendored
36
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
|
||||
}
|
||||
@@ -358,12 +378,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"
|
||||
|
||||
|
||||
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")
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
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.20"
|
||||
|
||||
Reference in New Issue
Block a user