From fa371b9bb76e478dabc649564e1f465c45057f72 Mon Sep 17 00:00:00 2001 From: Bicky Eric Kantona Date: Sat, 26 Sep 2020 01:38:48 +0700 Subject: [PATCH 001/146] serialize ID just like String --- graphql/id.go | 4 +--- graphql/id_test.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/graphql/id.go b/graphql/id.go index 2e78a5ec4b2..f1c5886a9ef 100644 --- a/graphql/id.go +++ b/graphql/id.go @@ -8,9 +8,7 @@ import ( ) func MarshalID(s string) Marshaler { - return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.Quote(s)) - }) + return MarshalString(s) } func UnmarshalID(v interface{}) (string, error) { switch v := v.(type) { diff --git a/graphql/id_test.go b/graphql/id_test.go index ad600102edb..89523f52b45 100644 --- a/graphql/id_test.go +++ b/graphql/id_test.go @@ -1,6 +1,7 @@ package graphql import ( + "bytes" "math" "testing" @@ -8,6 +9,25 @@ import ( ) func TestMarshalID(t *testing.T) { + marshalID := func(s string) string { + var buf bytes.Buffer + MarshalID(s).MarshalGQL(&buf) + return buf.String() + } + + assert.Equal(t, `"hello"`, marshalID("hello")) + assert.Equal(t, `"he\tllo"`, marshalID("he\tllo")) + assert.Equal(t, `"he\tllo"`, marshalID("he llo")) + assert.Equal(t, `"he\nllo"`, marshalID("he\nllo")) + assert.Equal(t, `"he\r\nllo"`, marshalID("he\r\nllo")) + assert.Equal(t, `"he\\llo"`, marshalID(`he\llo`)) + assert.Equal(t, `"quotes\"nested\"in\"quotes\""`, marshalID(`quotes"nested"in"quotes"`)) + assert.Equal(t, `"\u0000"`, marshalID("\u0000")) + assert.Equal(t, "\"\U000fe4ed\"", marshalID("\U000fe4ed")) + assert.Equal(t, "\"\\u001B\"", marshalID("\u001B")) +} + +func TestUnmarshalID(t *testing.T) { tests := []struct { Name string Input interface{} From 82ca6e24739f63266788b34e55248b68aed0202f Mon Sep 17 00:00:00 2001 From: Fumiaki MATSUSHIMA Date: Mon, 12 Oct 2020 15:24:37 +0900 Subject: [PATCH 002/146] Create package declaration to run dataloaden ref: https://github.com/vektah/dataloaden/issues/35 --- docs/content/reference/dataloaders.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/content/reference/dataloaders.md b/docs/content/reference/dataloaders.md index d5ece00e21a..6319502eb75 100644 --- a/docs/content/reference/dataloaders.md +++ b/docs/content/reference/dataloaders.md @@ -83,6 +83,7 @@ doesnt have generics. Instead we generate the code manually for our instance. go get github.com/vektah/dataloaden mkdir dataloader cd dataloader +echo 'package dataloader' > gen.go go run github.com/vektah/dataloaden UserLoader int *gqlgen-tutorials/dataloader/graph/model.User ``` From 9f85161930220becde384662e4da9f4b457ce19f Mon Sep 17 00:00:00 2001 From: frederikhors <41120635+frederikhors@users.noreply.github.com> Date: Tue, 20 Oct 2020 19:46:58 +0200 Subject: [PATCH 003/146] add uint, uint64, uint32 types in graphql --- graphql/uint.go | 81 ++++++++++++++++++++++++++++++++++++++++++++ graphql/uint_test.go | 71 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 graphql/uint.go create mode 100644 graphql/uint_test.go diff --git a/graphql/uint.go b/graphql/uint.go new file mode 100644 index 00000000000..9349c2f4d24 --- /dev/null +++ b/graphql/uint.go @@ -0,0 +1,81 @@ +package graphql + +import ( + "encoding/json" + "fmt" + "io" + "strconv" +) + +func MarshalUint(i uint) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) + }) +} + +func UnmarshalUint(v interface{}) (uint, error) { + switch v := v.(type) { + case string: + u64, err := strconv.ParseUint(v, 10, 64) + return uint(u64), err + case int: + return uint(v), nil + case int64: + return uint(v), nil + case json.Number: + u64, err := strconv.ParseUint(string(v), 10, 64) + return uint(u64), err + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} + +func MarshalUint64(i uint64) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(i, 10)) + }) +} + +func UnmarshalUint64(v interface{}) (uint64, error) { + switch v := v.(type) { + case string: + return strconv.ParseUint(v, 10, 64) + case int: + return uint64(v), nil + case int64: + return uint64(v), nil + case json.Number: + return strconv.ParseUint(string(v), 10, 64) + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} + +func MarshalUint32(i uint32) Marshaler { + return WriterFunc(func(w io.Writer) { + _, _ = io.WriteString(w, strconv.FormatUint(uint64(i), 10)) + }) +} + +func UnmarshalUint32(v interface{}) (uint32, error) { + switch v := v.(type) { + case string: + iv, err := strconv.ParseInt(v, 10, 32) + if err != nil { + return 0, err + } + return uint32(iv), nil + case int: + return uint32(v), nil + case int64: + return uint32(v), nil + case json.Number: + iv, err := strconv.ParseUint(string(v), 10, 32) + if err != nil { + return 0, err + } + return uint32(iv), nil + default: + return 0, fmt.Errorf("%T is not an uint", v) + } +} diff --git a/graphql/uint_test.go b/graphql/uint_test.go new file mode 100644 index 00000000000..98f08ef5261 --- /dev/null +++ b/graphql/uint_test.go @@ -0,0 +1,71 @@ +package graphql + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUint(t *testing.T) { + t.Run("marshal", func(t *testing.T) { + assert.Equal(t, "123", m2s(MarshalUint(123))) + }) + + t.Run("unmarshal", func(t *testing.T) { + assert.Equal(t, uint(123), mustUnmarshalUint(123)) + assert.Equal(t, uint(123), mustUnmarshalUint(int64(123))) + assert.Equal(t, uint(123), mustUnmarshalUint(json.Number("123"))) + assert.Equal(t, uint(123), mustUnmarshalUint("123")) + }) +} + +func mustUnmarshalUint(v interface{}) uint { + res, err := UnmarshalUint(v) + if err != nil { + panic(err) + } + return res +} + +func TestUint32(t *testing.T) { + t.Run("marshal", func(t *testing.T) { + assert.Equal(t, "123", m2s(MarshalUint32(123))) + }) + + t.Run("unmarshal", func(t *testing.T) { + assert.Equal(t, uint32(123), mustUnmarshalUint32(123)) + assert.Equal(t, uint32(123), mustUnmarshalUint32(int64(123))) + assert.Equal(t, uint32(123), mustUnmarshalUint32(json.Number("123"))) + assert.Equal(t, uint32(123), mustUnmarshalUint32("123")) + }) +} + +func mustUnmarshalUint32(v interface{}) uint32 { + res, err := UnmarshalUint32(v) + if err != nil { + panic(err) + } + return res +} + +func TestUint64(t *testing.T) { + t.Run("marshal", func(t *testing.T) { + assert.Equal(t, "123", m2s(MarshalUint64(123))) + }) + + t.Run("unmarshal", func(t *testing.T) { + assert.Equal(t, uint64(123), mustUnmarshalUint64(123)) + assert.Equal(t, uint64(123), mustUnmarshalUint64(int64(123))) + assert.Equal(t, uint64(123), mustUnmarshalUint64(json.Number("123"))) + assert.Equal(t, uint64(123), mustUnmarshalUint64("123")) + }) +} + +func mustUnmarshalUint64(v interface{}) uint64 { + res, err := UnmarshalUint64(v) + if err != nil { + panic(err) + } + return res +} From 18b5df19bba282e0217dc269f6e9e211b52fc707 Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Tue, 10 Nov 2020 15:37:22 -0800 Subject: [PATCH 004/146] codegen/config: Add a new API to finish an already-validated config LoadConfig parses the config from yaml, but it does a bunch of other things too. We want to parse the config ourselves, so that we can have extra fields which will be passed to our plugins. Right now, that means we either have to duplicate all of LoadConfig, or write the config back to disk only to ask gqlgen re-parse it. In this commit, I expose a new function that does all the parts of LoadConfig other than the actual YAML-reading: that way, a caller who wants to parse the YAML themselves (or otherwise programmatically compute the config) can do so without having to write it back to disk. An alternative would be to move all this logic to Config.Init(), but that could break existing clients. Either way would work for us. --- codegen/config/config.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index ba939fcf59a..cfb22b4bf7e 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -103,6 +103,16 @@ func LoadConfig(filename string) (*Config, error) { return nil, errors.Wrap(err, "unable to parse config") } + if err := CompleteConfig(config); err != nil { + return nil, err + } + + return config, nil +} + +// CompleteConfig fills in the schema and other values to a config loaded from +// YAML. +func CompleteConfig(config *Config) error { defaultDirectives := map[string]DirectiveConfig{ "skip": {SkipRuntime: true}, "include": {SkipRuntime: true}, @@ -140,12 +150,13 @@ func LoadConfig(filename string) (*Config, error) { return nil }); err != nil { - return nil, errors.Wrapf(err, "failed to walk schema at root %s", pathParts[0]) + return errors.Wrapf(err, "failed to walk schema at root %s", pathParts[0]) } } else { + var err error matches, err = filepath.Glob(f) if err != nil { - return nil, errors.Wrapf(err, "failed to glob schema filename %s", f) + return errors.Wrapf(err, "failed to glob schema filename %s", f) } } @@ -163,13 +174,12 @@ func LoadConfig(filename string) (*Config, error) { var schemaRaw []byte schemaRaw, err = ioutil.ReadFile(filename) if err != nil { - return nil, errors.Wrap(err, "unable to open schema") + return errors.Wrap(err, "unable to open schema") } config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) } - - return config, nil + return nil } func (c *Config) Init() error { From d0d5f7db3d8f09f087abedfe3958423c9f5e4fb9 Mon Sep 17 00:00:00 2001 From: j2gg0s Date: Sun, 15 Nov 2020 19:14:28 +0800 Subject: [PATCH 005/146] bugfix: Default Recover func should return gqlerror.Error --- graphql/handler/server_test.go | 22 ++++++++++++++++++++++ graphql/recovery.go | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/graphql/handler/server_test.go b/graphql/handler/server_test.go index 606e93f17ea..e00d06a8d69 100644 --- a/graphql/handler/server_test.go +++ b/graphql/handler/server_test.go @@ -2,6 +2,7 @@ package handler_test import ( "context" + "fmt" "net/http" "net/http/httptest" "net/url" @@ -162,6 +163,27 @@ func TestErrorServer(t *testing.T) { }) } +type panicTransport struct{} + +func (t panicTransport) Supports(r *http.Request) bool { + return true +} + +func (h panicTransport) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { + panic(fmt.Errorf("panic in transport")) +} + +func TestRecover(t *testing.T) { + srv := testserver.New() + srv.AddTransport(&panicTransport{}) + + t.Run("recover from panic", func(t *testing.T) { + resp := get(srv, "/foo?query={name}") + + assert.Equal(t, http.StatusUnprocessableEntity, resp.Code, resp.Body.String()) + }) +} + func get(handler http.Handler, target string) *httptest.ResponseRecorder { r := httptest.NewRequest("GET", target, nil) w := httptest.NewRecorder() diff --git a/graphql/recovery.go b/graphql/recovery.go index 3aa032dc5aa..9bc0e47e1df 100644 --- a/graphql/recovery.go +++ b/graphql/recovery.go @@ -2,10 +2,11 @@ package graphql import ( "context" - "errors" "fmt" "os" "runtime/debug" + + "github.com/vektah/gqlparser/v2/gqlerror" ) type RecoverFunc func(ctx context.Context, err interface{}) (userMessage error) @@ -15,5 +16,5 @@ func DefaultRecover(ctx context.Context, err interface{}) error { fmt.Fprintln(os.Stderr) debug.PrintStack() - return errors.New("internal system error") + return gqlerror.Errorf("internal system error") } From 4628ef8422c2118ee482dc15a65eedff5144d34c Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Wed, 25 Nov 2020 12:49:27 +1100 Subject: [PATCH 006/146] Dont hold error lock when calling into error presenters This can result in a deadlock if error handling code calls GetErrors. --- graphql/context_response.go | 5 +++-- graphql/context_response_test.go | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/graphql/context_response.go b/graphql/context_response.go index d4c2e75445c..c128fdb49ce 100644 --- a/graphql/context_response.go +++ b/graphql/context_response.go @@ -45,10 +45,11 @@ func AddErrorf(ctx context.Context, format string, args ...interface{}) { func AddError(ctx context.Context, err error) { c := getResponseContext(ctx) + presentedError := c.errorPresenter(ctx, ErrorOnPath(ctx, err)) + c.errorsMu.Lock() defer c.errorsMu.Unlock() - - c.errors = append(c.errors, c.errorPresenter(ctx, ErrorOnPath(ctx, err))) + c.errors = append(c.errors, presentedError) } func Recover(ctx context.Context, err interface{}) (userMessage error) { diff --git a/graphql/context_response_test.go b/graphql/context_response_test.go index aa300229c4e..acafe95aaec 100644 --- a/graphql/context_response_test.go +++ b/graphql/context_response_test.go @@ -79,3 +79,16 @@ func TestAddError(t *testing.T) { }) } } + +func TestGetErrorFromPresenter(t *testing.T) { + ctx := WithResponseContext(context.Background(), func(ctx context.Context, err error) *gqlerror.Error { + errs := GetErrors(ctx) + + // because we are still presenting the error it is not expected to be returned, but this should not deadlock. + require.Len(t, errs, 0) + return DefaultErrorPresenter(ctx, err) + }, nil) + + ctx = WithFieldContext(ctx, &FieldContext{}) + AddError(ctx, errors.New("foo1")) +} From 89a9f743240e589c476df6a01e122564314ec215 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Wed, 25 Nov 2020 13:12:05 +1100 Subject: [PATCH 007/146] Remove stale bot We tried it, but it's just causing more work both for maintainers and reporters of errors. --- .github/stale.yml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 66470e7554c..00000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,10 +0,0 @@ -daysUntilStale: 90 -daysUntilClose: 7 -staleLabel: stale -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -exemptLabels: - - accepted - - enhancement From 1123ba0da6c0cd0f5ab71d7e4c8aae7a5e8f40b4 Mon Sep 17 00:00:00 2001 From: Obed Osei Frimpong <3536601+oseifrimpong@users.noreply.github.com> Date: Thu, 26 Nov 2020 03:40:55 +0800 Subject: [PATCH 008/146] Update gin.md Changed this: `In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie then together in the Gin router: ` to: `In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie them together in the Gin router: ` --- docs/content/recipes/gin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/recipes/gin.md b/docs/content/recipes/gin.md index 155cc76e05e..2aedd026f6c 100644 --- a/docs/content/recipes/gin.md +++ b/docs/content/recipes/gin.md @@ -16,7 +16,7 @@ Install Gin: $ go get github.com/gin-gonic/gin ``` -In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie then together in the Gin router: +In your router file, define the handlers for the GraphQL and Playground endpoints in two different methods and tie them together in the Gin router: ```go import ( From f00e2c3f3d70a58ae85ab05d5f2b8adf543a306d Mon Sep 17 00:00:00 2001 From: Alex Snast Date: Thu, 3 Dec 2020 15:34:20 +0200 Subject: [PATCH 009/146] subscriptions: send complete message on resolver panic --- graphql/handler/transport/websocket.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/graphql/handler/transport/websocket.go b/graphql/handler/transport/websocket.go index 3089a877999..787a879f50d 100644 --- a/graphql/handler/transport/websocket.go +++ b/graphql/handler/transport/websocket.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "log" "net/http" @@ -232,25 +233,31 @@ func (c *wsConnection) subscribe(start time.Time, message *operationMessage) { go func() { defer func() { if r := recover(); r != nil { - userErr := rc.Recover(ctx, r) - c.sendError(message.ID, &gqlerror.Error{Message: userErr.Error()}) + err := rc.Recover(ctx, r) + var gqlerr *gqlerror.Error + if !errors.As(err, &gqlerr) { + gqlerr = &gqlerror.Error{} + if err != nil { + gqlerr.Message = err.Error() + } + } + c.sendError(message.ID, gqlerr) } + c.complete(message.ID) + c.mu.Lock() + delete(c.active, message.ID) + c.mu.Unlock() + cancel() }() + responses, ctx := c.exec.DispatchOperation(ctx, rc) for { response := responses(ctx) if response == nil { break } - c.sendResponse(message.ID, response) } - c.complete(message.ID) - - c.mu.Lock() - delete(c.active, message.ID) - c.mu.Unlock() - cancel() }() } From a9c8fabff6d56c9c523ca68764dcd9f9e6cd4f45 Mon Sep 17 00:00:00 2001 From: Maxim <862272+max107@users.noreply.github.com> Date: Sun, 6 Dec 2020 20:11:28 +0300 Subject: [PATCH 010/146] int64 support --- graphql/string.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/graphql/string.go b/graphql/string.go index 7c1b7d95775..742e50cc3b7 100644 --- a/graphql/string.go +++ b/graphql/string.go @@ -52,6 +52,8 @@ func UnmarshalString(v interface{}) (string, error) { return v, nil case int: return strconv.Itoa(v), nil + case int64: + return strconv.FormatInt(v, 10), nil case float64: return fmt.Sprintf("%f", v), nil case bool: From c30ff3ddec18b7a9465e0b81ab0af301d3899141 Mon Sep 17 00:00:00 2001 From: zikaeroh <48577114+zikaeroh@users.noreply.github.com> Date: Sun, 6 Dec 2020 20:08:14 -0800 Subject: [PATCH 011/146] Upgrade go-chi to v1.5.1 with module support --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 13777ee3887..3130a194457 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/agnivade/levenshtein v1.0.3 // indirect - github.com/go-chi/chi v3.3.2+incompatible + github.com/go-chi/chi v1.5.1 github.com/gogo/protobuf v1.0.0 // indirect github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect github.com/gorilla/mux v1.6.1 // indirect diff --git a/go.sum b/go.sum index 4c3da9b8125..8fcfa821c17 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/go-chi/chi v3.3.2+incompatible h1:uQNcQN3NsV1j4ANsPh42P4ew4t6rnRbJb8frvpp31qQ= -github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= +github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= From 918801eac861c0ceb5cf45969745f674b823ef7c Mon Sep 17 00:00:00 2001 From: Ricardo Cuenca Date: Fri, 11 Dec 2020 19:21:22 -0600 Subject: [PATCH 012/146] Change 'Changeset' doc example to mutation --- docs/content/reference/changesets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/reference/changesets.md b/docs/content/reference/changesets.md index 243ab30eb6a..329206ba5ef 100644 --- a/docs/content/reference/changesets.md +++ b/docs/content/reference/changesets.md @@ -9,7 +9,7 @@ Occasionally you need to distinguish presence from nil (undefined vs null). In g ```graphql -type Query { +type Mutation { updateUser(id: ID!, changes: UserChanges!): User } @@ -28,7 +28,7 @@ models: After running go generate you should end up with a resolver that looks like this: ```go -func (r *queryResolver) UpdateUser(ctx context.Context, id int, changes map[string]interface{}) (*User, error) { +func (r *mutationResolver) UpdateUser(ctx context.Context, id int, changes map[string]interface{}) (*User, error) { u := fetchFromDb(id) /// apply the changes saveToDb(u) From be4514c60a3cef3673b003a545818eb67e620506 Mon Sep 17 00:00:00 2001 From: David Douglas <48367195+ddouglas@users.noreply.github.com> Date: Tue, 12 Jan 2021 20:14:12 -0500 Subject: [PATCH 013/146] Upgrade graphql-playground to 1.7.26 --- graphql/playground/playground.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphql/playground/playground.go b/graphql/playground/playground.go index 45bbbd4f143..12f1030a8d2 100644 --- a/graphql/playground/playground.go +++ b/graphql/playground/playground.go @@ -50,10 +50,10 @@ func Handler(title string, endpoint string) http.HandlerFunc { err := page.Execute(w, map[string]string{ "title": title, "endpoint": endpoint, - "version": "1.7.20", - "cssSRI": "sha256-cS9Vc2OBt9eUf4sykRWukeFYaInL29+myBmFDSa7F/U=", + "version": "1.7.26", + "cssSRI": "sha256-dKnNLEFwKSVFpkpjRWe+o/jQDM6n/JsvQ0J3l5Dk3fc=", "faviconSRI": "sha256-GhTyE+McTU79R4+pRO6ih+4TfsTOrpPwD8ReKFzb3PM=", - "jsSRI": "sha256-4QG1Uza2GgGdlBL3RCBCGtGeZB6bDbsw8OltCMGeJsA=", + "jsSRI": "sha256-SG9YAy4eywTcLckwij7V4oSCG3hOdV1m+2e1XuNxIgk=", }) if err != nil { panic(err) From 956531936e9a7a0d9012c246153531a9bcf3c7bd Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Fri, 14 Aug 2020 16:17:38 -0700 Subject: [PATCH 014/146] Resolve requests for federation entities in parallel In apollo federation, we may be asked for data about a list of entities. These can typically be resolved in parallel, just as with sibling fields in ordinary GraphQL queries. Now we do! I also changed the behavior such that if one lookup fails, we don't cancel the others. This is more consistent with the behavior of other resolvers, and is more natural now that they execute in parallel. This, plus panic handling, required a little refactoring. The examples probably give the clearest picture of the changes. (And the clearest test; the changed functionality is already exercised by `integration-test.js` as watching the test server logs will attest.) Fixes #1278. --- codegen/field.go | 1 + .../accounts/graph/generated/federation.go | 54 +++++++++++++--- .../accounts/graph/generated/generated.go | 2 +- .../products/graph/generated/federation.go | 54 +++++++++++++--- .../products/graph/generated/generated.go | 2 +- .../reviews/graph/generated/federation.go | 61 +++++++++++++++---- .../reviews/graph/generated/generated.go | 2 +- plugin/federation/federation.gotpl | 56 ++++++++++++++--- 8 files changed, 189 insertions(+), 43 deletions(-) diff --git a/codegen/field.go b/codegen/field.go index c12520b703d..149b9060498 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -103,6 +103,7 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) { f.GoReceiverName = "ec" f.GoFieldName = "__resolve_entities" f.MethodHasContext = true + f.NoErr = true return nil case f.Name == "_service": f.GoFieldType = GoFieldMethod diff --git a/example/federation/accounts/graph/generated/federation.go b/example/federation/accounts/graph/generated/federation.go index 6c574a8a863..095c6ab8eb9 100644 --- a/example/federation/accounts/graph/generated/federation.go +++ b/example/federation/accounts/graph/generated/federation.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "strings" + "sync" "github.com/99designs/gqlgen/plugin/federation/fedruntime" ) @@ -30,32 +31,67 @@ func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime. }, nil } -func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) ([]fedruntime.Entity, error) { - list := []fedruntime.Entity{} - for _, rep := range representations { +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + resolveEntity := func(ctx context.Context, i int, rep map[string]interface{}) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + typeName, ok := rep["__typename"].(string) if !ok { - return nil, errors.New("__typename must be an existing string") + return errors.New("__typename must be an existing string") } switch typeName { case "User": id0, err := ec.unmarshalNID2string(ctx, rep["id"]) if err != nil { - return nil, errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) } entity, err := ec.resolvers.Entity().FindUserByID(ctx, id0) if err != nil { - return nil, err + return err } - list = append(list, entity) + list[i] = entity + return nil default: - return nil, errors.New("unknown type: " + typeName) + return errors.New("unknown type: " + typeName) + } + } + + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + switch len(representations) { + case 0: + return list + case 1: + err := resolveEntity(ctx, 0, representations[0]) + if err != nil { + ec.Error(ctx, err) + } + return list + default: + var g sync.WaitGroup + g.Add(len(representations)) + for i, rep := range representations { + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, i, rep) + if err != nil { + ec.Error(ctx, err) + } + g.Done() + }(i, rep) } + g.Wait() + return list } - return list, nil } diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index 525a1aed6e4..c640f13c27f 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -415,7 +415,7 @@ func (ec *executionContext) _Query__entities(ctx context.Context, field graphql. fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})) + return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})), nil }) if err != nil { ec.Error(ctx, err) diff --git a/example/federation/products/graph/generated/federation.go b/example/federation/products/graph/generated/federation.go index 6db7e70cd84..b92e6c227ca 100644 --- a/example/federation/products/graph/generated/federation.go +++ b/example/federation/products/graph/generated/federation.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "strings" + "sync" "github.com/99designs/gqlgen/plugin/federation/fedruntime" ) @@ -30,32 +31,67 @@ func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime. }, nil } -func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) ([]fedruntime.Entity, error) { - list := []fedruntime.Entity{} - for _, rep := range representations { +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + resolveEntity := func(ctx context.Context, i int, rep map[string]interface{}) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + typeName, ok := rep["__typename"].(string) if !ok { - return nil, errors.New("__typename must be an existing string") + return errors.New("__typename must be an existing string") } switch typeName { case "Product": id0, err := ec.unmarshalNString2string(ctx, rep["upc"]) if err != nil { - return nil, errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) } entity, err := ec.resolvers.Entity().FindProductByUpc(ctx, id0) if err != nil { - return nil, err + return err } - list = append(list, entity) + list[i] = entity + return nil default: - return nil, errors.New("unknown type: " + typeName) + return errors.New("unknown type: " + typeName) + } + } + + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + switch len(representations) { + case 0: + return list + case 1: + err := resolveEntity(ctx, 0, representations[0]) + if err != nil { + ec.Error(ctx, err) + } + return list + default: + var g sync.WaitGroup + g.Add(len(representations)) + for i, rep := range representations { + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, i, rep) + if err != nil { + ec.Error(ctx, err) + } + g.Done() + }(i, rep) } + g.Wait() + return list } - return list, nil } diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 775b6c09fef..711836daa9a 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -552,7 +552,7 @@ func (ec *executionContext) _Query__entities(ctx context.Context, field graphql. fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})) + return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})), nil }) if err != nil { ec.Error(ctx, err) diff --git a/example/federation/reviews/graph/generated/federation.go b/example/federation/reviews/graph/generated/federation.go index 60a34909578..3dff729b252 100644 --- a/example/federation/reviews/graph/generated/federation.go +++ b/example/federation/reviews/graph/generated/federation.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "strings" + "sync" "github.com/99designs/gqlgen/plugin/federation/fedruntime" ) @@ -30,46 +31,82 @@ func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime. }, nil } -func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) ([]fedruntime.Entity, error) { - list := []fedruntime.Entity{} - for _, rep := range representations { +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + resolveEntity := func(ctx context.Context, i int, rep map[string]interface{}) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + typeName, ok := rep["__typename"].(string) if !ok { - return nil, errors.New("__typename must be an existing string") + return errors.New("__typename must be an existing string") } switch typeName { case "Product": id0, err := ec.unmarshalNString2string(ctx, rep["upc"]) if err != nil { - return nil, errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) } entity, err := ec.resolvers.Entity().FindProductByUpc(ctx, id0) if err != nil { - return nil, err + return err } - list = append(list, entity) + list[i] = entity + return nil case "User": id0, err := ec.unmarshalNID2string(ctx, rep["id"]) if err != nil { - return nil, errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) } entity, err := ec.resolvers.Entity().FindUserByID(ctx, id0) if err != nil { - return nil, err + return err } - list = append(list, entity) + list[i] = entity + return nil default: - return nil, errors.New("unknown type: " + typeName) + return errors.New("unknown type: " + typeName) + } + } + + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + switch len(representations) { + case 0: + return list + case 1: + err := resolveEntity(ctx, 0, representations[0]) + if err != nil { + ec.Error(ctx, err) + } + return list + default: + var g sync.WaitGroup + g.Add(len(representations)) + for i, rep := range representations { + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, i, rep) + if err != nil { + ec.Error(ctx, err) + } + g.Done() + }(i, rep) } + g.Wait() + return list } - return list, nil } diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 108d3d2822a..15beb38eb42 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -568,7 +568,7 @@ func (ec *executionContext) _Query__entities(ctx context.Context, field graphql. fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})) + return ec.__resolve_entities(ctx, args["representations"].([]map[string]interface{})), nil }) if err != nil { ec.Error(ctx, err) diff --git a/plugin/federation/federation.gotpl b/plugin/federation/federation.gotpl index 96c25e85723..33427987f01 100644 --- a/plugin/federation/federation.gotpl +++ b/plugin/federation/federation.gotpl @@ -2,6 +2,7 @@ {{ reserveImport "errors" }} {{ reserveImport "fmt" }} {{ reserveImport "strings" }} +{{ reserveImport "sync" }} {{ reserveImport "github.com/99designs/gqlgen/plugin/federation/fedruntime" }} @@ -25,12 +26,20 @@ func (ec *executionContext) __resolve__service(ctx context.Context) (fedruntime. } {{if .Entities}} -func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) ([]fedruntime.Entity, error) { - list := []fedruntime.Entity{} - for _, rep := range representations { +func (ec *executionContext) __resolve_entities(ctx context.Context, representations []map[string]interface{}) []fedruntime.Entity { + list := make([]fedruntime.Entity, len(representations)) + resolveEntity := func(ctx context.Context, i int, rep map[string]interface{}) (err error) { + // we need to do our own panic handling, because we may be called in a + // goroutine, where the usual panic handling can't catch us + defer func () { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + } + }() + typeName, ok := rep["__typename"].(string) if !ok { - return nil, errors.New("__typename must be an existing string") + return errors.New("__typename must be an existing string") } switch typeName { {{ range .Entities }} @@ -39,31 +48,58 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati {{ range $i, $keyField := .KeyFields -}} id{{$i}}, err := ec.{{.TypeReference.UnmarshalFunc}}(ctx, rep["{{$keyField.Field.Name}}"]) if err != nil { - return nil, errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{$keyField.Field.Name}}")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{$keyField.Field.Name}}")) } {{end}} entity, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, {{ range $i, $_ := .KeyFields -}} id{{$i}}, {{end}}) if err != nil { - return nil, err + return err } {{ range .Requires }} {{ range .Fields}} entity.{{.NameGo}}, err = ec.{{.TypeReference.UnmarshalFunc}}(ctx, rep["{{.Name}}"]) if err != nil { - return nil, err + return err } {{ end }} {{ end }} - list = append(list, entity) + list[i] = entity + return nil {{ end }} {{ end }} default: - return nil, errors.New("unknown type: "+typeName) + return errors.New("unknown type: "+typeName) + } + } + + // if there are multiple entities to resolve, parallelize (similar to + // graphql.FieldSet.Dispatch) + switch len(representations) { + case 0: + return list + case 1: + err := resolveEntity(ctx, 0, representations[0]) + if err != nil { + ec.Error(ctx, err) + } + return list + default: + var g sync.WaitGroup + g.Add(len(representations)) + for i, rep := range representations { + go func(i int, rep map[string]interface{}) { + err := resolveEntity(ctx, i, rep) + if err != nil { + ec.Error(ctx, err) + } + g.Done() + }(i, rep) } + g.Wait() + return list } - return list, nil } {{end}} From 5ef5d14f864eb355ffb96d2727a19b61c5d2b362 Mon Sep 17 00:00:00 2001 From: Braeden Lisowski <47958989+lisowskibraeden@users.noreply.github.com> Date: Sat, 23 Jan 2021 19:23:58 -0600 Subject: [PATCH 015/146] Update cors.md I had problems reading this page and applying it to my project. With these changes it worked on my end --- docs/content/recipes/cors.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/content/recipes/cors.md b/docs/content/recipes/cors.md index 9e36110e7e7..0b0ac114bfa 100644 --- a/docs/content/recipes/cors.md +++ b/docs/content/recipes/cors.md @@ -22,6 +22,8 @@ import ( "github.com/99designs/gqlgen/graphql/handler" "github.com/go-chi/chi" "github.com/rs/cors" + "github.com/gorilla/websocket" + "github.com/99designs/gqlgen/graphql/playground" ) func main() { @@ -48,7 +50,7 @@ func main() { }, }) - router.Handle("/", handler.Playground("Starwars", "/query")) + router.Handle("/", playground.Handler("Starwars", "/query")) router.Handle("/query", srv) err := http.ListenAndServe(":8080", router) From 478c3f08b20fadd31c538ddd90bb7e88a4e2c1a9 Mon Sep 17 00:00:00 2001 From: Luca Steeb Date: Wed, 27 Jan 2021 21:47:14 +0700 Subject: [PATCH 016/146] feat(codegen): handle (v, ok) methods --- codegen/field.go | 3 + codegen/field.gotpl | 8 +- codegen/testserver/generated.go | 261 ++++++++++++++++++++++++++++++++ codegen/testserver/resolver.go | 8 + codegen/testserver/stub.go | 8 + codegen/testserver/v-ok.go | 17 +++ codegen/testserver/v-ok.graphql | 12 ++ codegen/testserver/v-ok_test.go | 47 ++++++ 8 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 codegen/testserver/v-ok.go create mode 100644 codegen/testserver/v-ok.graphql create mode 100644 codegen/testserver/v-ok_test.go diff --git a/codegen/field.go b/codegen/field.go index 26ed6b5518a..d1eceb002ef 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -25,6 +25,7 @@ type Field struct { Args []*FieldArgument // A list of arguments to be passed to this field MethodHasContext bool // If this is bound to a go method, does the method also take a context NoErr bool // If this is bound to a go method, does that method have an error as the second argument + VOkFunc bool // If this is bound to a go method, is it of shape (interface{}, bool) Object *Object // A link back to the parent object Default interface{} // The default value Stream bool // does this field return a channel? @@ -152,6 +153,8 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) { sig := target.Type().(*types.Signature) if sig.Results().Len() == 1 { f.NoErr = true + } else if s := sig.Results(); s.Len() == 2 && s.At(1).Type().String() == "bool" { + f.VOkFunc = true } else if sig.Results().Len() != 2 { return fmt.Errorf("method has wrong number of args") } diff --git a/codegen/field.gotpl b/codegen/field.gotpl index 66f715981a6..8e53772afac 100644 --- a/codegen/field.gotpl +++ b/codegen/field.gotpl @@ -112,7 +112,13 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ .Name | quote}}) } {{- else if .IsMethod -}} - {{- if .NoErr -}} + {{- if .VOkFunc -}} + v, ok := {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) + if !ok { + return nil, nil + } + return v, nil + {{- else if .NoErr -}} return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}), nil {{- else -}} return {{.GoReceiverName}}.{{.GoFieldName}}({{ .CallArgs }}) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index ea3c2f48547..c11404c472b 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -306,6 +306,8 @@ type ComplexityRoot struct { Shapes func(childComplexity int) int Slices func(childComplexity int) int User func(childComplexity int, id int) int + VOkCaseNil func(childComplexity int) int + VOkCaseValue func(childComplexity int) int Valid func(childComplexity int) int ValidType func(childComplexity int) int WrappedMap func(childComplexity int) int @@ -344,6 +346,14 @@ type ComplexityRoot struct { Updated func(childComplexity int) int } + VOkCaseNil struct { + Value func(childComplexity int) int + } + + VOkCaseValue struct { + Value func(childComplexity int) int + } + ValidType struct { DifferentCase func(childComplexity int) int DifferentCaseOld func(childComplexity int) int @@ -467,6 +477,8 @@ type QueryResolver interface { ScalarSlice(ctx context.Context) ([]byte, error) Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) OptionalUnion(ctx context.Context) (TestUnion, error) + VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) + VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) ValidType(ctx context.Context) (*ValidType, error) WrappedStruct(ctx context.Context) (*WrappedStruct, error) WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) @@ -1445,6 +1457,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.User(childComplexity, args["id"].(int)), true + case "Query.vOkCaseNil": + if e.complexity.Query.VOkCaseNil == nil { + break + } + + return e.complexity.Query.VOkCaseNil(childComplexity), true + + case "Query.vOkCaseValue": + if e.complexity.Query.VOkCaseValue == nil { + break + } + + return e.complexity.Query.VOkCaseValue(childComplexity), true + case "Query.valid": if e.complexity.Query.Valid == nil { break @@ -1623,6 +1649,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.User.Updated(childComplexity), true + case "VOkCaseNil.value": + if e.complexity.VOkCaseNil.Value == nil { + break + } + + return e.complexity.VOkCaseNil.Value(childComplexity), true + + case "VOkCaseValue.value": + if e.complexity.VOkCaseValue.Value == nil { + break + } + + return e.complexity.VOkCaseValue.Value(childComplexity), true + case "ValidType.differentCase": if e.complexity.ValidType.DifferentCase == nil { break @@ -2235,6 +2275,19 @@ union TestUnion = A | B extend type Query { optionalUnion: TestUnion } +`, BuiltIn: false}, + {Name: "v-ok.graphql", Input: `extend type Query { + vOkCaseValue: VOkCaseValue + vOkCaseNil: VOkCaseNil +} + +type VOkCaseValue @goModel(model:"testserver.VOkCaseValue") { + value: String +} + +type VOkCaseNil @goModel(model:"testserver.VOkCaseNil") { + value: String +} `, BuiltIn: false}, {Name: "validtypes.graphql", Input: `extend type Query { validType: ValidType @@ -7534,6 +7587,64 @@ func (ec *executionContext) _Query_optionalUnion(ctx context.Context, field grap return ec.marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐTestUnion(ctx, field.Selections, res) } +func (ec *executionContext) _Query_vOkCaseValue(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().VOkCaseValue(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*VOkCaseValue) + fc.Result = res + return ec.marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseValue(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_vOkCaseNil(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().VOkCaseNil(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*VOkCaseNil) + fc.Result = res + return ec.marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseNil(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_validType(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -8429,6 +8540,72 @@ func (ec *executionContext) _User_updated(ctx context.Context, field graphql.Col return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res) } +func (ec *executionContext) _VOkCaseNil_value(ctx context.Context, field graphql.CollectedField, obj *VOkCaseNil) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "VOkCaseNil", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + v, ok := obj.Value() + if !ok { + return nil, nil + } + return v, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _VOkCaseValue_value(ctx context.Context, field graphql.CollectedField, obj *VOkCaseValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "VOkCaseValue", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + v, ok := obj.Value() + if !ok { + return nil, nil + } + return v, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _ValidType_differentCase(ctx context.Context, field graphql.CollectedField, obj *ValidType) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12394,6 +12571,28 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_optionalUnion(ctx, field) return res }) + case "vOkCaseValue": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_vOkCaseValue(ctx, field) + return res + }) + case "vOkCaseNil": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_vOkCaseNil(ctx, field) + return res + }) case "validType": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -12620,6 +12819,54 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj return out } +var vOkCaseNilImplementors = []string{"VOkCaseNil"} + +func (ec *executionContext) _VOkCaseNil(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseNil) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseNilImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VOkCaseNil") + case "value": + out.Values[i] = ec._VOkCaseNil_value(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var vOkCaseValueImplementors = []string{"VOkCaseValue"} + +func (ec *executionContext) _VOkCaseValue(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseValueImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VOkCaseValue") + case "value": + out.Values[i] = ec._VOkCaseValue_value(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var validTypeImplementors = []string{"ValidType"} func (ec *executionContext) _ValidType(ctx context.Context, sel ast.SelectionSet, obj *ValidType) graphql.Marshaler { @@ -14642,6 +14889,20 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel return graphql.MarshalTime(*v) } +func (ec *executionContext) marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseNil(ctx context.Context, sel ast.SelectionSet, v *VOkCaseNil) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._VOkCaseNil(ctx, sel, v) +} + +func (ec *executionContext) marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseValue(ctx context.Context, sel ast.SelectionSet, v *VOkCaseValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._VOkCaseValue(ctx, sel, v) +} + func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx context.Context, v interface{}) (*ValidInput, error) { if v == nil { return nil, nil diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index 952d20943e8..c9528777d0b 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -272,6 +272,14 @@ func (r *queryResolver) OptionalUnion(ctx context.Context) (TestUnion, error) { panic("not implemented") } +func (r *queryResolver) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { + panic("not implemented") +} + +func (r *queryResolver) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { + panic("not implemented") +} + func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { panic("not implemented") } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index daf4052ea08..528cb1e7f10 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -95,6 +95,8 @@ type Stub struct { ScalarSlice func(ctx context.Context) ([]byte, error) Fallback func(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) OptionalUnion func(ctx context.Context) (TestUnion, error) + VOkCaseValue func(ctx context.Context) (*VOkCaseValue, error) + VOkCaseNil func(ctx context.Context) (*VOkCaseNil, error) ValidType func(ctx context.Context) (*ValidType, error) WrappedStruct func(ctx context.Context) (*WrappedStruct, error) WrappedScalar func(ctx context.Context) (otherpkg.Scalar, error) @@ -388,6 +390,12 @@ func (r *stubQuery) Fallback(ctx context.Context, arg FallbackToStringEncoding) func (r *stubQuery) OptionalUnion(ctx context.Context) (TestUnion, error) { return r.QueryResolver.OptionalUnion(ctx) } +func (r *stubQuery) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { + return r.QueryResolver.VOkCaseValue(ctx) +} +func (r *stubQuery) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { + return r.QueryResolver.VOkCaseNil(ctx) +} func (r *stubQuery) ValidType(ctx context.Context) (*ValidType, error) { return r.QueryResolver.ValidType(ctx) } diff --git a/codegen/testserver/v-ok.go b/codegen/testserver/v-ok.go new file mode 100644 index 00000000000..5ad96bd5b8d --- /dev/null +++ b/codegen/testserver/v-ok.go @@ -0,0 +1,17 @@ +package testserver + +// VOkCaseValue model +type VOkCaseValue struct { +} + +func (v VOkCaseValue) Value() (string, bool) { + return "hi", true +} + +// VOkCaseNil model +type VOkCaseNil struct { +} + +func (v VOkCaseNil) Value() (string, bool) { + return "", false +} diff --git a/codegen/testserver/v-ok.graphql b/codegen/testserver/v-ok.graphql new file mode 100644 index 00000000000..0d1530f3636 --- /dev/null +++ b/codegen/testserver/v-ok.graphql @@ -0,0 +1,12 @@ +extend type Query { + vOkCaseValue: VOkCaseValue + vOkCaseNil: VOkCaseNil +} + +type VOkCaseValue @goModel(model:"testserver.VOkCaseValue") { + value: String +} + +type VOkCaseNil @goModel(model:"testserver.VOkCaseNil") { + value: String +} diff --git a/codegen/testserver/v-ok_test.go b/codegen/testserver/v-ok_test.go new file mode 100644 index 00000000000..fe7037b587d --- /dev/null +++ b/codegen/testserver/v-ok_test.go @@ -0,0 +1,47 @@ +package testserver + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" +) + +func TestOk(t *testing.T) { + resolver := &Stub{} + resolver.QueryResolver.VOkCaseValue = func(ctx context.Context) (*VOkCaseValue, error) { + return &VOkCaseValue{}, nil + } + resolver.QueryResolver.VOkCaseNil = func(ctx context.Context) (*VOkCaseNil, error) { + return &VOkCaseNil{}, nil + } + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolver}), + )) + + t.Run("v ok case value", func(t *testing.T) { + var resp struct { + VOkCaseValue struct { + Value string + } + } + err := c.Post(`query { vOkCaseValue { value } }`, &resp) + require.NoError(t, err) + require.Equal(t, resp.VOkCaseValue.Value, "hi") + }) + + t.Run("v ok case nil", func(t *testing.T) { + var resp struct { + VOkCaseNil struct { + Value *string + } + } + err := c.Post(`query { vOkCaseNil { value } }`, &resp) + require.NoError(t, err) + require.Equal(t, true, resp.VOkCaseNil.Value == nil) + }) +} From 0e9d9c3a9d072c6e2262bf742705d723be8d2508 Mon Sep 17 00:00:00 2001 From: sanjeevchopra Date: Wed, 27 Jan 2021 17:16:11 -0800 Subject: [PATCH 017/146] updated sample code for disabling introspection --- docs/content/reference/introspection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/introspection.md b/docs/content/reference/introspection.md index daa26c6cb01..c1acb1e8160 100644 --- a/docs/content/reference/introspection.md +++ b/docs/content/reference/introspection.md @@ -29,7 +29,7 @@ Introspection can also be enabled on a per-request context basis. For example, y srv := handler.NewDefaultServer(es) srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { if !userForContext(ctx).IsAdmin { - graphql.GetOperationContext(ctx).DisableIntrospection = true + graphql.GetRequestContext(ctx).DisableIntrospection = true } return next(ctx) From 02b140038d1f192af2ff2cc05a08a691b300ec94 Mon Sep 17 00:00:00 2001 From: fmyd Date: Thu, 28 Jan 2021 17:53:21 +0900 Subject: [PATCH 018/146] fomatted query indent --- docs/content/getting-started.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 99a3be37270..db6ebaec1e3 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -136,7 +136,7 @@ go run server.go then open http://localhost:8080 in a browser. here are some queries to try: ```graphql mutation createTodo { - createTodo(input:{text:"todo", userId:"1"}) { + createTodo(input: { text: "todo", userId: "1" }) { user { id } @@ -146,13 +146,13 @@ mutation createTodo { } query findTodos { - todos { - text - done - user { - name - } + todos { + text + done + user { + name } + } } ``` @@ -205,7 +205,7 @@ At the top of our `resolver.go`, between `package` and `import`, add the followi //go:generate go run github.com/99designs/gqlgen ``` -This magic comment tells `go generate` what command to run when we want to regenerate our code. To run go generate recursively over your entire project, use this command: +This magic comment tells `go generate` what command to run when we want to regenerate our code. To run go generate recursively over your entire project, use this command: ```go go generate ./... From 18678b15ecbcf6075356623fbc0902606e440513 Mon Sep 17 00:00:00 2001 From: Shoichi Kaji Date: Sat, 6 Feb 2021 22:35:05 +0900 Subject: [PATCH 019/146] Fix data race The argument of unmarshalInput may be the same for concurrent use if it pass as graphql "variables". So we have to copy it before setting default values --- codegen/input.gotpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/codegen/input.gotpl b/codegen/input.gotpl index e8a5b50492b..c6eac4d47bb 100644 --- a/codegen/input.gotpl +++ b/codegen/input.gotpl @@ -2,7 +2,10 @@ {{- if not .HasUnmarshal }} func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, obj interface{}) ({{.Type | ref}}, error) { var it {{.Type | ref}} - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } {{ range $field := .Fields}} {{- if $field.Default}} if _, present := asMap[{{$field.Name|quote}}] ; !present { From 23eec79139fd4735d50d397a081edfefad09fd27 Mon Sep 17 00:00:00 2001 From: Shoichi Kaji Date: Sat, 6 Feb 2021 22:43:59 +0900 Subject: [PATCH 020/146] go generate ./... --- codegen/testserver/generated.go | 50 +++++++++++++++++----- example/config/generated.go | 5 ++- example/fileupload/generated.go | 5 ++- example/scalars/generated.go | 5 ++- example/starwars/generated/exec.go | 5 ++- example/todo/generated.go | 5 ++- example/type-system-extension/generated.go | 5 ++- integration/generated.go | 5 ++- 8 files changed, 68 insertions(+), 17 deletions(-) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index ea3c2f48547..34726a00876 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -9831,7 +9831,10 @@ func (ec *executionContext) _iIt_id(ctx context.Context, field graphql.Collected func (ec *executionContext) unmarshalInputInnerDirectives(ctx context.Context, obj interface{}) (InnerDirectives, error) { var it InnerDirectives - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -9873,7 +9876,10 @@ func (ec *executionContext) unmarshalInputInnerDirectives(ctx context.Context, o func (ec *executionContext) unmarshalInputInnerInput(ctx context.Context, obj interface{}) (InnerInput, error) { var it InnerInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -9893,7 +9899,10 @@ func (ec *executionContext) unmarshalInputInnerInput(ctx context.Context, obj in func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, obj interface{}) (InputDirectives, error) { var it InputDirectives - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10013,7 +10022,10 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o func (ec *executionContext) unmarshalInputInputWithEnumValue(ctx context.Context, obj interface{}) (InputWithEnumValue, error) { var it InputWithEnumValue - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10033,7 +10045,10 @@ func (ec *executionContext) unmarshalInputInputWithEnumValue(ctx context.Context func (ec *executionContext) unmarshalInputNestedInput(ctx context.Context, obj interface{}) (NestedInput, error) { var it NestedInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10053,7 +10068,10 @@ func (ec *executionContext) unmarshalInputNestedInput(ctx context.Context, obj i func (ec *executionContext) unmarshalInputNestedMapInput(ctx context.Context, obj interface{}) (NestedMapInput, error) { var it NestedMapInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10073,7 +10091,10 @@ func (ec *executionContext) unmarshalInputNestedMapInput(ctx context.Context, ob func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, obj interface{}) (OuterInput, error) { var it OuterInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10093,7 +10114,10 @@ func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, obj in func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Context, obj interface{}) (RecursiveInputSlice, error) { var it RecursiveInputSlice - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10113,7 +10137,10 @@ func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Contex func (ec *executionContext) unmarshalInputSpecialInput(ctx context.Context, obj interface{}) (SpecialInput, error) { var it SpecialInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { @@ -10133,7 +10160,10 @@ func (ec *executionContext) unmarshalInputSpecialInput(ctx context.Context, obj func (ec *executionContext) unmarshalInputValidInput(ctx context.Context, obj interface{}) (ValidInput, error) { var it ValidInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/config/generated.go b/example/config/generated.go index 4e985ada6b1..a00b4fb177e 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -1809,7 +1809,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputNewTodo(ctx context.Context, obj interface{}) (NewTodo, error) { var it NewTodo - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/fileupload/generated.go b/example/fileupload/generated.go index 9610785421c..c53925c44ba 100644 --- a/example/fileupload/generated.go +++ b/example/fileupload/generated.go @@ -1888,7 +1888,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputUploadFile(ctx context.Context, obj interface{}) (model.UploadFile, error) { var it model.UploadFile - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/scalars/generated.go b/example/scalars/generated.go index aa21a4bd1cd..c819142b65b 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -2146,7 +2146,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputSearchArgs(ctx context.Context, obj interface{}) (model.SearchArgs, error) { var it model.SearchArgs - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index 3964d7f1069..ed9e4a4760d 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -3484,7 +3484,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputReviewInput(ctx context.Context, obj interface{}) (models.Review, error) { var it models.Review - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/todo/generated.go b/example/todo/generated.go index cb73c7c6c47..e1214fe3a66 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -1856,7 +1856,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputTodoInput(ctx context.Context, obj interface{}) (TodoInput, error) { var it TodoInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index 2a8cc69338c..ebc4b5727d0 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -1874,7 +1874,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputTodoInput(ctx context.Context, obj interface{}) (TodoInput, error) { var it TodoInput - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } for k, v := range asMap { switch k { diff --git a/integration/generated.go b/integration/generated.go index 160d95ced50..0ff4474329d 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -2013,7 +2013,10 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co func (ec *executionContext) unmarshalInputDateFilter(ctx context.Context, obj interface{}) (models.DateFilter, error) { var it models.DateFilter - var asMap = obj.(map[string]interface{}) + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } if _, present := asMap["timezone"]; !present { asMap["timezone"] = "UTC" From ada1b928096db2d4cff8d476e62d8a84c41da47e Mon Sep 17 00:00:00 2001 From: Aaron Arinder Date: Sun, 7 Feb 2021 14:40:35 -0500 Subject: [PATCH 021/146] getting started: updating wording around implementing unimpl fns --- docs/content/getting-started.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 99a3be37270..821efe02669 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -103,14 +103,15 @@ func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { We just need to implement these two methods to get our server working: -First we need somewhere to track our state, lets put it in `graph/resolver.go`: +First we need somewhere to track our state, lets put it in `graph/resolver.go`. `graph/resolver.go` is where we declare any dependencies for our app, like our database. It gets initialized once in `server.go` when we create the graph. + ```go type Resolver struct{ todos []*model.Todo } ``` -This is where we declare any dependencies for our app like our database, it gets initialized once in `server.go` when -we create the graph. + +Returning to `graph/schema.resolvers.go`, let's implement our unimplemented function bodies: ```go func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { From 5b2531aee84fa4f971ea83c083f7113b2d6b7c6e Mon Sep 17 00:00:00 2001 From: Aaron Arinder Date: Sun, 7 Feb 2021 14:43:34 -0500 Subject: [PATCH 022/146] getting started: wording update --- docs/content/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 821efe02669..7e002273352 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -103,7 +103,7 @@ func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { We just need to implement these two methods to get our server working: -First we need somewhere to track our state, lets put it in `graph/resolver.go`. `graph/resolver.go` is where we declare any dependencies for our app, like our database. It gets initialized once in `server.go` when we create the graph. +First we need somewhere to track our state, lets put it in `graph/resolver.go`. The `graph/resolver.go` file is where we declare our app's dependencies, like our database. It gets initialized once in `server.go` when we create the graph. ```go type Resolver struct{ @@ -111,7 +111,7 @@ type Resolver struct{ } ``` -Returning to `graph/schema.resolvers.go`, let's implement our unimplemented function bodies: +Returning to `graph/schema.resolvers.go`, let's implement the bodies of our automatically generated resolver functions: ```go func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { From aa531ed87f327f0e03d243744a5f5e810d5c1230 Mon Sep 17 00:00:00 2001 From: Aaron Arinder Date: Sun, 7 Feb 2021 14:44:19 -0500 Subject: [PATCH 023/146] getting started: more wording updates --- docs/content/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 7e002273352..caa63c10890 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -111,7 +111,7 @@ type Resolver struct{ } ``` -Returning to `graph/schema.resolvers.go`, let's implement the bodies of our automatically generated resolver functions: +Returning to `graph/schema.resolvers.go`, let's implement the bodies of those automatically generated resolver functions: ```go func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { From 31d339ab390a2c4119fec42c54edabebd96ef730 Mon Sep 17 00:00:00 2001 From: Aaron Arinder Date: Sun, 7 Feb 2021 14:53:54 -0500 Subject: [PATCH 024/146] getting started: make running server own section --- docs/content/getting-started.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 99a3be37270..b7afd9e4831 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -128,12 +128,14 @@ func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { } ``` +### Run the server + We now have a working server, to start it: ```bash go run server.go ``` -then open http://localhost:8080 in a browser. here are some queries to try: +Open http://localhost:8080 in a browser. Here are some queries to try: ```graphql mutation createTodo { createTodo(input:{text:"todo", userId:"1"}) { From 67e652ad974418a9f6fa9cfa4c97eebc3db910bf Mon Sep 17 00:00:00 2001 From: Aaron Arinder Date: Sun, 7 Feb 2021 14:57:18 -0500 Subject: [PATCH 025/146] getting started: separate example mutation/query --- docs/content/getting-started.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index b7afd9e4831..083d1521b3f 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -135,7 +135,7 @@ We now have a working server, to start it: go run server.go ``` -Open http://localhost:8080 in a browser. Here are some queries to try: +Open http://localhost:8080 in a browser. Here are some queries to try, starting with creating a todo: ```graphql mutation createTodo { createTodo(input:{text:"todo", userId:"1"}) { @@ -146,7 +146,11 @@ mutation createTodo { done } } +``` + +And then querying for it: +```graphql query findTodos { todos { text From 41ad51ceefc190b70c4b5fa77c77641ede1d7281 Mon Sep 17 00:00:00 2001 From: Sayan Mallick Date: Tue, 9 Feb 2021 23:13:16 +0530 Subject: [PATCH 026/146] Edited the Gin-Gonic Recipe Docs --- docs/content/recipes/gin.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/content/recipes/gin.md b/docs/content/recipes/gin.md index 2aedd026f6c..76f935cc589 100644 --- a/docs/content/recipes/gin.md +++ b/docs/content/recipes/gin.md @@ -20,6 +20,8 @@ In your router file, define the handlers for the GraphQL and Playground endpoint ```go import ( + "api/graph" + "api/graph/generated" "github.com/gin-gonic/gin" "github.com/99designs/gqlgen/graphql/handler" @@ -30,7 +32,7 @@ import ( func graphqlHandler() gin.HandlerFunc { // NewExecutableSchema and Config are in the generated.go file // Resolver is in the resolver.go file - h := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: &Resolver{}})) + h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) return func(c *gin.Context) { h.ServeHTTP(c.Writer, c.Request) From 971da82c8e3d1cf7cca31bb9cfff91cab2a460d3 Mon Sep 17 00:00:00 2001 From: Sayan Mallick Date: Sat, 13 Feb 2021 10:10:16 +0530 Subject: [PATCH 027/146] Updated gin.md --- docs/content/recipes/gin.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/recipes/gin.md b/docs/content/recipes/gin.md index 76f935cc589..27b073aca78 100644 --- a/docs/content/recipes/gin.md +++ b/docs/content/recipes/gin.md @@ -20,8 +20,8 @@ In your router file, define the handlers for the GraphQL and Playground endpoint ```go import ( - "api/graph" - "api/graph/generated" + "github.com/[username]/gqlgen-todos/graph" // Replace username with your github username + "github.com/[username]/gqlgen-todos/graph/generated" // Replace username with your github username "github.com/gin-gonic/gin" "github.com/99designs/gqlgen/graphql/handler" From 269a58ad547f61b4ceaaa6586ed7898cafc041c1 Mon Sep 17 00:00:00 2001 From: frederikhors <41120635+frederikhors@users.noreply.github.com> Date: Sat, 13 Feb 2021 11:33:43 +0100 Subject: [PATCH 028/146] Add goreportcard badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e6ebdaac1d..b37574b9050 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gqlgen [![Continuous Integration](https://github.com/99designs/gqlgen/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) +# gqlgen [![Continuous Integration](https://github.com/99designs/gqlgen/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) ![gqlgen](https://user-images.githubusercontent.com/46195831/89802919-0bb8ef00-db2a-11ea-8ba4-88e7a58b2fd2.png) From c4bf36c5bd94b64e8d13060a77a7b8ac8050b794 Mon Sep 17 00:00:00 2001 From: frederikhors <41120635+frederikhors@users.noreply.github.com> Date: Sat, 13 Feb 2021 12:00:32 +0100 Subject: [PATCH 029/146] Add coveralls badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e6ebdaac1d..f6d6346911f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gqlgen [![Continuous Integration](https://github.com/99designs/gqlgen/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) +# gqlgen [![Continuous Integration](https://github.com/99designs/gqlgen/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) ![gqlgen](https://user-images.githubusercontent.com/46195831/89802919-0bb8ef00-db2a-11ea-8ba4-88e7a58b2fd2.png) From 45903a6597846c5ae71d82f156fc3ee3b743ec75 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Sat, 6 Mar 2021 11:13:46 +1100 Subject: [PATCH 030/146] Handle nillable list elements --- codegen/type.gotpl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/codegen/type.gotpl b/codegen/type.gotpl index bd5c8435113..f088bbd2489 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -90,11 +90,11 @@ ctx := graphql.WithFieldContext(ctx, fc) f := func(i int) { defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() if !isLen1 { defer wg.Done() } @@ -107,9 +107,16 @@ } {{ else }} ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) - {{- end}} + {{- end }} } {{ if not $type.IsScalar }} wg.Wait() {{ end }} + {{ if $type.Elem.NonNull }} + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + {{ end }} return ret {{- else }} {{- if $type.IsNilable }} From 55b774ba48146540bdef95d8cc027998eca7fd13 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Sat, 6 Mar 2021 11:20:31 +1100 Subject: [PATCH 031/146] Fix type ref --- codegen/type.gotpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/type.gotpl b/codegen/type.gotpl index f088bbd2489..85a7cf6a5f2 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -110,7 +110,7 @@ {{- end }} } {{ if not $type.IsScalar }} wg.Wait() {{ end }} - {{ if $type.Elem.NonNull }} + {{ if $type.Elem.GQL.NonNull }} for _, e := range ret { if e == graphql.Null { return graphql.Null From 0b5da15cd87f315af0bc851a50f21362e4312002 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Sat, 6 Mar 2021 12:10:13 +1100 Subject: [PATCH 032/146] Check in generated code --- codegen/testserver/generated.go | 106 +++++++++++++++++ example/chat/generated.go | 63 ++++++++++ example/config/generated.go | 69 +++++++++++ example/dataloader/generated.go | 84 +++++++++++++ .../accounts/graph/generated/generated.go | 63 ++++++++++ .../products/graph/generated/generated.go | 64 ++++++++++ .../reviews/graph/generated/generated.go | 64 ++++++++++ example/fileupload/generated.go | 69 +++++++++++ example/scalars/generated.go | 63 ++++++++++ example/selection/generated.go | 69 +++++++++++ example/starwars/generated/exec.go | 110 ++++++++++++++++++ example/todo/generated.go | 63 ++++++++++ example/type-system-extension/generated.go | 63 ++++++++++ integration/generated.go | 69 +++++++++++ 14 files changed, 1019 insertions(+) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index ea3c2f48547..2aac317f20b 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -13389,6 +13389,12 @@ func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋg ret[i] = ec.marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13445,6 +13451,13 @@ func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13486,6 +13499,13 @@ func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designs } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13551,6 +13571,12 @@ func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ret[i] = ec.marshalNString2string(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13673,6 +13699,13 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13774,6 +13807,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13847,6 +13887,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13896,6 +13943,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -13937,6 +13991,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14054,6 +14115,7 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs } wg.Wait() + return ret } @@ -14094,6 +14156,13 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14359,6 +14428,7 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99design } wg.Wait() + return ret } @@ -14399,6 +14469,7 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designs } wg.Wait() + return ret } @@ -14499,6 +14570,7 @@ func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + return ret } @@ -14551,6 +14623,12 @@ func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ret[i] = ec.marshalNString2string(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14710,6 +14788,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14750,6 +14835,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14790,6 +14882,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -14837,6 +14936,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/chat/generated.go b/example/chat/generated.go index 842b3e31ff9..9d162affae0 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -2447,6 +2447,13 @@ func (ec *executionContext) marshalNMessage2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2528,6 +2535,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2601,6 +2615,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2650,6 +2671,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2691,6 +2719,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2811,6 +2846,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2851,6 +2893,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2891,6 +2940,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2938,6 +2994,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/config/generated.go b/example/config/generated.go index 4e985ada6b1..00a1145a3ea 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -2354,6 +2354,13 @@ func (ec *executionContext) marshalNTodo2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2415,6 +2422,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2488,6 +2502,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2537,6 +2558,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2578,6 +2606,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2672,6 +2707,12 @@ func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ret[i] = ec.marshalNString2string(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2727,6 +2768,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2767,6 +2815,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2807,6 +2862,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2854,6 +2916,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index ef964a60ae8..342ac7cc389 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -2695,6 +2695,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2768,6 +2775,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2817,6 +2831,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2858,6 +2879,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2954,6 +2982,7 @@ func (ec *executionContext) marshalOCustomer2ᚕᚕᚖgithubᚗcomᚋ99designs } wg.Wait() + return ret } @@ -2994,6 +3023,13 @@ func (ec *executionContext) marshalOCustomer2ᚕᚖgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3030,6 +3066,12 @@ func (ec *executionContext) marshalOInt2ᚕintᚄ(ctx context.Context, sel ast.S ret[i] = ec.marshalNInt2int(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3106,6 +3148,13 @@ func (ec *executionContext) marshalOItem2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3146,6 +3195,13 @@ func (ec *executionContext) marshalOOrder2ᚕᚖgithubᚗcomᚋ99designsᚋgqlge } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3210,6 +3266,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3250,6 +3313,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3290,6 +3360,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3337,6 +3414,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index ddc536f26b8..1d64bbeda50 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -2276,6 +2276,12 @@ func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast. ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2313,6 +2319,7 @@ func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + return ret } @@ -2373,6 +2380,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2446,6 +2460,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2495,6 +2516,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2536,6 +2564,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2663,6 +2698,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2703,6 +2745,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2743,6 +2792,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2790,6 +2846,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 7a62335fdad..92c126f7aa3 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -2352,6 +2352,12 @@ func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast. ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2389,6 +2395,7 @@ func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + return ret } @@ -2449,6 +2456,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2522,6 +2536,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2571,6 +2592,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2612,6 +2640,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2716,6 +2751,7 @@ func (ec *executionContext) marshalOProduct2ᚕᚖgithubᚗcomᚋ99designsᚋgql } wg.Wait() + return ret } @@ -2794,6 +2830,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2834,6 +2877,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2874,6 +2924,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2921,6 +2978,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 8173a30dd32..192d961498f 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -2639,6 +2639,12 @@ func (ec *executionContext) marshalN_Any2ᚕmapᚄ(ctx context.Context, sel ast. ret[i] = ec.marshalN_Any2map(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2676,6 +2682,7 @@ func (ec *executionContext) marshalN_Entity2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + return ret } @@ -2736,6 +2743,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2809,6 +2823,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2858,6 +2879,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2899,6 +2927,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2988,6 +3023,7 @@ func (ec *executionContext) marshalOReview2ᚕᚖgithubᚗcomᚋ99designsᚋgqlg } wg.Wait() + return ret } @@ -3066,6 +3102,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3106,6 +3149,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3146,6 +3196,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3193,6 +3250,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/fileupload/generated.go b/example/fileupload/generated.go index 9610785421c..bb3f308cfc1 100644 --- a/example/fileupload/generated.go +++ b/example/fileupload/generated.go @@ -2352,6 +2352,13 @@ func (ec *executionContext) marshalNFile2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2437,6 +2444,12 @@ func (ec *executionContext) marshalNUpload2ᚕᚖgithubᚗcomᚋ99designsᚋgqlg ret[i] = ec.marshalNUpload2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚐUpload(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2530,6 +2543,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2603,6 +2623,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2652,6 +2679,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2693,6 +2727,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2806,6 +2847,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2846,6 +2894,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2886,6 +2941,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2933,6 +2995,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index aa21a4bd1cd..0773ab3b4dd 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -2754,6 +2754,13 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2805,6 +2812,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2878,6 +2892,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2927,6 +2948,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2968,6 +2996,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3184,6 +3219,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3224,6 +3266,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3264,6 +3313,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3311,6 +3367,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/selection/generated.go b/example/selection/generated.go index 053bf1dbf70..ddbd977d5d2 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -2218,6 +2218,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2291,6 +2298,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2340,6 +2354,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2381,6 +2402,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2470,6 +2498,13 @@ func (ec *executionContext) marshalOEvent2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2515,6 +2550,12 @@ func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ret[i] = ec.marshalNString2string(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2570,6 +2611,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2610,6 +2658,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2650,6 +2705,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2697,6 +2759,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index 3964d7f1069..d82d169b60b 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -4401,6 +4401,13 @@ func (ec *executionContext) marshalNEpisode2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4500,6 +4507,12 @@ func (ec *executionContext) marshalNInt2ᚕintᚄ(ctx context.Context, sel ast.S ret[i] = ec.marshalNInt2int(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4530,6 +4543,12 @@ func (ec *executionContext) marshalNInt2ᚕᚕintᚄ(ctx context.Context, sel as ret[i] = ec.marshalNInt2ᚕintᚄ(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4571,6 +4590,13 @@ func (ec *executionContext) marshalNReview2ᚕᚖgithubᚗcomᚋ99designsᚋgqlg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4633,6 +4659,13 @@ func (ec *executionContext) marshalNSearchResult2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4699,6 +4732,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4772,6 +4812,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4821,6 +4868,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4862,6 +4916,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -4958,6 +5019,13 @@ func (ec *executionContext) marshalOCharacter2ᚕgithubᚗcomᚋ99designsᚋgqlg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5030,6 +5098,13 @@ func (ec *executionContext) marshalOFriendsEdge2ᚕᚖgithubᚗcomᚋ99designs } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5140,6 +5215,13 @@ func (ec *executionContext) marshalOStarship2ᚕᚖgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5235,6 +5317,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5275,6 +5364,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5315,6 +5411,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -5362,6 +5465,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/todo/generated.go b/example/todo/generated.go index cb73c7c6c47..2e5ceeb2300 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -2385,6 +2385,13 @@ func (ec *executionContext) marshalNTodo2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2441,6 +2448,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2514,6 +2528,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2563,6 +2584,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2604,6 +2632,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2724,6 +2759,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2764,6 +2806,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2804,6 +2853,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2851,6 +2907,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index 2a8cc69338c..eb50a955fc6 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -2398,6 +2398,13 @@ func (ec *executionContext) marshalNTodo2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2454,6 +2461,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2527,6 +2541,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2576,6 +2597,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2617,6 +2645,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2737,6 +2772,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2777,6 +2819,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2817,6 +2866,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2864,6 +2920,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } diff --git a/integration/generated.go b/integration/generated.go index 160d95ced50..94a65076232 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -2632,6 +2632,12 @@ func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ret[i] = ec.marshalNString2string(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2673,6 +2679,13 @@ func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2746,6 +2759,13 @@ func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2795,6 +2815,13 @@ func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2836,6 +2863,13 @@ func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2906,6 +2940,12 @@ func (ec *executionContext) marshalOBoolean2ᚕboolᚄ(ctx context.Context, sel ret[i] = ec.marshalNBoolean2bool(ctx, sel, v[i]) } + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -2977,6 +3017,7 @@ func (ec *executionContext) marshalOElement2ᚕᚖgithubᚗcomᚋ99designsᚋgql } wg.Wait() + return ret } @@ -3093,6 +3134,13 @@ func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgq } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3133,6 +3181,13 @@ func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3173,6 +3228,13 @@ func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋg } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } @@ -3220,6 +3282,13 @@ func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgen } wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + return ret } From 635b1aef316c528b6f17416057d41a0948b42a2d Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Sat, 6 Mar 2021 12:51:20 +1100 Subject: [PATCH 033/146] Add Test Case --- codegen/testserver/generated.go | 105 ++++++++++++++++++++++++++++-- codegen/testserver/nulls.graphql | 1 + codegen/testserver/nulls_test.go | 16 ++++- codegen/testserver/resolver.go | 4 ++ codegen/testserver/slices.graphql | 8 +-- codegen/testserver/stub.go | 4 ++ 6 files changed, 129 insertions(+), 9 deletions(-) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 2aac317f20b..21876449d4f 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -278,6 +278,7 @@ type ComplexityRoot struct { EmbeddedCase3 func(childComplexity int) int EnumInInput func(childComplexity int, input *InputWithEnumValue) int ErrorBubble func(childComplexity int) int + ErrorBubbleList func(childComplexity int) int Errors func(childComplexity int) int Fallback func(childComplexity int, arg FallbackToStringEncoding) int InputNullableSlice func(childComplexity int, arg []string) int @@ -457,6 +458,7 @@ type QueryResolver interface { MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble(ctx context.Context) (*Error, error) + ErrorBubbleList(ctx context.Context) ([]*Error, error) Errors(ctx context.Context) (*Errors, error) Valid(ctx context.Context) (string, error) Panics(ctx context.Context) (*Panics, error) @@ -1199,6 +1201,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ErrorBubble(childComplexity), true + case "Query.errorBubbleList": + if e.complexity.Query.ErrorBubbleList == nil { + break + } + + return e.complexity.Query.ErrorBubbleList(childComplexity), true + case "Query.errors": if e.complexity.Query.Errors == nil { break @@ -2039,6 +2048,7 @@ input NestedInput { `, BuiltIn: false}, {Name: "nulls.graphql", Input: `extend type Query { errorBubble: Error + errorBubbleList: [Error!] errors: Errors valid: String! } @@ -2204,10 +2214,10 @@ scalar Time } type Slices { - test1: [String] - test2: [String!] - test3: [String]! - test4: [String!]! + test1: [String] + test2: [String!] + test3: [String]! + test4: [String!]! } scalar Bytes @@ -7212,6 +7222,35 @@ func (ec *executionContext) _Query_errorBubble(ctx context.Context, field graphq return ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) } +func (ec *executionContext) _Query_errorBubbleList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ErrorBubbleList(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*Error) + fc.Result = res + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_errors(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12266,6 +12305,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_errorBubble(ctx, field) return res }) + case "errorBubbleList": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errorBubbleList(ctx, field) + return res + }) case "errors": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -14216,6 +14266,53 @@ func (ec *executionContext) marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋ return ec._EmbeddedCase3(ctx, sel, v) } +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/codegen/testserver/nulls.graphql b/codegen/testserver/nulls.graphql index d93f6b0cf62..0f1af3dd30d 100644 --- a/codegen/testserver/nulls.graphql +++ b/codegen/testserver/nulls.graphql @@ -1,5 +1,6 @@ extend type Query { errorBubble: Error + errorBubbleList: [Error!] errors: Errors valid: String! } diff --git a/codegen/testserver/nulls_test.go b/codegen/testserver/nulls_test.go index e79eecc283a..5bf2112ae6d 100644 --- a/codegen/testserver/nulls_test.go +++ b/codegen/testserver/nulls_test.go @@ -14,13 +14,15 @@ func TestNullBubbling(t *testing.T) { resolvers.QueryResolver.Valid = func(ctx context.Context) (s string, e error) { return "Ok", nil } - resolvers.QueryResolver.Errors = func(ctx context.Context) (errors *Errors, e error) { return &Errors{}, nil } resolvers.QueryResolver.ErrorBubble = func(ctx context.Context) (i *Error, e error) { return &Error{ID: "E1234"}, nil } + resolvers.QueryResolver.ErrorBubbleList = func(ctx context.Context) (i []*Error, e error) { + return []*Error{nil}, nil + } c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) @@ -68,6 +70,18 @@ func TestNullBubbling(t *testing.T) { require.Equal(t, "Ok", resp.Valid) }) + t.Run("when non-null list element is null", func(t *testing.T) { + var resp struct { + Valid string + ErrorBubbleList []*struct{} + } + err := c.Post(`query { valid, errorBubbleList { id } }`, &resp) + + require.EqualError(t, err, `[{"message":"must not be null","path":["errorBubbleList", 0]}]`) + require.Nil(t, resp.ErrorBubbleList) + require.Equal(t, "Ok", resp.Valid) + }) + t.Run("null args", func(t *testing.T) { var resp struct { NullableArg *string diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index 952d20943e8..edc4001f51b 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -232,6 +232,10 @@ func (r *queryResolver) ErrorBubble(ctx context.Context) (*Error, error) { panic("not implemented") } +func (r *queryResolver) ErrorBubbleList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + func (r *queryResolver) Errors(ctx context.Context) (*Errors, error) { panic("not implemented") } diff --git a/codegen/testserver/slices.graphql b/codegen/testserver/slices.graphql index 671235d0b37..b1265c56c0b 100644 --- a/codegen/testserver/slices.graphql +++ b/codegen/testserver/slices.graphql @@ -4,10 +4,10 @@ extend type Query { } type Slices { - test1: [String] - test2: [String!] - test3: [String]! - test4: [String!]! + test1: [String] + test2: [String!] + test3: [String]! + test4: [String!]! } scalar Bytes diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index daf4052ea08..5ca93fd8046 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -85,6 +85,7 @@ type Stub struct { MapStringInterface func(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) MapNestedStringInterface func(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble func(ctx context.Context) (*Error, error) + ErrorBubbleList func(ctx context.Context) ([]*Error, error) Errors func(ctx context.Context) (*Errors, error) Valid func(ctx context.Context) (string, error) Panics func(ctx context.Context) (*Panics, error) @@ -358,6 +359,9 @@ func (r *stubQuery) MapNestedStringInterface(ctx context.Context, in *NestedMapI func (r *stubQuery) ErrorBubble(ctx context.Context) (*Error, error) { return r.QueryResolver.ErrorBubble(ctx) } +func (r *stubQuery) ErrorBubbleList(ctx context.Context) ([]*Error, error) { + return r.QueryResolver.ErrorBubbleList(ctx) +} func (r *stubQuery) Errors(ctx context.Context) (*Errors, error) { return r.QueryResolver.Errors(ctx) } From 469e31bddf27395e5d124694e683cecc44fa00d3 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Sat, 6 Mar 2021 13:00:03 +1100 Subject: [PATCH 034/146] Fix bad test case --- codegen/testserver/nulls_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/testserver/nulls_test.go b/codegen/testserver/nulls_test.go index 5bf2112ae6d..00fccb519c4 100644 --- a/codegen/testserver/nulls_test.go +++ b/codegen/testserver/nulls_test.go @@ -77,7 +77,7 @@ func TestNullBubbling(t *testing.T) { } err := c.Post(`query { valid, errorBubbleList { id } }`, &resp) - require.EqualError(t, err, `[{"message":"must not be null","path":["errorBubbleList", 0]}]`) + require.EqualError(t, err, `[{"message":"must not be null","path":["errorBubbleList",0]}]`) require.Nil(t, resp.ErrorBubbleList) require.Equal(t, "Ok", resp.Valid) }) From 1fac78e9b4d68a76d3ae2fc0b980e7569cc3eb3c Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Mon, 8 Mar 2021 10:38:46 +1100 Subject: [PATCH 035/146] Add test case for nullable field --- codegen/testserver/generated.go | 91 ++++++++++++++++++++++++++++++++ codegen/testserver/nulls.graphql | 1 + codegen/testserver/nulls_test.go | 18 ++++++- codegen/testserver/resolver.go | 4 ++ codegen/testserver/stub.go | 4 ++ 5 files changed, 117 insertions(+), 1 deletion(-) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 21876449d4f..b14d6110e55 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -279,6 +279,7 @@ type ComplexityRoot struct { EnumInInput func(childComplexity int, input *InputWithEnumValue) int ErrorBubble func(childComplexity int) int ErrorBubbleList func(childComplexity int) int + ErrorList func(childComplexity int) int Errors func(childComplexity int) int Fallback func(childComplexity int, arg FallbackToStringEncoding) int InputNullableSlice func(childComplexity int, arg []string) int @@ -459,6 +460,7 @@ type QueryResolver interface { MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble(ctx context.Context) (*Error, error) ErrorBubbleList(ctx context.Context) ([]*Error, error) + ErrorList(ctx context.Context) ([]*Error, error) Errors(ctx context.Context) (*Errors, error) Valid(ctx context.Context) (string, error) Panics(ctx context.Context) (*Panics, error) @@ -1208,6 +1210,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.ErrorBubbleList(childComplexity), true + case "Query.errorList": + if e.complexity.Query.ErrorList == nil { + break + } + + return e.complexity.Query.ErrorList(childComplexity), true + case "Query.errors": if e.complexity.Query.Errors == nil { break @@ -2049,6 +2058,7 @@ input NestedInput { {Name: "nulls.graphql", Input: `extend type Query { errorBubble: Error errorBubbleList: [Error!] + errorList: [Error] errors: Errors valid: String! } @@ -7251,6 +7261,35 @@ func (ec *executionContext) _Query_errorBubbleList(ctx context.Context, field gr return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx, field.Selections, res) } +func (ec *executionContext) _Query_errorList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ErrorList(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*Error) + fc.Result = res + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_errors(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12316,6 +12355,17 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_errorBubbleList(ctx, field) return res }) + case "errorList": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errorList(ctx, field) + return res + }) case "errors": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -14266,6 +14316,47 @@ func (ec *executionContext) marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋ return ec._EmbeddedCase3(ctx, sel, v) } +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/codegen/testserver/nulls.graphql b/codegen/testserver/nulls.graphql index 0f1af3dd30d..a1fea680ce2 100644 --- a/codegen/testserver/nulls.graphql +++ b/codegen/testserver/nulls.graphql @@ -1,6 +1,7 @@ extend type Query { errorBubble: Error errorBubbleList: [Error!] + errorList: [Error] errors: Errors valid: String! } diff --git a/codegen/testserver/nulls_test.go b/codegen/testserver/nulls_test.go index 00fccb519c4..4822829d174 100644 --- a/codegen/testserver/nulls_test.go +++ b/codegen/testserver/nulls_test.go @@ -23,6 +23,9 @@ func TestNullBubbling(t *testing.T) { resolvers.QueryResolver.ErrorBubbleList = func(ctx context.Context) (i []*Error, e error) { return []*Error{nil}, nil } + resolvers.QueryResolver.ErrorList = func(ctx context.Context) (i []*Error, e error) { + return []*Error{nil}, nil + } c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) @@ -70,6 +73,19 @@ func TestNullBubbling(t *testing.T) { require.Equal(t, "Ok", resp.Valid) }) + t.Run("when list element is null", func(t *testing.T) { + var resp struct { + Valid string + ErrorList []*struct{} + } + err := c.Post(`query { valid, errorList { id } }`, &resp) + + require.Nil(t, err) + require.Equal(t, len(resp.ErrorList), 1) + require.Nil(t, resp.ErrorList[0]) + require.Equal(t, "Ok", resp.Valid) + }) + t.Run("when non-null list element is null", func(t *testing.T) { var resp struct { Valid string @@ -104,7 +120,7 @@ func TestNullBubbling(t *testing.T) { resolvers.ErrorsResolver.D = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } resolvers.ErrorsResolver.E = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } - err := c.Post(`{ errors { + err := c.Post(`{ errors { a { id }, b { id }, c { id }, diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index edc4001f51b..7b197d0c9cf 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -236,6 +236,10 @@ func (r *queryResolver) ErrorBubbleList(ctx context.Context) ([]*Error, error) { panic("not implemented") } +func (r *queryResolver) ErrorList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + func (r *queryResolver) Errors(ctx context.Context) (*Errors, error) { panic("not implemented") } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 5ca93fd8046..4b584fbbbf6 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -86,6 +86,7 @@ type Stub struct { MapNestedStringInterface func(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) ErrorBubble func(ctx context.Context) (*Error, error) ErrorBubbleList func(ctx context.Context) ([]*Error, error) + ErrorList func(ctx context.Context) ([]*Error, error) Errors func(ctx context.Context) (*Errors, error) Valid func(ctx context.Context) (string, error) Panics func(ctx context.Context) (*Panics, error) @@ -362,6 +363,9 @@ func (r *stubQuery) ErrorBubble(ctx context.Context) (*Error, error) { func (r *stubQuery) ErrorBubbleList(ctx context.Context) ([]*Error, error) { return r.QueryResolver.ErrorBubbleList(ctx) } +func (r *stubQuery) ErrorList(ctx context.Context) ([]*Error, error) { + return r.QueryResolver.ErrorList(ctx) +} func (r *stubQuery) Errors(ctx context.Context) (*Errors, error) { return r.QueryResolver.Errors(ctx) } From 82a8e1bf39aec5225e05deb8e026083d859d50ef Mon Sep 17 00:00:00 2001 From: Michael Compton Date: Mon, 15 Mar 2021 15:04:14 +1100 Subject: [PATCH 036/146] Make it clearer what happened on init. (#1487) --- docs/content/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 92f99ded949..76f5bd39c42 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -85,8 +85,8 @@ type Mutation { ### Implement the resolvers -`gqlgen generate` compares the schema file (`graph/schema.graphqls`) with the models `graph/model/*` and wherever it -can it will bind directly to the model. +When executed, gqlgen's `generate` command compares the schema file (`graph/schema.graphqls`) with the models `graph/model/*`, and, wherever it +can, it will bind directly to the model. That was done alread when `init` was run. We'll edit the schema later in the tutorial, but for now, let's look at what was generated already. If we take a look in `graph/schema.resolvers.go` we will see all the times that gqlgen couldn't match them up. For us it was twice: From b995f7f1fa2e18b4016d167739213ec5de95a053 Mon Sep 17 00:00:00 2001 From: Michael Compton Date: Mon, 15 Mar 2021 17:09:56 +1100 Subject: [PATCH 037/146] Make spacing consistent (#1488) --- docs/content/reference/complexity.md | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/content/reference/complexity.md b/docs/content/reference/complexity.md index 81367c1cccd..e99ac130587 100644 --- a/docs/content/reference/complexity.md +++ b/docs/content/reference/complexity.md @@ -13,13 +13,13 @@ Consider a schema that allows listing blog posts. Each blog post is also related ```graphql type Query { - posts(count: Int = 10): [Post!]! + posts(count: Int = 10): [Post!]! } type Post { - title: String! - text: String! - related(count: Int = 10): [Post!]! + title: String! + text: String! + related(count: Int = 10): [Post!]! } ``` @@ -27,15 +27,15 @@ It's not too hard to craft a query that will cause a very large response: ```graphql { - posts(count: 100) { - related(count: 100) { - related(count: 100) { - related(count: 100) { - title - } - } - } - } + posts(count: 100) { + related(count: 100) { + related(count: 100) { + related(count: 100) { + title + } + } + } + } } ``` @@ -47,12 +47,12 @@ Limiting query complexity is as simple as specifying it with the provided extens ```go func main() { - c := Config{ Resolvers: &resolvers{} } + c := Config{ Resolvers: &resolvers{} } srv := handler.NewDefaultServer(blog.NewExecutableSchema(c)) srv.Use(extension.FixedComplexityLimit(5)) // This line is key - r.Handle("/query", srv) + r.Handle("/query", srv) } ``` @@ -66,17 +66,17 @@ To apply higher costs to certain fields, we can use custom complexity functions. ```go func main() { - c := Config{ Resolvers: &resolvers{} } + c := Config{ Resolvers: &resolvers{} } - countComplexity := func(childComplexity, count int) int { - return count * childComplexity - } - c.Complexity.Query.Posts = countComplexity - c.Complexity.Post.Related = countComplexity + countComplexity := func(childComplexity, count int) int { + return count * childComplexity + } + c.Complexity.Query.Posts = countComplexity + c.Complexity.Post.Related = countComplexity - srv := handler.NewDefaultServer(blog.NewExecutableSchema(c)) + srv := handler.NewDefaultServer(blog.NewExecutableSchema(c)) srv.Use(extension.FixedComplexityLimit(5)) - http.Handle("/query", gqlHandler) + http.Handle("/query", gqlHandler) } ``` From 7985db44855b160c1f2552bedbfed5bc150fc840 Mon Sep 17 00:00:00 2001 From: Michael Compton Date: Tue, 16 Mar 2021 09:38:18 +1100 Subject: [PATCH 038/146] Mention math.rand for the todo ID (#1489) --- docs/content/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 80122ba7632..5192de632cf 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -111,7 +111,7 @@ type Resolver struct{ } ``` -Returning to `graph/schema.resolvers.go`, let's implement the bodies of those automatically generated resolver functions: +Returning to `graph/schema.resolvers.go`, let's implement the bodies of those automatically generated resolver functions. For `CreateTodo`, we'll use `math.rand` to simply return a todo with a randomly generated ID and store that in the in-memory todos list --- in a real app, you're likely to use a database or some other backend service. ```go func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { From 54e387c45e97e7b7922f06baf1c6e57dd5a7ff2e Mon Sep 17 00:00:00 2001 From: KzKarino Date: Sat, 20 Mar 2021 21:20:12 +0900 Subject: [PATCH 039/146] Resolve indirect dependency vulnerability in example --- go.mod | 6 +++--- go.sum | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cb8e7ce0137..ad97c98e735 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.12 require ( github.com/agnivade/levenshtein v1.0.3 // indirect - github.com/gogo/protobuf v1.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect github.com/gorilla/mux v1.6.1 // indirect github.com/gorilla/websocket v1.4.2 @@ -24,8 +24,8 @@ require ( github.com/urfave/cli/v2 v2.1.1 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e github.com/vektah/gqlparser/v2 v2.1.0 - golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 + golang.org/x/tools v0.0.0-20210106214847-113979e3529a gopkg.in/yaml.v2 v2.2.4 - sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755 + sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 // indirect sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect ) diff --git a/go.sum b/go.sum index 707488e6c26..345d4c68387 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMN github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.1 h1:KOwqsTYZdeuMacU7CxjMNYEKeBvLbxW+psodrbcEa3A= @@ -23,6 +25,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -69,25 +73,44 @@ github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWp github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns= github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -96,5 +119,7 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755 h1:d2maSb13hr/ArmfK3rW+wNUKKfytCol7W1/vDHxMPiE= sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= From 03b57f3e01f34504261550aacb0b08f64843b6ad Mon Sep 17 00:00:00 2001 From: KzKarino Date: Sat, 20 Mar 2021 22:22:16 +0900 Subject: [PATCH 040/146] Run go mod tidy --- go.mod | 2 +- go.sum | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index ad97c98e735..f77773be11e 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,6 @@ require ( github.com/vektah/gqlparser/v2 v2.1.0 golang.org/x/tools v0.0.0-20210106214847-113979e3529a gopkg.in/yaml.v2 v2.2.4 - sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 // indirect + sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect ) diff --git a/go.sum b/go.sum index 345d4c68387..6dbb9486152 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= @@ -78,8 +76,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -96,6 +94,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -103,13 +102,13 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM= -golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= @@ -117,8 +116,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755 h1:d2maSb13hr/ArmfK3rW+wNUKKfytCol7W1/vDHxMPiE= -sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= From 8c3e64e1965081ff07bbe9353dd9246817232887 Mon Sep 17 00:00:00 2001 From: Joe Zhou Date: Sun, 21 Mar 2021 01:26:48 -0400 Subject: [PATCH 041/146] Improve APQ documentation --- docs/content/reference/apq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/content/reference/apq.md b/docs/content/reference/apq.md index 32df5effc04..2be30fa2429 100644 --- a/docs/content/reference/apq.md +++ b/docs/content/reference/apq.md @@ -16,8 +16,8 @@ to register query hash with original query on a server. In order to enable Automatic Persisted Queries you need to change your client. For more information see [Automatic Persisted Queries Link](https://github.com/apollographql/apollo-link-persisted-queries) documentation. -For the server you need to implement `PersistedQueryCache` interface and pass instance to -`handler.EnablePersistedQueryCache` option. +For the server you need to implement the `graphql.Cache` interface and pass an instance to +the `extension.AutomaticPersistedQuery` type. Make sure the extension is applied to your GraphQL handler. See example using [go-redis](https://github.com/go-redis/redis) package below: ```go From e02db808a857ce1ec31861b3b0b54fa4d5cb85e6 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Tue, 30 Mar 2021 13:00:26 +1100 Subject: [PATCH 042/146] Run go mod tidy after code generation --- .github/workflows/check-init | 12 ++++++++++++ .github/workflows/integration.yml | 8 ++++++++ api/generate.go | 3 +++ example/init/go.mod | 5 +++++ internal/code/packages.go | 10 ++++++++++ 5 files changed, 38 insertions(+) create mode 100755 .github/workflows/check-init create mode 100644 example/init/go.mod diff --git a/.github/workflows/check-init b/.github/workflows/check-init new file mode 100755 index 00000000000..9c09e84f407 --- /dev/null +++ b/.github/workflows/check-init @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +cd example/init + +go get github.com/99designs/gqlgen + +if { go run github.com/99designs/gqlgen init 2>&1 >&3 3>&- | grep '^' >&2; } 3>&1; then + echo "gqlgen init failed validation" + exit 125 +fi diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 273e4f5f4e8..8000b49bd50 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -22,3 +22,11 @@ jobs: - run: go mod download - run: cd example/federation ; npm install - run: .github/workflows/check-federation + + init: + runs-on: ubuntu-latest + container: golang:1.16-alpine + steps: + - uses: actions/checkout@v1 + - run: apk add --no-cache --no-progress alpine-sdk bash + - run: .github/workflows/check-init diff --git a/api/generate.go b/api/generate.go index 3a19c017de9..d9484005173 100644 --- a/api/generate.go +++ b/api/generate.go @@ -77,6 +77,9 @@ func Generate(cfg *config.Config, option ...Option) error { if err = codegen.GenerateCode(data); err != nil { return errors.Wrap(err, "generating core failed") } + if err = cfg.Packages.ModTidy(); err != nil { + return errors.Wrap(err, "tidy failed") + } for _, p := range plugins { if mut, ok := p.(plugin.CodeGenerator); ok { diff --git a/example/init/go.mod b/example/init/go.mod new file mode 100644 index 00000000000..40eb45b4f85 --- /dev/null +++ b/example/init/go.mod @@ -0,0 +1,5 @@ +module gqlgen.com/inittest + +go 1.16 + +replace github.com/99designs/gqlgen => ../.. diff --git a/internal/code/packages.go b/internal/code/packages.go index b14c45ad276..d3a4058530b 100644 --- a/internal/code/packages.go +++ b/internal/code/packages.go @@ -2,6 +2,7 @@ package code import ( "bytes" + "os/exec" "path/filepath" "github.com/pkg/errors" @@ -149,6 +150,15 @@ func (p *Packages) Evict(importPath string) { } } +func (p *Packages) ModTidy() error { + p.packages = nil + tidyCmd := exec.Command("go", "mod", "tidy") + if err := tidyCmd.Run(); err != nil { + return errors.Wrap(err, "go mod tidy failed") + } + return nil +} + // Errors returns any errors that were returned by Load, either from the call itself or any of the loaded packages. func (p *Packages) Errors() PkgErrors { var res []error //nolint:prealloc From 5f21f9d9ecdedca84810d7fda605c6eddd1f2335 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Tue, 30 Mar 2021 17:28:38 +1100 Subject: [PATCH 043/146] Remove chi from dataloader example --- example/dataloader/server/server.go | 6 ++---- go.mod | 1 - go.sum | 10 ---------- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/example/dataloader/server/server.go b/example/dataloader/server/server.go index d599330ff90..a11d46a0fe5 100644 --- a/example/dataloader/server/server.go +++ b/example/dataloader/server/server.go @@ -7,12 +7,10 @@ import ( "github.com/99designs/gqlgen/example/dataloader" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" - "github.com/go-chi/chi" ) func main() { - router := chi.NewRouter() - router.Use(dataloader.LoaderMiddleware) + router := http.NewServeMux() router.Handle("/", playground.Handler("Dataloader", "/query")) router.Handle("/query", handler.NewDefaultServer( @@ -20,5 +18,5 @@ func main() { )) log.Println("connect to http://localhost:8082/ for graphql playground") - log.Fatal(http.ListenAndServe(":8082", router)) + log.Fatal(http.ListenAndServe(":8082", dataloader.LoaderMiddleware(router))) } diff --git a/go.mod b/go.mod index 3130a194457..cb8e7ce0137 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.12 require ( github.com/agnivade/levenshtein v1.0.3 // indirect - github.com/go-chi/chi v1.5.1 github.com/gogo/protobuf v1.0.0 // indirect github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect github.com/gorilla/mux v1.6.1 // indirect diff --git a/go.sum b/go.sum index 8fcfa821c17..707488e6c26 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,4 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= @@ -9,14 +8,11 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= -github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= @@ -64,7 +60,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 h1:JJV9CsgM9EC9w2iVkwuz+sMx8yRFe89PJRUrv6hPCIA= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -77,7 +72,6 @@ github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4Xk golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= @@ -89,18 +83,14 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6 h1:iZgcI2DDp6zW5v9Z/5+f0NuqoxNdmzg4hivjk2WLXpY= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd h1:oMEQDWVXVNpceQoVd1JN3CQ7LYJJzs5qWqZIUcxXHHw= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM= golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 3cfc5b14d89ff8250656e40f967d1b0fae9de374 Mon Sep 17 00:00:00 2001 From: Ariel Mashraki Date: Sun, 11 Apr 2021 13:48:51 +0300 Subject: [PATCH 044/146] codegen/config: restore current working directory after changing it Before this commit, a call to config.LoadConfigFromDefaultLocations changed the working directory to the directory that contains the gqlgen config file. This commit changes the implementation to restore the working directory after loading the config. --- codegen/config/config.go | 24 +++++++++++++++--------- codegen/config/config_test.go | 5 +++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index ba939fcf59a..24ea9e7ef04 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -70,8 +70,8 @@ func LoadDefaultConfig() (*Config, error) { // LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories // walking up the tree. The closest config file will be returned. -func LoadConfigFromDefaultLocations() (*Config, error) { - cfgFile, err := findCfg() +func LoadConfigFromDefaultLocations() (cfg *Config, err error) { + cfgFile, cwd, err := findCfg() if err != nil { return nil, err } @@ -80,6 +80,12 @@ func LoadConfigFromDefaultLocations() (*Config, error) { if err != nil { return nil, errors.Wrap(err, "unable to enter config dir") } + defer func() { + if cerr := os.Chdir(cwd); cerr != nil { + cfg = nil + err = errors.Wrap(cerr, "unable to restore working directory") + } + }() return LoadConfig(cfgFile) } @@ -467,24 +473,24 @@ func inStrSlice(haystack []string, needle string) bool { // findCfg searches for the config file in this directory and all parents up the tree // looking for the closest match -func findCfg() (string, error) { - dir, err := os.Getwd() +func findCfg() (string, string, error) { + cwd, err := os.Getwd() if err != nil { - return "", errors.Wrap(err, "unable to get working dir to findCfg") + return "", "", errors.Wrap(err, "unable to get working dir to findCfg") } - cfg := findCfgInDir(dir) + cfg := findCfgInDir(cwd) - for cfg == "" && dir != filepath.Dir(dir) { + for dir := cwd; cfg == "" && dir != filepath.Dir(dir); { dir = filepath.Dir(dir) cfg = findCfgInDir(dir) } if cfg == "" { - return "", os.ErrNotExist + return "", "", os.ErrNotExist } - return cfg, nil + return cfg, cwd, nil } func findCfgInDir(dir string) string { diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index b16e90c11a5..de63b15d3f0 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -72,9 +72,14 @@ func TestLoadConfigFromDefaultLocation(t *testing.T) { err = os.Chdir(filepath.Join(testDir, "testdata", "cfg", "otherdir")) require.NoError(t, err) + before, err := os.Getwd() + require.NoError(t, err) cfg, err = LoadConfigFromDefaultLocations() require.NoError(t, err) require.Equal(t, StringList{"outer"}, cfg.SchemaFilename) + after, err := os.Getwd() + require.NoError(t, err) + require.Equal(t, before, after) }) t.Run("will return error if config doesn't exist", func(t *testing.T) { From 3f68ea27a1a9fea2064caf877f7e24d00aa439e6 Mon Sep 17 00:00:00 2001 From: ananya saxena Date: Sun, 11 Apr 2021 21:16:10 -0700 Subject: [PATCH 045/146] Special handling for pointers to slices (#1363) --- TESTING.md | 4 +- codegen/config/binder.go | 8 ++ codegen/testserver/generated.go | 153 ++++++++++++++++++++++++ codegen/testserver/ptr_to_slice.go | 5 + codegen/testserver/ptr_to_slice.graphql | 7 ++ codegen/testserver/ptr_to_slice_test.go | 37 ++++++ codegen/testserver/resolver.go | 4 + codegen/testserver/stub.go | 4 + codegen/type.go | 2 +- codegen/type.gotpl | 9 +- 10 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 codegen/testserver/ptr_to_slice.go create mode 100644 codegen/testserver/ptr_to_slice.graphql create mode 100644 codegen/testserver/ptr_to_slice_test.go diff --git a/TESTING.md b/TESTING.md index ad7e63352ac..72ba06056c6 100644 --- a/TESTING.md +++ b/TESTING.md @@ -5,7 +5,7 @@ Testing generated code is a little tricky, heres how its currently set up. ### Testing responses from a server -There is a server in `codegen/testserver` that is generated as part +There is a server in `codegen/testserver` that is generated as part of `go generate ./...`, and tests written against it. There are also a bunch of tests in against the examples, feel free to take examples from there. @@ -15,7 +15,7 @@ There are also a bunch of tests in against the examples, feel free to take examp These tests are **really** slow, because they need to run the whole codegen step. Use them very sparingly. If you can, find a way to unit test it instead. -Take a look at `codegen/input_test.go` for an example. +Take a look at `codegen/testserver/input_test.go` for an example. ### Testing introspection diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 2be7b7bdd6b..6de7ae117a3 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -217,6 +217,14 @@ func (t *TypeReference) IsSlice() bool { return t.GQL.Elem != nil && isSlice } +func (t *TypeReference) IsPtrToSlice() bool { + if t.IsPtr() { + _, isPointerToSlice := t.GO.(*types.Pointer).Elem().(*types.Slice) + return isPointerToSlice + } + return false +} + func (t *TypeReference) IsNamed() bool { _, isSlice := t.GO.(*types.Named) return isSlice diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 3064d382784..c39877b90f1 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -256,6 +256,10 @@ type ComplexityRoot struct { Value func(childComplexity int) int } + PtrToSliceContainer struct { + PtrToSlice func(childComplexity int) int + } + Query struct { Animal func(childComplexity int) int Autobind func(childComplexity int) int @@ -302,6 +306,7 @@ type ComplexityRoot struct { Panics func(childComplexity int) int PrimitiveObject func(childComplexity int) int PrimitiveStringObject func(childComplexity int) int + PtrToSliceContainer func(childComplexity int) int Recursive func(childComplexity int, input *RecursiveInputSlice) int ScalarSlice func(childComplexity int) int ShapeUnion func(childComplexity int) int @@ -476,6 +481,7 @@ type QueryResolver interface { Panics(ctx context.Context) (*Panics, error) PrimitiveObject(ctx context.Context) ([]Primitive, error) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) + PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) DefaultScalar(ctx context.Context, arg string) (string, error) Slices(ctx context.Context) (*Slices, error) ScalarSlice(ctx context.Context) ([]byte, error) @@ -1028,6 +1034,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.PrimitiveString.Value(childComplexity), true + case "PtrToSliceContainer.ptrToSlice": + if e.complexity.PtrToSliceContainer.PtrToSlice == nil { + break + } + + return e.complexity.PtrToSliceContainer.PtrToSlice(childComplexity), true + case "Query.animal": if e.complexity.Query.Animal == nil { break @@ -1423,6 +1436,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.PrimitiveStringObject(childComplexity), true + case "Query.ptrToSliceContainer": + if e.complexity.Query.PtrToSliceContainer == nil { + break + } + + return e.complexity.Query.PtrToSliceContainer(childComplexity), true + case "Query.recursive": if e.complexity.Query.Recursive == nil { break @@ -2146,6 +2166,14 @@ type PrimitiveString { doubled: String! len: Int! } +`, BuiltIn: false}, + {Name: "ptr_to_slice.graphql", Input: `type PtrToSliceContainer { + ptrToSlice: [String!] +} + +extend type Query { + ptrToSliceContainer: PtrToSliceContainer! +} `, BuiltIn: false}, {Name: "scalar_default.graphql", Input: `extend type Query { defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation! @@ -5811,6 +5839,35 @@ func (ec *executionContext) _PrimitiveString_len(ctx context.Context, field grap return ec.marshalNInt2int(ctx, field.Selections, res) } +func (ec *executionContext) _PtrToSliceContainer_ptrToSlice(ctx context.Context, field graphql.CollectedField, obj *PtrToSliceContainer) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToSliceContainer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PtrToSlice, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*[]string) + fc.Result = res + return ec.marshalOString2ᚖᚕstringᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_invalidIdentifier(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -7497,6 +7554,38 @@ func (ec *executionContext) _Query_primitiveStringObject(ctx context.Context, fi return ec.marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveStringᚄ(ctx, field.Selections, res) } +func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PtrToSliceContainer(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*PtrToSliceContainer) + fc.Result = res + return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_defaultScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -12042,6 +12131,30 @@ func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.Select return out } +var ptrToSliceContainerImplementors = []string{"PtrToSliceContainer"} + +func (ec *executionContext) _PtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, obj *PtrToSliceContainer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToSliceContainerImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToSliceContainer") + case "ptrToSlice": + out.Values[i] = ec._PtrToSliceContainer_ptrToSlice(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { @@ -12607,6 +12720,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } return res }) + case "ptrToSliceContainer": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_ptrToSliceContainer(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "defaultScalar": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -13856,6 +13983,20 @@ func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designs return ret } +func (ec *executionContext) marshalNPtrToSliceContainer2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v PtrToSliceContainer) graphql.Marshaler { + return ec._PtrToSliceContainer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v *PtrToSliceContainer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._PtrToSliceContainer(ctx, sel, v) +} + func (ec *executionContext) unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { res, err := ec.unmarshalInputRecursiveInputSlice(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -15118,6 +15259,18 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return graphql.MarshalString(*v) } +func (ec *executionContext) unmarshalOString2ᚖᚕstringᚄ(ctx context.Context, v interface{}) (*[]string, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v *[]string) graphql.Marshaler { + return ec.marshalOString2ᚕstringᚄ(ctx, sel, *v) +} + func (ec *executionContext) marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐTestUnion(ctx context.Context, sel ast.SelectionSet, v TestUnion) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/codegen/testserver/ptr_to_slice.go b/codegen/testserver/ptr_to_slice.go new file mode 100644 index 00000000000..b16bf48890f --- /dev/null +++ b/codegen/testserver/ptr_to_slice.go @@ -0,0 +1,5 @@ +package testserver + +type PtrToSliceContainer struct { + PtrToSlice *[]string +} diff --git a/codegen/testserver/ptr_to_slice.graphql b/codegen/testserver/ptr_to_slice.graphql new file mode 100644 index 00000000000..b773d83d428 --- /dev/null +++ b/codegen/testserver/ptr_to_slice.graphql @@ -0,0 +1,7 @@ +type PtrToSliceContainer { + ptrToSlice: [String!] +} + +extend type Query { + ptrToSliceContainer: PtrToSliceContainer! +} diff --git a/codegen/testserver/ptr_to_slice_test.go b/codegen/testserver/ptr_to_slice_test.go new file mode 100644 index 00000000000..2fe498feb8c --- /dev/null +++ b/codegen/testserver/ptr_to_slice_test.go @@ -0,0 +1,37 @@ +package testserver + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestPtrToSlice(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.PtrToSliceContainer = func(ctx context.Context) (wrappedStruct *PtrToSliceContainer, e error) { + ptrToSliceContainer := PtrToSliceContainer{ + PtrToSlice: &[]string{"hello"}, + } + return &ptrToSliceContainer, nil + } + + t.Run("pointer to slice", func(t *testing.T) { + var resp struct { + PtrToSliceContainer struct { + PtrToSlice []string + } + } + + err := c.Post(`query { ptrToSliceContainer { ptrToSlice }}`, &resp) + require.NoError(t, err) + + require.Equal(t, []string{"hello"}, resp.PtrToSliceContainer.PtrToSlice) + + }) +} diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index 867f692c1dd..ed813bf511e 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -260,6 +260,10 @@ func (r *queryResolver) PrimitiveStringObject(ctx context.Context) ([]PrimitiveS panic("not implemented") } +func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { + panic("not implemented") +} + func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { panic("not implemented") } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 051f1919534..8b6d7671a26 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -92,6 +92,7 @@ type Stub struct { Panics func(ctx context.Context) (*Panics, error) PrimitiveObject func(ctx context.Context) ([]Primitive, error) PrimitiveStringObject func(ctx context.Context) ([]PrimitiveString, error) + PtrToSliceContainer func(ctx context.Context) (*PtrToSliceContainer, error) DefaultScalar func(ctx context.Context, arg string) (string, error) Slices func(ctx context.Context) (*Slices, error) ScalarSlice func(ctx context.Context) ([]byte, error) @@ -383,6 +384,9 @@ func (r *stubQuery) PrimitiveObject(ctx context.Context) ([]Primitive, error) { func (r *stubQuery) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) { return r.QueryResolver.PrimitiveStringObject(ctx) } +func (r *stubQuery) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { + return r.QueryResolver.PtrToSliceContainer(ctx) +} func (r *stubQuery) DefaultScalar(ctx context.Context, arg string) (string, error) { return r.QueryResolver.DefaultScalar(ctx, arg) } diff --git a/codegen/type.go b/codegen/type.go index 06b370be7f2..5a059d70131 100644 --- a/codegen/type.go +++ b/codegen/type.go @@ -26,7 +26,7 @@ func processType(ret map[string]*config.TypeReference, ref *config.TypeReference } ret[key] = ref - if ref.IsSlice() { + if ref.IsSlice() || ref.IsPtrToSlice() { processType(ret, ref.Elem()) } } diff --git a/codegen/type.gotpl b/codegen/type.gotpl index 85a7cf6a5f2..9c421b02d3d 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -4,7 +4,10 @@ {{- if and $type.IsNilable (not $type.GQL.NonNull) }} if v == nil { return nil, nil } {{- end }} - {{- if $type.IsSlice }} + {{- if $type.IsPtrToSlice }} + res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) + {{- else if $type.IsSlice }} var vSlice []interface{} if v != nil { if tmp1, ok := v.([]interface{}); ok { @@ -66,7 +69,9 @@ {{ with $type.MarshalFunc }} func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler { - {{- if $type.IsSlice }} + {{- if $type.IsPtrToSlice }} + return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) + {{- else if $type.IsSlice }} {{- if not $type.GQL.NonNull }} if v == nil { return graphql.Null From f57d1a0285eebce853a6a008da3c9c7b4eb77c57 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Tue, 13 Apr 2021 12:24:50 +1000 Subject: [PATCH 046/146] Bump gqlparser to master & support repeated directives --- codegen/testserver/directive.graphql | 4 +- codegen/testserver/directive_test.go | 5 +- codegen/testserver/generated.go | 63 ++++++++++++++++--- example/chat/generated.go | 40 ++++++++++++ example/config/generated.go | 40 ++++++++++++ example/dataloader/generated.go | 40 ++++++++++++ .../accounts/graph/generated/generated.go | 40 ++++++++++++ .../products/graph/generated/generated.go | 40 ++++++++++++ .../reviews/graph/generated/generated.go | 40 ++++++++++++ example/fileupload/generated.go | 40 ++++++++++++ example/scalars/generated.go | 40 ++++++++++++ example/selection/generated.go | 40 ++++++++++++ example/starwars/generated/exec.go | 40 ++++++++++++ example/todo/generated.go | 37 +++++++++++ example/type-system-extension/generated.go | 40 ++++++++++++ go.mod | 2 +- go.sum | 6 +- graphql/introspection/introspection.go | 9 +-- graphql/introspection/schema.go | 9 +-- integration/generated.go | 40 ++++++++++++ 20 files changed, 590 insertions(+), 25 deletions(-) diff --git a/codegen/testserver/directive.graphql b/codegen/testserver/directive.graphql index 4005cfd8907..f878c4d5cf7 100644 --- a/codegen/testserver/directive.graphql +++ b/codegen/testserver/directive.graphql @@ -6,7 +6,7 @@ directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINI directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION directive @unimplemented on FIELD_DEFINITION -directive @order1(location: String!) on FIELD_DEFINITION | OBJECT +directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT extend type Query { @@ -42,7 +42,7 @@ input InnerDirectives { message: String! @length(min: 1, message: "not valid") } -type ObjectDirectives @order1(location: "ObjectDirectives_object_1") @order2(location: "ObjectDirectives_object_2") { +type ObjectDirectives @order1(location: "order1_1") @order1(location: "order1_2") @order2(location: "order2_1") { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull order: [String!]! diff --git a/codegen/testserver/directive_test.go b/codegen/testserver/directive_test.go index 32015005104..56786f58037 100644 --- a/codegen/testserver/directive_test.go +++ b/codegen/testserver/directive_test.go @@ -387,8 +387,9 @@ func TestDirectives(t *testing.T) { require.Equal(t, "Ok", resp.DirectiveObject.Text) require.True(t, resp.DirectiveObject.NullableText == nil) require.Equal(t, "Query_field", resp.DirectiveObject.Order[0]) - require.Equal(t, "ObjectDirectives_object_2", resp.DirectiveObject.Order[1]) - require.Equal(t, "ObjectDirectives_object_1", resp.DirectiveObject.Order[2]) + require.Equal(t, "order2_1", resp.DirectiveObject.Order[1]) + require.Equal(t, "order1_2", resp.DirectiveObject.Order[2]) + require.Equal(t, "order1_1", resp.DirectiveObject.Order[3]) }) t.Run("when directive returns nil & custom go field is not nilable", func(t *testing.T) { var resp struct { diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index c39877b90f1..7de02ba888b 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -1915,7 +1915,7 @@ directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINI directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION directive @unimplemented on FIELD_DEFINITION -directive @order1(location: String!) on FIELD_DEFINITION | OBJECT +directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT extend type Query { @@ -1951,7 +1951,7 @@ input InnerDirectives { message: String! @length(min: 1, message: "not valid") } -type ObjectDirectives @order1(location: "ObjectDirectives_object_1") @order2(location: "ObjectDirectives_object_2") { +type ObjectDirectives @order1(location: "order1_1") @order1(location: "order1_2") @order2(location: "order2_1") { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull order: [String!]! @@ -6569,7 +6569,7 @@ func (ec *executionContext) _Query_directiveObject(ctx context.Context, field gr return ec.resolvers.Query().DirectiveObject(rctx) } directive1 := func(ctx context.Context) (interface{}, error) { - location, err := ec.unmarshalNString2string(ctx, "ObjectDirectives_object_1") + location, err := ec.unmarshalNString2string(ctx, "order1_1") if err != nil { return nil, err } @@ -6579,16 +6579,26 @@ func (ec *executionContext) _Query_directiveObject(ctx context.Context, field gr return ec.directives.Order1(ctx, nil, directive0, location) } directive2 := func(ctx context.Context) (interface{}, error) { - location, err := ec.unmarshalNString2string(ctx, "ObjectDirectives_object_2") + location, err := ec.unmarshalNString2string(ctx, "order1_2") + if err != nil { + return nil, err + } + if ec.directives.Order1 == nil { + return nil, errors.New("directive order1 is not implemented") + } + return ec.directives.Order1(ctx, nil, directive1, location) + } + directive3 := func(ctx context.Context) (interface{}, error) { + location, err := ec.unmarshalNString2string(ctx, "order2_1") if err != nil { return nil, err } if ec.directives.Order2 == nil { return nil, errors.New("directive order2 is not implemented") } - return ec.directives.Order2(ctx, nil, directive1, location) + return ec.directives.Order2(ctx, nil, directive2, location) } - directive3 := func(ctx context.Context) (interface{}, error) { + directive4 := func(ctx context.Context) (interface{}, error) { location, err := ec.unmarshalNString2string(ctx, "Query_field") if err != nil { return nil, err @@ -6596,10 +6606,10 @@ func (ec *executionContext) _Query_directiveObject(ctx context.Context, field gr if ec.directives.Order1 == nil { return nil, errors.New("directive order1 is not implemented") } - return ec.directives.Order1(ctx, nil, directive2, location) + return ec.directives.Order1(ctx, nil, directive3, location) } - tmp, err := directive3(rctx) + tmp, err := directive4(rctx) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -9243,6 +9253,38 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -13319,6 +13361,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/chat/generated.go b/example/chat/generated.go index 9d162affae0..7ebbf06eb47 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -1010,6 +1010,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2162,6 +2197,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/config/generated.go b/example/config/generated.go index 00a1145a3ea..38b43adb236 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -857,6 +857,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2034,6 +2069,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 342ac7cc389..7ede23b8b1a 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -1120,6 +1120,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2335,6 +2370,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index 1d64bbeda50..52adf8bb3c5 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -785,6 +785,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1952,6 +1987,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 92c126f7aa3..5f544afd645 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -856,6 +856,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2028,6 +2063,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 192d961498f..0ef7c35a9e9 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -1043,6 +1043,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2301,6 +2336,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/fileupload/generated.go b/example/fileupload/generated.go index bb3f308cfc1..c8f57b81246 100644 --- a/example/fileupload/generated.go +++ b/example/fileupload/generated.go @@ -936,6 +936,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2082,6 +2117,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index 0773ab3b4dd..5e8060bdf98 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -1194,6 +1194,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2391,6 +2426,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/selection/generated.go b/example/selection/generated.go index ddbd977d5d2..bc3c24d4442 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -786,6 +786,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1908,6 +1943,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index d82d169b60b..5b6b13b20ac 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -2532,6 +2532,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -4094,6 +4129,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/todo/generated.go b/example/todo/generated.go index 2e5ceeb2300..9cf43c496a4 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -988,6 +988,38 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2054,6 +2086,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index eb50a955fc6..c09547397ee 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -922,6 +922,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2088,6 +2123,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/go.mod b/go.mod index f77773be11e..44dc5d01616 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/stretchr/testify v1.4.0 github.com/urfave/cli/v2 v2.1.1 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e - github.com/vektah/gqlparser/v2 v2.1.0 + github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4 golang.org/x/tools v0.0.0-20210106214847-113979e3529a gopkg.in/yaml.v2 v2.2.4 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 diff --git a/go.sum b/go.sum index 6dbb9486152..b2cb620c44e 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= -github.com/vektah/gqlparser/v2 v2.1.0 h1:uiKJ+T5HMGGQM2kRKQ8Pxw8+Zq9qhhZhz/lieYvCMns= -github.com/vektah/gqlparser/v2 v2.1.0/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms= +github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4 h1:Dvl56VBDvea05rrO4g2PjAiNXiBnSBzy0G4rRGJEgo8= +github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -81,7 +81,6 @@ golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= @@ -92,7 +91,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/graphql/introspection/introspection.go b/graphql/introspection/introspection.go index 5239c92839e..709fa962630 100644 --- a/graphql/introspection/introspection.go +++ b/graphql/introspection/introspection.go @@ -5,10 +5,11 @@ import "github.com/vektah/gqlparser/v2/ast" type ( Directive struct { - Name string - Description string - Locations []string - Args []InputValue + Name string + Description string + Locations []string + Args []InputValue + IsRepeatable bool } EnumValue struct { diff --git a/graphql/introspection/schema.go b/graphql/introspection/schema.go index 044e91d6e98..af56eff4205 100644 --- a/graphql/introspection/schema.go +++ b/graphql/introspection/schema.go @@ -60,9 +60,10 @@ func (s *Schema) directiveFromDef(d *ast.DirectiveDefinition) Directive { } return Directive{ - Name: d.Name, - Description: d.Description, - Locations: locs, - Args: args, + Name: d.Name, + Description: d.Description, + Locations: locs, + Args: args, + IsRepeatable: d.IsRepeatable, } } diff --git a/integration/generated.go b/integration/generated.go index 94a65076232..516e2da4d03 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -1061,6 +1061,41 @@ func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2324,6 +2359,11 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS if out.Values[i] == graphql.Null { invalids++ } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } From 1d768a29c960df5d54f6e675e0338619d5b04bfd Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Tue, 13 Apr 2021 12:38:17 +1000 Subject: [PATCH 047/146] Add test covering single element -> slice coercion --- codegen/testserver/input_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/codegen/testserver/input_test.go b/codegen/testserver/input_test.go index 1a54508d721..aaba53aa668 100644 --- a/codegen/testserver/input_test.go +++ b/codegen/testserver/input_test.go @@ -46,4 +46,24 @@ func TestInput(t *testing.T) { require.NoError(t, err) require.False(t, resp.InputNullableSlice) }) + + t.Run("coerce single value to slice", func(t *testing.T) { + check := func(ctx context.Context, arg []string) (b bool, e error) { + return len(arg) == 1 && arg[0] == "coerced", nil + } + resolvers.QueryResolver.InputSlice = check + resolvers.QueryResolver.InputNullableSlice = check + + var resp struct { + Coerced bool + } + var err error + err = c.Post(`query { coerced: inputSlice(arg: "coerced") }`, &resp) + require.NoError(t, err) + require.True(t, resp.Coerced) + + err = c.Post(`query { coerced: inputNullableSlice(arg: "coerced") }`, &resp) + require.NoError(t, err) + require.True(t, resp.Coerced) + }) } From 4e881981de33f2e2bf1fef11c2bf833995f60719 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Tue, 13 Apr 2021 16:35:43 +1000 Subject: [PATCH 048/146] Bump to gqlparser v2.2.0 --- go.mod | 4 ++-- go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 44dc5d01616..bbd03943083 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/99designs/gqlgen go 1.12 require ( - github.com/agnivade/levenshtein v1.0.3 // indirect + github.com/agnivade/levenshtein v1.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect github.com/gorilla/mux v1.6.1 // indirect @@ -23,7 +23,7 @@ require ( github.com/stretchr/testify v1.4.0 github.com/urfave/cli/v2 v2.1.1 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e - github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4 + github.com/vektah/gqlparser/v2 v2.2.0 golang.org/x/tools v0.0.0-20210106214847-113979e3529a gopkg.in/yaml.v2 v2.2.4 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 diff --git a/go.sum b/go.sum index b2cb620c44e..fe1fd7471b6 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0= -github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs= +github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= +github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -11,8 +11,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c h1:TUuUh0Xgj97tLMNtWtNvI9mIV6isjEb9lBMNv+77IGM= -github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= @@ -69,8 +69,8 @@ github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= -github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4 h1:Dvl56VBDvea05rrO4g2PjAiNXiBnSBzy0G4rRGJEgo8= -github.com/vektah/gqlparser/v2 v2.1.1-0.20210413003740-7cc8073a56b4/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= +github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From 481a4e44cbc114382dee087feb9cf18c15907d4a Mon Sep 17 00:00:00 2001 From: Franky W Date: Tue, 13 Apr 2021 10:03:09 +0200 Subject: [PATCH 049/146] Marshaling & Unmarshaling time return initial value There was a lack of symmetry that would prevent times for being symmetrical. That is because time.Parse actually parses an RFC3339Nano implicitly, thereby allowing nanosecond resolution on unmarshaling a time. Therefore we now marshal into nanoseconds, getting more information into GraphQL times when querying for a time, and restoring the symmetry --- graphql/time.go | 2 +- graphql/time_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 graphql/time_test.go diff --git a/graphql/time.go b/graphql/time.go index 9945f3fbfda..bd7b2e60807 100644 --- a/graphql/time.go +++ b/graphql/time.go @@ -13,7 +13,7 @@ func MarshalTime(t time.Time) Marshaler { } return WriterFunc(func(w io.Writer) { - io.WriteString(w, strconv.Quote(t.Format(time.RFC3339))) + io.WriteString(w, strconv.Quote(t.Format(time.RFC3339Nano))) }) } diff --git a/graphql/time_test.go b/graphql/time_test.go new file mode 100644 index 00000000000..32876436a61 --- /dev/null +++ b/graphql/time_test.go @@ -0,0 +1,25 @@ +package graphql + +import ( + "bytes" + "strconv" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestTime(t *testing.T) { + t.Run("symmetry", func(t *testing.T) { + initialTime := time.Now() + buf := bytes.NewBuffer([]byte{}) + MarshalTime(initialTime).MarshalGQL(buf) + + str, err := strconv.Unquote(buf.String()) + require.Nil(t, err) + newTime, err := UnmarshalTime(str) + require.Nil(t, err) + + require.True(t, initialTime.Equal(newTime), "expected times %v and %v to equal", initialTime, newTime) + }) +} From bb59cc43aa5bae2595ec823f8d7e67369e990082 Mon Sep 17 00:00:00 2001 From: Michael Compton Date: Thu, 15 Apr 2021 10:58:11 +1000 Subject: [PATCH 050/146] Add a CHANGELOG.md (#1512) --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000000..263ebc3eb64 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,43 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +* Added a changelog :-) Following the same style as [Apollo Client](https://github.com/apollographql/apollo-client) because that feels like it gives good thanks to the community contributors.
+By [@MichaelJCompton](https://github.com/MichaelJCompton) in [#1512](https://github.com/99designs/gqlgen/pull/1512) +* Added support for methods returning `(v, ok)` shaped values to support Prisma Go client.
+By [@steebchen](https://github.com/steebchen) in [#1449](https://github.com/99designs/gqlgen/pull/1449) + +### Changed + +* Updated to gqlparser to v2.2.0.
+By [@lwc](https://github.com/lwc) in [#1514](https://github.com/99designs/gqlgen/pull/1514) +* GraphQL playground updated to 1.7.26.
+By [@ddouglas](https://github.com/ddouglas) in [#1436](https://github.com/99designs/gqlgen/pull/1436) + +### Fixed + +* Removed a data race by copying when input fields have default values. +Bu [@skaji](https://github.com/skaji) in [#1456](https://github.com/99designs/gqlgen/pull/1456) +* v0.12.2 broke the handling of pointers to slices by calling the custom Marshal and Unmarshal functions on the entire slice. It now correctly calls the custom Marshal and Unmarshal methods for each element in the slice.
+By [@ananyasaxena](https://github.com/ananyasaxena) in [#1363](https://github.com/99designs/gqlgen/pull/1363) +* Changes in go1.16 that mean go.mod and go.sum aren't always up to date. Now `go mod tidy` is run after code generation.
+By [@lwc](https://github.com/lwc) in [#1501](https://github.com/99designs/gqlgen/pull/1501) +* Errors in resolving non-nullable arrays were not correctly bubbling up to the next nullable field.
+By [@wilhelmeek](https://github.com/wilhelmeek) in [#1480](https://github.com/99designs/gqlgen/pull/1480) +* Fixed a potential deadlock in calling error presenters.
+By [@vektah](https://github.com/vektah) in [#1399](https://github.com/99designs/gqlgen/pull/1399) +* Fixed `collectFields` not correctly respecting alias fields in fragments.
+By [@vmrajas](https://github.com/vmrajas) in [#1341](https://github.com/99designs/gqlgen/pull/1341) + + +## [0.13.0] - 2020-09-21 + +Base version at which changelog was introduced. + From 5ad012e3d7be1127706b9c8a3da0378df3a98ec1 Mon Sep 17 00:00:00 2001 From: MichaelJCompton Date: Thu, 15 Apr 2021 16:58:09 +1000 Subject: [PATCH 051/146] Revert "Merge pull request #1511 from a8m/a8m/restore-cwd" This reverts commit f4bf1f591b6a3884041876deb64ce0dd70c3c883, reversing changes made to 3f68ea27a1a9fea2064caf877f7e24d00aa439e6. Reverting this because it will break existing setups, moving where generated files get put. --- codegen/config/config.go | 24 +++++++++--------------- codegen/config/config_test.go | 5 ----- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index 24ea9e7ef04..ba939fcf59a 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -70,8 +70,8 @@ func LoadDefaultConfig() (*Config, error) { // LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories // walking up the tree. The closest config file will be returned. -func LoadConfigFromDefaultLocations() (cfg *Config, err error) { - cfgFile, cwd, err := findCfg() +func LoadConfigFromDefaultLocations() (*Config, error) { + cfgFile, err := findCfg() if err != nil { return nil, err } @@ -80,12 +80,6 @@ func LoadConfigFromDefaultLocations() (cfg *Config, err error) { if err != nil { return nil, errors.Wrap(err, "unable to enter config dir") } - defer func() { - if cerr := os.Chdir(cwd); cerr != nil { - cfg = nil - err = errors.Wrap(cerr, "unable to restore working directory") - } - }() return LoadConfig(cfgFile) } @@ -473,24 +467,24 @@ func inStrSlice(haystack []string, needle string) bool { // findCfg searches for the config file in this directory and all parents up the tree // looking for the closest match -func findCfg() (string, string, error) { - cwd, err := os.Getwd() +func findCfg() (string, error) { + dir, err := os.Getwd() if err != nil { - return "", "", errors.Wrap(err, "unable to get working dir to findCfg") + return "", errors.Wrap(err, "unable to get working dir to findCfg") } - cfg := findCfgInDir(cwd) + cfg := findCfgInDir(dir) - for dir := cwd; cfg == "" && dir != filepath.Dir(dir); { + for cfg == "" && dir != filepath.Dir(dir) { dir = filepath.Dir(dir) cfg = findCfgInDir(dir) } if cfg == "" { - return "", "", os.ErrNotExist + return "", os.ErrNotExist } - return cfg, cwd, nil + return cfg, nil } func findCfgInDir(dir string) string { diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index de63b15d3f0..b16e90c11a5 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -72,14 +72,9 @@ func TestLoadConfigFromDefaultLocation(t *testing.T) { err = os.Chdir(filepath.Join(testDir, "testdata", "cfg", "otherdir")) require.NoError(t, err) - before, err := os.Getwd() - require.NoError(t, err) cfg, err = LoadConfigFromDefaultLocations() require.NoError(t, err) require.Equal(t, StringList{"outer"}, cfg.SchemaFilename) - after, err := os.Getwd() - require.NoError(t, err) - require.Equal(t, before, after) }) t.Run("will return error if config doesn't exist", func(t *testing.T) { From 843edd9ea507bcf50b02cb43d0543f3fdf0ae875 Mon Sep 17 00:00:00 2001 From: Shivang Goswami Date: Mon, 19 Apr 2021 19:34:31 +0530 Subject: [PATCH 052/146] Update apq.md function definition mismatch line 67: cache, err := NewCache(cfg.RedisAddress, 24*time.Hour) line 41: func NewCache(redisAddress string, password string,ttl time.Duration) (*Cache, error) either password should be removed from 41 or added in line 67 Proposed the first one for now. --- docs/content/reference/apq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/apq.md b/docs/content/reference/apq.md index 2be30fa2429..b5cd6fc12c9 100644 --- a/docs/content/reference/apq.md +++ b/docs/content/reference/apq.md @@ -38,7 +38,7 @@ type Cache struct { const apqPrefix = "apq:" -func NewCache(redisAddress string, password string, ttl time.Duration) (*Cache, error) { +func NewCache(redisAddress string, ttl time.Duration) (*Cache, error) { client := redis.NewClient(&redis.Options{ Addr: redisAddress, }) From e82b401ddd97fe807a5066d3702b391ec317a358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Borgstr=C3=B6m?= Date: Wed, 28 Apr 2021 15:11:00 +0200 Subject: [PATCH 053/146] allow more than 10 different import sources with types --- codegen/templates/import.go | 2 +- codegen/templates/import_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/codegen/templates/import.go b/codegen/templates/import.go index 17bd96ab2eb..00a82ea5ef1 100644 --- a/codegen/templates/import.go +++ b/codegen/templates/import.go @@ -105,7 +105,7 @@ func (s *Imports) Lookup(path string) string { for s.findByAlias(alias) != nil { alias = imp.Name + strconv.Itoa(i) i++ - if i > 10 { + if i > 1000 { panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) } } diff --git a/codegen/templates/import_test.go b/codegen/templates/import_test.go index 2e8dd5a89aa..a91d2a8ccd3 100644 --- a/codegen/templates/import_test.go +++ b/codegen/templates/import_test.go @@ -1,6 +1,7 @@ package templates import ( + "fmt" "go/types" "os" "testing" @@ -45,6 +46,19 @@ func TestImports(t *testing.T) { }) }) + t.Run("duplicates above 10 are decollisioned", func(t *testing.T) { + a := Imports{destDir: wd, packages: &code.Packages{}} + for i := 0; i < 100; i++ { + cBar := fmt.Sprintf("github.com/99designs/gqlgen/codegen/templates/testdata/%d/bar", i) + if i > 0 { + require.Equal(t, fmt.Sprintf("bar%d", i), a.Lookup(cBar)) + } else { + require.Equal(t, "bar", a.Lookup(cBar)) + + } + } + }) + t.Run("package name defined in code will be used", func(t *testing.T) { a := Imports{destDir: wd, packages: &code.Packages{}} From 1efc152e4f9399a908620d1d4c1198b9662cb181 Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 30 Apr 2021 10:58:45 +0900 Subject: [PATCH 054/146] supported INPUT_OBJECT directive --- codegen/field.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/codegen/field.go b/codegen/field.go index d1eceb002ef..3a90530b9a7 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -89,6 +89,11 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) { if err != nil { errret = err } + for _, dir := range obj.Directives { + if dir.IsLocation(ast.LocationInputObject) { + dirs = append(dirs, dir) + } + } f.Directives = append(dirs, f.Directives...) } }() @@ -420,7 +425,8 @@ func (f *Field) ImplDirectives() []*Directive { loc = ast.LocationInputFieldDefinition } for i := range f.Directives { - if !f.Directives[i].Builtin && f.Directives[i].IsLocation(loc, ast.LocationObject) { + if !f.Directives[i].Builtin && + (f.Directives[i].IsLocation(loc, ast.LocationObject) || f.Directives[i].IsLocation(loc, ast.LocationInputObject)) { d = append(d, f.Directives[i]) } } From 91b54787166e1dd26e2f95493e02a43130950105 Mon Sep 17 00:00:00 2001 From: Kei Kamikawa Date: Fri, 30 Apr 2021 12:20:21 +0900 Subject: [PATCH 055/146] generated go code --- codegen/testserver/directive.graphql | 3 +- codegen/testserver/directive_test.go | 3 + codegen/testserver/generated.go | 78 +++++++++++++++++++--- example/type-system-extension/generated.go | 18 ++++- 4 files changed, 88 insertions(+), 14 deletions(-) diff --git a/codegen/testserver/directive.graphql b/codegen/testserver/directive.graphql index f878c4d5cf7..8cf2470986e 100644 --- a/codegen/testserver/directive.graphql +++ b/codegen/testserver/directive.graphql @@ -5,6 +5,7 @@ directive @logged(id: UUID!) on FIELD directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT directive @unimplemented on FIELD_DEFINITION directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT @@ -30,7 +31,7 @@ extend type Subscription { directiveUnimplemented: String @unimplemented } -input InputDirectives { +input InputDirectives @directive3 { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull inner: InnerDirectives! diff --git a/codegen/testserver/directive_test.go b/codegen/testserver/directive_test.go index 56786f58037..a35a2889884 100644 --- a/codegen/testserver/directive_test.go +++ b/codegen/testserver/directive_test.go @@ -162,6 +162,9 @@ func TestDirectives(t *testing.T) { Directive2: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { return next(ctx) }, + Directive3: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, Order1: func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) { order := []string{location} res, err = next(ctx) diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 376764a3a48..7995011c094 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -60,6 +60,7 @@ type DirectiveRoot struct { Custom func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Directive1 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Directive2 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Directive3 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) Length func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int, message *string) (res interface{}, err error) Logged func(ctx context.Context, obj interface{}, next graphql.Resolver, id string) (res interface{}, err error) MakeNil func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) @@ -1914,6 +1915,7 @@ directive @logged(id: UUID!) on FIELD directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @directive1 on FIELD_DEFINITION directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT directive @unimplemented on FIELD_DEFINITION directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT directive @order2(location: String!) on OBJECT @@ -1939,7 +1941,7 @@ extend type Subscription { directiveUnimplemented: String @unimplemented } -input InputDirectives { +input InputDirectives @directive3 { text: String! @length(min: 0, max: 7, message: "not valid") nullableText: String @toNull inner: InnerDirectives! @@ -10298,6 +10300,12 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("text")) directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { min, err := ec.unmarshalNInt2int(ctx, 0) if err != nil { return nil, err @@ -10313,10 +10321,10 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o if ec.directives.Length == nil { return nil, errors.New("directive length is not implemented") } - return ec.directives.Length(ctx, obj, directive0, min, max, message) + return ec.directives.Length(ctx, obj, directive1, min, max, message) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } @@ -10332,13 +10340,19 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nullableText")) directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOString2ᚖstring(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { if ec.directives.ToNull == nil { return nil, errors.New("directive toNull is not implemented") } - return ec.directives.ToNull(ctx, obj, directive0) + return ec.directives.ToNull(ctx, obj, directive1) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } @@ -10354,17 +10368,53 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) - it.Inner, err = ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.Inner = data + } else if tmp == nil { + it.Inner = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } case "innerNullable": var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("innerNullable")) - it.InnerNullable, err = ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.InnerNullable = data + } else if tmp == nil { + it.InnerNullable = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } case "thirdParty": var err error @@ -10374,6 +10424,12 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o return ec.unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐThirdParty(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { min, err := ec.unmarshalNInt2int(ctx, 0) if err != nil { return nil, err @@ -10385,10 +10441,10 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o if ec.directives.Length == nil { return nil, errors.New("directive length is not implemented") } - return ec.directives.Length(ctx, obj, directive0, min, max, nil) + return ec.directives.Length(ctx, obj, directive1, min, max, nil) } - tmp, err := directive1(ctx) + tmp, err := directive2(ctx) if err != nil { return it, graphql.ErrorOnPath(ctx, err) } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index ff7ad36e8b5..4c0ea402cd9 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -1920,9 +1920,23 @@ func (ec *executionContext) unmarshalInputTodoInput(ctx context.Context, obj int var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("text")) - it.Text, err = ec.unmarshalNString2string(ctx, v) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.InputLogging == nil { + return nil, errors.New("directive inputLogging is not implemented") + } + return ec.directives.InputLogging(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) if err != nil { - return it, err + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + it.Text = data + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + return it, graphql.ErrorOnPath(ctx, err) } } } From f0ccab79549f184b1225dbc946d703400673aa5b Mon Sep 17 00:00:00 2001 From: Mathieu Post Date: Thu, 6 May 2021 11:43:27 +0200 Subject: [PATCH 056/146] Return type loading errors in config.Binder.FindObject --- codegen/config/binder.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 6de7ae117a3..68211834081 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -117,6 +117,10 @@ func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, erro pkg := b.pkgs.LoadWithTypes(pkgName) if pkg == nil { + err := b.pkgs.Errors() + if err != nil { + return nil, errors.Wrapf(err, "package could not be loaded: %s", fullName) + } return nil, errors.Errorf("required package was not loaded: %s", fullName) } From 145101e439f5460cbe7e85f8618e4de74104b676 Mon Sep 17 00:00:00 2001 From: Dany Henriquez <2287263+DanyHenriquez@users.noreply.github.com> Date: Fri, 2 Jul 2021 16:58:44 +0200 Subject: [PATCH 057/146] Update apq.md --- docs/content/reference/apq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/apq.md b/docs/content/reference/apq.md index 2be30fa2429..97dd2c3f549 100644 --- a/docs/content/reference/apq.md +++ b/docs/content/reference/apq.md @@ -14,7 +14,7 @@ to register query hash with original query on a server. ## Usage In order to enable Automatic Persisted Queries you need to change your client. For more information see -[Automatic Persisted Queries Link](https://github.com/apollographql/apollo-link-persisted-queries) documentation. +[Automatic Persisted Queries Link](https://www.apollographql.com/docs/react/api/link/persisted-queries/) documentation. For the server you need to implement the `graphql.Cache` interface and pass an instance to the `extension.AutomaticPersistedQuery` type. Make sure the extension is applied to your GraphQL handler. From 3e45ddc151232c5d05eb719f4722a9306f06afa1 Mon Sep 17 00:00:00 2001 From: talhaguy Date: Sun, 18 Jul 2021 11:34:46 -0700 Subject: [PATCH 058/146] Correct minor casing issue --- docs/content/reference/dataloaders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/dataloaders.md b/docs/content/reference/dataloaders.md index d5ece00e21a..775042eb2ca 100644 --- a/docs/content/reference/dataloaders.md +++ b/docs/content/reference/dataloaders.md @@ -157,7 +157,7 @@ func (r *todoResolver) UserLoader(ctx context.Context, obj *model.Todo) (*model. } ``` -The end result? just 2 queries! +The end result? Just 2 queries! ```sql SELECT id, todo, user_id FROM todo SELECT id, name from user WHERE id IN (?,?,?,?,?) From be9a0791a9217a05e105914dbae11e29a651ea54 Mon Sep 17 00:00:00 2001 From: Dany Henriquez <2287263+DanyHenriquez@users.noreply.github.com> Date: Sun, 25 Jul 2021 11:07:00 +0200 Subject: [PATCH 059/146] Update apq.md --- docs/content/reference/apq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/apq.md b/docs/content/reference/apq.md index 97dd2c3f549..e8d59bd377d 100644 --- a/docs/content/reference/apq.md +++ b/docs/content/reference/apq.md @@ -14,7 +14,7 @@ to register query hash with original query on a server. ## Usage In order to enable Automatic Persisted Queries you need to change your client. For more information see -[Automatic Persisted Queries Link](https://www.apollographql.com/docs/react/api/link/persisted-queries/) documentation. +[Automatic Persisted Queries Link](https://www.apollographql.com/docs/resources/graphql-glossary/#automatic-persisted-queries-apq) documentation. For the server you need to implement the `graphql.Cache` interface and pass an instance to the `extension.AutomaticPersistedQuery` type. Make sure the extension is applied to your GraphQL handler. From eb36f04ffde9a706467839b0aadb5671e4ed16a9 Mon Sep 17 00:00:00 2001 From: Nathan Yergler Date: Tue, 23 Mar 2021 11:19:58 -0700 Subject: [PATCH 060/146] Return introspection document in stable order This avoids spurious changes when generating client code using something like graphql-codegen. --- graphql/introspection/schema.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/graphql/introspection/schema.go b/graphql/introspection/schema.go index 044e91d6e98..91896045127 100644 --- a/graphql/introspection/schema.go +++ b/graphql/introspection/schema.go @@ -1,6 +1,7 @@ package introspection import ( + "sort" "strings" "github.com/vektah/gqlparser/v2/ast" @@ -11,12 +12,20 @@ type Schema struct { } func (s *Schema) Types() []Type { - types := make([]Type, 0, len(s.schema.Types)) + typeIndex := map[string]Type{} + typeNames := make([]string, 0, len(s.schema.Types)) for _, typ := range s.schema.Types { if strings.HasPrefix(typ.Name, "__") { continue } - types = append(types, *WrapTypeFromDef(s.schema, typ)) + typeNames = append(typeNames, typ.Name) + typeIndex[typ.Name] = *WrapTypeFromDef(s.schema, typ) + } + sort.Strings(typeNames) + + types := make([]Type, len(typeNames)) + for i, t := range typeNames { + types[i] = typeIndex[t] } return types } @@ -34,10 +43,18 @@ func (s *Schema) SubscriptionType() *Type { } func (s *Schema) Directives() []Directive { - res := make([]Directive, 0, len(s.schema.Directives)) + dIndex := map[string]Directive{} + dNames := make([]string, 0, len(s.schema.Directives)) for _, d := range s.schema.Directives { - res = append(res, s.directiveFromDef(d)) + dNames = append(dNames, d.Name) + dIndex[d.Name] = s.directiveFromDef(d) + } + sort.Strings(dNames) + + res := make([]Directive, len(dNames)) + for i, d := range dNames { + res[i] = dIndex[d] } return res From 54cef3ddcdd3c5e106f8347ccd8afd9bbb8bdb44 Mon Sep 17 00:00:00 2001 From: TSH96 Date: Sat, 7 Aug 2021 16:47:14 +0800 Subject: [PATCH 061/146] Bypass complexity limit on __Schema queries. --- complexity/complexity.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/complexity/complexity.go b/complexity/complexity.go index 1877aae5fbd..e3ecf7612d5 100644 --- a/complexity/complexity.go +++ b/complexity/complexity.go @@ -26,6 +26,11 @@ func (cw complexityWalker) selectionSetComplexity(selectionSet ast.SelectionSet) switch s := selection.(type) { case *ast.Field: fieldDefinition := cw.schema.Types[s.Definition.Type.Name()] + + if fieldDefinition.Name == "__Schema" { + continue + } + var childComplexity int switch fieldDefinition.Kind { case ast.Object, ast.Interface, ast.Union: From 5adb73bbba5375f07cd21d1fe498c6a252b6f933 Mon Sep 17 00:00:00 2001 From: TSH96 Date: Sat, 7 Aug 2021 17:04:30 +0800 Subject: [PATCH 062/146] add bypass __schema field test case --- graphql/handler/extension/complexity_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/graphql/handler/extension/complexity_test.go b/graphql/handler/extension/complexity_test.go index b5c9bf99f28..e533403e1a5 100644 --- a/graphql/handler/extension/complexity_test.go +++ b/graphql/handler/extension/complexity_test.go @@ -95,6 +95,16 @@ func TestFixedComplexity(t *testing.T) { require.Equal(t, 2, stats.ComplexityLimit) require.Equal(t, 4, stats.Complexity) }) + + t.Run("bypass __schema field", func(t *testing.T) { + h.SetCalculatedComplexity(4) + resp := doRequest(h, "POST", "/graphql", `{ "operationName":"IntrospectionQuery", "query":"query IntrospectionQuery { __schema { queryType { name } mutationType { name }}}"}`) + require.Equal(t, http.StatusOK, resp.Code, resp.Body.String()) + require.Equal(t, `{"data":{"name":"test"}}`, resp.Body.String()) + + require.Equal(t, 2, stats.ComplexityLimit) + require.Equal(t, 0, stats.Complexity) + }) } func doRequest(handler http.Handler, method string, target string, body string) *httptest.ResponseRecorder { From 01b25c5534453574296c52065c04d1923b3607c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Aug 2021 19:14:23 +0000 Subject: [PATCH 063/146] Bump path-parse from 1.0.6 to 1.0.7 in /integration Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7. - [Release notes](https://github.com/jbgutierrez/path-parse/releases) - [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7) --- updated-dependencies: - dependency-name: path-parse dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 95a128a71b0..35bf5d4232e 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -8908,9 +8908,9 @@ "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { From 29133c1152b4d89ab897bf75e0114fffad32351e Mon Sep 17 00:00:00 2001 From: Aaron M Date: Sat, 14 Aug 2021 08:41:37 -0600 Subject: [PATCH 064/146] Fix spaces -> tabs typo in authentication.md The indentation here was supposed to be a tab rather than spaces so the readme was off. --- docs/content/recipes/authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/recipes/authentication.md b/docs/content/recipes/authentication.md index 6ae59e73b8d..c77f5d9dd07 100644 --- a/docs/content/recipes/authentication.md +++ b/docs/content/recipes/authentication.md @@ -88,7 +88,7 @@ func main() { router.Use(auth.Middleware(db)) - srv := handler.NewDefaultServer(starwars.NewExecutableSchema(starwars.NewResolver())) + srv := handler.NewDefaultServer(starwars.NewExecutableSchema(starwars.NewResolver())) router.Handle("/", playground.Handler("Starwars", "/query")) router.Handle("/query", srv) From edf630a3da614949b9f0246299b08a61d25f6635 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Aug 2021 18:37:14 +0000 Subject: [PATCH 065/146] Bump tar from 6.0.5 to 6.1.11 in /integration Bumps [tar](https://github.com/npm/node-tar) from 6.0.5 to 6.1.11. - [Release notes](https://github.com/npm/node-tar/releases) - [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-tar/compare/v6.0.5...v6.1.11) --- updated-dependencies: - dependency-name: tar dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 95a128a71b0..bdc8a3e830c 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -10177,9 +10177,9 @@ "dev": true }, "tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", From 721158f3cdb00744c33380c05ab020f31b894325 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:42 +0000 Subject: [PATCH 066/146] Bump ws from 7.3.1 to 7.4.6 in /integration Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.4.6. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.3.1...7.4.6) --- updated-dependencies: - dependency-name: ws dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- integration/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..90b2b47a0b9 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -11037,9 +11037,9 @@ } }, "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "dev": true }, "xdg-basedir": { diff --git a/integration/package.json b/integration/package.json index 8c8c6d365b8..f2d1002335c 100644 --- a/integration/package.json +++ b/integration/package.json @@ -16,7 +16,7 @@ "jest": "^24.9.0", "node-fetch": "^2.6.0", "subscriptions-transport-ws": "^0.9.18", - "ws": "^7.3.1" + "ws": "^7.4.6" }, "dependencies": { "@babel/preset-env": "^7.11.0" From 36be94fff25cfe702f6b93a7fd595972ceb41a4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:44 +0000 Subject: [PATCH 067/146] Bump node-fetch from 2.6.0 to 2.6.1 in /integration Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.0...v2.6.1) --- updated-dependencies: - dependency-name: node-fetch dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- integration/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..1ed95a5e6fd 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -8298,9 +8298,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, "node-int64": { diff --git a/integration/package.json b/integration/package.json index 8c8c6d365b8..c9188bc9bdc 100644 --- a/integration/package.json +++ b/integration/package.json @@ -14,7 +14,7 @@ "graphql-cli": "^3.0.14", "graphql-tag": "^2.11.0", "jest": "^24.9.0", - "node-fetch": "^2.6.0", + "node-fetch": "^2.6.1", "subscriptions-transport-ws": "^0.9.18", "ws": "^7.3.1" }, From 94e9406e93a5afee6f193fc936f200287c4f5847 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:46 +0000 Subject: [PATCH 068/146] Bump hosted-git-info from 2.8.5 to 2.8.9 in /integration Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9. - [Release notes](https://github.com/npm/hosted-git-info/releases) - [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) - [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9) --- updated-dependencies: - dependency-name: hosted-git-info dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..2e3615f597b 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -6218,9 +6218,9 @@ } }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { From 13db61111eae250a02ead0cd9faa456d98dc007b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:52 +0000 Subject: [PATCH 069/146] Bump browserslist from 4.14.0 to 4.17.0 in /integration Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.14.0 to 4.17.0. - [Release notes](https://github.com/browserslist/browserslist/releases) - [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md) - [Commits](https://github.com/browserslist/browserslist/compare/4.14.0...4.17.0) --- updated-dependencies: - dependency-name: browserslist dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 62 ++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..baaea2eb56e 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -3982,14 +3982,37 @@ } }, "browserslist": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", - "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.0.tgz", + "integrity": "sha512-g2BJ2a0nEYvEFQC208q8mVAhfNwpZ5Mu8BwgtCdZKO3qx98HChmeg448fPdUzld8aFmfLgVh7yymqV+q1lJZ5g==", "requires": { - "caniuse-lite": "^1.0.30001111", - "electron-to-chromium": "^1.3.523", - "escalade": "^3.0.2", - "node-releases": "^1.1.60" + "caniuse-lite": "^1.0.30001254", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.830", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + }, + "dependencies": { + "caniuse-lite": { + "version": "1.0.30001255", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001255.tgz", + "integrity": "sha512-F+A3N9jTZL882f/fg/WWVnKSu6IOo3ueLz4zwaOPbPYHNmM/ZaDUyzyJwS1mZhX7Ex5jqTyW599Gdelh5PDYLQ==" + }, + "electron-to-chromium": { + "version": "1.3.830", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.830.tgz", + "integrity": "sha512-gBN7wNAxV5vl1430dG+XRcQhD4pIeYeak6p6rjdCtlz5wWNwDad8jwvphe5oi1chL5MV6RNRikfffBBiFuj+rQ==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "node-releases": { + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==" + } } }, "bser": { @@ -4122,11 +4145,6 @@ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, - "caniuse-lite": { - "version": "1.0.30001119", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001119.tgz", - "integrity": "sha512-Hpwa4obv7EGP+TjkCh/wVvbtNJewxmtg4yVJBLFnxo35vbPapBr138bUWENkb5j5L9JZJ9RXLn4OrXRG/cecPQ==" - }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -4313,6 +4331,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==" + }, "columnify": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", @@ -5031,11 +5054,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "electron-to-chromium": { - "version": "1.3.553", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.553.tgz", - "integrity": "sha512-wi/hoMuTGK6OJoLOHqmXFA9BWOQGF2nInCfk+/Owhd4VVfuenKE2LZr9TtFCmwyda2SE9hG+sRnqRCwhYgFeIg==" - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5129,11 +5147,6 @@ "es6-promise": "^4.0.3" } }, - "escalade": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.2.tgz", - "integrity": "sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ==" - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -8328,11 +8341,6 @@ "which": "^1.3.0" } }, - "node-releases": { - "version": "1.1.60", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", - "integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==" - }, "node-request-by-swagger": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/node-request-by-swagger/-/node-request-by-swagger-1.1.4.tgz", From de89d3a6f28cffb44704f6f9b6876c8c81d9f7aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:54 +0000 Subject: [PATCH 070/146] Bump y18n from 3.2.1 to 3.2.2 in /integration Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/commits) --- updated-dependencies: - dependency-name: y18n dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..3b70afefe1b 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -7037,9 +7037,9 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yargs": { @@ -7427,9 +7427,9 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yargs": { @@ -11061,9 +11061,9 @@ "dev": true }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, "yallist": { From 24d8c703c122cd007fe2eb81457a2eae89b49be8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:16:57 +0000 Subject: [PATCH 071/146] Bump ini from 1.3.5 to 1.3.8 in /integration Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) --- updated-dependencies: - dependency-name: ini dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..9534a53be54 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -6396,9 +6396,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "inquirer": { From fd133c0b7a2d552e73da63180e3af2e4bf4aa434 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Sep 2021 02:17:10 +0000 Subject: [PATCH 072/146] Bump normalize-url from 4.5.0 to 4.5.1 in /integration Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1. - [Release notes](https://github.com/sindresorhus/normalize-url/releases) - [Commits](https://github.com/sindresorhus/normalize-url/commits) --- updated-dependencies: - dependency-name: normalize-url dependency-type: indirect ... Signed-off-by: dependabot[bot] --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 7a50b745f3b..d43897c3520 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -8361,9 +8361,9 @@ } }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "npm-path": { From db6154b9eac60bf3ec82b959c0e6bfe1e79f0bb8 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 6 Sep 2021 12:48:11 +1000 Subject: [PATCH 073/146] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e04f5557b9..c4946c9dad1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# gqlgen [![Continuous Integration](https://github.com/99designs/gqlgen/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) +# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) ![gqlgen](https://user-images.githubusercontent.com/46195831/89802919-0bb8ef00-db2a-11ea-8ba4-88e7a58b2fd2.png) From 56451d92d626be6d15317b44e448c857297ddb68 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Wed, 8 Sep 2021 16:17:35 +1000 Subject: [PATCH 074/146] release v0.14.0 --- CHANGELOG.md | 22 +++++++++++++++++----- docs/build.sh | 3 ++- graphql/version.go | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 263ebc3eb64..8e19f19baaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -### Added +### Added + +### Changed + +### Fixed + + +## v0.14.0 - 2021-09-08 + +### Added * Added a changelog :-) Following the same style as [Apollo Client](https://github.com/apollographql/apollo-client) because that feels like it gives good thanks to the community contributors.
By [@MichaelJCompton](https://github.com/MichaelJCompton) in [#1512](https://github.com/99designs/gqlgen/pull/1512) * Added support for methods returning `(v, ok)` shaped values to support Prisma Go client.
By [@steebchen](https://github.com/steebchen) in [#1449](https://github.com/99designs/gqlgen/pull/1449) +* Added a new API to finish an already validated config
+By [@benjaminjkraft](https://github.com/benjaminjkraft) in [#1387](https://github.com/99designs/gqlgen/pull/1387) ### Changed @@ -23,8 +34,8 @@ By [@ddouglas](https://github.com/ddouglas) in [#1436](https://github.com/99desi ### Fixed -* Removed a data race by copying when input fields have default values. -Bu [@skaji](https://github.com/skaji) in [#1456](https://github.com/99designs/gqlgen/pull/1456) +* Removed a data race by copying when input fields have default values.
+By [@skaji](https://github.com/skaji) in [#1456](https://github.com/99designs/gqlgen/pull/1456) * v0.12.2 broke the handling of pointers to slices by calling the custom Marshal and Unmarshal functions on the entire slice. It now correctly calls the custom Marshal and Unmarshal methods for each element in the slice.
By [@ananyasaxena](https://github.com/ananyasaxena) in [#1363](https://github.com/99designs/gqlgen/pull/1363) * Changes in go1.16 that mean go.mod and go.sum aren't always up to date. Now `go mod tidy` is run after code generation.
@@ -35,9 +46,10 @@ By [@wilhelmeek](https://github.com/wilhelmeek) in [#1480](https://github.com/99 By [@vektah](https://github.com/vektah) in [#1399](https://github.com/99designs/gqlgen/pull/1399) * Fixed `collectFields` not correctly respecting alias fields in fragments.
By [@vmrajas](https://github.com/vmrajas) in [#1341](https://github.com/99designs/gqlgen/pull/1341) +* Return introspection document in stable order.
+* By [@nyergler](https://github.com/nyergler) in [#1497](https://github.com/99designs/gqlgen/pull/1497) - -## [0.13.0] - 2020-09-21 +## v0.13.0 - 2020-09-21 Base version at which changelog was introduced. diff --git a/docs/build.sh b/docs/build.sh index 02f3174d801..d677f22f72c 100755 --- a/docs/build.sh +++ b/docs/build.sh @@ -10,8 +10,9 @@ RESET='\033[0m' HOST=https://gqlgen.com VERSIONS_ARRAY=( - 'v0.13.0' + 'v0.14.0' 'origin/master' + 'v0.13.0' 'v0.12.2' 'v0.11.3' 'v0.10.2' diff --git a/graphql/version.go b/graphql/version.go index c3051fcb017..b2230af89d6 100644 --- a/graphql/version.go +++ b/graphql/version.go @@ -1,3 +1,3 @@ package graphql -const Version = "v0.13.0-dev" +const Version = "v0.14.0" From a991e3e73ec4d624f6b23124d83198ce51af8ae3 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 8 Sep 2021 21:50:43 +1000 Subject: [PATCH 075/146] Update errors to use go1.13 semantics --- api/generate.go | 22 +++++++++++----------- cmd/gen.go | 4 ++-- codegen/args.go | 3 +-- codegen/config/binder.go | 8 ++++---- codegen/config/config.go | 27 +++++++++++++-------------- codegen/config/config_test.go | 4 ++-- codegen/data.go | 7 +++---- codegen/directive.go | 5 ++--- codegen/field.go | 17 ++++++++--------- codegen/interface.go | 3 +-- codegen/object.go | 4 ++-- codegen/templates/templates.go | 13 ++++++------- codegen/util.go | 7 +++---- go.mod | 3 +-- internal/code/packages.go | 5 +++-- plugin/resolvergen/resolver.go | 4 ++-- plugin/servergen/server.go | 4 ++-- 17 files changed, 66 insertions(+), 74 deletions(-) diff --git a/api/generate.go b/api/generate.go index d9484005173..8d4b88de69d 100644 --- a/api/generate.go +++ b/api/generate.go @@ -1,6 +1,7 @@ package api import ( + "fmt" "syscall" "github.com/99designs/gqlgen/codegen" @@ -9,7 +10,6 @@ import ( "github.com/99designs/gqlgen/plugin/federation" "github.com/99designs/gqlgen/plugin/modelgen" "github.com/99designs/gqlgen/plugin/resolvergen" - "github.com/pkg/errors" ) func Generate(cfg *config.Config, option ...Option) error { @@ -40,7 +40,7 @@ func Generate(cfg *config.Config, option ...Option) error { } if err := cfg.LoadSchema(); err != nil { - return errors.Wrap(err, "failed to load schema") + return fmt.Errorf("failed to load schema: %w", err) } for _, p := range plugins { @@ -53,50 +53,50 @@ func Generate(cfg *config.Config, option ...Option) error { // LoadSchema again now we have everything if err := cfg.LoadSchema(); err != nil { - return errors.Wrap(err, "failed to load schema") + return fmt.Errorf("failed to load schema: %w", err) } if err := cfg.Init(); err != nil { - return errors.Wrap(err, "generating core failed") + return fmt.Errorf("generating core failed: %w", err) } for _, p := range plugins { if mut, ok := p.(plugin.ConfigMutator); ok { err := mut.MutateConfig(cfg) if err != nil { - return errors.Wrap(err, p.Name()) + return fmt.Errorf("%s: %w", p.Name(), err) } } } // Merge again now that the generated models have been injected into the typemap data, err := codegen.BuildData(cfg) if err != nil { - return errors.Wrap(err, "merging type systems failed") + return fmt.Errorf("merging type systems failed: %w", err) } if err = codegen.GenerateCode(data); err != nil { - return errors.Wrap(err, "generating core failed") + return fmt.Errorf("generating core failed: %w", err) } if err = cfg.Packages.ModTidy(); err != nil { - return errors.Wrap(err, "tidy failed") + return fmt.Errorf("tidy failed: %w", err) } for _, p := range plugins { if mut, ok := p.(plugin.CodeGenerator); ok { err := mut.GenerateCode(data) if err != nil { - return errors.Wrap(err, p.Name()) + return fmt.Errorf("%s: %w", p.Name(), err) } } } if err = codegen.GenerateCode(data); err != nil { - return errors.Wrap(err, "generating core failed") + return fmt.Errorf("generating core failed: %w", err) } if !cfg.SkipValidation { if err := validate(cfg); err != nil { - return errors.Wrap(err, "validation failed") + return fmt.Errorf("validation failed: %w", err) } } diff --git a/cmd/gen.go b/cmd/gen.go index b875bb43d02..9c564e6a414 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -1,11 +1,11 @@ package cmd import ( + "errors" "os" "github.com/99designs/gqlgen/api" "github.com/99designs/gqlgen/codegen/config" - "github.com/pkg/errors" "github.com/urfave/cli/v2" ) @@ -26,7 +26,7 @@ var genCmd = &cli.Command{ } } else { cfg, err = config.LoadConfigFromDefaultLocations() - if os.IsNotExist(errors.Cause(err)) { + if os.IsNotExist(errors.Unwrap(err)) { cfg, err = config.LoadDefaultConfig() } diff --git a/codegen/args.go b/codegen/args.go index 20a26e97542..09254262aef 100644 --- a/codegen/args.go +++ b/codegen/args.go @@ -7,7 +7,6 @@ import ( "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/codegen/templates" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" ) @@ -67,7 +66,7 @@ func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgu if arg.DefaultValue != nil { newArg.Default, err = arg.DefaultValue.Value(nil) if err != nil { - return nil, errors.Errorf("default value is not valid: %s", err.Error()) + return nil, fmt.Errorf("default value is not valid: %w", err) } } diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 68211834081..209c1205d19 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -1,13 +1,13 @@ package config import ( + "errors" "fmt" "go/token" "go/types" "github.com/99designs/gqlgen/codegen/templates" "github.com/99designs/gqlgen/internal/code" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" ) @@ -119,9 +119,9 @@ func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, erro if pkg == nil { err := b.pkgs.Errors() if err != nil { - return nil, errors.Wrapf(err, "package could not be loaded: %s", fullName) + return nil, fmt.Errorf("package could not be loaded: %s: %w", fullName, err) } - return nil, errors.Errorf("required package was not loaded: %s", fullName) + return nil, fmt.Errorf("required package was not loaded: %s", fullName) } // function based marshalers take precedence @@ -148,7 +148,7 @@ func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, erro } } - return nil, errors.Errorf("unable to find type %s\n", fullName) + return nil, fmt.Errorf("unable to find type %s\n", fullName) } func (b *Binder) PointerTo(ref *TypeReference) *TypeReference { diff --git a/codegen/config/config.go b/codegen/config/config.go index cfb22b4bf7e..75af82e5808 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/99designs/gqlgen/internal/code" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" "gopkg.in/yaml.v2" @@ -59,7 +58,7 @@ func LoadDefaultConfig() (*Config, error) { var schemaRaw []byte schemaRaw, err = ioutil.ReadFile(filename) if err != nil { - return nil, errors.Wrap(err, "unable to open schema") + return nil, fmt.Errorf("unable to open schema: %w", err) } config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) @@ -78,7 +77,7 @@ func LoadConfigFromDefaultLocations() (*Config, error) { err = os.Chdir(filepath.Dir(cfgFile)) if err != nil { - return nil, errors.Wrap(err, "unable to enter config dir") + return nil, fmt.Errorf("unable to enter config dir: %w", err) } return LoadConfig(cfgFile) } @@ -96,11 +95,11 @@ func LoadConfig(filename string) (*Config, error) { b, err := ioutil.ReadFile(filename) if err != nil { - return nil, errors.Wrap(err, "unable to read config") + return nil, fmt.Errorf("unable to read config: %w", err) } if err := yaml.UnmarshalStrict(b, config); err != nil { - return nil, errors.Wrap(err, "unable to parse config") + return nil, fmt.Errorf("unable to parse config: %w", err) } if err := CompleteConfig(config); err != nil { @@ -150,13 +149,13 @@ func CompleteConfig(config *Config) error { return nil }); err != nil { - return errors.Wrapf(err, "failed to walk schema at root %s", pathParts[0]) + return fmt.Errorf("failed to walk schema at root %s: %w", pathParts[0], err) } } else { var err error matches, err = filepath.Glob(f) if err != nil { - return errors.Wrapf(err, "failed to glob schema filename %s", f) + return fmt.Errorf("failed to glob schema filename %s: %w", f, err) } } @@ -174,7 +173,7 @@ func CompleteConfig(config *Config) error { var schemaRaw []byte schemaRaw, err = ioutil.ReadFile(filename) if err != nil { - return errors.Wrap(err, "unable to open schema") + return fmt.Errorf("unable to open schema: %w", err) } config.Sources = append(config.Sources, &ast.Source{Name: filename, Input: string(schemaRaw)}) @@ -343,10 +342,10 @@ func (c *Config) check() error { fileList := map[string][]FilenamePackage{} if err := c.Models.Check(); err != nil { - return errors.Wrap(err, "config.models") + return fmt.Errorf("config.models: %w", err) } if err := c.Exec.Check(); err != nil { - return errors.Wrap(err, "config.exec") + return fmt.Errorf("config.exec: %w", err) } fileList[c.Exec.ImportPath()] = append(fileList[c.Exec.ImportPath()], FilenamePackage{ Filename: c.Exec.Filename, @@ -356,7 +355,7 @@ func (c *Config) check() error { if c.Model.IsDefined() { if err := c.Model.Check(); err != nil { - return errors.Wrap(err, "config.model") + return fmt.Errorf("config.model: %w", err) } fileList[c.Model.ImportPath()] = append(fileList[c.Model.ImportPath()], FilenamePackage{ Filename: c.Model.Filename, @@ -366,7 +365,7 @@ func (c *Config) check() error { } if c.Resolver.IsDefined() { if err := c.Resolver.Check(); err != nil { - return errors.Wrap(err, "config.resolver") + return fmt.Errorf("config.resolver: %w", err) } fileList[c.Resolver.ImportPath()] = append(fileList[c.Resolver.ImportPath()], FilenamePackage{ Filename: c.Resolver.Filename, @@ -376,7 +375,7 @@ func (c *Config) check() error { } if c.Federation.IsDefined() { if err := c.Federation.Check(); err != nil { - return errors.Wrap(err, "config.federation") + return fmt.Errorf("config.federation: %w", err) } fileList[c.Federation.ImportPath()] = append(fileList[c.Federation.ImportPath()], FilenamePackage{ Filename: c.Federation.Filename, @@ -480,7 +479,7 @@ func inStrSlice(haystack []string, needle string) bool { func findCfg() (string, error) { dir, err := os.Getwd() if err != nil { - return "", errors.Wrap(err, "unable to get working dir to findCfg") + return "", fmt.Errorf("unable to get working dir to findCfg: %w", err) } cfg := findCfgInDir(dir) diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index b16e90c11a5..8ac68dd8360 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -1,12 +1,12 @@ package config import ( + "errors" "os" "path/filepath" "runtime" "testing" - "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/vektah/gqlparser/v2" @@ -105,7 +105,7 @@ func TestLoadDefaultConfig(t *testing.T) { require.NoError(t, err) cfg, err = LoadDefaultConfig() - require.True(t, os.IsNotExist(errors.Cause(err))) + require.True(t, os.IsNotExist(errors.Unwrap(err))) }) } diff --git a/codegen/data.go b/codegen/data.go index bedbef9d441..1a92b787801 100644 --- a/codegen/data.go +++ b/codegen/data.go @@ -4,7 +4,6 @@ import ( "fmt" "sort" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" "github.com/99designs/gqlgen/codegen/config" @@ -67,14 +66,14 @@ func BuildData(cfg *config.Config) (*Data, error) { case ast.Object: obj, err := b.buildObject(schemaType) if err != nil { - return nil, errors.Wrap(err, "unable to build object definition") + return nil, fmt.Errorf("unable to build object definition: %w", err) } s.Objects = append(s.Objects, obj) case ast.InputObject: input, err := b.buildObject(schemaType) if err != nil { - return nil, errors.Wrap(err, "unable to build input definition") + return nil, fmt.Errorf("unable to build input definition: %w", err) } s.Inputs = append(s.Inputs, input) @@ -82,7 +81,7 @@ func BuildData(cfg *config.Config) (*Data, error) { case ast.Union, ast.Interface: s.Interfaces[schemaType.Name], err = b.buildInterface(schemaType) if err != nil { - return nil, errors.Wrap(err, "unable to bind to interface") + return nil, fmt.Errorf("unable to bind to interface: %w", err) } } } diff --git a/codegen/directive.go b/codegen/directive.go index 5d4c038ffa7..2be102c2ca0 100644 --- a/codegen/directive.go +++ b/codegen/directive.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/99designs/gqlgen/codegen/templates" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" ) @@ -52,7 +51,7 @@ func (b *builder) buildDirectives() (map[string]*Directive, error) { for name, dir := range b.Schema.Directives { if _, ok := directives[name]; ok { - return nil, errors.Errorf("directive with name %s already exists", name) + return nil, fmt.Errorf("directive with name %s already exists", name) } var args []*FieldArgument @@ -72,7 +71,7 @@ func (b *builder) buildDirectives() (map[string]*Directive, error) { var err error newArg.Default, err = arg.DefaultValue.Value(nil) if err != nil { - return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error()) + return nil, fmt.Errorf("default value for directive argument %s(%s) is not valid: %w", dir.Name, arg.Name, err) } } args = append(args, newArg) diff --git a/codegen/field.go b/codegen/field.go index e091e7fe6c0..86fee340d4a 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -10,7 +10,6 @@ import ( "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/codegen/templates" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" ) @@ -51,7 +50,7 @@ func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, e var err error f.Default, err = field.DefaultValue.Value(nil) if err != nil { - return nil, errors.Errorf("default value %s is not valid: %s", field.Name, err.Error()) + return nil, fmt.Errorf("default value %s is not valid: %w", field.Name, err) } } @@ -177,7 +176,7 @@ func (b *builder) bindField(obj *Object, f *Field) (errret error) { } if err = b.bindArgs(f, params); err != nil { - return errors.Wrapf(err, "%s:%d", pos.Filename, pos.Line) + return fmt.Errorf("%s:%d: %w", pos.Filename, pos.Line, err) } result := sig.Results().At(0) @@ -246,7 +245,7 @@ func (b *builder) findBindTarget(t types.Type, name string) (types.Object, error return foundField, nil case foundField != nil && foundMethod != nil: // Error - return nil, errors.Errorf("found more than one way to bind for %s", name) + return nil, fmt.Errorf("found more than one way to bind for %s", name) } // Search embeds @@ -271,7 +270,7 @@ func (b *builder) findBindStructTagTarget(in types.Type, name string) (types.Obj tags := reflect.StructTag(t.Tag(i)) if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) { if found != nil { - return nil, errors.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val) + return nil, fmt.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val) } found = field @@ -309,7 +308,7 @@ func (b *builder) findBindMethoderTarget(methodFunc func(i int) *types.Func, met } if found != nil { - return nil, errors.Errorf("found more than one matching method to bind for %s", name) + return nil, fmt.Errorf("found more than one matching method to bind for %s", name) } found = method @@ -331,7 +330,7 @@ func (b *builder) findBindFieldTarget(in types.Type, name string) (types.Object, } if found != nil { - return nil, errors.Errorf("found more than one matching field to bind for %s", name) + return nil, fmt.Errorf("found more than one matching field to bind for %s", name) } found = field @@ -375,7 +374,7 @@ func (b *builder) findBindStructEmbedsTarget(strukt *types.Struct, name string) } if f != nil && found != nil { - return nil, errors.Errorf("found more than one way to bind for %s", name) + return nil, fmt.Errorf("found more than one way to bind for %s", name) } if f != nil { @@ -397,7 +396,7 @@ func (b *builder) findBindInterfaceEmbedsTarget(iface *types.Interface, name str } if f != nil && found != nil { - return nil, errors.Errorf("found more than one way to bind for %s", name) + return nil, fmt.Errorf("found more than one way to bind for %s", name) } if f != nil { diff --git a/codegen/interface.go b/codegen/interface.go index a55ce1e6bf9..cdc4d4d32ed 100644 --- a/codegen/interface.go +++ b/codegen/interface.go @@ -4,7 +4,6 @@ import ( "fmt" "go/types" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" "github.com/99designs/gqlgen/codegen/config" @@ -49,7 +48,7 @@ func (b *builder) buildInterface(typ *ast.Definition) (*Interface, error) { implementorType, err := findGoNamedType(obj) if err != nil { - return nil, errors.Wrapf(err, "can not find backing go type %s", obj.String()) + return nil, fmt.Errorf("can not find backing go type %s: %w", obj.String(), err) } else if implementorType == nil { return nil, fmt.Errorf("can not find backing go type %s", obj.String()) } diff --git a/codegen/object.go b/codegen/object.go index 7b91c900497..f730a7e1e31 100644 --- a/codegen/object.go +++ b/codegen/object.go @@ -1,13 +1,13 @@ package codegen import ( + "fmt" "go/types" "strconv" "strings" "unicode" "github.com/99designs/gqlgen/codegen/config" - "github.com/pkg/errors" "github.com/vektah/gqlparser/v2/ast" ) @@ -36,7 +36,7 @@ type Object struct { func (b *builder) buildObject(typ *ast.Definition) (*Object, error) { dirs, err := b.getDirectives(typ.Directives) if err != nil { - return nil, errors.Wrap(err, typ.Name) + return nil, fmt.Errorf("%s: %w", typ.Name, err) } obj := &Object{ diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index 79b0c5c7d46..637b43515dc 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -18,7 +18,6 @@ import ( "github.com/99designs/gqlgen/internal/code" "github.com/99designs/gqlgen/internal/imports" - "github.com/pkg/errors" ) // CurrentImports keeps track of all the import declarations that are needed during the execution of a plugin. @@ -79,7 +78,7 @@ func Render(cfg Options) error { var err error t, err = t.New("template.gotpl").Parse(cfg.Template) if err != nil { - return errors.Wrap(err, "error with provided template") + return fmt.Errorf("error with provided template: %w", err) } roots = append(roots, "template.gotpl") } else { @@ -99,7 +98,7 @@ func Render(cfg Options) error { t, err = t.New(name).Parse(string(b)) if err != nil { - return errors.Wrap(err, cfg.Filename) + return fmt.Errorf("%s: %w", cfg.Filename, err) } roots = append(roots, name) @@ -107,7 +106,7 @@ func Render(cfg Options) error { return nil }) if err != nil { - return errors.Wrap(err, "locating templates") + return fmt.Errorf("locating templates: %w", err) } } @@ -129,7 +128,7 @@ func Render(cfg Options) error { } err := t.Lookup(root).Execute(&buf, cfg.Data) if err != nil { - return errors.Wrap(err, root) + return fmt.Errorf("%s: %w", root, err) } if cfg.RegionTags { buf.WriteString("\n// endregion " + center(70, "*", " "+root+" ") + "\n") @@ -584,7 +583,7 @@ func render(filename string, tpldata interface{}) (*bytes.Buffer, error) { func write(filename string, b []byte, packages *code.Packages) error { err := os.MkdirAll(filepath.Dir(filename), 0755) if err != nil { - return errors.Wrap(err, "failed to create directory") + return fmt.Errorf("failed to create directory: %w", err) } formatted, err := imports.Prune(filename, b, packages) @@ -595,7 +594,7 @@ func write(filename string, b []byte, packages *code.Packages) error { err = ioutil.WriteFile(filename, formatted, 0644) if err != nil { - return errors.Wrapf(err, "failed to write %s", filename) + return fmt.Errorf("failed to write %s: %w", filename, err) } return nil diff --git a/codegen/util.go b/codegen/util.go index 59dfde08cdc..d1c4533809a 100644 --- a/codegen/util.go +++ b/codegen/util.go @@ -1,10 +1,9 @@ package codegen import ( + "fmt" "go/types" "strings" - - "github.com/pkg/errors" ) func findGoNamedType(def types.Type) (*types.Named, error) { @@ -14,7 +13,7 @@ func findGoNamedType(def types.Type) (*types.Named, error) { namedType, ok := def.(*types.Named) if !ok { - return nil, errors.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def) + return nil, fmt.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def) } return namedType, nil @@ -34,7 +33,7 @@ func findGoInterface(def types.Type) (*types.Interface, error) { underlying, ok := namedType.Underlying().(*types.Interface) if !ok { - return nil, errors.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String()) + return nil, fmt.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String()) } return underlying, nil diff --git a/go.mod b/go.mod index bbd03943083..0d2e66841ab 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/99designs/gqlgen -go 1.12 +go 1.13 require ( github.com/agnivade/levenshtein v1.1.0 // indirect @@ -16,7 +16,6 @@ require ( github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 github.com/opentracing/basictracer-go v1.0.0 // indirect github.com/opentracing/opentracing-go v1.0.2 - github.com/pkg/errors v0.8.1 github.com/rs/cors v1.6.0 github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 // indirect github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 // indirect diff --git a/internal/code/packages.go b/internal/code/packages.go index d3a4058530b..c9491802eb9 100644 --- a/internal/code/packages.go +++ b/internal/code/packages.go @@ -2,10 +2,11 @@ package code import ( "bytes" + "errors" + "fmt" "os/exec" "path/filepath" - "github.com/pkg/errors" "golang.org/x/tools/go/packages" ) @@ -154,7 +155,7 @@ func (p *Packages) ModTidy() error { p.packages = nil tidyCmd := exec.Command("go", "mod", "tidy") if err := tidyCmd.Run(); err != nil { - return errors.Wrap(err, "go mod tidy failed") + return fmt.Errorf("go mod tidy failed: %w", err) } return nil } diff --git a/plugin/resolvergen/resolver.go b/plugin/resolvergen/resolver.go index 204801efbe5..1a76b1053c0 100644 --- a/plugin/resolvergen/resolver.go +++ b/plugin/resolvergen/resolver.go @@ -1,6 +1,7 @@ package resolvergen import ( + "errors" "os" "path/filepath" "strings" @@ -10,7 +11,6 @@ import ( "github.com/99designs/gqlgen/codegen/templates" "github.com/99designs/gqlgen/internal/rewrite" "github.com/99designs/gqlgen/plugin" - "github.com/pkg/errors" ) func New() plugin.Plugin { @@ -144,7 +144,7 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error { } } - if _, err := os.Stat(data.Config.Resolver.Filename); os.IsNotExist(errors.Cause(err)) { + if _, err := os.Stat(data.Config.Resolver.Filename); os.IsNotExist(errors.Unwrap(err)) { err := templates.Render(templates.Options{ PackageName: data.Config.Resolver.Package, FileNotice: ` diff --git a/plugin/servergen/server.go b/plugin/servergen/server.go index 029c9ae398e..e430310c539 100644 --- a/plugin/servergen/server.go +++ b/plugin/servergen/server.go @@ -1,13 +1,13 @@ package servergen import ( + "errors" "log" "os" "github.com/99designs/gqlgen/codegen" "github.com/99designs/gqlgen/codegen/templates" "github.com/99designs/gqlgen/plugin" - "github.com/pkg/errors" ) func New(filename string) plugin.Plugin { @@ -29,7 +29,7 @@ func (m *Plugin) GenerateCode(data *codegen.Data) error { ResolverPackageName: data.Config.Resolver.ImportPath(), } - if _, err := os.Stat(m.filename); os.IsNotExist(errors.Cause(err)) { + if _, err := os.Stat(m.filename); os.IsNotExist(errors.Unwrap(err)) { return templates.Render(templates.Options{ PackageName: "main", Filename: m.filename, From 60d80d4aee61337793d2cade8a7ab35c2892613a Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Thu, 9 Sep 2021 14:32:57 +1000 Subject: [PATCH 076/146] Update cmd/gen.go Co-authored-by: Luke Cawood --- cmd/gen.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/gen.go b/cmd/gen.go index 9c564e6a414..706313cee30 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -26,7 +26,7 @@ var genCmd = &cli.Command{ } } else { cfg, err = config.LoadConfigFromDefaultLocations() - if os.IsNotExist(errors.Unwrap(err)) { + if errors.Is(err, fs.ErrNotExist) { cfg, err = config.LoadDefaultConfig() } From de7d19c812bed562d2841c6c08fb080d706195d1 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Thu, 9 Sep 2021 14:33:10 +1000 Subject: [PATCH 077/146] Update codegen/config/config_test.go Co-authored-by: Luke Cawood --- codegen/config/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index 8ac68dd8360..f0d6ab89822 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -105,7 +105,7 @@ func TestLoadDefaultConfig(t *testing.T) { require.NoError(t, err) cfg, err = LoadDefaultConfig() - require.True(t, os.IsNotExist(errors.Unwrap(err))) + require.True(t, errors.Is(err, fs.ErrNotExist)) }) } From a6c6de6b73741caa1ac02cf8adea79afcd4ed78b Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Thu, 9 Sep 2021 14:33:21 +1000 Subject: [PATCH 078/146] Update plugin/resolvergen/resolver.go Co-authored-by: Luke Cawood --- plugin/resolvergen/resolver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/resolvergen/resolver.go b/plugin/resolvergen/resolver.go index 1a76b1053c0..8c61836f750 100644 --- a/plugin/resolvergen/resolver.go +++ b/plugin/resolvergen/resolver.go @@ -144,7 +144,7 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error { } } - if _, err := os.Stat(data.Config.Resolver.Filename); os.IsNotExist(errors.Unwrap(err)) { + if _, err := os.Stat(data.Config.Resolver.Filename); errors.Is(err, fs.ErrNotExist) { err := templates.Render(templates.Options{ PackageName: data.Config.Resolver.Package, FileNotice: ` From d747387036fb300fc384fa6f17a76f6547dc6a1b Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Thu, 9 Sep 2021 14:33:30 +1000 Subject: [PATCH 079/146] Update plugin/servergen/server.go Co-authored-by: Luke Cawood --- plugin/servergen/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/servergen/server.go b/plugin/servergen/server.go index e430310c539..05fe885fcd6 100644 --- a/plugin/servergen/server.go +++ b/plugin/servergen/server.go @@ -29,7 +29,7 @@ func (m *Plugin) GenerateCode(data *codegen.Data) error { ResolverPackageName: data.Config.Resolver.ImportPath(), } - if _, err := os.Stat(m.filename); os.IsNotExist(errors.Unwrap(err)) { + if _, err := os.Stat(m.filename); errors.Is(err, fs.ErrNotExist) { return templates.Render(templates.Options{ PackageName: "main", Filename: m.filename, From 5c7acc1bc8198ed57a38867ae0c452987da91911 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 09:21:30 +1000 Subject: [PATCH 080/146] Fix imports --- cmd/gen.go | 2 +- codegen/config/config_test.go | 1 + plugin/resolvergen/resolver.go | 1 + plugin/servergen/server.go | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/gen.go b/cmd/gen.go index 706313cee30..f973cc22c0f 100644 --- a/cmd/gen.go +++ b/cmd/gen.go @@ -2,7 +2,7 @@ package cmd import ( "errors" - "os" + "io/fs" "github.com/99designs/gqlgen/api" "github.com/99designs/gqlgen/codegen/config" diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index f0d6ab89822..9dcd0a59958 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -2,6 +2,7 @@ package config import ( "errors" + "io/fs" "os" "path/filepath" "runtime" diff --git a/plugin/resolvergen/resolver.go b/plugin/resolvergen/resolver.go index 8c61836f750..e63501d2bc6 100644 --- a/plugin/resolvergen/resolver.go +++ b/plugin/resolvergen/resolver.go @@ -2,6 +2,7 @@ package resolvergen import ( "errors" + "io/fs" "os" "path/filepath" "strings" diff --git a/plugin/servergen/server.go b/plugin/servergen/server.go index 05fe885fcd6..cdabc409fe6 100644 --- a/plugin/servergen/server.go +++ b/plugin/servergen/server.go @@ -2,6 +2,7 @@ package servergen import ( "errors" + "io/fs" "log" "os" From ed210385722431111b8842ec7da7b42051b77d91 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 09:38:37 +1000 Subject: [PATCH 081/146] Update to go 1.17 --- .github/workflows/integration.yml | 6 +++--- .github/workflows/lint.yml | 4 ++-- .github/workflows/test.yml | 2 +- go.mod | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 8000b49bd50..7f0fb419433 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -5,7 +5,7 @@ jobs: integration: runs-on: ubuntu-latest timeout-minutes: 3 - container: golang:1.13-alpine + container: golang:1.17-alpine steps: - uses: actions/checkout@v1 - run: apk add --no-cache --no-progress nodejs npm git bash @@ -15,7 +15,7 @@ jobs: federation: runs-on: ubuntu-latest - container: golang:1.13-alpine + container: golang:1.17-alpine steps: - uses: actions/checkout@v1 - run: apk add --no-cache --no-progress nodejs npm git bash @@ -25,7 +25,7 @@ jobs: init: runs-on: ubuntu-latest - container: golang:1.16-alpine + container: golang:1.17-alpine steps: - uses: actions/checkout@v1 - run: apk add --no-cache --no-progress alpine-sdk bash diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 27b256b6f9f..44695d14b86 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -7,7 +7,7 @@ jobs: steps: - uses: actions/checkout@v1 - uses: actions/setup-go@v2 - with: { go-version: 1.14 } + with: { go-version: 1.17 } - run: go mod download - run: .github/workflows/check-fmt - run: .github/workflows/check-linting @@ -18,7 +18,7 @@ jobs: steps: - uses: actions/checkout@v1 - uses: actions/setup-go@v2 - with: { go-version: 1.14 } + with: { go-version: 1.17 } - run: go mod download - run: .github/workflows/check-coverage env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1df7ffaf751..a27fff46648 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ jobs: test: strategy: matrix: - go: [1.13, 1.14] + go: 1.17 os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} diff --git a/go.mod b/go.mod index 0d2e66841ab..8ebf9dc744a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/99designs/gqlgen -go 1.13 +go 1.17 require ( github.com/agnivade/levenshtein v1.1.0 // indirect From 10bb1ef262af49031c3d5224eb094586e6fd8083 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 09:41:17 +1000 Subject: [PATCH 082/146] Go mod tidy --- go.mod | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/go.mod b/go.mod index 8ebf9dc744a..b1dd02f0e3c 100644 --- a/go.mod +++ b/go.mod @@ -28,3 +28,16 @@ require ( sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect ) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pkg/errors v0.8.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.0.1 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + golang.org/x/mod v0.3.0 // indirect + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect +) From 402f44950b4694a3a5fd65d3225e06ccd76fbf9d Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 09:44:59 +1000 Subject: [PATCH 083/146] go fmt --- graphql/executable_schema_mock.go | 3 ++- internal/imports/testdata/unused.go | 8 +++++--- internal/rewrite/testdata/example.go | 6 ++++-- tools.go | 1 + 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/graphql/executable_schema_mock.go b/graphql/executable_schema_mock.go index 0c021d3d003..6f38818391f 100644 --- a/graphql/executable_schema_mock.go +++ b/graphql/executable_schema_mock.go @@ -5,8 +5,9 @@ package graphql import ( "context" - "github.com/vektah/gqlparser/v2/ast" "sync" + + "github.com/vektah/gqlparser/v2/ast" ) var ( diff --git a/internal/imports/testdata/unused.go b/internal/imports/testdata/unused.go index db4c9b4d278..95cbe2d00ff 100644 --- a/internal/imports/testdata/unused.go +++ b/internal/imports/testdata/unused.go @@ -1,8 +1,10 @@ package testdata -import _ "underscore" -import a "fmt" -import "time" +import ( + a "fmt" + "time" + _ "underscore" +) type foo struct { Time time.Time `json:"text"` diff --git a/internal/rewrite/testdata/example.go b/internal/rewrite/testdata/example.go index a688348210b..949bbe8235d 100644 --- a/internal/rewrite/testdata/example.go +++ b/internal/rewrite/testdata/example.go @@ -1,8 +1,10 @@ package testdata -import "fmt" +import ( + "fmt" -import lol "bytes" + lol "bytes" +) type Foo struct { Field int diff --git a/tools.go b/tools.go index e63a71a8055..47e0bd690cb 100644 --- a/tools.go +++ b/tools.go @@ -1,3 +1,4 @@ +//go:build tools // +build tools package main From 90c5eb59b0fde89eb0c42e5b9c5ad276a8335f8f Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 09:49:50 +1000 Subject: [PATCH 084/146] go generate --- graphql/executable_schema_mock.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/graphql/executable_schema_mock.go b/graphql/executable_schema_mock.go index 6f38818391f..0c021d3d003 100644 --- a/graphql/executable_schema_mock.go +++ b/graphql/executable_schema_mock.go @@ -5,9 +5,8 @@ package graphql import ( "context" - "sync" - "github.com/vektah/gqlparser/v2/ast" + "sync" ) var ( From 5216db5849eb5298722ee233cc98fa1e85db3237 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 10:54:05 +1000 Subject: [PATCH 085/146] Fix TestAutobinding test failure by checking the module --- codegen/config/config.go | 2 +- go.mod | 8 ++++---- go.sum | 11 +++++++++++ internal/code/packages.go | 3 ++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index 75af82e5808..09ae7835600 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -519,7 +519,7 @@ func (c *Config) autobind() error { } for i, p := range ps { - if p == nil { + if p.Module == nil { return fmt.Errorf("unable to load %s - make sure you're using an import path to a package that exists", c.AutoBind[i]) } if t := p.Types.Scope().Lookup(t.Name); t != nil { diff --git a/go.mod b/go.mod index b1dd02f0e3c..78a5fb6b034 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/urfave/cli/v2 v2.1.1 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e github.com/vektah/gqlparser/v2 v2.2.0 - golang.org/x/tools v0.0.0-20210106214847-113979e3529a + golang.org/x/tools v0.1.5 gopkg.in/yaml.v2 v2.2.4 sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect @@ -36,8 +36,8 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - golang.org/x/mod v0.3.0 // indirect - golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect - golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect + golang.org/x/mod v0.4.2 // indirect + golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/go.sum b/go.sum index fe1fd7471b6..d580c9b649a 100644 --- a/go.sum +++ b/go.sum @@ -79,12 +79,16 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -94,6 +98,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -103,6 +112,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/code/packages.go b/internal/code/packages.go index c9491802eb9..39ba374eab6 100644 --- a/internal/code/packages.go +++ b/internal/code/packages.go @@ -15,7 +15,8 @@ var mode = packages.NeedName | packages.NeedImports | packages.NeedTypes | packages.NeedSyntax | - packages.NeedTypesInfo + packages.NeedTypesInfo | + packages.NeedModule // Packages is a wrapper around x/tools/go/packages that maintains a (hopefully prewarmed) cache of packages // that can be invalidated as writes are made and packages are known to change. From ed8054b054c4e7dae1c2ad12d86a8d4d26c194e9 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 13:32:59 +1000 Subject: [PATCH 086/146] Update to a post-release version --- graphql/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphql/version.go b/graphql/version.go index b2230af89d6..b44ff9ee3f1 100644 --- a/graphql/version.go +++ b/graphql/version.go @@ -1,3 +1,3 @@ package graphql -const Version = "v0.14.0" +const Version = "v0.14.0-dev" From 682a7d662bd2491213c45b8556461533cee56997 Mon Sep 17 00:00:00 2001 From: MengZeLee Date: Fri, 10 Sep 2021 15:09:36 +0800 Subject: [PATCH 087/146] fix Options response header operatee the header of ResponseWriter should before WriteHeader called --- graphql/handler/transport/options.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphql/handler/transport/options.go b/graphql/handler/transport/options.go index 674a00c7f09..6b725ff3e3e 100644 --- a/graphql/handler/transport/options.go +++ b/graphql/handler/transport/options.go @@ -18,8 +18,8 @@ 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.WriteHeader(http.StatusOK) w.Header().Set("Allow", "OPTIONS, GET, POST") + w.WriteHeader(http.StatusOK) case http.MethodHead: w.WriteHeader(http.StatusMethodNotAllowed) } From 59da23feb5e135b3c2c0ce976b0214643147e85c Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 21:19:23 +1000 Subject: [PATCH 088/146] Create a temporary file on init so go recognises the directory as a package --- .github/workflows/check-init | 2 +- cmd/init.go | 97 ++++++++++++++++++------------------ codegen/config/config.go | 2 +- 3 files changed, 50 insertions(+), 51 deletions(-) diff --git a/.github/workflows/check-init b/.github/workflows/check-init index 9c09e84f407..4197a5644e8 100755 --- a/.github/workflows/check-init +++ b/.github/workflows/check-init @@ -4,7 +4,7 @@ set -euo pipefail cd example/init -go get github.com/99designs/gqlgen +go get -d github.com/99designs/gqlgen if { go run github.com/99designs/gqlgen init 2>&1 >&3 3>&- | grep '^' >&2; } 3>&1; then echo "gqlgen init failed validation" diff --git a/cmd/init.go b/cmd/init.go index ad95a5cec50..daa449969a7 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -2,8 +2,10 @@ package cmd import ( "bytes" + "errors" "fmt" "html/template" + "io/fs" "io/ioutil" "os" "path/filepath" @@ -122,77 +124,74 @@ var initCmd = &cli.Command{ return fmt.Errorf("unable to determine import path for current directory, you probably need to run go mod init first") } - if err := initSchema(ctx.String("schema")); err != nil { + if err := initFile(ctx.String("schema"), schemaDefault); err != nil { return err } - if !configExists(configFilename) { - if err := initConfig(configFilename, pkgName); err != nil { + + cfg, err := loadConfig(configFilename) + + if err != nil { + if configFilename == "" { + configFilename = "gqlgen.yml" + } + + fmt.Println("Creating", configFilename) + if err := initFile(configFilename, executeConfigTemplate(pkgName)); err != nil { return err } - } - GenerateGraphServer(serverFilename) - return nil - }, -} + // create the package directory with a temporary file so that go recognises it as a package + // and autobinding doesn't error out + tmpPackageNameFile := "graph/model/_tmp_gqlgen_init.go" + if err := initFile(tmpPackageNameFile, "package model"); err != nil { + return err + } + defer os.Remove(tmpPackageNameFile) -func GenerateGraphServer(serverFilename string) { - cfg, err := config.LoadConfigFromDefaultLocations() - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - } + if cfg, err = loadConfig(configFilename); err != nil { + panic(err) + } + } else { + fmt.Println("Skipping creating gqlgen.yml as it already exists") + } - if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - } + fmt.Println("Creating graph/...") + fmt.Println("Creating", serverFilename) + if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + } - fmt.Fprintf(os.Stdout, "Exec \"go run ./%s\" to start GraphQL server\n", serverFilename) + fmt.Fprintf(os.Stdout, "\nExec \"go run ./%s\" to start GraphQL server\n", serverFilename) + return nil + }, } -func configExists(configFilename string) bool { - var cfg *config.Config - +func loadConfig(configFilename string) (*config.Config, error) { if configFilename != "" { - cfg, _ = config.LoadConfig(configFilename) + return config.LoadConfig(configFilename) } else { - cfg, _ = config.LoadConfigFromDefaultLocations() + return config.LoadConfigFromDefaultLocations() } - return cfg != nil } -func initConfig(configFilename string, pkgName string) error { - if configFilename == "" { - configFilename = "gqlgen.yml" - } - - if err := os.MkdirAll(filepath.Dir(configFilename), 0755); err != nil { - return fmt.Errorf("unable to create config dir: " + err.Error()) - } - +func executeConfigTemplate(pkgName string) string { var buf bytes.Buffer if err := configTemplate.Execute(&buf, pkgName); err != nil { panic(err) } - if err := ioutil.WriteFile(configFilename, buf.Bytes(), 0644); err != nil { - return fmt.Errorf("unable to write cfg file: " + err.Error()) - } - - return nil + return buf.String() } -func initSchema(schemaFilename string) error { - _, err := os.Stat(schemaFilename) - if !os.IsNotExist(err) { - return nil - } - - if err := os.MkdirAll(filepath.Dir(schemaFilename), 0755); err != nil { - return fmt.Errorf("unable to create schema dir: " + err.Error()) - } - - if err = ioutil.WriteFile(schemaFilename, []byte(schemaDefault), 0644); err != nil { - return fmt.Errorf("unable to write schema file: " + err.Error()) +func initFile(filename, contents string) error { + _, err := os.Stat(filename) + if errors.Is(err, fs.ErrNotExist) { + if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { + return fmt.Errorf("unable to create directory for file '%s': %w", filename, err) + } + if err = ioutil.WriteFile(filename, []byte(contents), 0644); err != nil { + return fmt.Errorf("unable to write file '%s': %w", filename, err) + } } return nil } diff --git a/codegen/config/config.go b/codegen/config/config.go index 09ae7835600..d29630d027e 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -519,7 +519,7 @@ func (c *Config) autobind() error { } for i, p := range ps { - if p.Module == nil { + if p == nil || p.Module == nil { return fmt.Errorf("unable to load %s - make sure you're using an import path to a package that exists", c.AutoBind[i]) } if t := p.Types.Scope().Lookup(t.Name); t != nil { From 1c63cfff8f2943d2ab3316f850b89bba83548c05 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 21:29:35 +1000 Subject: [PATCH 089/146] Add missing model package file --- example/federation/accounts/graph/model/model.go | 1 + example/federation/products/graph/model/model.go | 1 + 2 files changed, 2 insertions(+) create mode 100644 example/federation/accounts/graph/model/model.go create mode 100644 example/federation/products/graph/model/model.go diff --git a/example/federation/accounts/graph/model/model.go b/example/federation/accounts/graph/model/model.go new file mode 100644 index 00000000000..8b537907051 --- /dev/null +++ b/example/federation/accounts/graph/model/model.go @@ -0,0 +1 @@ +package model diff --git a/example/federation/products/graph/model/model.go b/example/federation/products/graph/model/model.go new file mode 100644 index 00000000000..8b537907051 --- /dev/null +++ b/example/federation/products/graph/model/model.go @@ -0,0 +1 @@ +package model From c6b9f2926b14c0367ffb82db4e2c250c4fc7aab2 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 21:30:02 +1000 Subject: [PATCH 090/146] go mod tidy --- go.sum | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/go.sum b/go.sum index d580c9b649a..14f53f5b1ab 100644 --- a/go.sum +++ b/go.sum @@ -73,11 +73,11 @@ github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7 github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -85,18 +85,17 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -110,7 +109,6 @@ golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= From a644175b8f80ba1fbc220799b4cd9ce257ccc7ac Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 21:36:34 +1000 Subject: [PATCH 091/146] Update error checks for go 1.17 --- codegen/config/config_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index 9dcd0a59958..56001118afb 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -83,7 +83,7 @@ func TestLoadConfigFromDefaultLocation(t *testing.T) { require.NoError(t, err) cfg, err = LoadConfigFromDefaultLocations() - require.True(t, os.IsNotExist(err)) + require.True(t, errors.Is(err, fs.ErrNotExist)) }) } From a8903ca2aca700217fe29c2b8c262b6ee45959fb Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 21:42:48 +1000 Subject: [PATCH 092/146] Wrap errors --- client/client.go | 8 ++++---- client/websocket.go | 18 +++++++++--------- internal/rewrite/rewriter.go | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/client/client.go b/client/client.go index 64367931e9f..9c5f56c8fc3 100644 --- a/client/client.go +++ b/client/client.go @@ -82,7 +82,7 @@ func (p *Client) Post(query string, response interface{}, options ...Option) err func (p *Client) RawPost(query string, options ...Option) (*Response, error) { r, err := p.newRequest(query, options...) if err != nil { - return nil, fmt.Errorf("build: %s", err.Error()) + return nil, fmt.Errorf("build: %w", err) } w := httptest.NewRecorder() @@ -97,7 +97,7 @@ func (p *Client) RawPost(query string, options ...Option) (*Response, error) { respDataRaw := &Response{} err = json.Unmarshal(w.Body.Bytes(), &respDataRaw) if err != nil { - return nil, fmt.Errorf("decode: %s", err.Error()) + return nil, fmt.Errorf("decode: %w", err) } return respDataRaw, nil @@ -123,7 +123,7 @@ func (p *Client) newRequest(query string, options ...Option) (*http.Request, err case "application/json": requestBody, err := json.Marshal(bd) if err != nil { - return nil, fmt.Errorf("encode: %s", err.Error()) + return nil, fmt.Errorf("encode: %w", err) } bd.HTTP.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody)) default: @@ -141,7 +141,7 @@ func unpack(data interface{}, into interface{}) error { ZeroFields: true, }) if err != nil { - return fmt.Errorf("mapstructure: %s", err.Error()) + return fmt.Errorf("mapstructure: %w", err) } return d.Decode(data) diff --git a/client/websocket.go b/client/websocket.go index 35c74dddcd3..ca6ee7c4723 100644 --- a/client/websocket.go +++ b/client/websocket.go @@ -53,12 +53,12 @@ func (p *Client) WebsocketOnce(query string, resp interface{}, options ...Option func (p *Client) WebsocketWithPayload(query string, initPayload map[string]interface{}, options ...Option) *Subscription { r, err := p.newRequest(query, options...) if err != nil { - return errorSubscription(fmt.Errorf("request: %s", err.Error())) + return errorSubscription(fmt.Errorf("request: %w", err)) } requestBody, err := ioutil.ReadAll(r.Body) if err != nil { - return errorSubscription(fmt.Errorf("parse body: %s", err.Error())) + return errorSubscription(fmt.Errorf("parse body: %w", err)) } srv := httptest.NewServer(p.h) @@ -66,24 +66,24 @@ func (p *Client) WebsocketWithPayload(query string, initPayload map[string]inter c, _, err := websocket.DefaultDialer.Dial(host+r.URL.Path, r.Header) if err != nil { - return errorSubscription(fmt.Errorf("dial: %s", err.Error())) + return errorSubscription(fmt.Errorf("dial: %w", err)) } initMessage := operationMessage{Type: connectionInitMsg} if initPayload != nil { initMessage.Payload, err = json.Marshal(initPayload) if err != nil { - return errorSubscription(fmt.Errorf("parse payload: %s", err.Error())) + return errorSubscription(fmt.Errorf("parse payload: %w", err)) } } if err = c.WriteJSON(initMessage); err != nil { - return errorSubscription(fmt.Errorf("init: %s", err.Error())) + return errorSubscription(fmt.Errorf("init: %w", err)) } var ack operationMessage if err = c.ReadJSON(&ack); err != nil { - return errorSubscription(fmt.Errorf("ack: %s", err.Error())) + return errorSubscription(fmt.Errorf("ack: %w", err)) } if ack.Type != connectionAckMsg { @@ -92,7 +92,7 @@ func (p *Client) WebsocketWithPayload(query string, initPayload map[string]inter var ka operationMessage if err = c.ReadJSON(&ka); err != nil { - return errorSubscription(fmt.Errorf("ack: %s", err.Error())) + return errorSubscription(fmt.Errorf("ack: %w", err)) } if ka.Type != connectionKaMsg { @@ -100,7 +100,7 @@ func (p *Client) WebsocketWithPayload(query string, initPayload map[string]inter } if err = c.WriteJSON(operationMessage{Type: startMsg, ID: "1", Payload: requestBody}); err != nil { - return errorSubscription(fmt.Errorf("start: %s", err.Error())) + return errorSubscription(fmt.Errorf("start: %w", err)) } return &Subscription{ @@ -125,7 +125,7 @@ func (p *Client) WebsocketWithPayload(query string, initPayload map[string]inter var respDataRaw Response err = json.Unmarshal(op.Payload, &respDataRaw) if err != nil { - return fmt.Errorf("decode: %s", err.Error()) + return fmt.Errorf("decode: %w", err) } // we want to unpack even if there is an error, so we can see partial responses diff --git a/internal/rewrite/rewriter.go b/internal/rewrite/rewriter.go index 1b9adb171ee..f70fbdc1d59 100644 --- a/internal/rewrite/rewriter.go +++ b/internal/rewrite/rewriter.go @@ -58,7 +58,7 @@ func (r *Rewriter) getFile(filename string) string { if _, ok := r.files[filename]; !ok { b, err := ioutil.ReadFile(filename) if err != nil { - panic(fmt.Errorf("unable to load file, already exists: %s", err.Error())) + panic(fmt.Errorf("unable to load file, already exists: %w", err)) } r.files[filename] = string(b) From 71e5784352a3c6d7b91bf9f2307fcebc959ab8b0 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 10 Sep 2021 22:53:55 +1000 Subject: [PATCH 093/146] Simplify init --- cmd/init.go | 95 ++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/cmd/init.go b/cmd/init.go index daa449969a7..4cf70dde68b 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -111,69 +111,71 @@ var initCmd = &cli.Command{ Usage: "create a new gqlgen project", Flags: []cli.Flag{ &cli.BoolFlag{Name: "verbose, v", Usage: "show logs"}, - &cli.StringFlag{Name: "config, c", Usage: "the config filename"}, + &cli.StringFlag{Name: "config, c", Usage: "the config filename", Value: "gqlgen.yml"}, &cli.StringFlag{Name: "server", Usage: "where to write the server stub to", Value: "server.go"}, &cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "graph/schema.graphqls"}, }, Action: func(ctx *cli.Context) error { configFilename := ctx.String("config") serverFilename := ctx.String("server") + schemaFilename := ctx.String("schema") pkgName := code.ImportPathForDir(".") if pkgName == "" { return fmt.Errorf("unable to determine import path for current directory, you probably need to run go mod init first") } - if err := initFile(ctx.String("schema"), schemaDefault); err != nil { + // check schema and config don't already exist + if fileExists(configFilename) { + return fmt.Errorf("%s already exists\n", configFilename) + } + if fileExists(schemaFilename) { + return fmt.Errorf("%s already exists\n", schemaFilename) + } + if fileExists(serverFilename) { + return fmt.Errorf("%s already exists\n", serverFilename) + } + _, err := config.LoadConfigFromDefaultLocations() + if err == nil { + return fmt.Errorf("gqlgen.yml already exists in a parent directory\n") + } + + // create config + fmt.Println("Creating", configFilename) + if err := initFile(configFilename, executeConfigTemplate(pkgName)); err != nil { + return err + } + + // create schema + fmt.Println("Creating", schemaFilename) + if err := initFile(schemaFilename, schemaDefault); err != nil { + return err + } + + // create the package directory with a temporary file so that go recognises it as a package + // and autobinding doesn't error out + tmpPackageNameFile := "graph/model/_tmp_gqlgen_init.go" + if err := initFile(tmpPackageNameFile, "package model"); err != nil { return err } + defer os.Remove(tmpPackageNameFile) - cfg, err := loadConfig(configFilename) - - if err != nil { - if configFilename == "" { - configFilename = "gqlgen.yml" - } - - fmt.Println("Creating", configFilename) - if err := initFile(configFilename, executeConfigTemplate(pkgName)); err != nil { - return err - } - - // create the package directory with a temporary file so that go recognises it as a package - // and autobinding doesn't error out - tmpPackageNameFile := "graph/model/_tmp_gqlgen_init.go" - if err := initFile(tmpPackageNameFile, "package model"); err != nil { - return err - } - defer os.Remove(tmpPackageNameFile) - - if cfg, err = loadConfig(configFilename); err != nil { - panic(err) - } - } else { - fmt.Println("Skipping creating gqlgen.yml as it already exists") + var cfg *config.Config + if cfg, err = config.LoadConfig(configFilename); err != nil { + panic(err) } - fmt.Println("Creating graph/...") fmt.Println("Creating", serverFilename) + fmt.Println("Generating...") if err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename))); err != nil { fmt.Fprintln(os.Stderr, err.Error()) } - fmt.Fprintf(os.Stdout, "\nExec \"go run ./%s\" to start GraphQL server\n", serverFilename) + fmt.Printf("\nExec \"go run ./%s\" to start GraphQL server\n", serverFilename) return nil }, } -func loadConfig(configFilename string) (*config.Config, error) { - if configFilename != "" { - return config.LoadConfig(configFilename) - } else { - return config.LoadConfigFromDefaultLocations() - } -} - func executeConfigTemplate(pkgName string) string { var buf bytes.Buffer if err := configTemplate.Execute(&buf, pkgName); err != nil { @@ -183,15 +185,18 @@ func executeConfigTemplate(pkgName string) string { return buf.String() } -func initFile(filename, contents string) error { +func fileExists(filename string) bool { _, err := os.Stat(filename) - if errors.Is(err, fs.ErrNotExist) { - if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { - return fmt.Errorf("unable to create directory for file '%s': %w", filename, err) - } - if err = ioutil.WriteFile(filename, []byte(contents), 0644); err != nil { - return fmt.Errorf("unable to write file '%s': %w", filename, err) - } + return !errors.Is(err, fs.ErrNotExist) +} + +func initFile(filename, contents string) error { + if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil { + return fmt.Errorf("unable to create directory for file '%s': %w\n", filename, err) } + if err := ioutil.WriteFile(filename, []byte(contents), 0644); err != nil { + return fmt.Errorf("unable to write file '%s': %w\n", filename, err) + } + return nil } From f67a5b2611ca89dfb0ffd3dd4c72cebb8f2532ef Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 12:46:35 +1000 Subject: [PATCH 094/146] Update github.com/urfave/cli/v2 --- go.mod | 7 +++---- go.sum | 12 +++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 78a5fb6b034..f63d58e4b43 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 // indirect github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 // indirect github.com/stretchr/testify v1.4.0 - github.com/urfave/cli/v2 v2.1.1 + github.com/urfave/cli/v2 v2.3.0 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e github.com/vektah/gqlparser/v2 v2.2.0 golang.org/x/tools v0.1.5 @@ -30,12 +30,11 @@ require ( ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/pkg/errors v0.8.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect golang.org/x/mod v0.4.2 // indirect golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect diff --git a/go.sum b/go.sum index 14f53f5b1ab..e80fdd19148 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,9 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,13 +52,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 h1:SWV2fHctRpRrp49VXJ6UZja7gU9QLHwRpIPBN89SKEo= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 h1:JJV9CsgM9EC9w2iVkwuz+sMx8yRFe89PJRUrv6hPCIA= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= @@ -65,8 +66,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= -github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= @@ -121,6 +122,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= From 9162c53fc32471c96d874764b47bf71f0c493fce Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 13:20:57 +1000 Subject: [PATCH 095/146] Fix newlines in error messages --- cmd/init.go | 12 ++++-------- cmd/root.go | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cmd/init.go b/cmd/init.go index 4cf70dde68b..1a528be4d85 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -126,14 +126,10 @@ var initCmd = &cli.Command{ } // check schema and config don't already exist - if fileExists(configFilename) { - return fmt.Errorf("%s already exists\n", configFilename) - } - if fileExists(schemaFilename) { - return fmt.Errorf("%s already exists\n", schemaFilename) - } - if fileExists(serverFilename) { - return fmt.Errorf("%s already exists\n", serverFilename) + for _, filename := range []string{configFilename, schemaFilename, serverFilename} { + if fileExists(filename) { + return fmt.Errorf("%s already exists", filename) + } } _, err := config.LoadConfigFromDefaultLocations() if err == nil { diff --git a/cmd/root.go b/cmd/root.go index 2776aa2842f..ce96c1b86d2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -39,7 +39,7 @@ func Execute() { } if err := app.Run(os.Args); err != nil { - fmt.Fprint(os.Stderr, err.Error()) + fmt.Fprint(os.Stderr, err.Error()+"\n") os.Exit(1) } } From f93fb2489285eef0542c4aa7b11341a8479b606a Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Wed, 8 Sep 2021 14:50:35 +1000 Subject: [PATCH 096/146] Split examples into separate go module --- .github/workflows/check-fmt | 1 + .github/workflows/check-generate | 2 +- .github/workflows/test.yml | 4 +- codegen/config/binder_test.go | 6 +- codegen/config/config_test.go | 8 +- .../testdata/autobinding/chat/message.go | 12 ++ .../autobinding/scalars/model/model.go | 30 ++++ example/go.mod | 39 +++++ example/go.sum | 157 ++++++++++++++++++ example/tools.go | 7 + go.mod | 15 +- go.sum | 43 ----- tools.go | 1 - 13 files changed, 257 insertions(+), 68 deletions(-) create mode 100644 codegen/config/testdata/autobinding/chat/message.go create mode 100644 codegen/config/testdata/autobinding/scalars/model/model.go create mode 100644 example/go.mod create mode 100644 example/go.sum create mode 100644 example/tools.go diff --git a/.github/workflows/check-fmt b/.github/workflows/check-fmt index cf68afec76e..de84fb0d7b4 100755 --- a/.github/workflows/check-fmt +++ b/.github/workflows/check-fmt @@ -3,6 +3,7 @@ set -euo pipefail go fmt ./... +cd example && go fmt ./... if [[ $(git --no-pager diff) ]] ; then echo "you need to run "go fmt" and commit the changes" git --no-pager diff diff --git a/.github/workflows/check-generate b/.github/workflows/check-generate index 25bd59626dc..0832cc10e06 100755 --- a/.github/workflows/check-generate +++ b/.github/workflows/check-generate @@ -3,7 +3,7 @@ set -euo pipefail go generate ./... - +cd example && go generate ./... if [[ $(git --no-pager diff) ]] ; then echo "you need to run "go generate ./..." and commit the changes" git --no-pager diff diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a27fff46648..d1234892d9f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,5 +14,5 @@ jobs: - uses: actions/setup-go@v2 with: go-version: ${{ matrix.go }} - - run: go mod download - - run: go test -race ./... + - run: go mod download && go test -race ./... + - run: cd example && go mod download && go test -race ./... diff --git a/codegen/config/binder_test.go b/codegen/config/binder_test.go index 67e9ed011ba..55227563d82 100644 --- a/codegen/config/binder_test.go +++ b/codegen/config/binder_test.go @@ -28,7 +28,7 @@ func TestSlicePointerBinding(t *testing.T) { panic(err) } - require.Equal(t, ta.GO.String(), "[]*github.com/99designs/gqlgen/example/chat.Message") + require.Equal(t, ta.GO.String(), "[]*github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message") }) t.Run("with OmitSliceElementPointers", func(t *testing.T) { @@ -41,14 +41,14 @@ func TestSlicePointerBinding(t *testing.T) { panic(err) } - require.Equal(t, ta.GO.String(), "[]github.com/99designs/gqlgen/example/chat.Message") + require.Equal(t, ta.GO.String(), "[]github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message") }) } func createBinder(cfg Config) (*Binder, *ast.Schema) { cfg.Models = TypeMap{ "Message": TypeMapEntry{ - Model: []string{"github.com/99designs/gqlgen/example/chat.Message"}, + Model: []string{"github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message"}, }, } cfg.Packages = &code.Packages{} diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index 56001118afb..2e7935e58d7 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -174,8 +174,8 @@ func TestAutobinding(t *testing.T) { cfg := Config{ Models: TypeMap{}, AutoBind: []string{ - "github.com/99designs/gqlgen/example/chat", - "github.com/99designs/gqlgen/example/scalars/model", + "github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat", + "github.com/99designs/gqlgen/codegen/config/testdata/autobinding/scalars/model", }, Packages: &code.Packages{}, } @@ -187,8 +187,8 @@ func TestAutobinding(t *testing.T) { require.NoError(t, cfg.autobind()) - require.Equal(t, "github.com/99designs/gqlgen/example/scalars/model.Banned", cfg.Models["Banned"].Model[0]) - require.Equal(t, "github.com/99designs/gqlgen/example/chat.Message", cfg.Models["Message"].Model[0]) + require.Equal(t, "github.com/99designs/gqlgen/codegen/config/testdata/autobinding/scalars/model.Banned", cfg.Models["Banned"].Model[0]) + require.Equal(t, "github.com/99designs/gqlgen/codegen/config/testdata/autobinding/chat.Message", cfg.Models["Message"].Model[0]) }) t.Run("with file path", func(t *testing.T) { diff --git a/codegen/config/testdata/autobinding/chat/message.go b/codegen/config/testdata/autobinding/chat/message.go new file mode 100644 index 00000000000..b35be48c938 --- /dev/null +++ b/codegen/config/testdata/autobinding/chat/message.go @@ -0,0 +1,12 @@ +package chat + +import ( + "time" +) + +type Message struct { + ID string `json:"id"` + Text string `json:"text"` + CreatedBy string `json:"createdBy"` + CreatedAt time.Time `json:"createdAt"` +} diff --git a/codegen/config/testdata/autobinding/scalars/model/model.go b/codegen/config/testdata/autobinding/scalars/model/model.go new file mode 100644 index 00000000000..944a48b6720 --- /dev/null +++ b/codegen/config/testdata/autobinding/scalars/model/model.go @@ -0,0 +1,30 @@ +package model + +import ( + "fmt" + "io" + "strings" +) + +type Banned bool + +func (b Banned) MarshalGQL(w io.Writer) { + if b { + w.Write([]byte("true")) + } else { + w.Write([]byte("false")) + } +} + +func (b *Banned) UnmarshalGQL(v interface{}) error { + switch v := v.(type) { + case string: + *b = strings.ToLower(v) == "true" + return nil + case bool: + *b = Banned(v) + return nil + default: + return fmt.Errorf("%T is not a bool", v) + } +} diff --git a/example/go.mod b/example/go.mod new file mode 100644 index 00000000000..17b7a590983 --- /dev/null +++ b/example/go.mod @@ -0,0 +1,39 @@ +module github.com/99designs/gqlgen/example + +go 1.17 + +replace github.com/99designs/gqlgen => ../ + +require ( + github.com/99designs/gqlgen v0.0.0-00010101000000-000000000000 + github.com/gorilla/websocket v1.4.2 + github.com/mitchellh/mapstructure v1.4.1 + github.com/opentracing/opentracing-go v1.2.0 + github.com/rs/cors v1.8.0 + github.com/stretchr/testify v1.7.0 + github.com/vektah/dataloaden v0.3.0 + github.com/vektah/gqlparser/v2 v2.2.0 + sourcegraph.com/sourcegraph/appdash v0.0.0-20210831040556-ec77a7fbcadc +) + +require ( + github.com/agnivade/levenshtein v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/hashicorp/golang-lru v0.5.0 // indirect + github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect + github.com/mattn/go-colorable v0.1.4 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/opentracing/basictracer-go v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect + github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect + golang.org/x/mod v0.5.0 // indirect + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect + golang.org/x/tools v0.1.5 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect +) diff --git a/example/go.sum b/example/go.sum new file mode 100644 index 00000000000..42cad480e85 --- /dev/null +++ b/example/go.sum @@ -0,0 +1,157 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM= +github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= +github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= +github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= +github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/vektah/dataloaden v0.3.0 h1:ZfVN2QD6swgvp+tDqdH/OIT/wu3Dhu0cus0k5gIZS84= +github.com/vektah/dataloaden v0.3.0/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= +github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= +github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +sourcegraph.com/sourcegraph/appdash v0.0.0-20210831040556-ec77a7fbcadc h1:nJW47Hpj4Gr/742Zg4BWuWGuEtZ5d7CpPkMDA9o/CHo= +sourcegraph.com/sourcegraph/appdash v0.0.0-20210831040556-ec77a7fbcadc/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= +sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= diff --git a/example/tools.go b/example/tools.go new file mode 100644 index 00000000000..d182ed9edc4 --- /dev/null +++ b/example/tools.go @@ -0,0 +1,7 @@ +// +build tools + +package main + +import ( + _ "github.com/vektah/dataloaden" +) diff --git a/go.mod b/go.mod index f63d58e4b43..3279db16b8d 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,6 @@ module github.com/99designs/gqlgen go 1.17 require ( - github.com/agnivade/levenshtein v1.1.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect - github.com/gorilla/mux v1.6.1 // indirect github.com/gorilla/websocket v1.4.2 github.com/hashicorp/golang-lru v0.5.0 github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 @@ -14,29 +10,20 @@ require ( github.com/mattn/go-colorable v0.1.4 github.com/mattn/go-isatty v0.0.12 github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 - github.com/opentracing/basictracer-go v1.0.0 // indirect - github.com/opentracing/opentracing-go v1.0.2 - github.com/rs/cors v1.6.0 - github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 // indirect - github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 // indirect github.com/stretchr/testify v1.4.0 github.com/urfave/cli/v2 v2.3.0 - github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e github.com/vektah/gqlparser/v2 v2.2.0 golang.org/x/tools v0.1.5 gopkg.in/yaml.v2 v2.2.4 - sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 - sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 // indirect ) require ( + github.com/agnivade/levenshtein v1.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pkg/errors v0.8.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/go.sum b/go.sum index e80fdd19148..7b2e44208c2 100644 --- a/go.sum +++ b/go.sum @@ -14,18 +14,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= -github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.1 h1:KOwqsTYZdeuMacU7CxjMNYEKeBvLbxW+psodrbcEa3A= -github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -42,62 +34,35 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI= -github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371 h1:SWV2fHctRpRrp49VXJ6UZja7gU9QLHwRpIPBN89SKEo= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0 h1:JJV9CsgM9EC9w2iVkwuz+sMx8yRFe89PJRUrv6hPCIA= -github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg= -github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U= github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= @@ -107,15 +72,11 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -125,7 +86,3 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0 h1:ucqkfpjg9WzSUubAO62csmucvxl4/JeW3F4I4909XkM= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67 h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI= -sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k= diff --git a/tools.go b/tools.go index 47e0bd690cb..ef46208c161 100644 --- a/tools.go +++ b/tools.go @@ -5,5 +5,4 @@ package main import ( _ "github.com/matryer/moq" - _ "github.com/vektah/dataloaden" ) From 777dabde381c1c4b1b6bb0316658f65cce22c654 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 17:27:42 +1000 Subject: [PATCH 097/146] Update the linter --- .github/workflows/check-linting | 8 -------- .github/workflows/lint.yml | 5 +++-- 2 files changed, 3 insertions(+), 10 deletions(-) delete mode 100755 .github/workflows/check-linting diff --git a/.github/workflows/check-linting b/.github/workflows/check-linting deleted file mode 100755 index b7b771bcb35..00000000000 --- a/.github/workflows/check-linting +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -mkdir /tmp/golangci -curl -sL --fail https://github.com/golangci/golangci-lint/releases/download/v1.29.0/golangci-lint-1.29.0-linux-amd64.tar.gz | tar zxv --strip-components=1 --dir=/tmp/golangci - -/tmp/golangci/golangci-lint run diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 44695d14b86..0c2e46242fd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,13 +5,14 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: { go-version: 1.17 } - run: go mod download - run: .github/workflows/check-fmt - - run: .github/workflows/check-linting - run: .github/workflows/check-generate + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 coverage: runs-on: ubuntu-latest From 85e7a4a0aae4c80c8522350d17400184fac48882 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 17:34:21 +1000 Subject: [PATCH 098/146] Linting fixes --- .golangci.yml | 2 +- client/websocket.go | 2 +- codegen/args.go | 2 +- codegen/config/config.go | 2 +- codegen/directive.go | 4 ++-- codegen/templates/templates.go | 4 ++-- codegen/util.go | 4 ++-- graphql/handler/transport/websocket_test.go | 2 +- internal/code/compare.go | 1 - internal/imports/prune_test.go | 2 +- internal/rewrite/rewriter_test.go | 2 +- plugin/resolvergen/resolver.go | 2 +- 12 files changed, 14 insertions(+), 15 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 8d513868009..21099b69b05 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -21,12 +21,12 @@ linters: - gosimple - govet - ineffassign - - interfacer - misspell - nakedret - prealloc - staticcheck - structcheck + - typecheck - unconvert - unused - varcheck diff --git a/client/websocket.go b/client/websocket.go index ca6ee7c4723..996ec7848c8 100644 --- a/client/websocket.go +++ b/client/websocket.go @@ -62,7 +62,7 @@ func (p *Client) WebsocketWithPayload(query string, initPayload map[string]inter } srv := httptest.NewServer(p.h) - host := strings.Replace(srv.URL, "http://", "ws://", -1) + host := strings.ReplaceAll(srv.URL, "http://", "ws://") c, _, err := websocket.DefaultDialer.Dial(host+r.URL.Path, r.Header) if err != nil { diff --git a/codegen/args.go b/codegen/args.go index 09254262aef..69af1404174 100644 --- a/codegen/args.go +++ b/codegen/args.go @@ -25,7 +25,7 @@ type FieldArgument struct { Value interface{} // value set in Data } -//ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive +// ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive func (f *FieldArgument) ImplDirectives() []*Directive { d := make([]*Directive, 0) for i := range f.Directives { diff --git a/codegen/config/config.go b/codegen/config/config.go index d29630d027e..29161a622a6 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -31,7 +31,7 @@ type Config struct { Packages *code.Packages `yaml:"-"` Schema *ast.Schema `yaml:"-"` - // Deprecated use Federation instead. Will be removed next release + // Deprecated: use Federation instead. Will be removed next release Federated bool `yaml:"federated,omitempty"` } diff --git a/codegen/directive.go b/codegen/directive.go index 2be102c2ca0..973061129a2 100644 --- a/codegen/directive.go +++ b/codegen/directive.go @@ -11,7 +11,7 @@ import ( type DirectiveList map[string]*Directive -//LocationDirectives filter directives by location +// LocationDirectives filter directives by location func (dl DirectiveList) LocationDirectives(location string) DirectiveList { return locationDirectives(dl, ast.DirectiveLocation(location)) } @@ -23,7 +23,7 @@ type Directive struct { Builtin bool } -//IsLocation check location directive +// IsLocation check location directive func (d *Directive) IsLocation(location ...ast.DirectiveLocation) bool { for _, l := range d.Locations { for _, a := range location { diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index 637b43515dc..3518a48d026 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -486,7 +486,7 @@ var commonInitialisms = map[string]bool{ } func rawQuote(s string) string { - return "`" + strings.Replace(s, "`", "`+\"`\"+`", -1) + "`" + return "`" + strings.ReplaceAll(s, "`", "`+\"`\"+`") + "`" } func notNil(field string, data interface{}) bool { @@ -548,7 +548,7 @@ func Dump(val interface{}) string { } func prefixLines(prefix, s string) string { - return prefix + strings.Replace(s, "\n", "\n"+prefix, -1) + return prefix + strings.ReplaceAll(s, "\n", "\n"+prefix) } func resolveName(name string, skip int) string { diff --git a/codegen/util.go b/codegen/util.go index d1c4533809a..fa2ceed3dfe 100644 --- a/codegen/util.go +++ b/codegen/util.go @@ -40,7 +40,7 @@ func findGoInterface(def types.Type) (*types.Interface, error) { } func equalFieldName(source, target string) bool { - source = strings.Replace(source, "_", "", -1) - target = strings.Replace(target, "_", "", -1) + source = strings.ReplaceAll(source, "_", "") + target = strings.ReplaceAll(target, "_", "") return strings.EqualFold(source, target) } diff --git a/graphql/handler/transport/websocket_test.go b/graphql/handler/transport/websocket_test.go index a02fb17002d..566777b621a 100644 --- a/graphql/handler/transport/websocket_test.go +++ b/graphql/handler/transport/websocket_test.go @@ -268,7 +268,7 @@ func TestWebsocketInitFunc(t *testing.T) { } func wsConnect(url string) *websocket.Conn { - c, resp, err := websocket.DefaultDialer.Dial(strings.Replace(url, "http://", "ws://", -1), nil) + c, resp, err := websocket.DefaultDialer.Dial(strings.ReplaceAll(url, "http://", "ws://"), nil) if err != nil { panic(err) } diff --git a/internal/code/compare.go b/internal/code/compare.go index dce9aea558f..dda434154c1 100644 --- a/internal/code/compare.go +++ b/internal/code/compare.go @@ -7,7 +7,6 @@ import ( // CompatibleTypes isnt a strict comparison, it allows for pointer differences func CompatibleTypes(expected types.Type, actual types.Type) error { - //fmt.Println("Comparing ", expected.String(), actual.String()) // Special case to deal with pointer mismatches { diff --git a/internal/imports/prune_test.go b/internal/imports/prune_test.go index 26ff109fc52..b7205fbedda 100644 --- a/internal/imports/prune_test.go +++ b/internal/imports/prune_test.go @@ -14,7 +14,7 @@ func TestPrune(t *testing.T) { b, err := Prune("testdata/unused.go", mustReadFile("testdata/unused.go"), &code.Packages{}) require.NoError(t, err) - require.Equal(t, strings.Replace(string(mustReadFile("testdata/unused.expected.go")), "\r\n", "\n", -1), string(b)) + require.Equal(t, strings.ReplaceAll(string(mustReadFile("testdata/unused.expected.go")), "\r\n", "\n"), string(b)) } func mustReadFile(filename string) []byte { diff --git a/internal/rewrite/rewriter_test.go b/internal/rewrite/rewriter_test.go index bd9968eadcf..202c6938b3a 100644 --- a/internal/rewrite/rewriter_test.go +++ b/internal/rewrite/rewriter_test.go @@ -21,7 +21,7 @@ func TestRewriter(t *testing.T) { m.Field++ // trailing comment -`, strings.Replace(body, "\r\n", "\n", -1)) +`, strings.ReplaceAll(body, "\r\n", "\n")) imps := r.ExistingImports("testdata/example.go") require.Len(t, imps, 2) diff --git a/plugin/resolvergen/resolver.go b/plugin/resolvergen/resolver.go index e63501d2bc6..b4985426246 100644 --- a/plugin/resolvergen/resolver.go +++ b/plugin/resolvergen/resolver.go @@ -173,7 +173,7 @@ type ResolverBuild struct { type File struct { // These are separated because the type definition of the resolver object may live in a different file from the - //resolver method implementations, for example when extending a type in a different graphql schema file + // resolver method implementations, for example when extending a type in a different graphql schema file Objects []*codegen.Object Resolvers []*Resolver imports []rewrite.Import From 6960c0c2adbe9e2359e0d7cb332d1eaceccb6b6f Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 17:58:07 +1000 Subject: [PATCH 099/146] Bump non-module deps --- example/go.mod | 2 +- example/go.sum | 12 ++++-- go.mod | 6 +-- go.sum | 20 +++++++--- graphql/executable_schema_mock.go | 65 +++++++++++++++---------------- graphql/handler/debug/tracer.go | 2 +- 6 files changed, 58 insertions(+), 49 deletions(-) diff --git a/example/go.mod b/example/go.mod index 17b7a590983..b8fdd4c8f0d 100644 --- a/example/go.mod +++ b/example/go.mod @@ -22,7 +22,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/hashicorp/golang-lru v0.5.0 // indirect - github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect + github.com/logrusorgru/aurora/v3 v3.0.0 // indirect github.com/mattn/go-colorable v0.1.4 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/opentracing/basictracer-go v1.1.0 // indirect diff --git a/example/go.sum b/example/go.sum index 42cad480e85..5ec1311ef26 100644 --- a/example/go.sum +++ b/example/go.sum @@ -38,16 +38,16 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= +github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= +github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -88,6 +88,7 @@ github.com/vektah/dataloaden v0.3.0/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -105,10 +106,12 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -132,6 +135,7 @@ golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= diff --git a/go.mod b/go.mod index 3279db16b8d..ffd9f7234dd 100644 --- a/go.mod +++ b/go.mod @@ -5,11 +5,11 @@ go 1.17 require ( github.com/gorilla/websocket v1.4.2 github.com/hashicorp/golang-lru v0.5.0 - github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 - github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 + github.com/logrusorgru/aurora/v3 v3.0.0 + github.com/matryer/moq v0.2.3 github.com/mattn/go-colorable v0.1.4 github.com/mattn/go-isatty v0.0.12 - github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 + github.com/mitchellh/mapstructure v1.2.3 github.com/stretchr/testify v1.4.0 github.com/urfave/cli/v2 v2.3.0 github.com/vektah/gqlparser/v2 v2.2.0 diff --git a/go.sum b/go.sum index 7b2e44208c2..e0c714883e9 100644 --- a/go.sum +++ b/go.sum @@ -23,17 +23,17 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg= -github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= +github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= +github.com/matryer/moq v0.2.3 h1:Q06vEqnBYjjfx5KKgHfYRKE/lvlRu+Nj+xodG4YdHnU= +github.com/matryer/moq v0.2.3/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8= -github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.2.3 h1:f/MjBEBDLttYCGfRaKBbKSRVF5aV2O6fnBpzknuE3jU= +github.com/mitchellh/mapstructure v1.2.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -49,20 +49,26 @@ github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/vektah/gqlparser/v2 v2.2.0 h1:bAc3slekAAJW6sZTi07aGq0OrfaCjj4jxARAaC7g2EM= github.com/vektah/gqlparser/v2 v2.2.0/go.mod h1:i3mQIGIrbK2PD1RrCeMTlVbkF2FJ6WkU1KJlJlC+3F4= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= @@ -73,10 +79,12 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/graphql/executable_schema_mock.go b/graphql/executable_schema_mock.go index 0c021d3d003..5d7433162fe 100644 --- a/graphql/executable_schema_mock.go +++ b/graphql/executable_schema_mock.go @@ -9,37 +9,31 @@ import ( "sync" ) -var ( - lockExecutableSchemaMockComplexity sync.RWMutex - lockExecutableSchemaMockExec sync.RWMutex - lockExecutableSchemaMockSchema sync.RWMutex -) - // Ensure, that ExecutableSchemaMock does implement ExecutableSchema. // If this is not the case, regenerate this file with moq. var _ ExecutableSchema = &ExecutableSchemaMock{} // ExecutableSchemaMock is a mock implementation of ExecutableSchema. // -// func TestSomethingThatUsesExecutableSchema(t *testing.T) { +// func TestSomethingThatUsesExecutableSchema(t *testing.T) { // -// // make and configure a mocked ExecutableSchema -// mockedExecutableSchema := &ExecutableSchemaMock{ -// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { -// panic("mock out the Complexity method") -// }, -// ExecFunc: func(ctx context.Context) ResponseHandler { -// panic("mock out the Exec method") -// }, -// SchemaFunc: func() *ast.Schema { -// panic("mock out the Schema method") -// }, -// } +// // make and configure a mocked ExecutableSchema +// mockedExecutableSchema := &ExecutableSchemaMock{ +// ComplexityFunc: func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) { +// panic("mock out the Complexity method") +// }, +// ExecFunc: func(ctx context.Context) ResponseHandler { +// panic("mock out the Exec method") +// }, +// SchemaFunc: func() *ast.Schema { +// panic("mock out the Schema method") +// }, +// } // -// // use mockedExecutableSchema in code that requires ExecutableSchema -// // and then make assertions. +// // use mockedExecutableSchema in code that requires ExecutableSchema +// // and then make assertions. // -// } +// } type ExecutableSchemaMock struct { // ComplexityFunc mocks the Complexity method. ComplexityFunc func(typeName string, fieldName string, childComplexity int, args map[string]interface{}) (int, bool) @@ -72,6 +66,9 @@ type ExecutableSchemaMock struct { Schema []struct { } } + lockComplexity sync.RWMutex + lockExec sync.RWMutex + lockSchema sync.RWMutex } // Complexity calls ComplexityFunc. @@ -90,9 +87,9 @@ func (mock *ExecutableSchemaMock) Complexity(typeName string, fieldName string, ChildComplexity: childComplexity, Args: args, } - lockExecutableSchemaMockComplexity.Lock() + mock.lockComplexity.Lock() mock.calls.Complexity = append(mock.calls.Complexity, callInfo) - lockExecutableSchemaMockComplexity.Unlock() + mock.lockComplexity.Unlock() return mock.ComplexityFunc(typeName, fieldName, childComplexity, args) } @@ -111,9 +108,9 @@ func (mock *ExecutableSchemaMock) ComplexityCalls() []struct { ChildComplexity int Args map[string]interface{} } - lockExecutableSchemaMockComplexity.RLock() + mock.lockComplexity.RLock() calls = mock.calls.Complexity - lockExecutableSchemaMockComplexity.RUnlock() + mock.lockComplexity.RUnlock() return calls } @@ -127,9 +124,9 @@ func (mock *ExecutableSchemaMock) Exec(ctx context.Context) ResponseHandler { }{ Ctx: ctx, } - lockExecutableSchemaMockExec.Lock() + mock.lockExec.Lock() mock.calls.Exec = append(mock.calls.Exec, callInfo) - lockExecutableSchemaMockExec.Unlock() + mock.lockExec.Unlock() return mock.ExecFunc(ctx) } @@ -142,9 +139,9 @@ func (mock *ExecutableSchemaMock) ExecCalls() []struct { var calls []struct { Ctx context.Context } - lockExecutableSchemaMockExec.RLock() + mock.lockExec.RLock() calls = mock.calls.Exec - lockExecutableSchemaMockExec.RUnlock() + mock.lockExec.RUnlock() return calls } @@ -155,9 +152,9 @@ func (mock *ExecutableSchemaMock) Schema() *ast.Schema { } callInfo := struct { }{} - lockExecutableSchemaMockSchema.Lock() + mock.lockSchema.Lock() mock.calls.Schema = append(mock.calls.Schema, callInfo) - lockExecutableSchemaMockSchema.Unlock() + mock.lockSchema.Unlock() return mock.SchemaFunc() } @@ -168,8 +165,8 @@ func (mock *ExecutableSchemaMock) SchemaCalls() []struct { } { var calls []struct { } - lockExecutableSchemaMockSchema.RLock() + mock.lockSchema.RLock() calls = mock.calls.Schema - lockExecutableSchemaMockSchema.RUnlock() + mock.lockSchema.RUnlock() return calls } diff --git a/graphql/handler/debug/tracer.go b/graphql/handler/debug/tracer.go index 3a4c8436b4b..2aa968a496c 100644 --- a/graphql/handler/debug/tracer.go +++ b/graphql/handler/debug/tracer.go @@ -8,7 +8,7 @@ import ( "os" "strings" - . "github.com/logrusorgru/aurora" + . "github.com/logrusorgru/aurora/v3" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" From 00ed6fb1a74b1c94d195b38025b1721f9c77db90 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Mon, 13 Sep 2021 19:52:37 +1000 Subject: [PATCH 100/146] Also test against 1.16 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d1234892d9f..53ced469708 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ jobs: test: strategy: matrix: - go: 1.17 + go: [1.16, 1.17] os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} From 2272e05bc00cc9f38e6d3179a8981651812acbba Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Tue, 14 Sep 2021 11:35:35 +1000 Subject: [PATCH 101/146] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c4946c9dad1..f1bbf8217e3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) +![gqlgen](https://user-images.githubusercontent.com/980499/133180111-d064b38c-6eb9-444b-a60f-7005a6e68222.png) + -![gqlgen](https://user-images.githubusercontent.com/46195831/89802919-0bb8ef00-db2a-11ea-8ba4-88e7a58b2fd2.png) +# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) ## What is gqlgen? From 24d4edcf128f7fa327d97fd85d087fef2e230943 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Tue, 14 Sep 2021 11:42:45 +1000 Subject: [PATCH 102/146] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f1bbf8217e3..81d8ac0a8d9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![gqlgen](https://user-images.githubusercontent.com/980499/133180111-d064b38c-6eb9-444b-a60f-7005a6e68222.png) -# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![GoDoc](https://godoc.org/github.com/99designs/gqlgen?status.svg)](https://godoc.org/github.com/99designs/gqlgen) +# gqlgen [![Integration](https://github.com/99designs/gqlgen/actions/workflows/integration.yml/badge.svg)](https://github.com/99designs/gqlgen/actions) [![Coverage Status](https://coveralls.io/repos/github/99designs/gqlgen/badge.svg?branch=master)](https://coveralls.io/github/99designs/gqlgen?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/99designs/gqlgen)](https://goreportcard.com/report/github.com/99designs/gqlgen) [![Go Reference](https://pkg.go.dev/badge/github.com/99designs/gqlgen.svg)](https://pkg.go.dev/github.com/99designs/gqlgen) [![Read the Docs](https://badgen.net/badge/docs/available/green)](http://gqlgen.com/) ## What is gqlgen? From 41d6926f38922cd0a01d93f30ac8702d9f9bcf48 Mon Sep 17 00:00:00 2001 From: Luke Cawood Date: Wed, 15 Sep 2021 10:49:35 +1000 Subject: [PATCH 103/146] Replace gitter with discord in contributing.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 461709ecf8e..3919b2a4b83 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Want to contribute to gqlgen? Here are some guidelines for how we accept help. ## Getting in Touch -Our [gitter](https://gitter.im/gqlgen/Lobby) channel is the best place to ask questions or get advice on using gqlgen. +Our [discord](https://discord.gg/DYEq3EMs4U) server is the best place to ask questions or get advice on using gqlgen. ## Reporting Bugs and Issues From 5c52f27c49d65d97a05bba14fc12ce8873d2b959 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 15:04:08 +1000 Subject: [PATCH 104/146] Update docs for getting started --- README.md | 37 ++++++++++++++++++++++++++------- docs/content/getting-started.md | 30 +++++++++++++++++++------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 81d8ac0a8d9..79a672b3a27 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## What is gqlgen? -[gqlgen](https://github.com/99designs/gqlgen) is a Go library for building GraphQL servers without any fuss.
+[gqlgen](https://github.com/99designs/gqlgen) is a Go library for building GraphQL servers without any fuss.
- **gqlgen is based on a Schema first approach** — You get to Define your API using the GraphQL [Schema Definition Language](http://graphql.org/learn/schema/). - **gqlgen prioritizes Type safety** — You should never see `map[string]interface{}` here. @@ -13,13 +13,36 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go graphql [implementations](https://gqlgen.com/feature-comparison/) -## Getting Started -- To install gqlgen run the command `go get github.com/99designs/gqlgen` in your project directory.
-- You could initialize a new project using the recommended folder structure by running this command `go run github.com/99designs/gqlgen init`. +## Quick start +```shell +# Initialise a new go module +mkdir example +cd example +go mod init gqlgen.com/example -You could find a more comprehensive guide to help you get started [here](https://gqlgen.com/getting-started/).
-We also have a couple of real-world [examples](https://github.com/99designs/gqlgen/tree/master/example) that show how to GraphQL applications with **gqlgen** seamlessly, -You can see these [examples](https://github.com/99designs/gqlgen/tree/master/example) here or visit [godoc](https://godoc.org/github.com/99designs/gqlgen). +# Add github.com/99designs/gqlgen to your project's tools.go +cat < tools.go +// +build tools + +package tools + +import ( + _ "github.com/99designs/gqlgen" +) +EOD +go mod tidy + +# Initialise gqlgen config +go run github.com/99designs/gqlgen init + +# Start the graphql server +go run server.go +``` + +More help to get started: + - [Getting started guide](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started + - [Real-world examples](https://github.com/99designs/gqlgen/tree/master/example) show how to create GraphQL applications + - [Reference docs](https://pkg.go.dev/github.com/99designs/gqlgen) for the APIs ## Reporting Issues diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 5192de632cf..2f8dd6ce57e 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -18,19 +18,33 @@ You can find the finished code for this tutorial [here](https://github.com/vekta Create a directory for your project, and initialise it as a Go Module: -```sh -$ mkdir gqlgen-todos -$ cd gqlgen-todos -$ go mod init github.com/[username]/gqlgen-todos -$ go get github.com/99designs/gqlgen +```shell +mkdir gqlgen-todos +cd gqlgen-todos +go mod init github.com/[username]/gqlgen-todos +``` + +Next, add the gqlgen tool as a dependency [using your project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) + +```shell +cat < tools.go +// +build tools + +package tools + +import ( + _ "github.com/99designs/gqlgen" +) +EOD +go mod tidy ``` ## Building the server ### Create the project skeleton -```bash -$ go run github.com/99designs/gqlgen init +```shell +go run github.com/99designs/gqlgen init ``` This will create our suggested package layout. You can modify these paths in gqlgen.yml if you need to. @@ -86,7 +100,7 @@ type Mutation { ### Implement the resolvers When executed, gqlgen's `generate` command compares the schema file (`graph/schema.graphqls`) with the models `graph/model/*`, and, wherever it -can, it will bind directly to the model. That was done alread when `init` was run. We'll edit the schema later in the tutorial, but for now, let's look at what was generated already. +can, it will bind directly to the model. That was done alread when `init` was run. We'll edit the schema later in the tutorial, but for now, let's look at what was generated already. If we take a look in `graph/schema.resolvers.go` we will see all the times that gqlgen couldn't match them up. For us it was twice: From cacd49a6d0421093bdb67d17551ea0323ceb438a Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 17:01:51 +1000 Subject: [PATCH 105/146] Update README.md --- README.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 79a672b3a27..8f3fd8c2097 100644 --- a/README.md +++ b/README.md @@ -14,30 +14,33 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go graphql [implementations](https://gqlgen.com/feature-comparison/) ## Quick start -```shell -# Initialise a new go module -mkdir example -cd example -go mod init gqlgen.com/example +1. [Initialise a new go module](https://golang.org/doc/tutorial/create-module) -# Add github.com/99designs/gqlgen to your project's tools.go -cat < tools.go -// +build tools + mkdir example + cd example + go mod init gqlgen.com/example -package tools +2. Add gqlgen to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) -import ( - _ "github.com/99designs/gqlgen" -) -EOD -go mod tidy + cat < tools.go + // +build tools + + package tools + + import ( + _ "github.com/99designs/gqlgen" + ) + EOD + + go mod tidy -# Initialise gqlgen config -go run github.com/99designs/gqlgen init +3. Initialise gqlgen config and generate models -# Start the graphql server -go run server.go -``` + go run github.com/99designs/gqlgen init + +4. Start the graphql server + + go run server.go More help to get started: - [Getting started guide](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started From b938e55811966ef5ff96cc911597327af92c493c Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 19:18:09 +1000 Subject: [PATCH 106/146] Update README.md --- README.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/README.md b/README.md index 8f3fd8c2097..03e0fdafe89 100644 --- a/README.md +++ b/README.md @@ -22,16 +22,7 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g 2. Add gqlgen to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) - cat < tools.go - // +build tools - - package tools - - import ( - _ "github.com/99designs/gqlgen" - ) - EOD - + printf '// +build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go go mod tidy 3. Initialise gqlgen config and generate models From 73809f6912ed01c8ea18dbb5d7ea98e803ddb9c7 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 19:48:47 +1000 Subject: [PATCH 107/146] Update getting started --- docs/content/getting-started.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 2f8dd6ce57e..44b503fab40 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -14,9 +14,9 @@ This tutorial will take you through the process of building a GraphQL server wit You can find the finished code for this tutorial [here](https://github.com/vektah/gqlgen-tutorials/tree/master/gettingstarted) -## Setup Project +## Set up Project -Create a directory for your project, and initialise it as a Go Module: +Create a directory for your project, and [initialise it as a Go Module](https://golang.org/doc/tutorial/create-module): ```shell mkdir gqlgen-todos @@ -24,10 +24,10 @@ cd gqlgen-todos go mod init github.com/[username]/gqlgen-todos ``` -Next, add the gqlgen tool as a dependency [using your project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) +Next, create a `tools.go` file and add gqlgen as a [tool dependency for your module](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module). -```shell -cat < tools.go +```go +//go:build tools // +build tools package tools @@ -35,10 +35,18 @@ package tools import ( _ "github.com/99designs/gqlgen" ) -EOD +``` + +To automatically add the dependency to your `go.mod` run +```shell go mod tidy ``` +If you want to specify a particular version of gqlgen, you can use `go get`. For example +```shell +go get -d github.com/99designs/gqlgen@v0.14.0 +``` + ## Building the server ### Create the project skeleton From 488cf7e8180e653c7a085c137d14734c5897393b Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 20:08:05 +1000 Subject: [PATCH 108/146] Update docs/content/getting-started.md --- docs/content/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 44b503fab40..2a96b0fd72b 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -231,7 +231,7 @@ func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, At the top of our `resolver.go`, between `package` and `import`, add the following line: ```go -//go:generate go run github.com/99designs/gqlgen +//go:generate go run github.com/99designs/gqlgen generate ``` This magic comment tells `go generate` what command to run when we want to regenerate our code. To run go generate recursively over your entire project, use this command: From ce7a8ee469108e1c2dd62511249199312b32729a Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Wed, 15 Sep 2021 21:03:12 +1000 Subject: [PATCH 109/146] Fix link in docs --- docs/config.yml | 3 +++ docs/content/reference/godoc.md | 18 ------------------ 2 files changed, 3 insertions(+), 18 deletions(-) delete mode 100644 docs/content/reference/godoc.md diff --git a/docs/config.yml b/docs/config.yml index 57d47d5a035..f99a6731bdf 100644 --- a/docs/config.yml +++ b/docs/config.yml @@ -21,3 +21,6 @@ menu: - name: Recipes identifier: recipes weight: 10 + - name: pkg.go.dev → + parent: reference + url: https://pkg.go.dev/github.com/99designs/gqlgen diff --git a/docs/content/reference/godoc.md b/docs/content/reference/godoc.md deleted file mode 100644 index d6c864e85fa..00000000000 --- a/docs/content/reference/godoc.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: "godoc" -description: -linkTitle: | - godoc - - - - -menu: - main: - parent: 'reference' - weight: 0 - url: https://godoc.org/github.com/99designs/gqlgen ---- From 43b56cbaf3f1de1d1ad379055ab1de157592cf38 Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Wed, 15 Sep 2021 14:18:27 -0700 Subject: [PATCH 110/146] Forward `go mod tidy` stdout/stderr This is a command that can fail (in my case I think for stupid reasons in a hell of my own construction, but nonetheless). Right now we just get ``` $ go run github.com/Khan/webapp/dev/cmd/gqlgen tidy failed: go mod tidy failed: exit status 1 exit status 3 ``` which is not the most informative. Now, instead, we'll forward its output to our own stdout/stderr rather than devnull. --- internal/code/packages.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/code/packages.go b/internal/code/packages.go index 39ba374eab6..17d59f42c91 100644 --- a/internal/code/packages.go +++ b/internal/code/packages.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "os" "os/exec" "path/filepath" @@ -155,6 +156,8 @@ func (p *Packages) Evict(importPath string) { func (p *Packages) ModTidy() error { p.packages = nil tidyCmd := exec.Command("go", "mod", "tidy") + tidyCmd.Stdout = os.Stdout + tidyCmd.Stderr = os.Stdout if err := tidyCmd.Run(); err != nil { return fmt.Errorf("go mod tidy failed: %w", err) } From eec81df05e18dd9ac977b5a661964df212bf4627 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 17 Sep 2021 10:58:07 +1000 Subject: [PATCH 111/146] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 03e0fdafe89..9822341efc0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g mkdir example cd example - go mod init gqlgen.com/example + go mod init example 2. Add gqlgen to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) From 880cd73dbe0d602168639a7d3f59638473a4a91c Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Fri, 17 Sep 2021 10:59:36 +1000 Subject: [PATCH 112/146] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9822341efc0..6f3dd50cb90 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g go run server.go More help to get started: - - [Getting started guide](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started + - [Getting started tutorial](https://gqlgen.com/getting-started/) - a comprehensive guide to help you get started - [Real-world examples](https://github.com/99designs/gqlgen/tree/master/example) show how to create GraphQL applications - [Reference docs](https://pkg.go.dev/github.com/99designs/gqlgen) for the APIs From c53bc0e53cacb9f9930ec3125388b85820241a27 Mon Sep 17 00:00:00 2001 From: Dmitry Gridnev Date: Sat, 18 Sep 2021 18:35:19 +0300 Subject: [PATCH 113/146] Update disabling Introspection --- docs/content/reference/introspection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/reference/introspection.md b/docs/content/reference/introspection.md index c1acb1e8160..daa26c6cb01 100644 --- a/docs/content/reference/introspection.md +++ b/docs/content/reference/introspection.md @@ -29,7 +29,7 @@ Introspection can also be enabled on a per-request context basis. For example, y srv := handler.NewDefaultServer(es) srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { if !userForContext(ctx).IsAdmin { - graphql.GetRequestContext(ctx).DisableIntrospection = true + graphql.GetOperationContext(ctx).DisableIntrospection = true } return next(ctx) From f93f73ac395209cd158862b86b2a0c136bc3e11b Mon Sep 17 00:00:00 2001 From: Robert Marsal <507871+robertmarsal@users.noreply.github.com> Date: Wed, 22 Sep 2021 16:03:09 +0100 Subject: [PATCH 114/146] Fix typo in the getting-started docs --- docs/content/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/getting-started.md b/docs/content/getting-started.md index 2a96b0fd72b..45534c68e98 100644 --- a/docs/content/getting-started.md +++ b/docs/content/getting-started.md @@ -108,7 +108,7 @@ type Mutation { ### Implement the resolvers When executed, gqlgen's `generate` command compares the schema file (`graph/schema.graphqls`) with the models `graph/model/*`, and, wherever it -can, it will bind directly to the model. That was done alread when `init` was run. We'll edit the schema later in the tutorial, but for now, let's look at what was generated already. +can, it will bind directly to the model. That was done already when `init` was run. We'll edit the schema later in the tutorial, but for now, let's look at what was generated already. If we take a look in `graph/schema.resolvers.go` we will see all the times that gqlgen couldn't match them up. For us it was twice: From 1a0b19feff6f02d2af6631c9d847bc243f8ede39 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Tue, 28 Sep 2021 14:04:59 +1000 Subject: [PATCH 115/146] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6f3dd50cb90..fc039f8283c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g cd example go mod init example -2. Add gqlgen to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) +2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module) printf '// +build tools\npackage tools\nimport _ "github.com/99designs/gqlgen"' | gofmt > tools.go go mod tidy From 47ce074a3c30a981bbeef8f3465fca4330aba783 Mon Sep 17 00:00:00 2001 From: minus Date: Sat, 2 Oct 2021 16:28:06 +0200 Subject: [PATCH 116/146] Fix example run instructions Making ./example a separate Go module [1] broke the `go run` invocations listed in a few example readmes [2]. Using relative paths from the respective example directory should be clear enough. [1]: commit f93fb2489285eef0542c4aa7b11341a8479b606a / issue/PR #1607 [2]: example/todo/server/server.go:10:2: no required module provides package github.com/99designs/gqlgen/example/todo; to add it: go get github.com/99designs/gqlgen/example/todo --- example/chat/readme.md | 3 +-- example/fileupload/readme.md | 2 +- example/selection/readme.md | 2 +- example/starwars/readme.md | 2 +- example/todo/readme.md | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/example/chat/readme.md b/example/chat/readme.md index be1925cbb4e..95b944fd826 100644 --- a/example/chat/readme.md +++ b/example/chat/readme.md @@ -4,12 +4,11 @@ Example app using subscriptions to build a chat room. to run this server ```bash -go run ./example/chat/server/server.go +go run ./server/server.go ``` to run the react app ```bash -cd ./example/chat npm install npm run start ``` diff --git a/example/fileupload/readme.md b/example/fileupload/readme.md index ae0eb4d0950..9b859be69c4 100644 --- a/example/fileupload/readme.md +++ b/example/fileupload/readme.md @@ -4,7 +4,7 @@ This server demonstrates how to handle file upload to run this server ```bash -go run ./example/fileupload/server/server.go +go run ./server/server.go ``` and open http://localhost:8087 in your browser diff --git a/example/selection/readme.md b/example/selection/readme.md index f37be6eb6a9..6380de00f9d 100644 --- a/example/selection/readme.md +++ b/example/selection/readme.md @@ -4,7 +4,7 @@ This is the simplest example of a graphql server. to run this server ```bash -go run ./example/selection/server/server.go +go run ./server/server.go ``` and open http://localhost:8086 in your browser diff --git a/example/starwars/readme.md b/example/starwars/readme.md index 921d2f01cf2..e615c8889a8 100644 --- a/example/starwars/readme.md +++ b/example/starwars/readme.md @@ -8,7 +8,7 @@ This server demonstrates a few advanced features of graphql: to run this server ```bash -go run ./example/starwars/server/server.go +go run ./server/server.go ``` and open http://localhost:8080 in your browser diff --git a/example/todo/readme.md b/example/todo/readme.md index e8dc2e8e183..bc94297ca96 100644 --- a/example/todo/readme.md +++ b/example/todo/readme.md @@ -4,7 +4,7 @@ This is the simplest example of a graphql server. to run this server ```bash -go run ./example/todo/server/server.go +go run ./server/server.go ``` and open http://localhost:8081 in your browser From 210c1aa6edf8b34d6e2f35e8c66b3d404cf7e8eb Mon Sep 17 00:00:00 2001 From: wilhelm Date: Thu, 7 Oct 2021 22:21:57 +1100 Subject: [PATCH 117/146] Appropriately Handle Falsy Default Field Values (#1623) --- codegen/input.gotpl | 2 +- codegen/testserver/defaults.graphql | 20 ++ codegen/testserver/defaults_test.go | 68 ++++++ codegen/testserver/generated.go | 365 +++++++++++++++++++++++++++- codegen/testserver/models-gen.go | 10 + codegen/testserver/resolver.go | 8 + codegen/testserver/schema.graphql | 20 +- codegen/testserver/stub.go | 8 + 8 files changed, 486 insertions(+), 15 deletions(-) create mode 100644 codegen/testserver/defaults.graphql create mode 100644 codegen/testserver/defaults_test.go diff --git a/codegen/input.gotpl b/codegen/input.gotpl index c6eac4d47bb..64681b61da3 100644 --- a/codegen/input.gotpl +++ b/codegen/input.gotpl @@ -7,7 +7,7 @@ asMap[k] = v } {{ range $field := .Fields}} - {{- if $field.Default}} + {{- if notNil "Default" $field }} if _, present := asMap[{{$field.Name|quote}}] ; !present { asMap[{{$field.Name|quote}}] = {{ $field.Default | dump }} } diff --git a/codegen/testserver/defaults.graphql b/codegen/testserver/defaults.graphql new file mode 100644 index 00000000000..1c9a9ebf03d --- /dev/null +++ b/codegen/testserver/defaults.graphql @@ -0,0 +1,20 @@ +extend type Query { + defaultParameters( + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true + ): DefaultParametersMirror! +} + +extend type Mutation { + defaultInput(input: DefaultInput!): DefaultParametersMirror! +} + +input DefaultInput { + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true +} + +type DefaultParametersMirror { + falsyBoolean: Boolean + truthyBoolean: Boolean +} diff --git a/codegen/testserver/defaults_test.go b/codegen/testserver/defaults_test.go new file mode 100644 index 00000000000..2bb1f85de6c --- /dev/null +++ b/codegen/testserver/defaults_test.go @@ -0,0 +1,68 @@ +package testserver + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func assertDefaults(t *testing.T, ret *DefaultParametersMirror) { + require.NotNil(t, ret) + require.NotNil(t, ret.FalsyBoolean) + require.Equal(t, *ret.FalsyBoolean, false) + require.NotNil(t, ret.TruthyBoolean) + require.Equal(t, *ret.TruthyBoolean, true) +} + +func TestDefaults(t *testing.T) { + resolvers := &Stub{} + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + c := client.New(srv) + + t.Run("default field parameters", func(t *testing.T) { + resolvers.QueryResolver.DefaultParameters = func( + ctx context.Context, + falsyBoolean, truthyBoolean *bool, + ) (*DefaultParametersMirror, error) { + return &DefaultParametersMirror{ + FalsyBoolean: falsyBoolean, + TruthyBoolean: truthyBoolean, + }, nil + } + + var resp struct{ DefaultParameters *DefaultParametersMirror } + err := c.Post(`query { + defaultParameters { + falsyBoolean + truthyBoolean + } + }`, &resp) + require.NoError(t, err) + assertDefaults(t, resp.DefaultParameters) + }) + + t.Run("default input fields", func(t *testing.T) { + resolvers.MutationResolver.DefaultInput = func( + ctx context.Context, + input DefaultInput, + ) (*DefaultParametersMirror, error) { + return &DefaultParametersMirror{ + FalsyBoolean: input.FalsyBoolean, + TruthyBoolean: input.TruthyBoolean, + }, nil + } + + var resp struct{ DefaultInput *DefaultParametersMirror } + err := c.Post(`mutation { + defaultInput(input: {}) { + falsyBoolean + truthyBoolean + } + }`, &resp) + require.NoError(t, err) + assertDefaults(t, resp.DefaultInput) + }) +} diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 7995011c094..b03dc9769e4 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -136,6 +136,11 @@ type ComplexityRoot struct { Foo func(childComplexity int) int } + DefaultParametersMirror struct { + FalsyBoolean func(childComplexity int) int + TruthyBoolean func(childComplexity int) int + } + Dog struct { DogBreed func(childComplexity int) int Species func(childComplexity int) int @@ -217,6 +222,7 @@ type ComplexityRoot struct { } Mutation struct { + DefaultInput func(childComplexity int, input DefaultInput) int UpdateSomething func(childComplexity int, input SpecialInput) int } @@ -265,6 +271,7 @@ type ComplexityRoot struct { Animal func(childComplexity int) int Autobind func(childComplexity int) int Collision func(childComplexity int) int + DefaultParameters func(childComplexity int, falsyBoolean *bool, truthyBoolean *bool) int DefaultScalar func(childComplexity int, arg string) int DeprecatedField func(childComplexity int) int DirectiveArg func(childComplexity int, arg string) int @@ -416,6 +423,7 @@ type ModelMethodsResolver interface { ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) } type MutationResolver interface { + DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) } type OverlappingFieldsResolver interface { @@ -450,6 +458,7 @@ type QueryResolver interface { Autobind(ctx context.Context) (*Autobind, error) DeprecatedField(ctx context.Context) (string, error) Overlapping(ctx context.Context) (*OverlappingFields, error) + DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) DirectiveArg(ctx context.Context, arg string) (*string, error) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) @@ -698,6 +707,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ContentUser.Foo(childComplexity), true + case "DefaultParametersMirror.falsyBoolean": + if e.complexity.DefaultParametersMirror.FalsyBoolean == nil { + break + } + + return e.complexity.DefaultParametersMirror.FalsyBoolean(childComplexity), true + + case "DefaultParametersMirror.truthyBoolean": + if e.complexity.DefaultParametersMirror.TruthyBoolean == nil { + break + } + + return e.complexity.DefaultParametersMirror.TruthyBoolean(childComplexity), true + case "Dog.dogBreed": if e.complexity.Dog.DogBreed == nil { break @@ -901,6 +924,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ModelMethods.WithContext(childComplexity), true + case "Mutation.defaultInput": + if e.complexity.Mutation.DefaultInput == nil { + break + } + + args, err := ec.field_Mutation_defaultInput_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DefaultInput(childComplexity, args["input"].(DefaultInput)), true + case "Mutation.updateSomething": if e.complexity.Mutation.UpdateSomething == nil { break @@ -1063,6 +1098,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Collision(childComplexity), true + case "Query.defaultParameters": + if e.complexity.Query.DefaultParameters == nil { + break + } + + args, err := ec.field_Query_defaultParameters_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DefaultParameters(childComplexity, args["falsyBoolean"].(*bool), args["truthyBoolean"].(*bool)), true + case "Query.defaultScalar": if e.complexity.Query.DefaultScalar == nil { break @@ -1907,6 +1954,27 @@ type OverlappingFields { newFoo: Int! new_foo: Int! } +`, BuiltIn: false}, + {Name: "defaults.graphql", Input: `extend type Query { + defaultParameters( + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true + ): DefaultParametersMirror! +} + +extend type Mutation { + defaultInput(input: DefaultInput!): DefaultParametersMirror! +} + +input DefaultInput { + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true +} + +type DefaultParametersMirror { + falsyBoolean: Boolean + truthyBoolean: Boolean +} `, BuiltIn: false}, {Name: "directive.graphql", Input: `directive @length(min: Int!, max: Int, message: String) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION @@ -2188,15 +2256,21 @@ type EmbeddedDefaultScalar { value: DefaultScalarImplementation } `, BuiltIn: false}, - {Name: "schema.graphql", Input: `directive @goModel(model: String, models: [String!]) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION -directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + {Name: "schema.graphql", Input: `directive @goModel( + model: String + models: [String!] +) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION +directive @goField( + forceResolver: Boolean + name: String +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION type Query { invalidIdentifier: InvalidIdentifier collision: It mapInput(input: Changes): Boolean recursive(input: RecursiveInputSlice): Boolean - nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean + nestedInputs(input: [[OuterInput]] = [[{ inner: { id: 1 } }]]): Boolean nestedOutputs: [[OuterObject]] modelMethods: ModelMethods user(id: Int!): User! @@ -2243,7 +2317,7 @@ type It { id: ID! } -input Changes @goModel(model:"map[string]interface{}") { +input Changes @goModel(model: "map[string]interface{}") { a: Int b: Int } @@ -2253,14 +2327,14 @@ input RecursiveInputSlice { } input InnerInput { - id:Int! + id: Int! } input OuterInput { inner: InnerInput! } -scalar ThirdParty @goModel(model:"testserver.ThirdParty") +scalar ThirdParty @goModel(model: "testserver.ThirdParty") type OuterObject { inner: InnerObject! @@ -2274,7 +2348,7 @@ type ForcedResolver { field: Circle @goField(forceResolver: true) } -type EmbeddedPointer @goModel(model:"testserver.EmbeddedPointerModel") { +type EmbeddedPointer @goModel(model: "testserver.EmbeddedPointerModel") { ID: String Title: String } @@ -2550,6 +2624,21 @@ func (ec *executionContext) dir_range_args(ctx context.Context, rawArgs map[stri return args, nil } +func (ec *executionContext) field_Mutation_defaultInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 DefaultInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_updateSomething_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2610,6 +2699,30 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query_defaultParameters_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *bool + if tmp, ok := rawArgs["falsyBoolean"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("falsyBoolean")) + arg0, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["falsyBoolean"] = arg0 + var arg1 *bool + if tmp, ok := rawArgs["truthyBoolean"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("truthyBoolean")) + arg1, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["truthyBoolean"] = arg1 + return args, nil +} + func (ec *executionContext) field_Query_defaultScalar_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -4221,6 +4334,64 @@ func (ec *executionContext) _Content_User_foo(ctx context.Context, field graphql return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } +func (ec *executionContext) _DefaultParametersMirror_falsyBoolean(ctx context.Context, field graphql.CollectedField, obj *DefaultParametersMirror) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DefaultParametersMirror", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.FalsyBoolean, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _DefaultParametersMirror_truthyBoolean(ctx context.Context, field graphql.CollectedField, obj *DefaultParametersMirror) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DefaultParametersMirror", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TruthyBoolean, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + func (ec *executionContext) _Dog_species(ctx context.Context, field graphql.CollectedField, obj *Dog) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -5146,6 +5317,45 @@ func (ec *executionContext) _ModelMethods_withContext(ctx context.Context, field return ec.marshalNBoolean2bool(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation_defaultInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_defaultInput_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DefaultInput(rctx, args["input"].(DefaultInput)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*DefaultParametersMirror) + fc.Result = res + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx, field.Selections, res) +} + func (ec *executionContext) _Mutation_updateSomething(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -6369,6 +6579,45 @@ func (ec *executionContext) _Query_overlapping(ctx context.Context, field graphq return ec.marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOverlappingFields(ctx, field.Selections, res) } +func (ec *executionContext) _Query_defaultParameters(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_defaultParameters_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DefaultParameters(rctx, args["falsyBoolean"].(*bool), args["truthyBoolean"].(*bool)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*DefaultParametersMirror) + fc.Result = res + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_directiveArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -10217,6 +10466,44 @@ func (ec *executionContext) _iIt_id(ctx context.Context, field graphql.Collected // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputDefaultInput(ctx context.Context, obj interface{}) (DefaultInput, error) { + var it DefaultInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + if _, present := asMap["falsyBoolean"]; !present { + asMap["falsyBoolean"] = false + } + if _, present := asMap["truthyBoolean"]; !present { + asMap["truthyBoolean"] = true + } + + for k, v := range asMap { + switch k { + case "falsyBoolean": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("falsyBoolean")) + it.FalsyBoolean, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + case "truthyBoolean": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("truthyBoolean")) + it.TruthyBoolean, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputInnerDirectives(ctx context.Context, obj interface{}) (InnerDirectives, error) { var it InnerDirectives asMap := map[string]interface{}{} @@ -11357,6 +11644,32 @@ func (ec *executionContext) _Content_User(ctx context.Context, sel ast.Selection return out } +var defaultParametersMirrorImplementors = []string{"DefaultParametersMirror"} + +func (ec *executionContext) _DefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, obj *DefaultParametersMirror) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, defaultParametersMirrorImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DefaultParametersMirror") + case "falsyBoolean": + out.Values[i] = ec._DefaultParametersMirror_falsyBoolean(ctx, field, obj) + case "truthyBoolean": + out.Values[i] = ec._DefaultParametersMirror_truthyBoolean(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var dogImplementors = []string{"Dog", "Animal"} func (ec *executionContext) _Dog(ctx context.Context, sel ast.SelectionSet, obj *Dog) graphql.Marshaler { @@ -11942,6 +12255,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") + case "defaultInput": + out.Values[i] = ec._Mutation_defaultInput(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } case "updateSomething": out.Values[i] = ec._Mutation_updateSomething(ctx, field) if out.Values[i] == graphql.Null { @@ -12478,6 +12796,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr res = ec._Query_overlapping(ctx, field) return res }) + case "defaultParameters": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_defaultParameters(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "directiveArg": field := field out.Concurrently(i, func() (res graphql.Marshaler) { @@ -13769,6 +14101,25 @@ func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋ return ec._CheckIssue896(ctx, sel, v) } +func (ec *executionContext) unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultInput(ctx context.Context, v interface{}) (DefaultInput, error) { + res, err := ec.unmarshalInputDefaultInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDefaultParametersMirror2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v DefaultParametersMirror) graphql.Marshaler { + return ec._DefaultParametersMirror(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v *DefaultParametersMirror) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DefaultParametersMirror(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDefaultScalarImplementation2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalString(v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/codegen/testserver/models-gen.go b/codegen/testserver/models-gen.go index 3bae2a74c69..9dc8fd02fb8 100644 --- a/codegen/testserver/models-gen.go +++ b/codegen/testserver/models-gen.go @@ -64,6 +64,16 @@ type ContentUser struct { func (ContentUser) IsContentChild() {} +type DefaultInput struct { + FalsyBoolean *bool `json:"falsyBoolean"` + TruthyBoolean *bool `json:"truthyBoolean"` +} + +type DefaultParametersMirror struct { + FalsyBoolean *bool `json:"falsyBoolean"` + TruthyBoolean *bool `json:"truthyBoolean"` +} + type Dog struct { Species string `json:"species"` DogBreed string `json:"dogBreed"` diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index ed813bf511e..20f8a7b726d 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -44,6 +44,10 @@ func (r *modelMethodsResolver) ResolverField(ctx context.Context, obj *ModelMeth panic("not implemented") } +func (r *mutationResolver) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { + panic("not implemented") +} + func (r *mutationResolver) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { panic("not implemented") } @@ -132,6 +136,10 @@ func (r *queryResolver) Overlapping(ctx context.Context) (*OverlappingFields, er panic("not implemented") } +func (r *queryResolver) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { + panic("not implemented") +} + func (r *queryResolver) DirectiveArg(ctx context.Context, arg string) (*string, error) { panic("not implemented") } diff --git a/codegen/testserver/schema.graphql b/codegen/testserver/schema.graphql index 1672d7be8a2..ebc67e129ec 100644 --- a/codegen/testserver/schema.graphql +++ b/codegen/testserver/schema.graphql @@ -1,12 +1,18 @@ -directive @goModel(model: String, models: [String!]) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION -directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION +directive @goModel( + model: String + models: [String!] +) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION +directive @goField( + forceResolver: Boolean + name: String +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION type Query { invalidIdentifier: InvalidIdentifier collision: It mapInput(input: Changes): Boolean recursive(input: RecursiveInputSlice): Boolean - nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean + nestedInputs(input: [[OuterInput]] = [[{ inner: { id: 1 } }]]): Boolean nestedOutputs: [[OuterObject]] modelMethods: ModelMethods user(id: Int!): User! @@ -53,7 +59,7 @@ type It { id: ID! } -input Changes @goModel(model:"map[string]interface{}") { +input Changes @goModel(model: "map[string]interface{}") { a: Int b: Int } @@ -63,14 +69,14 @@ input RecursiveInputSlice { } input InnerInput { - id:Int! + id: Int! } input OuterInput { inner: InnerInput! } -scalar ThirdParty @goModel(model:"testserver.ThirdParty") +scalar ThirdParty @goModel(model: "testserver.ThirdParty") type OuterObject { inner: InnerObject! @@ -84,7 +90,7 @@ type ForcedResolver { field: Circle @goField(forceResolver: true) } -type EmbeddedPointer @goModel(model:"testserver.EmbeddedPointerModel") { +type EmbeddedPointer @goModel(model: "testserver.EmbeddedPointerModel") { ID: String Title: String } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 8b6d7671a26..310de5587dc 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -28,6 +28,7 @@ type Stub struct { ResolverField func(ctx context.Context, obj *ModelMethods) (bool, error) } MutationResolver struct { + DefaultInput func(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) UpdateSomething func(ctx context.Context, input SpecialInput) (string, error) } OverlappingFieldsResolver struct { @@ -60,6 +61,7 @@ type Stub struct { Autobind func(ctx context.Context) (*Autobind, error) DeprecatedField func(ctx context.Context) (string, error) Overlapping func(ctx context.Context) (*OverlappingFields, error) + DefaultParameters func(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) DirectiveArg func(ctx context.Context, arg string) (*string, error) DirectiveNullableArg func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) DirectiveInputNullable func(ctx context.Context, arg *InputDirectives) (*string, error) @@ -207,6 +209,9 @@ func (r *stubModelMethods) ResolverField(ctx context.Context, obj *ModelMethods) type stubMutation struct{ *Stub } +func (r *stubMutation) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { + return r.MutationResolver.DefaultInput(ctx, input) +} func (r *stubMutation) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { return r.MutationResolver.UpdateSomething(ctx, input) } @@ -288,6 +293,9 @@ func (r *stubQuery) DeprecatedField(ctx context.Context) (string, error) { func (r *stubQuery) Overlapping(ctx context.Context) (*OverlappingFields, error) { return r.QueryResolver.Overlapping(ctx) } +func (r *stubQuery) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { + return r.QueryResolver.DefaultParameters(ctx, falsyBoolean, truthyBoolean) +} func (r *stubQuery) DirectiveArg(ctx context.Context, arg string) (*string, error) { return r.QueryResolver.DirectiveArg(ctx, arg) } From a3d9e8ce9689533ab8c3ab4b3b4cd22df3cbfa03 Mon Sep 17 00:00:00 2001 From: Ashish Malik <87957768+ash99d@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:37:05 +1100 Subject: [PATCH 118/146] Remove redundant favicon (#1638) --- graphql/playground/playground.go | 1 - 1 file changed, 1 deletion(-) diff --git a/graphql/playground/playground.go b/graphql/playground/playground.go index 12f1030a8d2..98094991998 100644 --- a/graphql/playground/playground.go +++ b/graphql/playground/playground.go @@ -10,7 +10,6 @@ var page = template.Must(template.New("graphiql").Parse(` - Date: Sun, 10 Oct 2021 22:00:40 +0900 Subject: [PATCH 119/146] Update time format for `Time` scalar (#1648) * Use more precise time format * update test * update docs * Apply suggestions from code review * Update scalars.md --- codegen/testserver/time_test.go | 8 ++++---- docs/content/reference/scalars.md | 2 +- graphql/time.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/codegen/testserver/time_test.go b/codegen/testserver/time_test.go index 291567e7a1b..012625283db 100644 --- a/codegen/testserver/time_test.go +++ b/codegen/testserver/time_test.go @@ -45,9 +45,9 @@ func TestTime(t *testing.T) { t.Run("with values", func(t *testing.T) { resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) { - updated := time.Date(2010, 1, 1, 0, 0, 20, 0, time.UTC) + updated := time.Date(2010, 1, 1, 0, 0, 20, 1, time.UTC) return &User{ - Created: time.Date(2010, 1, 1, 0, 0, 10, 0, time.UTC), + Created: time.Date(2010, 1, 1, 0, 0, 10, 1, time.UTC), Updated: &updated, }, nil } @@ -62,7 +62,7 @@ func TestTime(t *testing.T) { err := c.Post(`query { user(id: 1) { created, updated } }`, &resp) require.NoError(t, err) - require.Equal(t, "2010-01-01T00:00:10Z", resp.User.Created) - require.Equal(t, "2010-01-01T00:00:20Z", resp.User.Updated) + require.Equal(t, "2010-01-01T00:00:10.000000001Z", resp.User.Created) + require.Equal(t, "2010-01-01T00:00:20.000000001Z", resp.User.Updated) }) } diff --git a/docs/content/reference/scalars.md b/docs/content/reference/scalars.md index 9bda307f553..10e835d42cb 100644 --- a/docs/content/reference/scalars.md +++ b/docs/content/reference/scalars.md @@ -15,7 +15,7 @@ gqlgen ships with some built-in helpers for common custom scalar use-cases, `Tim scalar Time ``` -Maps a `Time` GraphQL scalar to a Go `time.Time` struct. +Maps a `Time` GraphQL scalar to a Go `time.Time` struct. This scalar adheres to the [time.RFC3339Nano](https://pkg.go.dev/time#pkg-constants) format. ### Map diff --git a/graphql/time.go b/graphql/time.go index bd7b2e60807..ef3d17da329 100644 --- a/graphql/time.go +++ b/graphql/time.go @@ -19,7 +19,7 @@ func MarshalTime(t time.Time) Marshaler { func UnmarshalTime(v interface{}) (time.Time, error) { if tmpStr, ok := v.(string); ok { - return time.Parse(time.RFC3339, tmpStr) + return time.Parse(time.RFC3339Nano, tmpStr) } - return time.Time{}, errors.New("time should be RFC3339 formatted string") + return time.Time{}, errors.New("time should be RFC3339Nano formatted string") } From 5287e4e5f30548d233f58111d128787c673c7f01 Mon Sep 17 00:00:00 2001 From: Richard Lindhout Date: Sun, 10 Oct 2021 16:02:15 +0200 Subject: [PATCH 120/146] Add QR and KVK to common initialisms (#1419) * Add QR and KVK to common initialisms * Update templates.go * Sort commonInitialisms Co-authored-by: Steve Coffman --- codegen/templates/templates.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index 3518a48d026..77bac847367 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -458,9 +458,11 @@ var commonInitialisms = map[string]bool{ "ID": true, "IP": true, "JSON": true, + "KVK": true, "LHS": true, "PGP": true, "QPS": true, + "QR": true, "RAM": true, "RHS": true, "RPC": true, @@ -468,16 +470,17 @@ var commonInitialisms = map[string]bool{ "SMTP": true, "SQL": true, "SSH": true, + "SVG": true, "TCP": true, "TLS": true, "TTL": true, "UDP": true, "UI": true, "UID": true, - "UUID": true, "URI": true, "URL": true, "UTF8": true, + "UUID": true, "VM": true, "XML": true, "XMPP": true, From 7081dedb0efc6ed650118c7fce65ca3bdb33b8de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 10 Oct 2021 10:02:58 -0400 Subject: [PATCH 121/146] Bump tmpl from 1.0.4 to 1.0.5 in /integration (#1627) Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/daaku/nodejs-tmpl/releases) - [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) --- updated-dependencies: - dependency-name: tmpl dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- integration/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration/package-lock.json b/integration/package-lock.json index 00e48730d7b..cc5129bc422 100644 --- a/integration/package-lock.json +++ b/integration/package-lock.json @@ -10336,9 +10336,9 @@ } }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-fast-properties": { From 50f6a2aa603842fcdc158ab135fa117d1716d7e2 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Mon, 11 Oct 2021 09:16:01 -0400 Subject: [PATCH 122/146] Fixes #1653: update docs and wrap error if not *gqlerror.Error (#1654) Signed-off-by: Steve Coffman --- docs/content/reference/errors.md | 2 +- graphql/error.go | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/content/reference/errors.md b/docs/content/reference/errors.md index fa1a7f89508..69acbf89713 100644 --- a/docs/content/reference/errors.md +++ b/docs/content/reference/errors.md @@ -114,7 +114,7 @@ server := handler.NewDefaultServer(MakeExecutableSchema(resolvers) server.SetRecoverFunc(func(ctx context.Context, err interface{}) error { // notify bug tracker... - return errors.New("Internal server error!") + return gqlerror.Errorf("Internal server error!") }) ``` diff --git a/graphql/error.go b/graphql/error.go index 9e38fe4237b..4fe520b2852 100644 --- a/graphql/error.go +++ b/graphql/error.go @@ -10,19 +10,23 @@ import ( type ErrorPresenterFunc func(ctx context.Context, err error) *gqlerror.Error func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error { - return err.(*gqlerror.Error) + var gqlErr *gqlerror.Error + if errors.As(err, &gqlErr) { + return gqlErr + } + return gqlerror.WrapPath(GetPath(ctx), err) } func ErrorOnPath(ctx context.Context, err error) error { if err == nil { return nil } - var gqlerr *gqlerror.Error - if errors.As(err, &gqlerr) { - if gqlerr.Path == nil { - gqlerr.Path = GetPath(ctx) + var gqlErr *gqlerror.Error + if errors.As(err, &gqlErr) { + if gqlErr.Path == nil { + gqlErr.Path = GetPath(ctx) } - return gqlerr + return gqlErr } return gqlerror.WrapPath(GetPath(ctx), err) } From 589a774290cfaf8f39d6099650e930c6f10cd670 Mon Sep 17 00:00:00 2001 From: Tim Kuhlman Date: Mon, 11 Oct 2021 17:28:12 -0600 Subject: [PATCH 123/146] Enable lowercase type names in GraphQL schema to properly render (#1359) The difficulty with lowercased type names is that in go code any lowercased name is not exported. This change makes the names title case for go code while preserving the proper case when interacting with the GraphQL schema. Co-authored-by: Liam Murphy --- codegen/field.go | 2 +- codegen/generated!.gotpl | 6 +- codegen/object.go | 2 +- example/config/generated.go | 144 ++++++++++++++++++++++++++++++ example/config/model.go | 5 ++ example/config/user.graphql | 6 ++ example/config/user.resolvers.go | 20 +++++ plugin/resolvergen/resolver.go | 2 +- plugin/resolvergen/resolver.gotpl | 4 +- 9 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 example/config/user.resolvers.go diff --git a/codegen/field.go b/codegen/field.go index 86fee340d4a..0833c1ebfba 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -461,7 +461,7 @@ func (f *Field) GoNameUnexported() string { } func (f *Field) ShortInvocation() string { - return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs()) + return fmt.Sprintf("%s().%s(%s)", strings.Title(f.Object.Definition.Name), f.GoFieldName, f.CallArgs()) } func (f *Field) ArgsFunc() string { diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index 864d15deb55..e3304d1d8b3 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -32,7 +32,7 @@ type Config struct { type ResolverRoot interface { {{- range $object := .Objects -}} {{ if $object.HasResolvers -}} - {{$object.Name}}() {{$object.Name}}Resolver + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver {{ end }} {{- end }} } @@ -46,7 +46,7 @@ type DirectiveRoot struct { type ComplexityRoot struct { {{ range $object := .Objects }} {{ if not $object.IsReserved -}} - {{ $object.Name|go }} struct { + {{ucFirst $object.Name|go }} struct { {{ range $_, $fields := $object.UniqueFields }} {{- $field := index $fields 0 -}} {{ if not $field.IsReserved -}} @@ -60,7 +60,7 @@ type ComplexityRoot struct { {{ range $object := .Objects -}} {{ if $object.HasResolvers }} - type {{$object.Name}}Resolver interface { + type {{ucFirst $object.Name}}Resolver interface { {{ range $field := $object.Fields -}} {{- if $field.IsResolver }} {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} diff --git a/codegen/object.go b/codegen/object.go index f730a7e1e31..6cf922d47c4 100644 --- a/codegen/object.go +++ b/codegen/object.go @@ -46,7 +46,7 @@ func (b *builder) buildObject(typ *ast.Definition) (*Object, error) { Stream: typ == b.Schema.Subscription, Directives: dirs, ResolverInterface: types.NewNamed( - types.NewTypeName(0, b.Config.Exec.Pkg(), typ.Name+"Resolver", nil), + types.NewTypeName(0, b.Config.Exec.Pkg(), strings.Title(typ.Name)+"Resolver", nil), nil, nil, ), diff --git a/example/config/generated.go b/example/config/generated.go index 5c1c8afad4d..192997e0b7d 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -37,6 +37,7 @@ type ResolverRoot interface { Mutation() MutationResolver Query() QueryResolver Todo() TodoResolver + Role() RoleResolver } type DirectiveRoot struct { @@ -62,6 +63,11 @@ type ComplexityRoot struct { User struct { FullName func(childComplexity int) int ID func(childComplexity int) int + Role func(childComplexity int) int + } + + Role struct { + Name func(childComplexity int) int } } @@ -74,6 +80,9 @@ type QueryResolver interface { type TodoResolver interface { ID(ctx context.Context, obj *Todo) (string, error) } +type RoleResolver interface { + Name(ctx context.Context, obj *UserRole) (string, error) +} type executableSchema struct { resolvers ResolverRoot @@ -158,6 +167,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.User.ID(childComplexity), true + case "User.role": + if e.complexity.User.Role == nil { + break + } + + return e.complexity.User.Role(childComplexity), true + + case "role.name": + if e.complexity.Role.Name == nil { + break + } + + return e.complexity.Role.Name(childComplexity), true + } return 0, false } @@ -250,6 +273,12 @@ input NewTodo { @goModel(model:"github.com/99designs/gqlgen/example/config.User") { id: ID! name: String! @goField(name:"FullName") + role: role! +} + +type role +@goModel(model:"github.com/99designs/gqlgen/example/config.UserRole") { + name: String! } `, BuiltIn: false}, } @@ -720,6 +749,41 @@ func (ec *executionContext) _User_name(ctx context.Context, field graphql.Collec return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _User_role(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Role, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(UserRole) + fc.Result = res + return ec.marshalNrole2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋconfigᚐUserRole(ctx, field.Selections, res) +} + func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1838,6 +1902,41 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } +func (ec *executionContext) _role_name(ctx context.Context, field graphql.CollectedField, obj *UserRole) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "role", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Role().Name(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + // endregion **************************** field.gotpl ***************************** // region **************************** input.gotpl ***************************** @@ -2033,6 +2132,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj if out.Values[i] == graphql.Null { invalids++ } + case "role": + out.Values[i] = ec._User_role(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2290,6 +2394,42 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o return out } +var roleImplementors = []string{"role"} + +func (ec *executionContext) _role(ctx context.Context, sel ast.SelectionSet, obj *UserRole) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, roleImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("role") + case "name": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._role_name(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + // endregion **************************** object.gotpl **************************** // region ***************************** type.gotpl ***************************** @@ -2684,6 +2824,10 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a return res } +func (ec *executionContext) marshalNrole2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋconfigᚐUserRole(ctx context.Context, sel ast.SelectionSet, v UserRole) graphql.Marshaler { + return ec._role(ctx, sel, &v) +} + func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) { res, err := graphql.UnmarshalBoolean(v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/example/config/model.go b/example/config/model.go index 46038be7f88..4632c4eadef 100644 --- a/example/config/model.go +++ b/example/config/model.go @@ -5,8 +5,13 @@ import "fmt" type User struct { ID string FirstName, LastName string + Role UserRole } func (user *User) FullName() string { return fmt.Sprintf("%s %s", user.FirstName, user.LastName) } + +type UserRole struct { + RoleName string +} diff --git a/example/config/user.graphql b/example/config/user.graphql index 52c688bd331..5fb3772fc2f 100644 --- a/example/config/user.graphql +++ b/example/config/user.graphql @@ -2,4 +2,10 @@ type User @goModel(model:"github.com/99designs/gqlgen/example/config.User") { id: ID! name: String! @goField(name:"FullName") + role: role! +} + +type role +@goModel(model:"github.com/99designs/gqlgen/example/config.UserRole") { + name: String! } diff --git a/example/config/user.resolvers.go b/example/config/user.resolvers.go new file mode 100644 index 00000000000..1d819f99433 --- /dev/null +++ b/example/config/user.resolvers.go @@ -0,0 +1,20 @@ +package config + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. + +import ( + "context" +) + +func (r *roleResolver) Name(ctx context.Context, obj *UserRole) (string, error) { + if obj == nil { + return "", nil + } + return obj.RoleName, nil +} + +// Role returns RoleResolver implementation. +func (r *Resolver) Role() RoleResolver { return &roleResolver{r} } + +type roleResolver struct{ *Resolver } diff --git a/plugin/resolvergen/resolver.go b/plugin/resolvergen/resolver.go index b4985426246..857f5ea31d6 100644 --- a/plugin/resolvergen/resolver.go +++ b/plugin/resolvergen/resolver.go @@ -95,7 +95,7 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error { } rewriter.MarkStructCopied(templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)) - rewriter.GetMethodBody(data.Config.Resolver.Type, o.Name) + rewriter.GetMethodBody(data.Config.Resolver.Type, strings.Title(o.Name)) files[fn].Objects = append(files[fn].Objects, o) } for _, f := range o.Fields { diff --git a/plugin/resolvergen/resolver.gotpl b/plugin/resolvergen/resolver.gotpl index 543bf136e85..16c684d6283 100644 --- a/plugin/resolvergen/resolver.gotpl +++ b/plugin/resolvergen/resolver.gotpl @@ -26,8 +26,8 @@ {{ end }} {{ range $object := .Objects -}} - // {{$object.Name}} returns {{ $object.ResolverInterface | ref }} implementation. - func (r *{{$.ResolverType}}) {{$object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} } + // {{ucFirst $object.Name}} returns {{ $object.ResolverInterface | ref }} implementation. + func (r *{{$.ResolverType}}) {{ucFirst $object.Name}}() {{ $object.ResolverInterface | ref }} { return &{{lcFirst $object.Name}}{{ucFirst $.ResolverType}}{r} } {{ end }} {{ range $object := .Objects -}} From fd1bd7c9b3b3804ce1b90b786cd3fb9281918882 Mon Sep 17 00:00:00 2001 From: Suraj Chafle <5341407+schafle@users.noreply.github.com> Date: Mon, 11 Oct 2021 16:31:10 -0700 Subject: [PATCH 124/146] adding support for sending extension with gqlgen client (#1633) Co-authored-by: Suraj Chafle --- client/client.go | 1 + client/client_test.go | 27 +++++++++++++++++++++++++++ client/options.go | 7 +++++++ 3 files changed, 35 insertions(+) diff --git a/client/client.go b/client/client.go index 9c5f56c8fc3..7a2825c952b 100644 --- a/client/client.go +++ b/client/client.go @@ -30,6 +30,7 @@ type ( Query string `json:"query"` Variables map[string]interface{} `json:"variables,omitempty"` OperationName string `json:"operationName,omitempty"` + Extensions map[string]interface{} `json:"extensions,omitempty"` HTTP *http.Request `json:"-"` } diff --git a/client/client_test.go b/client/client_test.go index 64a75a30c6a..569151cd8a2 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -101,3 +101,30 @@ func TestAddCookie(t *testing.T) { client.AddCookie(&http.Cookie{Name: "foo", Value: "value"}), ) } + +func TestAddExtensions(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + b, err := ioutil.ReadAll(r.Body) + if err != nil { + panic(err) + } + require.Equal(t, `{"query":"user(id:1){name}","extensions":{"persistedQuery":{"sha256Hash":"ceec2897e2da519612279e63f24658c3e91194cbb2974744fa9007a7e1e9f9e7","version":1}}}`, string(b)) + err = json.NewEncoder(w).Encode(map[string]interface{}{ + "data": map[string]interface{}{ + "Name": "Bob", + }, + }) + if err != nil { + panic(err) + } + }) + + c := client.New(h) + + var resp struct { + Name string + } + c.MustPost("user(id:1){name}", &resp, + client.Extensions(map[string]interface{}{"persistedQuery": map[string]interface{}{"version": 1, "sha256Hash": "ceec2897e2da519612279e63f24658c3e91194cbb2974744fa9007a7e1e9f9e7"}}), + ) +} diff --git a/client/options.go b/client/options.go index e600f382852..bf4280ac711 100644 --- a/client/options.go +++ b/client/options.go @@ -20,6 +20,13 @@ func Operation(name string) Option { } } +// Extensions sets the extensions to be sent with the outgoing request +func Extensions(extensions map[string]interface{}) Option { + return func(bd *Request) { + bd.Extensions = extensions + } +} + // Path sets the url that this request will be made against, useful if you are mounting your entire router // and need to specify the url to the graphql endpoint. func Path(url string) Option { From 393f755421ae42d207655984dbe6b8b990440384 Mon Sep 17 00:00:00 2001 From: dylanhuang Date: Tue, 12 Oct 2021 07:46:42 +0800 Subject: [PATCH 125/146] add extraTag directive (#1173) --- codegen/config/config.go | 36 +++++++++++++++++++++++++++++------- docs/content/config.md | 5 ++++- plugin/modelgen/models.go | 7 ++++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index 29161a622a6..b9292bc1828 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -231,6 +231,10 @@ func (c *Config) injectTypesFromSchema() error { SkipRuntime: true, } + c.Directives["extraTag"] = DirectiveConfig{ + SkipRuntime: true, + } + for _, schemaType := range c.Schema.Types { if schemaType == c.Schema.Query || schemaType == c.Schema.Mutation || schemaType == c.Schema.Subscription { continue @@ -253,9 +257,15 @@ func (c *Config) injectTypesFromSchema() error { if schemaType.Kind == ast.Object || schemaType.Kind == ast.InputObject { for _, field := range schemaType.Fields { + typeMapField := TypeMapField{ + ExtraTag: c.Models[schemaType.Name].Fields[field.Name].ExtraTag, + FieldName: c.Models[schemaType.Name].Fields[field.Name].FieldName, + Resolver: c.Models[schemaType.Name].Fields[field.Name].Resolver, + } + directive := false if fd := field.Directives.ForName("goField"); fd != nil { - forceResolver := c.Models[schemaType.Name].Fields[field.Name].Resolver - fieldName := c.Models[schemaType.Name].Fields[field.Name].FieldName + forceResolver := typeMapField.Resolver + fieldName := typeMapField.FieldName if ra := fd.Arguments.ForName("forceResolver"); ra != nil { if fr, err := ra.Value.Value(nil); err == nil { @@ -269,17 +279,28 @@ func (c *Config) injectTypesFromSchema() error { } } + typeMapField.FieldName = fieldName + typeMapField.Resolver = forceResolver + directive = true + } + + if ex := field.Directives.ForName("extraTag"); ex != nil { + args := []string{} + for _, arg := range ex.Arguments { + args = append(args, arg.Name+`:"`+arg.Value.Raw+`"`) + } + typeMapField.ExtraTag = strings.Join(args, " ") + directive = true + } + + if directive { if c.Models[schemaType.Name].Fields == nil { c.Models[schemaType.Name] = TypeMapEntry{ Model: c.Models[schemaType.Name].Model, Fields: map[string]TypeMapField{}, } } - - c.Models[schemaType.Name].Fields[field.Name] = TypeMapField{ - FieldName: fieldName, - Resolver: forceResolver, - } + c.Models[schemaType.Name].Fields[field.Name] = typeMapField } } } @@ -296,6 +317,7 @@ type TypeMapEntry struct { type TypeMapField struct { Resolver bool `yaml:"resolver"` FieldName string `yaml:"fieldName"` + ExtraTag string `yaml:"extraTag"` GeneratedMethod string `yaml:"-"` } diff --git a/docs/content/config.md b/docs/content/config.md index f4e16b3a08d..21cfa328ffb 100644 --- a/docs/content/config.md +++ b/docs/content/config.md @@ -89,6 +89,9 @@ directive @goModel(model: String, models: [String!]) on OBJECT directive @goField(forceResolver: Boolean, name: String) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + +directive @extraTag on INPUT_FIELD_DEFINITION + | FIELD_DEFINITION ``` > Here be dragons @@ -101,6 +104,6 @@ Now you can use these directives when defining types in your schema: ```graphql type User @goModel(model: "github.com/my/app/models.User") { id: ID! @goField(name: "todoId") - name: String! @goField(forceResolver: true) + name: String! @goField(forceResolver: true) @extraTag(xorm: "-") } ``` diff --git a/plugin/modelgen/models.go b/plugin/modelgen/models.go index e0ca186632f..eca6a3064d4 100644 --- a/plugin/modelgen/models.go +++ b/plugin/modelgen/models.go @@ -162,11 +162,16 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error { typ = types.NewPointer(typ) } + tag := `json:"` + field.Name + `"` + if extraTag := cfg.Models[schemaType.Name].Fields[field.Name].ExtraTag; extraTag != "" { + tag = tag + " " + extraTag + } + it.Fields = append(it.Fields, &Field{ Name: name, Type: typ, Description: field.Description, - Tag: `json:"` + field.Name + `"`, + Tag: tag, }) } From af2ac061db4e08616cecff2ed74649465ee5fc20 Mon Sep 17 00:00:00 2001 From: Vivek J <65152794+vnj-uber@users.noreply.github.com> Date: Tue, 12 Oct 2021 20:06:03 +0530 Subject: [PATCH 126/146] handling unconventional naming used in type names (#1549) * handling unconventional naming used in type names * Fix merge resolution mistake * Fix merge resolution mistake Signed-off-by: Steve Coffman Co-authored-by: Steve Coffman --- codegen/generated!.gotpl | 6 +++--- codegen/testserver/generated.go | 12 ++++++------ .../federation/accounts/graph/generated/generated.go | 6 +++--- .../federation/products/graph/generated/generated.go | 6 +++--- .../federation/reviews/graph/generated/generated.go | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index e3304d1d8b3..3e51d6434af 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -46,7 +46,7 @@ type DirectiveRoot struct { type ComplexityRoot struct { {{ range $object := .Objects }} {{ if not $object.IsReserved -}} - {{ucFirst $object.Name|go }} struct { + {{ ucFirst $object.Name }} struct { {{ range $_, $fields := $object.UniqueFields }} {{- $field := index $fields 0 -}} {{ if not $field.IsReserved -}} @@ -92,7 +92,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in {{- $last := eq (add $i 1) $len }} {{- if not $field.IsReserved }} {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: - if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil { + if e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}} == nil { break } {{ if $field.Args }} @@ -101,7 +101,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } {{ end }} - return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true + return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true {{ end }} {{- end }} {{- end }} diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index b03dc9769e4..8001f44f472 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -128,11 +128,11 @@ type ComplexityRoot struct { ID func(childComplexity int) int } - ContentPost struct { + Content_Post struct { Foo func(childComplexity int) int } - ContentUser struct { + Content_User struct { Foo func(childComplexity int) int } @@ -694,18 +694,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ConcreteNodeInterface.ID(childComplexity), true case "Content_Post.foo": - if e.complexity.ContentPost.Foo == nil { + if e.complexity.Content_Post.Foo == nil { break } - return e.complexity.ContentPost.Foo(childComplexity), true + return e.complexity.Content_Post.Foo(childComplexity), true case "Content_User.foo": - if e.complexity.ContentUser.Foo == nil { + if e.complexity.Content_User.Foo == nil { break } - return e.complexity.ContentUser.Foo(childComplexity), true + return e.complexity.Content_User.Foo(childComplexity), true case "DefaultParametersMirror.falsyBoolean": if e.complexity.DefaultParametersMirror.FalsyBoolean == nil { diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index f6173dc7d43..395c1321a6e 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -60,7 +60,7 @@ type ComplexityRoot struct { Username func(childComplexity int) int } - Service struct { + _Service struct { SDL func(childComplexity int) int } } @@ -140,11 +140,11 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.User.Username(childComplexity), true case "_Service.sdl": - if e.complexity.Service.SDL == nil { + if e.complexity._Service.SDL == nil { break } - return e.complexity.Service.SDL(childComplexity), true + return e.complexity._Service.SDL(childComplexity), true } return 0, false diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 10c6bc0f0a1..76e13f15460 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -61,7 +61,7 @@ type ComplexityRoot struct { __resolve_entities func(childComplexity int, representations []map[string]interface{}) int } - Service struct { + _Service struct { SDL func(childComplexity int) int } } @@ -153,11 +153,11 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]interface{})), true case "_Service.sdl": - if e.complexity.Service.SDL == nil { + if e.complexity._Service.SDL == nil { break } - return e.complexity.Service.SDL(childComplexity), true + return e.complexity._Service.SDL(childComplexity), true } return 0, false diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 048028855e1..30c5a3e3723 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -72,7 +72,7 @@ type ComplexityRoot struct { Reviews func(childComplexity int) int } - Service struct { + _Service struct { SDL func(childComplexity int) int } } @@ -196,11 +196,11 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.User.Reviews(childComplexity), true case "_Service.sdl": - if e.complexity.Service.SDL == nil { + if e.complexity._Service.SDL == nil { break } - return e.complexity.Service.SDL(childComplexity), true + return e.complexity._Service.SDL(childComplexity), true } return 0, false From 9e0817cdc7428ea9f3a1542faaca72ce9c5f317c Mon Sep 17 00:00:00 2001 From: Thomas Prebble <6523587+tprebs@users.noreply.github.com> Date: Tue, 12 Oct 2021 15:40:13 +0100 Subject: [PATCH 127/146] Add graphql schema aware field level hook to modelgen (#1650) * Add ast aware field level hook to modelgen Currently, the only mechanism for extending the model generation is to use a BuildMutateHook at the end of the model generation process. This can be quite limiting as the hook only has scope of the model build and not the graphql schema which has been parsed. This change adds a hook at the end of the field creation process which provides access to the parsed graphql type definition and field definition. This allows for more flexibility for example adding additional tags to the model based off custom directives * Add recipe for using the modelgen FieldMutateHook * fix goimport linting issue in models_test --- docs/content/recipes/modelgen-hook.md | 87 +++++++++++++++++++++++++ plugin/modelgen/models.go | 21 +++++- plugin/modelgen/models_test.go | 35 ++++++++++ plugin/modelgen/out/generated.go | 5 ++ plugin/modelgen/testdata/schema.graphql | 8 +++ 5 files changed, 154 insertions(+), 2 deletions(-) diff --git a/docs/content/recipes/modelgen-hook.md b/docs/content/recipes/modelgen-hook.md index 88d9fd967de..eb65d625c26 100644 --- a/docs/content/recipes/modelgen-hook.md +++ b/docs/content/recipes/modelgen-hook.md @@ -5,6 +5,8 @@ linkTitle: "Modelgen hook" menu: { main: { parent: 'recipes' } } --- +## BuildMutateHook + The following recipe shows how to use a `modelgen` plugin hook to mutate generated models before they are rendered into a resulting file. This feature has many uses but the example focuses only on inserting ORM-specific tags into generated struct fields. This @@ -77,3 +79,88 @@ type Object struct { field2 *int `json:"field2" orm_binding:"Object.field2"` } ``` + +## FieldMutateHook + +For more fine grained control over model generation, a graphql schema aware a FieldHook can be provided. This hook has access to type and field graphql definitions enabling the hook to modify the `modelgen.Field` using directives defined within the schema. + +The below recipe uses this feature to add validate tags to the generated model for use with `go-playground/validator` where the validate tags are defined in a constraint directive in the schema. + +``` go +import ( + "fmt" + "github.com/vektah/gqlparser/v2/ast" + "os" + + "github.com/99designs/gqlgen/api" + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin/modelgen" +) + +// Defining mutation function +func constraintFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *modelgen.Field) (*modelgen.Field, error) { + + c := fd.Directives.ForName("constraint") + if c != nil { + formatConstraint := c.Arguments.ForName("format") + + if formatConstraint != nil{ + f.Tag += " validate:"+formatConstraint.Value.String() + } + + } + + return f, nil +} + +func main() { + cfg, err := config.LoadConfigFromDefaultLocations() + if err != nil { + fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) + os.Exit(2) + } + + // Attaching the mutation function onto modelgen plugin + p := modelgen.Plugin{ + FieldHook: constraintFieldHook, + } + + err = api.Generate(cfg, + api.NoPlugins(), + api.AddPlugin(&p), + ) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(3) + } +} +``` + +This schema: + +```graphql +directive @constraint( + format: String +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + +input ObjectInput { + contactEmail: String @constraint(format: "email") + website: String @constraint(format: "uri") +} +``` + +Will generate the model: + +```go +type ObjectInput struct { + contactEmail *string `json:"contactEmail" validate:"email"` + website *string `json:"website" validate:"uri"` +} +``` + +If a constraint being used during generation shoud not be published during introspection, the directive should be listed with `skip_runtime:true` in gqlgen.yml +```yaml +directives: + constraint: + skip_runtime: true +``` diff --git a/plugin/modelgen/models.go b/plugin/modelgen/models.go index eca6a3064d4..1a26a7463fd 100644 --- a/plugin/modelgen/models.go +++ b/plugin/modelgen/models.go @@ -13,6 +13,11 @@ import ( type BuildMutateHook = func(b *ModelBuild) *ModelBuild +type FieldMutateHook = func(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) + +func defaultFieldMutateHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { + return f, nil +} func defaultBuildMutateHook(b *ModelBuild) *ModelBuild { return b } @@ -58,11 +63,13 @@ type EnumValue struct { func New() plugin.Plugin { return &Plugin{ MutateHook: defaultBuildMutateHook, + FieldHook: defaultFieldMutateHook, } } type Plugin struct { MutateHook BuildMutateHook + FieldHook FieldMutateHook } var _ plugin.ConfigMutator = &Plugin{} @@ -167,12 +174,22 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error { tag = tag + " " + extraTag } - it.Fields = append(it.Fields, &Field{ + f := &Field{ Name: name, Type: typ, Description: field.Description, Tag: tag, - }) + } + + if m.FieldHook != nil { + mf, err := m.FieldHook(schemaType, field, f) + if err != nil { + return fmt.Errorf("generror: field %v.%v: %w", it.Name, field.Name, err) + } + f = mf + } + + it.Fields = append(it.Fields, f) } b.Models = append(b.Models, it) diff --git a/plugin/modelgen/models_test.go b/plugin/modelgen/models_test.go index 20becda9140..a5f02624de8 100644 --- a/plugin/modelgen/models_test.go +++ b/plugin/modelgen/models_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" + "github.com/vektah/gqlparser/v2/ast" + "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/plugin/modelgen/out" "github.com/stretchr/testify/require" @@ -18,6 +20,7 @@ func TestModelGeneration(t *testing.T) { require.NoError(t, cfg.Init()) p := Plugin{ MutateHook: mutateHook, + FieldHook: mutateFieldHook, } require.NoError(t, p.MutateConfig(cfg)) @@ -65,6 +68,22 @@ func TestModelGeneration(t *testing.T) { } }) + t.Run("field hooks are applied", func(t *testing.T) { + file, err := ioutil.ReadFile("./out/generated.go") + require.NoError(t, err) + + fileText := string(file) + + expectedTags := []string{ + `json:"name" anotherTag:"tag"`, + `json:"enum" yetAnotherTag:"12"`, + } + + for _, tag := range expectedTags { + require.True(t, strings.Contains(fileText, tag)) + } + }) + t.Run("concrete types implement interface", func(t *testing.T) { var _ out.FooBarer = out.FooBarr{} }) @@ -79,3 +98,19 @@ func mutateHook(b *ModelBuild) *ModelBuild { return b } + +func mutateFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *Field) (*Field, error) { + + if fd.Directives == nil || td.Name != "FieldMutationHook" { + return f, nil + } + + directive := fd.Directives.ForName("addTag") + if directive != nil { + args := directive.ArgumentMap(map[string]interface{}{}) + if tag, ok := args["tag"]; ok { + f.Tag += " " + tag.(string) + } + } + return f, nil +} diff --git a/plugin/modelgen/out/generated.go b/plugin/modelgen/out/generated.go index bddf95bbfff..d2ea061b685 100644 --- a/plugin/modelgen/out/generated.go +++ b/plugin/modelgen/out/generated.go @@ -30,6 +30,11 @@ type UnionWithDescription interface { IsUnionWithDescription() } +type FieldMutationHook struct { + Name *string `json:"name" anotherTag:"tag" database:"FieldMutationHookname"` + Enum *ExistingEnum `json:"enum" yetAnotherTag:"12" database:"FieldMutationHookenum"` +} + type MissingInput struct { Name *string `json:"name" database:"MissingInputname"` Enum *MissingEnum `json:"enum" database:"MissingInputenum"` diff --git a/plugin/modelgen/testdata/schema.graphql b/plugin/modelgen/testdata/schema.graphql index 7f0c0c93e95..cc36774f84e 100644 --- a/plugin/modelgen/testdata/schema.graphql +++ b/plugin/modelgen/testdata/schema.graphql @@ -1,3 +1,6 @@ +directive @addTag(tag: String!) on INPUT_FIELD_DEFINITION + | FIELD_DEFINITION + type Query { thisShoudlntGetGenerated: Boolean } @@ -54,6 +57,11 @@ input ExistingInput { enum: ExistingEnum } +type FieldMutationHook { + name: String @addTag(tag :"anotherTag:\"tag\"") + enum: ExistingEnum @addTag(tag: "yetAnotherTag:\"12\"") +} + enum ExistingEnum { Hello Goodbye From bfea93cdf3594edf0924e5ecd251eea09a1d35cb Mon Sep 17 00:00:00 2001 From: Dan Wendorf Date: Tue, 12 Oct 2021 07:48:09 -0700 Subject: [PATCH 128/146] Reload config packages after generating models (#1491) If models are generated in a package that has already been loaded, and that package refers to another package that has already been loaded, we can find ourselves in a position where it appears that a GQL `union` is not satisfied. For example, if we have: ``` union Subject = User ``` with this gqlgen.yml in github.com/wendorf/gqlgen-error/gql: ``` schema: - schema.graphql exec: filename: generated.go model: filename: models_gen.go models: User: model: github.com/wendorf/gqlgen-error/gql.User Subject: model: github.com/wendorf/gqlgen-error/models.Subject ``` Note that our User model is in the github.com/wendorf/gqlgen-error.gql package, and our models_gen.go will be generated in that same package. When we try to run gqlgen, we get this error: ``` merging type systems failed: unable to bind to interface: github.com/wendorf/gqlgen-error/gql.User does not satisfy the interface github.com/wendorf/gqlgen-error/models.Subject ``` Digging deeper, it's because we use types.Implements in codegen/interface.go, which does a shallow object comparison. Because the type has been reloaded, it refers to a _different_ interface type object than the one we're comparing against, and get a false negative. By clearing the package cache and repopulating it, the whole package cache is generated at the same time, and comparisons across packages work. To see a demo of this, check out https://github.com/wendorf/gqlgen-error and try the following: 1. Checkout the works-with-v0.10.2 branch and `go generate ./...` to see that it works 2. Checkout the breaks-with-v0.13.0 branch (or run go get github.com/99designs/gqlgen@v0.13.0 yourself) and `go generate ./...` to see errors 3. Checkout the works-with-pull-request branch and `go generate ./...` to see that it works again. This branch adds a go.mod replace directive to use the gqlgen code in this PR. The demo starts at v0.10.2 since it is the last release without this problem. https://github.com/99designs/gqlgen/pull/1020 introduces the code that fails in this scenario. --- codegen/config/config.go | 23 +++++++++++++++-------- internal/code/packages.go | 7 +++++++ plugin/modelgen/models.go | 11 ++++++++++- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/codegen/config/config.go b/codegen/config/config.go index b9292bc1828..404befada20 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -203,15 +203,8 @@ func (c *Config) Init() error { } c.injectBuiltins() - // prefetch all packages in one big packages.Load call - pkgs := []string{ - "github.com/99designs/gqlgen/graphql", - "github.com/99designs/gqlgen/graphql/introspection", - } - pkgs = append(pkgs, c.Models.ReferencedPackages()...) - pkgs = append(pkgs, c.AutoBind...) - c.Packages.LoadAll(pkgs...) + c.Packages.LoadAll(c.packageList()...) // check everything is valid on the way out err = c.check() @@ -222,6 +215,20 @@ func (c *Config) Init() error { return nil } +func (c *Config) packageList() []string { + pkgs := []string{ + "github.com/99designs/gqlgen/graphql", + "github.com/99designs/gqlgen/graphql/introspection", + } + pkgs = append(pkgs, c.Models.ReferencedPackages()...) + pkgs = append(pkgs, c.AutoBind...) + return pkgs +} + +func (c *Config) ReloadAllPackages() { + c.Packages.ReloadAll(c.packageList()...) +} + func (c *Config) injectTypesFromSchema() error { c.Directives["goModel"] = DirectiveConfig{ SkipRuntime: true, diff --git a/internal/code/packages.go b/internal/code/packages.go index 17d59f42c91..2976804ba80 100644 --- a/internal/code/packages.go +++ b/internal/code/packages.go @@ -30,6 +30,13 @@ type Packages struct { numNameCalls int // stupid test steam. ignore. } +// ReloadAll will call LoadAll after clearing the package cache, so we can reload +// packages in the case that the packages have changed +func (p *Packages) ReloadAll(importPaths ...string) []*packages.Package { + p.packages = nil + return p.LoadAll(importPaths...) +} + // LoadAll will call packages.Load and return the package data for the given packages, // but if the package already have been loaded it will return cached values instead. func (p *Packages) LoadAll(importPaths ...string) []*packages.Package { diff --git a/plugin/modelgen/models.go b/plugin/modelgen/models.go index 1a26a7463fd..2a413a5e238 100644 --- a/plugin/modelgen/models.go +++ b/plugin/modelgen/models.go @@ -236,13 +236,22 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error { b = m.MutateHook(b) } - return templates.Render(templates.Options{ + err := templates.Render(templates.Options{ PackageName: cfg.Model.Package, Filename: cfg.Model.Filename, Data: b, GeneratedHeader: true, Packages: cfg.Packages, }) + if err != nil { + return err + } + + // We may have generated code in a package we already loaded, so we reload all packages + // to allow packages to be compared correctly + cfg.ReloadAllPackages() + + return nil } func isStruct(t types.Type) bool { From 35199c49ab02648b518d5653ee25eac3e3627602 Mon Sep 17 00:00:00 2001 From: Travis Cline Date: Tue, 12 Oct 2021 07:55:29 -0700 Subject: [PATCH 129/146] codegen: ensure Elem present before using (#1317) --- codegen/type.gotpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codegen/type.gotpl b/codegen/type.gotpl index 9c421b02d3d..be563c8866e 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -30,7 +30,7 @@ {{- if $type.Unmarshaler }} {{- if $type.CastType }} tmp, err := {{ $type.Unmarshaler | call }}(v) - {{- if $type.IsNilable }} + {{- if and $type.IsNilable $type.Elem }} res := {{ $type.Elem.GO | ref }}(tmp) {{- else}} res := {{ $type.GO | ref }}(tmp) @@ -48,7 +48,7 @@ {{- else if eq ($type.GO | ref) "map[string]interface{}" }} return v.(map[string]interface{}), nil {{- else if $type.IsMarshaler }} - {{- if $type.IsNilable }} + {{- if and $type.IsNilable $type.Elem }} var res = new({{ $type.Elem.GO | ref }}) {{- else}} var res {{ $type.GO | ref }} From 629c91a2dff9982a5c469f25e8076ab7737e167a Mon Sep 17 00:00:00 2001 From: Bicky Eric Kantona Date: Tue, 12 Oct 2021 21:57:52 +0700 Subject: [PATCH 130/146] remove extra WithOperationContext call (#1641) --- graphql/handler/transport/http_post.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/graphql/handler/transport/http_post.go b/graphql/handler/transport/http_post.go index 70d971ac84c..deefeb38d00 100644 --- a/graphql/handler/transport/http_post.go +++ b/graphql/handler/transport/http_post.go @@ -48,7 +48,6 @@ func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecu writeJson(w, resp) return } - ctx := graphql.WithOperationContext(r.Context(), rc) - responses, ctx := exec.DispatchOperation(ctx, rc) + responses, ctx := exec.DispatchOperation(r.Context(), rc) writeJson(w, responses(ctx)) } From f8c46600aa005be4d62e52ca6f4a0467480c58c2 Mon Sep 17 00:00:00 2001 From: Carl Dunham Date: Tue, 12 Oct 2021 19:15:51 -0700 Subject: [PATCH 131/146] fix double indirect bug (#1604) * invalid code generated * update code generation for pointer-to-pointer updating fixes #1587 --- codegen/config/binder.go | 10 + codegen/testserver/generated.go | 592 ++++++++++++++++++++ codegen/testserver/ptr_to_ptr_input.go | 23 + codegen/testserver/ptr_to_ptr_input.graphql | 25 + codegen/testserver/ptr_to_ptr_input_test.go | 174 ++++++ codegen/testserver/resolver.go | 4 + codegen/testserver/stub.go | 4 + codegen/type.go | 2 +- codegen/type.gotpl | 17 +- 9 files changed, 849 insertions(+), 2 deletions(-) create mode 100644 codegen/testserver/ptr_to_ptr_input.go create mode 100644 codegen/testserver/ptr_to_ptr_input.graphql create mode 100644 codegen/testserver/ptr_to_ptr_input_test.go diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 209c1205d19..459114d6fce 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -212,6 +212,16 @@ func (t *TypeReference) IsPtr() bool { return isPtr } +// fix for https://github.com/golang/go/issues/31103 may make it possible to remove this (may still be useful) +// +func (t *TypeReference) IsPtrToPtr() bool { + if p, isPtr := t.GO.(*types.Pointer); isPtr { + _, isPtr := p.Elem().(*types.Pointer) + return isPtr + } + return false +} + func (t *TypeReference) IsNilable() bool { return IsNilable(t.GO) } diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 8001f44f472..2f04bf50feb 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -223,6 +223,7 @@ type ComplexityRoot struct { Mutation struct { DefaultInput func(childComplexity int, input DefaultInput) int + UpdatePtrToPtr func(childComplexity int, input UpdatePtrToPtrOuter) int UpdateSomething func(childComplexity int, input SpecialInput) int } @@ -263,6 +264,17 @@ type ComplexityRoot struct { Value func(childComplexity int) int } + PtrToPtrInner struct { + Key func(childComplexity int) int + Value func(childComplexity int) int + } + + PtrToPtrOuter struct { + Inner func(childComplexity int) int + Name func(childComplexity int) int + StupidInner func(childComplexity int) int + } + PtrToSliceContainer struct { PtrToSlice func(childComplexity int) int } @@ -425,6 +437,7 @@ type ModelMethodsResolver interface { type MutationResolver interface { DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) + UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) } type OverlappingFieldsResolver interface { OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) @@ -936,6 +949,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.DefaultInput(childComplexity, args["input"].(DefaultInput)), true + case "Mutation.updatePtrToPtr": + if e.complexity.Mutation.UpdatePtrToPtr == nil { + break + } + + args, err := ec.field_Mutation_updatePtrToPtr_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdatePtrToPtr(childComplexity, args["input"].(UpdatePtrToPtrOuter)), true + case "Mutation.updateSomething": if e.complexity.Mutation.UpdateSomething == nil { break @@ -1070,6 +1095,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.PrimitiveString.Value(childComplexity), true + case "PtrToPtrInner.key": + if e.complexity.PtrToPtrInner.Key == nil { + break + } + + return e.complexity.PtrToPtrInner.Key(childComplexity), true + + case "PtrToPtrInner.value": + if e.complexity.PtrToPtrInner.Value == nil { + break + } + + return e.complexity.PtrToPtrInner.Value(childComplexity), true + + case "PtrToPtrOuter.inner": + if e.complexity.PtrToPtrOuter.Inner == nil { + break + } + + return e.complexity.PtrToPtrOuter.Inner(childComplexity), true + + case "PtrToPtrOuter.name": + if e.complexity.PtrToPtrOuter.Name == nil { + break + } + + return e.complexity.PtrToPtrOuter.Name(childComplexity), true + + case "PtrToPtrOuter.stupidInner": + if e.complexity.PtrToPtrOuter.StupidInner == nil { + break + } + + return e.complexity.PtrToPtrOuter.StupidInner(childComplexity), true + case "PtrToSliceContainer.ptrToSlice": if e.complexity.PtrToSliceContainer.PtrToSlice == nil { break @@ -2236,6 +2296,32 @@ type PrimitiveString { doubled: String! len: Int! } +`, BuiltIn: false}, + {Name: "ptr_to_ptr_input.graphql", Input: `type PtrToPtrOuter { + name: String! + inner: PtrToPtrInner + stupidInner: PtrToPtrInner +} + +type PtrToPtrInner { + key: String! + value: String! +} + +input UpdatePtrToPtrOuter { + name: String + inner: UpdatePtrToPtrInner + stupidInner: UpdatePtrToPtrInner +} + +input UpdatePtrToPtrInner { + key: String + value: String +} + +extend type Mutation { + updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter! +} `, BuiltIn: false}, {Name: "ptr_to_slice.graphql", Input: `type PtrToSliceContainer { ptrToSlice: [String!] @@ -2639,6 +2725,21 @@ func (ec *executionContext) field_Mutation_defaultInput_args(ctx context.Context return args, nil } +func (ec *executionContext) field_Mutation_updatePtrToPtr_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 UpdatePtrToPtrOuter + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrOuter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_updateSomething_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -5395,6 +5496,45 @@ func (ec *executionContext) _Mutation_updateSomething(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation_updatePtrToPtr(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_updatePtrToPtr_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdatePtrToPtr(rctx, args["input"].(UpdatePtrToPtrOuter)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*PtrToPtrOuter) + fc.Result = res + return ec.marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx, field.Selections, res) +} + func (ec *executionContext) _ObjectDirectives_text(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectives) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -6051,6 +6191,160 @@ func (ec *executionContext) _PrimitiveString_len(ctx context.Context, field grap return ec.marshalNInt2int(ctx, field.Selections, res) } +func (ec *executionContext) _PtrToPtrInner_key(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrInner) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrInner", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Key, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrInner_value(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrInner) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrInner", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_name(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_inner(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Inner, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*PtrToPtrInner) + fc.Result = res + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_stupidInner(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StupidInner, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*******PtrToPtrInner) + fc.Result = res + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, field.Selections, res) +} + func (ec *executionContext) _PtrToSliceContainer_ptrToSlice(ctx context.Context, field graphql.CollectedField, obj *PtrToSliceContainer) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -10887,6 +11181,76 @@ func (ec *executionContext) unmarshalInputSpecialInput(ctx context.Context, obj return it, nil } +func (ec *executionContext) unmarshalInputUpdatePtrToPtrInner(ctx context.Context, obj interface{}) (UpdatePtrToPtrInner, error) { + var it UpdatePtrToPtrInner + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "key": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + it.Key, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "value": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("value")) + it.Value, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputUpdatePtrToPtrOuter(ctx context.Context, obj interface{}) (UpdatePtrToPtrOuter, error) { + var it UpdatePtrToPtrOuter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + it.Name, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "inner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) + it.Inner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return it, err + } + case "stupidInner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("stupidInner")) + it.StupidInner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputValidInput(ctx context.Context, obj interface{}) (ValidInput, error) { var it ValidInput asMap := map[string]interface{}{} @@ -12265,6 +12629,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { invalids++ } + case "updatePtrToPtr": + out.Values[i] = ec._Mutation_updatePtrToPtr(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12577,6 +12946,69 @@ func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.Select return out } +var ptrToPtrInnerImplementors = []string{"PtrToPtrInner"} + +func (ec *executionContext) _PtrToPtrInner(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrInner) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrInnerImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToPtrInner") + case "key": + out.Values[i] = ec._PtrToPtrInner_key(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "value": + out.Values[i] = ec._PtrToPtrInner_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var ptrToPtrOuterImplementors = []string{"PtrToPtrOuter"} + +func (ec *executionContext) _PtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrOuter) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrOuterImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToPtrOuter") + case "name": + out.Values[i] = ec._PtrToPtrOuter_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "inner": + out.Values[i] = ec._PtrToPtrOuter_inner(ctx, field, obj) + case "stupidInner": + out.Values[i] = ec._PtrToPtrOuter_stupidInner(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var ptrToSliceContainerImplementors = []string{"PtrToSliceContainer"} func (ec *executionContext) _PtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, obj *PtrToSliceContainer) graphql.Marshaler { @@ -14467,6 +14899,20 @@ func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designs return ret } +func (ec *executionContext) marshalNPtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v PtrToPtrOuter) graphql.Marshaler { + return ec._PtrToPtrOuter(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrOuter) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._PtrToPtrOuter(ctx, sel, v) +} + func (ec *executionContext) marshalNPtrToSliceContainer2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v PtrToSliceContainer) graphql.Marshaler { return ec._PtrToSliceContainer(ctx, sel, &v) } @@ -14633,6 +15079,11 @@ func (ec *executionContext) marshalNUUID2string(ctx context.Context, sel ast.Sel return res } +func (ec *executionContext) unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrOuter(ctx context.Context, v interface{}) (UpdatePtrToPtrOuter, error) { + res, err := ec.unmarshalInputUpdatePtrToPtrOuter(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalNUser2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUser(ctx context.Context, sel ast.SelectionSet, v User) graphql.Marshaler { return ec._User(ctx, sel, &v) } @@ -15554,6 +16005,55 @@ func (ec *executionContext) marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._Panics(ctx, sel, v) } +func (ec *executionContext) marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._PtrToPtrInner(ctx, sel, v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v **PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ***PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ****PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *****PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ******PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *******PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) +} + func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSliceᚄ(ctx context.Context, v interface{}) ([]RecursiveInputSlice, error) { if v == nil { return nil, nil @@ -15792,6 +16292,98 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel return graphql.MarshalTime(*v) } +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*UpdatePtrToPtrInner, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputUpdatePtrToPtrInner(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (**UpdatePtrToPtrInner, error) { + var pres *UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (***UpdatePtrToPtrInner, error) { + var pres **UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (****UpdatePtrToPtrInner, error) { + var pres ***UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*****UpdatePtrToPtrInner, error) { + var pres ****UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (******UpdatePtrToPtrInner, error) { + var pres *****UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*******UpdatePtrToPtrInner, error) { + var pres ******UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (********UpdatePtrToPtrInner, error) { + var pres *******UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + func (ec *executionContext) marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseNil(ctx context.Context, sel ast.SelectionSet, v *VOkCaseNil) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/codegen/testserver/ptr_to_ptr_input.go b/codegen/testserver/ptr_to_ptr_input.go new file mode 100644 index 00000000000..a29ff466299 --- /dev/null +++ b/codegen/testserver/ptr_to_ptr_input.go @@ -0,0 +1,23 @@ +package testserver + +type PtrToPtrOuter struct { + Name string + Inner *PtrToPtrInner + StupidInner *******PtrToPtrInner +} + +type PtrToPtrInner struct { + Key string + Value string +} + +type UpdatePtrToPtrOuter struct { + Name *string + Inner **UpdatePtrToPtrInner + StupidInner ********UpdatePtrToPtrInner +} + +type UpdatePtrToPtrInner struct { + Key *string + Value *string +} diff --git a/codegen/testserver/ptr_to_ptr_input.graphql b/codegen/testserver/ptr_to_ptr_input.graphql new file mode 100644 index 00000000000..c34b5c56fc5 --- /dev/null +++ b/codegen/testserver/ptr_to_ptr_input.graphql @@ -0,0 +1,25 @@ +type PtrToPtrOuter { + name: String! + inner: PtrToPtrInner + stupidInner: PtrToPtrInner +} + +type PtrToPtrInner { + key: String! + value: String! +} + +input UpdatePtrToPtrOuter { + name: String + inner: UpdatePtrToPtrInner + stupidInner: UpdatePtrToPtrInner +} + +input UpdatePtrToPtrInner { + key: String + value: String +} + +extend type Mutation { + updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter! +} diff --git a/codegen/testserver/ptr_to_ptr_input_test.go b/codegen/testserver/ptr_to_ptr_input_test.go new file mode 100644 index 00000000000..0e0320bbf0d --- /dev/null +++ b/codegen/testserver/ptr_to_ptr_input_test.go @@ -0,0 +1,174 @@ +package testserver + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +type UpdatePtrToPtrResults struct { + UpdatedPtrToPtr PtrToPtrOuter `json:"updatePtrToPtr"` +} + +func TestPtrToPtr(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.MutationResolver.UpdatePtrToPtr = func(ctx context.Context, in UpdatePtrToPtrOuter) (ret *PtrToPtrOuter, err error) { + ret = &PtrToPtrOuter{ + Name: "oldName", + Inner: &PtrToPtrInner{ + Key: "oldKey", + Value: "oldValue", + }, + StupidInner: nest7(&PtrToPtrInner{ + Key: "oldStupidKey", + Value: "oldStupidValue", + }), + } + + if in.Name != nil { + ret.Name = *in.Name + } + + if in.Inner != nil { + inner := *in.Inner + if inner == nil { + ret.Inner = nil + } else { + if in.Inner == nil { + ret.Inner = &PtrToPtrInner{} + } + if inner.Key != nil { + ret.Inner.Key = *inner.Key + } + if inner.Value != nil { + ret.Inner.Value = *inner.Value + } + } + } + + if in.StupidInner != nil { + si := *in.StupidInner + if si == nil { + ret.StupidInner = nil + } else { + deepIn := ******si + deepOut := ******ret.StupidInner + if deepIn.Key != nil { + deepOut.Key = *deepIn.Key + } + if deepIn.Value != nil { + deepOut.Value = *deepIn.Value + } + } + } + return + } + + t.Run("pointer to pointer input missing", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { name: "newName" }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "newName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("pointer to pointer input non-null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { + updatePtrToPtr(input: { + inner: { + key: "newKey" + value: "newValue" + } + }) + { name, inner { key, value }, stupidInner { key, value }} + }`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "newKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "newValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("pointer to pointer input null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { inner: null }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.Nil(t, resp.UpdatedPtrToPtr.Inner) + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("many pointers input non-null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { + updatePtrToPtr(input: { + stupidInner: { + key: "newKey" + value: "newValue" + } + }) + { name, inner { key, value }, stupidInner { key, value }} + }`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "newKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "newValue") + }) + + t.Run("many pointers input null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { stupidInner: null }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.Nil(t, resp.UpdatedPtrToPtr.StupidInner) + }) +} + +func nest7(in *PtrToPtrInner) *******PtrToPtrInner { + si2 := &in + si3 := &si2 + si4 := &si3 + si5 := &si4 + si6 := &si5 + si7 := &si6 + + return si7 +} diff --git a/codegen/testserver/resolver.go b/codegen/testserver/resolver.go index 20f8a7b726d..6388f83ad3d 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/resolver.go @@ -52,6 +52,10 @@ func (r *mutationResolver) UpdateSomething(ctx context.Context, input SpecialInp panic("not implemented") } +func (r *mutationResolver) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { + panic("not implemented") +} + func (r *overlappingFieldsResolver) OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) { panic("not implemented") } diff --git a/codegen/testserver/stub.go b/codegen/testserver/stub.go index 310de5587dc..79fde9c00ad 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/stub.go @@ -30,6 +30,7 @@ type Stub struct { MutationResolver struct { DefaultInput func(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) UpdateSomething func(ctx context.Context, input SpecialInput) (string, error) + UpdatePtrToPtr func(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) } OverlappingFieldsResolver struct { OldFoo func(ctx context.Context, obj *OverlappingFields) (int, error) @@ -215,6 +216,9 @@ func (r *stubMutation) DefaultInput(ctx context.Context, input DefaultInput) (*D func (r *stubMutation) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { return r.MutationResolver.UpdateSomething(ctx, input) } +func (r *stubMutation) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { + return r.MutationResolver.UpdatePtrToPtr(ctx, input) +} type stubOverlappingFields struct{ *Stub } diff --git a/codegen/type.go b/codegen/type.go index 5a059d70131..20b09dc9755 100644 --- a/codegen/type.go +++ b/codegen/type.go @@ -26,7 +26,7 @@ func processType(ret map[string]*config.TypeReference, ref *config.TypeReference } ret[key] = ref - if ref.IsSlice() || ref.IsPtrToSlice() { + if ref.IsSlice() || ref.IsPtrToSlice() || ref.IsPtrToPtr() { processType(ret, ref.Elem()) } } diff --git a/codegen/type.gotpl b/codegen/type.gotpl index be563c8866e..e9468ae3a23 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -1,7 +1,7 @@ {{- range $type := .ReferencedTypes }} {{ with $type.UnmarshalFunc }} func (ec *executionContext) {{ . }}(ctx context.Context, v interface{}) ({{ $type.GO | ref }}, error) { - {{- if and $type.IsNilable (not $type.GQL.NonNull) }} + {{- if and $type.IsNilable (not $type.GQL.NonNull) (not $type.IsPtrToPtr) }} if v == nil { return nil, nil } {{- end }} {{- if $type.IsPtrToSlice }} @@ -26,6 +26,16 @@ } } return res, nil + {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} + var pres {{ $type.Elem.GO | ref }} + if v != nil { + res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil {{- else }} {{- if $type.Unmarshaler }} {{- if $type.CastType }} @@ -123,6 +133,11 @@ } {{ end }} return ret + {{- else if and $type.IsPtrToPtr (not $type.Unmarshaler) (not $type.IsMarshaler) }} + if v == nil { + return graphql.Null + } + return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v) {{- else }} {{- if $type.IsNilable }} if v == nil { From f6c35be2128d8d0ec6c0c0d63bc0f135292ab5fe Mon Sep 17 00:00:00 2001 From: Thomas Prebble <6523587+tprebs@users.noreply.github.com> Date: Wed, 13 Oct 2021 14:12:52 +0100 Subject: [PATCH 132/146] Add ReplacePlugin option to replace a specific plugin (#1657) * Add Helper Option for replacing plugins * Update recipe to use ReplacePlugin instead of NoPlugin and AddPlugin * fix linting issue on comment --- api/option.go | 20 +++++++++ api/option_test.go | 58 +++++++++++++++++++++++++++ docs/content/recipes/modelgen-hook.md | 18 ++++----- 3 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 api/option_test.go diff --git a/api/option.go b/api/option.go index f7ba6774bd0..ab41dfa2051 100644 --- a/api/option.go +++ b/api/option.go @@ -18,3 +18,23 @@ func AddPlugin(p plugin.Plugin) Option { *plugins = append(*plugins, p) } } + +// ReplacePlugin replaces any existing plugin with a matching plugin name +func ReplacePlugin(p plugin.Plugin) Option { + return func(cfg *config.Config, plugins *[]plugin.Plugin) { + if plugins != nil { + found := false + ps := *plugins + for i, o := range ps { + if p.Name() == o.Name() { + ps[i] = p + found = true + } + } + if !found { + ps = append(ps, p) + } + *plugins = ps + } + } +} diff --git a/api/option_test.go b/api/option_test.go new file mode 100644 index 00000000000..749e29dd408 --- /dev/null +++ b/api/option_test.go @@ -0,0 +1,58 @@ +package api + +import ( + "testing" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/plugin" + "github.com/99designs/gqlgen/plugin/federation" + "github.com/99designs/gqlgen/plugin/modelgen" + "github.com/99designs/gqlgen/plugin/resolvergen" + "github.com/stretchr/testify/require" +) + +type testPlugin struct { +} + +// Name returns the plugin name +func (t *testPlugin) Name() string { + return "modelgen" +} + +// MutateConfig mutates the configuration +func (t *testPlugin) MutateConfig(_ *config.Config) error { + return nil +} + +func TestReplacePlugin(t *testing.T) { + + t.Run("replace plugin if exists", func(t *testing.T) { + pg := []plugin.Plugin{ + federation.New(), + modelgen.New(), + resolvergen.New(), + } + + expectedPlugin := &testPlugin{} + ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) + + require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, expectedPlugin, pg[1]) + require.EqualValues(t, resolvergen.New(), pg[2]) + }) + + t.Run("add plugin if doesn't exist", func(t *testing.T) { + pg := []plugin.Plugin{ + federation.New(), + resolvergen.New(), + } + + expectedPlugin := &testPlugin{} + ReplacePlugin(expectedPlugin)(config.DefaultConfig(), &pg) + + require.EqualValues(t, federation.New(), pg[0]) + require.EqualValues(t, resolvergen.New(), pg[1]) + require.EqualValues(t, expectedPlugin, pg[2]) + }) + +} diff --git a/docs/content/recipes/modelgen-hook.md b/docs/content/recipes/modelgen-hook.md index eb65d625c26..695ca74cb92 100644 --- a/docs/content/recipes/modelgen-hook.md +++ b/docs/content/recipes/modelgen-hook.md @@ -49,10 +49,8 @@ func main() { MutateHook: mutateHook, } - err = api.Generate(cfg, - api.NoPlugins(), - api.AddPlugin(&p), - ) + err = api.Generate(cfg, api.ReplacePlugin(&p)) + if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(3) @@ -82,7 +80,7 @@ type Object struct { ## FieldMutateHook -For more fine grained control over model generation, a graphql schema aware a FieldHook can be provided. This hook has access to type and field graphql definitions enabling the hook to modify the `modelgen.Field` using directives defined within the schema. +For more fine grained control over model generation, a graphql schema aware a FieldHook can be provided. This hook has access to type and field graphql definitions enabling the hook to modify the `modelgen.Field` using directives defined within the schema. The below recipe uses this feature to add validate tags to the generated model for use with `go-playground/validator` where the validate tags are defined in a constraint directive in the schema. @@ -103,11 +101,11 @@ func constraintFieldHook(td *ast.Definition, fd *ast.FieldDefinition, f *modelge c := fd.Directives.ForName("constraint") if c != nil { formatConstraint := c.Arguments.ForName("format") - + if formatConstraint != nil{ f.Tag += " validate:"+formatConstraint.Value.String() } - + } return f, nil @@ -125,10 +123,8 @@ func main() { FieldHook: constraintFieldHook, } - err = api.Generate(cfg, - api.NoPlugins(), - api.AddPlugin(&p), - ) + err = api.Generate(cfg, api.ReplacePlugin(&p)) + if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(3) From 6758654c4e28dc0589147c9e962c9d4c1fd44705 Mon Sep 17 00:00:00 2001 From: Masahiro Wakame Date: Wed, 13 Oct 2021 22:19:36 +0900 Subject: [PATCH 133/146] raise panic when nested @requires are used on federation (#1655) --- plugin/federation/federation.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index 7d9abc9774c..cdcea8c4f0c 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -243,7 +243,12 @@ func (f *federation) setEntities(schema *ast.Schema) { if dir == nil { continue } - fields := strings.Split(dir.Arguments[0].Value.Raw, " ") + args := dir.Arguments[0].Value.Raw + if strings.Contains(args, "{") { + // TODO: see. https://github.com/99designs/gqlgen/issues/1138 + panic("Nested fields are not currently supported in @requires declaration.") + } + fields := strings.Split(args, " ") requireFields := []*RequireField{} for _, f := range fields { requireFields = append(requireFields, &RequireField{ From 1318f12792e86c76a2cdff9132ebac5b3e30e148 Mon Sep 17 00:00:00 2001 From: Alex Sonneveld Date: Thu, 14 Oct 2021 00:33:29 +1100 Subject: [PATCH 134/146] Update GQLgen test client to work with multipart form data (#1418) * Update GQLgen test client to work with multipart form data Update the GQLgen to support multipart form data, like those present within the fileupload examples. - Add missing space between "unsupported encoding " and failing content-type header error * Add WithFiles client option for fileupload GQLgen client tests Add a `WithFiles` GQLgen client option to support the fileupload input within tests, using the core Golang `os` package and File type, which converts `os.File`s to their appropriate multipart form data within a request. - If there are no files this should just simply convert a `application/json` Content-Type to supported `multipart/form-data` * Update fileupload test to use GQLgen test client Update the fileupload test to use the GQLgen test client and `WithFiles` option to remove the need for `createUploadRequest` helper with raw http posts - Fix setting the Content Type by using the appropriate `http` package function to dectect it + https://godoc.org/net/http#DetectContentType * Update WithFiles option test with multipart Reader * Update file upload tests `WithFiles` option Update the file upload tests to use the GQL test client and its `WithFiles` option to remove the need for a custom raw HTTP post request builder `createUploadRequest`. - Also update `WithFiles` option to group & map identical files; e.g. ``` { "0": ["variables.req.0.file", "variables.req.1.file"] } ``` * Make sure `WithFiles` does not add duplicates to multipart form data * Fix use of byte vs string in `WithFiles` tests --- client/client.go | 10 +- client/client_test.go | 41 ++++ client/withfilesoption.go | 133 +++++++++++++ client/withfilesoption_test.go | 225 +++++++++++++++++++++ example/fileupload/fileupload_test.go | 268 +++++++++++--------------- 5 files changed, 520 insertions(+), 157 deletions(-) create mode 100644 client/withfilesoption.go create mode 100644 client/withfilesoption_test.go diff --git a/client/client.go b/client/client.go index 7a2825c952b..e29c5fe5b3d 100644 --- a/client/client.go +++ b/client/client.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "regexp" "github.com/mitchellh/mapstructure" ) @@ -120,15 +121,18 @@ func (p *Client) newRequest(query string, options ...Option) (*http.Request, err option(bd) } - switch bd.HTTP.Header.Get("Content-Type") { - case "application/json": + contentType := bd.HTTP.Header.Get("Content-Type") + switch { + case regexp.MustCompile(`multipart/form-data; ?boundary=.*`).MatchString(contentType): + break + case "application/json" == contentType: requestBody, err := json.Marshal(bd) if err != nil { return nil, fmt.Errorf("encode: %w", err) } bd.HTTP.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody)) default: - panic("unsupported encoding" + bd.HTTP.Header.Get("Content-Type")) + panic("unsupported encoding " + bd.HTTP.Header.Get("Content-Type")) } return bd.HTTP, nil diff --git a/client/client_test.go b/client/client_test.go index 569151cd8a2..176c48d12ae 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,9 +1,12 @@ package client_test import ( + "bytes" "encoding/json" "io/ioutil" + "mime/multipart" "net/http" + "net/textproto" "testing" "github.com/99designs/gqlgen/client" @@ -39,6 +42,44 @@ func TestClient(t *testing.T) { require.Equal(t, "bob", resp.Name) } +func TestClientMultipartFormData(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + bodyBytes, err := ioutil.ReadAll(r.Body) + require.NoError(t, err) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="operations"`) + require.Contains(t, string(bodyBytes), `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="map"`) + require.Contains(t, string(bodyBytes), `{"0":["variables.file"]}`) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="0"; filename="example.txt"`) + require.Contains(t, string(bodyBytes), `Content-Type: text/plain`) + require.Contains(t, string(bodyBytes), `Hello World`) + + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + func(bd *client.Request) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + bodyWriter.WriteField("operations", `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) + bodyWriter.WriteField("map", `{"0":["variables.file"]}`) + + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="0"; filename="example.txt"`) + h.Set("Content-Type", "text/plain") + ff, _ := bodyWriter.CreatePart(h) + ff.Write([]byte("Hello World")) + bodyWriter.Close() + + bd.HTTP.Body = ioutil.NopCloser(bodyBuf) + bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) + }, + ) +} + func TestAddHeader(t *testing.T) { h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "ASDF", r.Header.Get("Test-Key")) diff --git a/client/withfilesoption.go b/client/withfilesoption.go new file mode 100644 index 00000000000..eff0d1c25f3 --- /dev/null +++ b/client/withfilesoption.go @@ -0,0 +1,133 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "mime/multipart" + "net/http" + "net/textproto" + "os" + "strings" +) + +type fileFormDataMap struct { + mapKey string + file *os.File +} + +func findFiles(parentMapKey string, variables map[string]interface{}) []*fileFormDataMap { + files := []*fileFormDataMap{} + for key, value := range variables { + if v, ok := value.(map[string]interface{}); ok { + files = append(files, findFiles(parentMapKey+"."+key, v)...) + } else if v, ok := value.([]map[string]interface{}); ok { + for i, arr := range v { + files = append(files, findFiles(fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), arr)...) + } + } else if v, ok := value.([]*os.File); ok { + for i, file := range v { + files = append(files, &fileFormDataMap{ + mapKey: fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), + file: file, + }) + } + } else if v, ok := value.(*os.File); ok { + files = append(files, &fileFormDataMap{ + mapKey: parentMapKey + "." + key, + file: v, + }) + } + } + + return files +} + +// WithFiles encodes the outgoing request body as multipart form data for file variables +func WithFiles() Option { + return func(bd *Request) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + + //-b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="operations" + // + // {"query":"mutation ($input: Input!) {}","variables":{"input":{"file":{}}} + requestBody, _ := json.Marshal(bd) + bodyWriter.WriteField("operations", string(requestBody)) + + // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="map" + // + // `{ "0":["variables.input.file"] }` + // or + // `{ "0":["variables.input.files.0"], "1":["variables.input.files.1"] }` + // or + // `{ "0": ["variables.input.0.file"], "1": ["variables.input.1.file"] }` + // or + // `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` + mapData := "" + filesData := findFiles("variables", bd.Variables) + filesGroup := [][]*fileFormDataMap{} + for _, fd := range filesData { + foundDuplicate := false + for j, fg := range filesGroup { + f1, _ := fd.file.Stat() + f2, _ := fg[0].file.Stat() + if os.SameFile(f1, f2) { + foundDuplicate = true + filesGroup[j] = append(filesGroup[j], fd) + } + } + + if !foundDuplicate { + filesGroup = append(filesGroup, []*fileFormDataMap{fd}) + } + } + if len(filesGroup) > 0 { + mapDataFiles := []string{} + + for i, fileData := range filesGroup { + mapDataFiles = append( + mapDataFiles, + fmt.Sprintf(`"%d":[%s]`, i, strings.Join(collect(fileData, wrapMapKeyInQuotes), ",")), + ) + } + + mapData = `{` + strings.Join(mapDataFiles, ",") + `}` + } + bodyWriter.WriteField("map", mapData) + + // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="0"; filename="tempFile" + // Content-Type: text/plain; charset=utf-8 + // or + // Content-Type: application/octet-stream + // + for i, fileData := range filesGroup { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%d"; filename="%s"`, i, fileData[0].file.Name())) + b, _ := ioutil.ReadFile(fileData[0].file.Name()) + h.Set("Content-Type", http.DetectContentType(b)) + ff, _ := bodyWriter.CreatePart(h) + ff.Write(b) + } + bodyWriter.Close() + + bd.HTTP.Body = ioutil.NopCloser(bodyBuf) + bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) + } +} + +func collect(strArr []*fileFormDataMap, f func(s *fileFormDataMap) string) []string { + result := make([]string, len(strArr)) + for i, str := range strArr { + result[i] = f(str) + } + return result +} + +func wrapMapKeyInQuotes(s *fileFormDataMap) string { + return fmt.Sprintf("\"%s\"", s.mapKey) +} diff --git a/client/withfilesoption_test.go b/client/withfilesoption_test.go new file mode 100644 index 00000000000..f3528936ff4 --- /dev/null +++ b/client/withfilesoption_test.go @@ -0,0 +1,225 @@ +package client_test + +import ( + "fmt" + "io" + "io/ioutil" + "mime" + "mime/multipart" + "net/http" + "os" + "regexp" + "strings" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/stretchr/testify/require" +) + +func TestWithFiles(t *testing.T) { + tempFile1, _ := ioutil.TempFile(os.TempDir(), "tempFile1") + tempFile2, _ := ioutil.TempFile(os.TempDir(), "tempFile2") + tempFile3, _ := ioutil.TempFile(os.TempDir(), "tempFile3") + defer os.Remove(tempFile1.Name()) + defer os.Remove(tempFile2.Name()) + defer os.Remove(tempFile3.Name()) + tempFile1.WriteString(`The quick brown fox jumps over the lazy dog`) + tempFile2.WriteString(`hello world`) + tempFile3.WriteString(`La-Li-Lu-Le-Lo`) + + t.Run("with one file", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + fmt.Printf("Part %q: %q\n", contentDisposition, slurp) + + if contentDisposition == `form-data; name="operations"` { + require.Equal(t, `{"query":"{ id }","variables":{"file":{}}}`, string(slurp)) + } + if contentDisposition == `form-data; name="map"` { + require.Equal(t, `{"0":["variables.file"]}`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("file", tempFile1), + client.WithFiles(), + ) + }) + + t.Run("with multiple files", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + fmt.Printf("Part %q: %q\n", contentDisposition, slurp) + + if contentDisposition == `form-data; name="operations"` { + require.Equal(t, `{"query":"{ id }","variables":{"input":{"files":[{},{}]}}}`, string(slurp)) + } + if contentDisposition == `form-data; name="map"` { + require.Equal(t, `{"0":["variables.input.files.0"],"1":["variables.input.files.1"]}`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `hello world`, string(slurp)) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("input", map[string]interface{}{ + "files": []*os.File{tempFile1, tempFile2}, + }), + client.WithFiles(), + ) + }) + + t.Run("with multiple files across multiple variables", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + fmt.Printf("Part %q: %q\n", contentDisposition, slurp) + + if contentDisposition == `form-data; name="operations"` { + require.Equal(t, `{"query":"{ id }","variables":{"req":{"files":[{},{}],"foo":{"bar":{}}}}}`, string(slurp)) + } + if contentDisposition == `form-data; name="map"` { + require.Equal(t, `{"0":["variables.req.files.0"],"1":["variables.req.files.1"],"2":["variables.req.foo.bar"]}`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `hello world`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="2"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `La-Li-Lu-Le-Lo`, string(slurp)) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("req", map[string]interface{}{ + "files": []*os.File{tempFile1, tempFile2}, + "foo": map[string]interface{}{ + "bar": tempFile3, + }, + }), + client.WithFiles(), + ) + }) + + t.Run("with multiple files and file reuse", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + fmt.Printf("Part %q: %q\n", contentDisposition, slurp) + + if contentDisposition == `form-data; name="operations"` { + require.Equal(t, `{"query":"{ id }","variables":{"files":[{},{},{}]}}`, string(slurp)) + } + if contentDisposition == `form-data; name="map"` { + require.Equal(t, `{"0":["variables.files.0","variables.files.2"],"1":["variables.files.1"]}`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) + } + if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Equal(t, `hello world`, string(slurp)) + } + require.False(t, regexp.MustCompile(`form-data; name="2"; filename=.*`).MatchString(contentDisposition)) + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("files", []*os.File{tempFile1, tempFile2, tempFile1}), + client.WithFiles(), + ) + }) +} diff --git a/example/fileupload/fileupload_test.go b/example/fileupload/fileupload_test.go index 8d68252e009..158825edfbf 100644 --- a/example/fileupload/fileupload_test.go +++ b/example/fileupload/fileupload_test.go @@ -2,17 +2,14 @@ package fileupload import ( - "bytes" "context" - "fmt" "io" "io/ioutil" - "mime/multipart" - "net/http" "net/http/httptest" - "net/textproto" + "os" "testing" + gqlclient "github.com/99designs/gqlgen/client" "github.com/99designs/gqlgen/example/fileupload/model" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" @@ -21,10 +18,23 @@ import ( ) func TestFileUpload(t *testing.T) { - client := http.Client{} + resolver := &Stub{} + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() + gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) + + aTxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") + defer os.Remove(aTxtFile.Name()) + aTxtFile.WriteString(`test`) + + a1TxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") + b1TxtFile, _ := ioutil.TempFile(os.TempDir(), "b.txt") + defer os.Remove(a1TxtFile.Name()) + defer os.Remove(b1TxtFile.Name()) + a1TxtFile.WriteString(`test1`) + b1TxtFile.WriteString(`test2`) t.Run("valid single file upload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.SingleUpload = func(ctx context.Context, file graphql.Upload) (*model.File, error) { require.NotNil(t, file) require.NotNil(t, file.File) @@ -39,34 +49,28 @@ func TestFileUpload(t *testing.T) { ContentType: file.ContentType, }, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id, name, content, contentType } }", "variables": { "file": null } }` - mapData := `{ "0": ["variables.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test", - contentType: "text/plain", - }, + mutation := `mutation ($file: Upload!) { + singleUpload(file: $file) { + id + name + content + contentType + } + }` + var result struct { + SingleUpload *model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - responseString := string(responseBody) - require.Equal(t, `{"data":{"singleUpload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, responseString) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("file", aTxtFile), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.SingleUpload.ID) + require.Contains(t, result.SingleUpload.Name, "a.txt") + require.Equal(t, "test", result.SingleUpload.Content) + require.Equal(t, "text/plain; charset=utf-8", result.SingleUpload.ContentType) }) t.Run("valid single file upload with payload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.SingleUploadWithPayload = func(ctx context.Context, req model.UploadFile) (*model.File, error) { require.Equal(t, req.ID, 1) require.NotNil(t, req.File) @@ -82,33 +86,28 @@ func TestFileUpload(t *testing.T) { ContentType: req.File.ContentType, }, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation ($req: UploadFile!) { singleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": {"file": null, "id": 1 } } }` - mapData := `{ "0": ["variables.req.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test", - contentType: "text/plain", - }, + mutation := `mutation ($req: UploadFile!) { + singleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + SingleUploadWithPayload *model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"singleUploadWithPayload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("req", map[string]interface{}{"id": 1, "file": aTxtFile}), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.SingleUploadWithPayload.ID) + require.Contains(t, result.SingleUploadWithPayload.Name, "a.txt") + require.Equal(t, "test", result.SingleUploadWithPayload.Content) + require.Equal(t, "text/plain; charset=utf-8", result.SingleUploadWithPayload.ContentType) }) t.Run("valid file list upload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.MultipleUpload = func(ctx context.Context, files []*graphql.Upload) ([]*model.File, error) { require.Len(t, files, 2) var contents []string @@ -128,39 +127,32 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id, name, content, contentType } }", "variables": { "files": [null, null] } }` - mapData := `{ "0": ["variables.files.0"], "1": ["variables.files.1"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - { - mapKey: "1", - name: "b.txt", - content: "test2", - contentType: "text/plain", - }, + mutation := `mutation($files: [Upload!]!) { + multipleUpload(files: $files) { + id + name + content + contentType + } + }` + var result struct { + MultipleUpload []*model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUpload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("files", []*os.File{a1TxtFile, b1TxtFile}), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUpload[0].ID) + require.Contains(t, result.MultipleUpload[0].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUpload[0].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUpload[0].ContentType) + require.Equal(t, 2, result.MultipleUpload[1].ID) + require.Contains(t, result.MultipleUpload[1].Name, "b.txt") + require.Equal(t, "test2", result.MultipleUpload[1].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUpload[1].ContentType) }) t.Run("valid file list upload with payload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.MultipleUploadWithPayload = func(ctx context.Context, req []*model.UploadFile) ([]*model.File, error) { require.Len(t, req, 2) var ids []int @@ -184,35 +176,32 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` - mapData := `{ "0": ["variables.req.0.file"], "1": ["variables.req.1.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - { - mapKey: "1", - name: "b.txt", - content: "test2", - contentType: "text/plain", - }, + mutation := `mutation($req: [UploadFile!]!) { + multipleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + MultipleUploadWithPayload []*model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ + {"id": 1, "file": a1TxtFile}, + {"id": 2, "file": b1TxtFile}, + }), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) + require.Contains(t, result.MultipleUploadWithPayload[0].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUploadWithPayload[0].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[0].ContentType) + require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) + require.Contains(t, result.MultipleUploadWithPayload[1].Name, "b.txt") + require.Equal(t, "test2", result.MultipleUploadWithPayload[1].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[1].ContentType) }) t.Run("valid file list upload with payload and file reuse", func(t *testing.T) { @@ -252,32 +241,39 @@ func TestFileUpload(t *testing.T) { return resp, nil } - operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` - mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - } - test := func(uploadMaxMemory int64) { hndlr := handler.New(NewExecutableSchema(Config{Resolvers: resolver})) hndlr.AddTransport(transport.MultipartForm{MaxMemory: uploadMaxMemory}) srv := httptest.NewServer(hndlr) defer srv.Close() - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"a.txt","content":"test1","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) + + mutation := `mutation($req: [UploadFile!]!) { + multipleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + MultipleUploadWithPayload []*model.File + } + + err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ + {"id": 1, "file": a1TxtFile}, + {"id": 2, "file": a1TxtFile}, + }), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) + require.Contains(t, result.MultipleUploadWithPayload[0].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUploadWithPayload[0].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[0].ContentType) + require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) + require.Contains(t, result.MultipleUploadWithPayload[1].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUploadWithPayload[1].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[1].ContentType) } t.Run("payload smaller than UploadMaxMemory, stored in memory", func(t *testing.T) { @@ -289,39 +285,3 @@ func TestFileUpload(t *testing.T) { }) }) } - -type file struct { - mapKey string - name string - content string - contentType string -} - -func createUploadRequest(t *testing.T, url, operations, mapData string, files []file) *http.Request { - bodyBuf := &bytes.Buffer{} - bodyWriter := multipart.NewWriter(bodyBuf) - - err := bodyWriter.WriteField("operations", operations) - require.NoError(t, err) - - err = bodyWriter.WriteField("map", mapData) - require.NoError(t, err) - - for i := range files { - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, files[i].mapKey, files[i].name)) - h.Set("Content-Type", files[i].contentType) - ff, err := bodyWriter.CreatePart(h) - require.NoError(t, err) - _, err = ff.Write([]byte(files[i].content)) - require.NoError(t, err) - } - err = bodyWriter.Close() - require.NoError(t, err) - - req, err := http.NewRequest("POST", fmt.Sprintf("%s/graphql", url), bodyBuf) - require.NoError(t, err) - - req.Header.Set("Content-Type", bodyWriter.FormDataContentType()) - return req -} From 8359f9749e6fd54be20325ff6aafb05503124238 Mon Sep 17 00:00:00 2001 From: foreverest Date: Wed, 13 Oct 2021 08:41:24 -0700 Subject: [PATCH 135/146] Allow custom websocket upgrader (#1595) --- docs/content/recipes/cors.md | 2 +- example/chat/server/server.go | 2 +- graphql/handler/transport/websocket.go | 10 ++++++++-- handler/handler.go | 5 ++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/content/recipes/cors.md b/docs/content/recipes/cors.md index 0b0ac114bfa..129768410d3 100644 --- a/docs/content/recipes/cors.md +++ b/docs/content/recipes/cors.md @@ -40,7 +40,7 @@ func main() { srv := handler.NewDefaultServer(starwars.NewExecutableSchema(starwars.NewResolver())) srv.AddTransport(&transport.Websocket{ - Upgrader: websocket.Upgrader{ + Upgrader: &websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { // Check against your desired domains here return r.Host == "example.org" diff --git a/example/chat/server/server.go b/example/chat/server/server.go index 1592f6b0ab5..e07595319ca 100644 --- a/example/chat/server/server.go +++ b/example/chat/server/server.go @@ -34,7 +34,7 @@ func main() { srv.AddTransport(transport.POST{}) srv.AddTransport(transport.Websocket{ KeepAlivePingInterval: 10 * time.Second, - Upgrader: websocket.Upgrader{ + Upgrader: &websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, diff --git a/graphql/handler/transport/websocket.go b/graphql/handler/transport/websocket.go index 787a879f50d..94ac293c827 100644 --- a/graphql/handler/transport/websocket.go +++ b/graphql/handler/transport/websocket.go @@ -32,7 +32,7 @@ const ( type ( Websocket struct { - Upgrader websocket.Upgrader + Upgrader WebsocketUpgrader InitFunc WebsocketInitFunc KeepAlivePingInterval time.Duration } @@ -52,10 +52,16 @@ type ( ID string `json:"id,omitempty"` Type string `json:"type"` } + WebsocketUpgrader interface { + Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*websocket.Conn, error) + } WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error) ) -var _ graphql.Transport = Websocket{} +var ( + _ graphql.Transport = Websocket{} + _ WebsocketUpgrader = &websocket.Upgrader{} +) func (t Websocket) Supports(r *http.Request) bool { return r.Header.Get("Upgrade") != "" diff --git a/handler/handler.go b/handler/handler.go index 892df53986a..8eb2680a655 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -11,7 +11,6 @@ import ( "github.com/99designs/gqlgen/graphql/handler/lru" "github.com/99designs/gqlgen/graphql/handler/transport" "github.com/99designs/gqlgen/graphql/playground" - "github.com/gorilla/websocket" ) // Deprecated: switch to graphql/handler.New @@ -74,7 +73,7 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc // Deprecated: switch to graphql/handler.New type Config struct { cacheSize int - upgrader websocket.Upgrader + upgrader transport.WebsocketUpgrader websocketInitFunc transport.WebsocketInitFunc connectionKeepAlivePingInterval time.Duration recover graphql.RecoverFunc @@ -93,7 +92,7 @@ type Config struct { type Option func(cfg *Config) // Deprecated: switch to graphql/handler.New -func WebsocketUpgrader(upgrader websocket.Upgrader) Option { +func WebsocketUpgrader(upgrader transport.WebsocketUpgrader) Option { return func(cfg *Config) { cfg.upgrader = upgrader } From 41c867658a9eacf94b3c682121b03727e18940d5 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Wed, 13 Oct 2021 19:57:02 -0400 Subject: [PATCH 136/146] Revert 1595 (#1658) Signed-off-by: Steve Coffman --- docs/content/recipes/cors.md | 2 +- example/chat/server/server.go | 2 +- graphql/handler/transport/websocket.go | 10 ++-------- handler/handler.go | 5 +++-- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/content/recipes/cors.md b/docs/content/recipes/cors.md index 129768410d3..0b0ac114bfa 100644 --- a/docs/content/recipes/cors.md +++ b/docs/content/recipes/cors.md @@ -40,7 +40,7 @@ func main() { srv := handler.NewDefaultServer(starwars.NewExecutableSchema(starwars.NewResolver())) srv.AddTransport(&transport.Websocket{ - Upgrader: &websocket.Upgrader{ + Upgrader: websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { // Check against your desired domains here return r.Host == "example.org" diff --git a/example/chat/server/server.go b/example/chat/server/server.go index e07595319ca..1592f6b0ab5 100644 --- a/example/chat/server/server.go +++ b/example/chat/server/server.go @@ -34,7 +34,7 @@ func main() { srv.AddTransport(transport.POST{}) srv.AddTransport(transport.Websocket{ KeepAlivePingInterval: 10 * time.Second, - Upgrader: &websocket.Upgrader{ + Upgrader: websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, diff --git a/graphql/handler/transport/websocket.go b/graphql/handler/transport/websocket.go index 94ac293c827..787a879f50d 100644 --- a/graphql/handler/transport/websocket.go +++ b/graphql/handler/transport/websocket.go @@ -32,7 +32,7 @@ const ( type ( Websocket struct { - Upgrader WebsocketUpgrader + Upgrader websocket.Upgrader InitFunc WebsocketInitFunc KeepAlivePingInterval time.Duration } @@ -52,16 +52,10 @@ type ( ID string `json:"id,omitempty"` Type string `json:"type"` } - WebsocketUpgrader interface { - Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*websocket.Conn, error) - } WebsocketInitFunc func(ctx context.Context, initPayload InitPayload) (context.Context, error) ) -var ( - _ graphql.Transport = Websocket{} - _ WebsocketUpgrader = &websocket.Upgrader{} -) +var _ graphql.Transport = Websocket{} func (t Websocket) Supports(r *http.Request) bool { return r.Header.Get("Upgrade") != "" diff --git a/handler/handler.go b/handler/handler.go index 8eb2680a655..892df53986a 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -11,6 +11,7 @@ import ( "github.com/99designs/gqlgen/graphql/handler/lru" "github.com/99designs/gqlgen/graphql/handler/transport" "github.com/99designs/gqlgen/graphql/playground" + "github.com/gorilla/websocket" ) // Deprecated: switch to graphql/handler.New @@ -73,7 +74,7 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc // Deprecated: switch to graphql/handler.New type Config struct { cacheSize int - upgrader transport.WebsocketUpgrader + upgrader websocket.Upgrader websocketInitFunc transport.WebsocketInitFunc connectionKeepAlivePingInterval time.Duration recover graphql.RecoverFunc @@ -92,7 +93,7 @@ type Config struct { type Option func(cfg *Config) // Deprecated: switch to graphql/handler.New -func WebsocketUpgrader(upgrader transport.WebsocketUpgrader) Option { +func WebsocketUpgrader(upgrader websocket.Upgrader) Option { return func(cfg *Config) { cfg.upgrader = upgrader } From 658195b79d8c9072a90419ce3ddccda4e430ebf0 Mon Sep 17 00:00:00 2001 From: Steve Coffman Date: Wed, 13 Oct 2021 20:11:27 -0400 Subject: [PATCH 137/146] Revert "Update GQLgen test client to work with multipart form data (#1418)" (#1659) This reverts commit 1318f12792e86c76a2cdff9132ebac5b3e30e148. --- client/client.go | 10 +- client/client_test.go | 41 ---- client/withfilesoption.go | 133 ------------- client/withfilesoption_test.go | 225 --------------------- example/fileupload/fileupload_test.go | 268 +++++++++++++++----------- 5 files changed, 157 insertions(+), 520 deletions(-) delete mode 100644 client/withfilesoption.go delete mode 100644 client/withfilesoption_test.go diff --git a/client/client.go b/client/client.go index e29c5fe5b3d..7a2825c952b 100644 --- a/client/client.go +++ b/client/client.go @@ -9,7 +9,6 @@ import ( "io/ioutil" "net/http" "net/http/httptest" - "regexp" "github.com/mitchellh/mapstructure" ) @@ -121,18 +120,15 @@ func (p *Client) newRequest(query string, options ...Option) (*http.Request, err option(bd) } - contentType := bd.HTTP.Header.Get("Content-Type") - switch { - case regexp.MustCompile(`multipart/form-data; ?boundary=.*`).MatchString(contentType): - break - case "application/json" == contentType: + switch bd.HTTP.Header.Get("Content-Type") { + case "application/json": requestBody, err := json.Marshal(bd) if err != nil { return nil, fmt.Errorf("encode: %w", err) } bd.HTTP.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody)) default: - panic("unsupported encoding " + bd.HTTP.Header.Get("Content-Type")) + panic("unsupported encoding" + bd.HTTP.Header.Get("Content-Type")) } return bd.HTTP, nil diff --git a/client/client_test.go b/client/client_test.go index 176c48d12ae..569151cd8a2 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,12 +1,9 @@ package client_test import ( - "bytes" "encoding/json" "io/ioutil" - "mime/multipart" "net/http" - "net/textproto" "testing" "github.com/99designs/gqlgen/client" @@ -42,44 +39,6 @@ func TestClient(t *testing.T) { require.Equal(t, "bob", resp.Name) } -func TestClientMultipartFormData(t *testing.T) { - h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - bodyBytes, err := ioutil.ReadAll(r.Body) - require.NoError(t, err) - require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="operations"`) - require.Contains(t, string(bodyBytes), `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) - require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="map"`) - require.Contains(t, string(bodyBytes), `{"0":["variables.file"]}`) - require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="0"; filename="example.txt"`) - require.Contains(t, string(bodyBytes), `Content-Type: text/plain`) - require.Contains(t, string(bodyBytes), `Hello World`) - - w.Write([]byte(`{}`)) - }) - - c := client.New(h) - - var resp struct{} - c.MustPost("{ id }", &resp, - func(bd *client.Request) { - bodyBuf := &bytes.Buffer{} - bodyWriter := multipart.NewWriter(bodyBuf) - bodyWriter.WriteField("operations", `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) - bodyWriter.WriteField("map", `{"0":["variables.file"]}`) - - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", `form-data; name="0"; filename="example.txt"`) - h.Set("Content-Type", "text/plain") - ff, _ := bodyWriter.CreatePart(h) - ff.Write([]byte("Hello World")) - bodyWriter.Close() - - bd.HTTP.Body = ioutil.NopCloser(bodyBuf) - bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) - }, - ) -} - func TestAddHeader(t *testing.T) { h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "ASDF", r.Header.Get("Test-Key")) diff --git a/client/withfilesoption.go b/client/withfilesoption.go deleted file mode 100644 index eff0d1c25f3..00000000000 --- a/client/withfilesoption.go +++ /dev/null @@ -1,133 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "mime/multipart" - "net/http" - "net/textproto" - "os" - "strings" -) - -type fileFormDataMap struct { - mapKey string - file *os.File -} - -func findFiles(parentMapKey string, variables map[string]interface{}) []*fileFormDataMap { - files := []*fileFormDataMap{} - for key, value := range variables { - if v, ok := value.(map[string]interface{}); ok { - files = append(files, findFiles(parentMapKey+"."+key, v)...) - } else if v, ok := value.([]map[string]interface{}); ok { - for i, arr := range v { - files = append(files, findFiles(fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), arr)...) - } - } else if v, ok := value.([]*os.File); ok { - for i, file := range v { - files = append(files, &fileFormDataMap{ - mapKey: fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), - file: file, - }) - } - } else if v, ok := value.(*os.File); ok { - files = append(files, &fileFormDataMap{ - mapKey: parentMapKey + "." + key, - file: v, - }) - } - } - - return files -} - -// WithFiles encodes the outgoing request body as multipart form data for file variables -func WithFiles() Option { - return func(bd *Request) { - bodyBuf := &bytes.Buffer{} - bodyWriter := multipart.NewWriter(bodyBuf) - - //-b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d - // Content-Disposition: form-data; name="operations" - // - // {"query":"mutation ($input: Input!) {}","variables":{"input":{"file":{}}} - requestBody, _ := json.Marshal(bd) - bodyWriter.WriteField("operations", string(requestBody)) - - // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d - // Content-Disposition: form-data; name="map" - // - // `{ "0":["variables.input.file"] }` - // or - // `{ "0":["variables.input.files.0"], "1":["variables.input.files.1"] }` - // or - // `{ "0": ["variables.input.0.file"], "1": ["variables.input.1.file"] }` - // or - // `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` - mapData := "" - filesData := findFiles("variables", bd.Variables) - filesGroup := [][]*fileFormDataMap{} - for _, fd := range filesData { - foundDuplicate := false - for j, fg := range filesGroup { - f1, _ := fd.file.Stat() - f2, _ := fg[0].file.Stat() - if os.SameFile(f1, f2) { - foundDuplicate = true - filesGroup[j] = append(filesGroup[j], fd) - } - } - - if !foundDuplicate { - filesGroup = append(filesGroup, []*fileFormDataMap{fd}) - } - } - if len(filesGroup) > 0 { - mapDataFiles := []string{} - - for i, fileData := range filesGroup { - mapDataFiles = append( - mapDataFiles, - fmt.Sprintf(`"%d":[%s]`, i, strings.Join(collect(fileData, wrapMapKeyInQuotes), ",")), - ) - } - - mapData = `{` + strings.Join(mapDataFiles, ",") + `}` - } - bodyWriter.WriteField("map", mapData) - - // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d - // Content-Disposition: form-data; name="0"; filename="tempFile" - // Content-Type: text/plain; charset=utf-8 - // or - // Content-Type: application/octet-stream - // - for i, fileData := range filesGroup { - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%d"; filename="%s"`, i, fileData[0].file.Name())) - b, _ := ioutil.ReadFile(fileData[0].file.Name()) - h.Set("Content-Type", http.DetectContentType(b)) - ff, _ := bodyWriter.CreatePart(h) - ff.Write(b) - } - bodyWriter.Close() - - bd.HTTP.Body = ioutil.NopCloser(bodyBuf) - bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) - } -} - -func collect(strArr []*fileFormDataMap, f func(s *fileFormDataMap) string) []string { - result := make([]string, len(strArr)) - for i, str := range strArr { - result[i] = f(str) - } - return result -} - -func wrapMapKeyInQuotes(s *fileFormDataMap) string { - return fmt.Sprintf("\"%s\"", s.mapKey) -} diff --git a/client/withfilesoption_test.go b/client/withfilesoption_test.go deleted file mode 100644 index f3528936ff4..00000000000 --- a/client/withfilesoption_test.go +++ /dev/null @@ -1,225 +0,0 @@ -package client_test - -import ( - "fmt" - "io" - "io/ioutil" - "mime" - "mime/multipart" - "net/http" - "os" - "regexp" - "strings" - "testing" - - "github.com/99designs/gqlgen/client" - "github.com/stretchr/testify/require" -) - -func TestWithFiles(t *testing.T) { - tempFile1, _ := ioutil.TempFile(os.TempDir(), "tempFile1") - tempFile2, _ := ioutil.TempFile(os.TempDir(), "tempFile2") - tempFile3, _ := ioutil.TempFile(os.TempDir(), "tempFile3") - defer os.Remove(tempFile1.Name()) - defer os.Remove(tempFile2.Name()) - defer os.Remove(tempFile3.Name()) - tempFile1.WriteString(`The quick brown fox jumps over the lazy dog`) - tempFile2.WriteString(`hello world`) - tempFile3.WriteString(`La-Li-Lu-Le-Lo`) - - t.Run("with one file", func(t *testing.T) { - h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - require.NoError(t, err) - require.True(t, strings.HasPrefix(mediaType, "multipart/")) - - mr := multipart.NewReader(r.Body, params["boundary"]) - for { - p, err := mr.NextPart() - if err == io.EOF { - break - } - require.NoError(t, err) - - slurp, err := ioutil.ReadAll(p) - require.NoError(t, err) - - contentDisposition := p.Header.Get("Content-Disposition") - fmt.Printf("Part %q: %q\n", contentDisposition, slurp) - - if contentDisposition == `form-data; name="operations"` { - require.Equal(t, `{"query":"{ id }","variables":{"file":{}}}`, string(slurp)) - } - if contentDisposition == `form-data; name="map"` { - require.Equal(t, `{"0":["variables.file"]}`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) - } - } - w.Write([]byte(`{}`)) - }) - - c := client.New(h) - - var resp struct{} - c.MustPost("{ id }", &resp, - client.Var("file", tempFile1), - client.WithFiles(), - ) - }) - - t.Run("with multiple files", func(t *testing.T) { - h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - require.NoError(t, err) - require.True(t, strings.HasPrefix(mediaType, "multipart/")) - - mr := multipart.NewReader(r.Body, params["boundary"]) - for { - p, err := mr.NextPart() - if err == io.EOF { - break - } - require.NoError(t, err) - - slurp, err := ioutil.ReadAll(p) - require.NoError(t, err) - - contentDisposition := p.Header.Get("Content-Disposition") - fmt.Printf("Part %q: %q\n", contentDisposition, slurp) - - if contentDisposition == `form-data; name="operations"` { - require.Equal(t, `{"query":"{ id }","variables":{"input":{"files":[{},{}]}}}`, string(slurp)) - } - if contentDisposition == `form-data; name="map"` { - require.Equal(t, `{"0":["variables.input.files.0"],"1":["variables.input.files.1"]}`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `hello world`, string(slurp)) - } - } - w.Write([]byte(`{}`)) - }) - - c := client.New(h) - - var resp struct{} - c.MustPost("{ id }", &resp, - client.Var("input", map[string]interface{}{ - "files": []*os.File{tempFile1, tempFile2}, - }), - client.WithFiles(), - ) - }) - - t.Run("with multiple files across multiple variables", func(t *testing.T) { - h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - require.NoError(t, err) - require.True(t, strings.HasPrefix(mediaType, "multipart/")) - - mr := multipart.NewReader(r.Body, params["boundary"]) - for { - p, err := mr.NextPart() - if err == io.EOF { - break - } - require.NoError(t, err) - - slurp, err := ioutil.ReadAll(p) - require.NoError(t, err) - - contentDisposition := p.Header.Get("Content-Disposition") - fmt.Printf("Part %q: %q\n", contentDisposition, slurp) - - if contentDisposition == `form-data; name="operations"` { - require.Equal(t, `{"query":"{ id }","variables":{"req":{"files":[{},{}],"foo":{"bar":{}}}}}`, string(slurp)) - } - if contentDisposition == `form-data; name="map"` { - require.Equal(t, `{"0":["variables.req.files.0"],"1":["variables.req.files.1"],"2":["variables.req.foo.bar"]}`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `hello world`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="2"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `La-Li-Lu-Le-Lo`, string(slurp)) - } - } - w.Write([]byte(`{}`)) - }) - - c := client.New(h) - - var resp struct{} - c.MustPost("{ id }", &resp, - client.Var("req", map[string]interface{}{ - "files": []*os.File{tempFile1, tempFile2}, - "foo": map[string]interface{}{ - "bar": tempFile3, - }, - }), - client.WithFiles(), - ) - }) - - t.Run("with multiple files and file reuse", func(t *testing.T) { - h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) - require.NoError(t, err) - require.True(t, strings.HasPrefix(mediaType, "multipart/")) - - mr := multipart.NewReader(r.Body, params["boundary"]) - for { - p, err := mr.NextPart() - if err == io.EOF { - break - } - require.NoError(t, err) - - slurp, err := ioutil.ReadAll(p) - require.NoError(t, err) - - contentDisposition := p.Header.Get("Content-Disposition") - fmt.Printf("Part %q: %q\n", contentDisposition, slurp) - - if contentDisposition == `form-data; name="operations"` { - require.Equal(t, `{"query":"{ id }","variables":{"files":[{},{},{}]}}`, string(slurp)) - } - if contentDisposition == `form-data; name="map"` { - require.Equal(t, `{"0":["variables.files.0","variables.files.2"],"1":["variables.files.1"]}`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `The quick brown fox jumps over the lazy dog`, string(slurp)) - } - if regexp.MustCompile(`form-data; name="1"; filename=.*`).MatchString(contentDisposition) { - require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) - require.Equal(t, `hello world`, string(slurp)) - } - require.False(t, regexp.MustCompile(`form-data; name="2"; filename=.*`).MatchString(contentDisposition)) - } - w.Write([]byte(`{}`)) - }) - - c := client.New(h) - - var resp struct{} - c.MustPost("{ id }", &resp, - client.Var("files", []*os.File{tempFile1, tempFile2, tempFile1}), - client.WithFiles(), - ) - }) -} diff --git a/example/fileupload/fileupload_test.go b/example/fileupload/fileupload_test.go index 158825edfbf..8d68252e009 100644 --- a/example/fileupload/fileupload_test.go +++ b/example/fileupload/fileupload_test.go @@ -2,14 +2,17 @@ package fileupload import ( + "bytes" "context" + "fmt" "io" "io/ioutil" + "mime/multipart" + "net/http" "net/http/httptest" - "os" + "net/textproto" "testing" - gqlclient "github.com/99designs/gqlgen/client" "github.com/99designs/gqlgen/example/fileupload/model" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" @@ -18,23 +21,10 @@ import ( ) func TestFileUpload(t *testing.T) { - resolver := &Stub{} - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) - - aTxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") - defer os.Remove(aTxtFile.Name()) - aTxtFile.WriteString(`test`) - - a1TxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") - b1TxtFile, _ := ioutil.TempFile(os.TempDir(), "b.txt") - defer os.Remove(a1TxtFile.Name()) - defer os.Remove(b1TxtFile.Name()) - a1TxtFile.WriteString(`test1`) - b1TxtFile.WriteString(`test2`) + client := http.Client{} t.Run("valid single file upload", func(t *testing.T) { + resolver := &Stub{} resolver.MutationResolver.SingleUpload = func(ctx context.Context, file graphql.Upload) (*model.File, error) { require.NotNil(t, file) require.NotNil(t, file.File) @@ -49,28 +39,34 @@ func TestFileUpload(t *testing.T) { ContentType: file.ContentType, }, nil } + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() - mutation := `mutation ($file: Upload!) { - singleUpload(file: $file) { - id - name - content - contentType - } - }` - var result struct { - SingleUpload *model.File + operations := `{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id, name, content, contentType } }", "variables": { "file": null } }` + mapData := `{ "0": ["variables.file"] }` + files := []file{ + { + mapKey: "0", + name: "a.txt", + content: "test", + contentType: "text/plain", + }, } + req := createUploadRequest(t, srv.URL, operations, mapData, files) - err := gql.Post(mutation, &result, gqlclient.Var("file", aTxtFile), gqlclient.WithFiles()) + resp, err := client.Do(req) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + responseBody, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + responseString := string(responseBody) + require.Equal(t, `{"data":{"singleUpload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, responseString) + err = resp.Body.Close() require.Nil(t, err) - require.Equal(t, 1, result.SingleUpload.ID) - require.Contains(t, result.SingleUpload.Name, "a.txt") - require.Equal(t, "test", result.SingleUpload.Content) - require.Equal(t, "text/plain; charset=utf-8", result.SingleUpload.ContentType) }) t.Run("valid single file upload with payload", func(t *testing.T) { + resolver := &Stub{} resolver.MutationResolver.SingleUploadWithPayload = func(ctx context.Context, req model.UploadFile) (*model.File, error) { require.Equal(t, req.ID, 1) require.NotNil(t, req.File) @@ -86,28 +82,33 @@ func TestFileUpload(t *testing.T) { ContentType: req.File.ContentType, }, nil } + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() - mutation := `mutation ($req: UploadFile!) { - singleUploadWithPayload(req: $req) { - id - name - content - contentType - } - }` - var result struct { - SingleUploadWithPayload *model.File + operations := `{ "query": "mutation ($req: UploadFile!) { singleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": {"file": null, "id": 1 } } }` + mapData := `{ "0": ["variables.req.file"] }` + files := []file{ + { + mapKey: "0", + name: "a.txt", + content: "test", + contentType: "text/plain", + }, } + req := createUploadRequest(t, srv.URL, operations, mapData, files) - err := gql.Post(mutation, &result, gqlclient.Var("req", map[string]interface{}{"id": 1, "file": aTxtFile}), gqlclient.WithFiles()) + resp, err := client.Do(req) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + responseBody, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, `{"data":{"singleUploadWithPayload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, string(responseBody)) + err = resp.Body.Close() require.Nil(t, err) - require.Equal(t, 1, result.SingleUploadWithPayload.ID) - require.Contains(t, result.SingleUploadWithPayload.Name, "a.txt") - require.Equal(t, "test", result.SingleUploadWithPayload.Content) - require.Equal(t, "text/plain; charset=utf-8", result.SingleUploadWithPayload.ContentType) }) t.Run("valid file list upload", func(t *testing.T) { + resolver := &Stub{} resolver.MutationResolver.MultipleUpload = func(ctx context.Context, files []*graphql.Upload) ([]*model.File, error) { require.Len(t, files, 2) var contents []string @@ -127,32 +128,39 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() - mutation := `mutation($files: [Upload!]!) { - multipleUpload(files: $files) { - id - name - content - contentType - } - }` - var result struct { - MultipleUpload []*model.File + operations := `{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id, name, content, contentType } }", "variables": { "files": [null, null] } }` + mapData := `{ "0": ["variables.files.0"], "1": ["variables.files.1"] }` + files := []file{ + { + mapKey: "0", + name: "a.txt", + content: "test1", + contentType: "text/plain", + }, + { + mapKey: "1", + name: "b.txt", + content: "test2", + contentType: "text/plain", + }, } + req := createUploadRequest(t, srv.URL, operations, mapData, files) - err := gql.Post(mutation, &result, gqlclient.Var("files", []*os.File{a1TxtFile, b1TxtFile}), gqlclient.WithFiles()) + resp, err := client.Do(req) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + responseBody, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, `{"data":{"multipleUpload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) + err = resp.Body.Close() require.Nil(t, err) - require.Equal(t, 1, result.MultipleUpload[0].ID) - require.Contains(t, result.MultipleUpload[0].Name, "a.txt") - require.Equal(t, "test1", result.MultipleUpload[0].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUpload[0].ContentType) - require.Equal(t, 2, result.MultipleUpload[1].ID) - require.Contains(t, result.MultipleUpload[1].Name, "b.txt") - require.Equal(t, "test2", result.MultipleUpload[1].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUpload[1].ContentType) }) t.Run("valid file list upload with payload", func(t *testing.T) { + resolver := &Stub{} resolver.MutationResolver.MultipleUploadWithPayload = func(ctx context.Context, req []*model.UploadFile) ([]*model.File, error) { require.Len(t, req, 2) var ids []int @@ -176,32 +184,35 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() - mutation := `mutation($req: [UploadFile!]!) { - multipleUploadWithPayload(req: $req) { - id - name - content - contentType - } - }` - var result struct { - MultipleUploadWithPayload []*model.File + operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` + mapData := `{ "0": ["variables.req.0.file"], "1": ["variables.req.1.file"] }` + files := []file{ + { + mapKey: "0", + name: "a.txt", + content: "test1", + contentType: "text/plain", + }, + { + mapKey: "1", + name: "b.txt", + content: "test2", + contentType: "text/plain", + }, } + req := createUploadRequest(t, srv.URL, operations, mapData, files) - err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ - {"id": 1, "file": a1TxtFile}, - {"id": 2, "file": b1TxtFile}, - }), gqlclient.WithFiles()) + resp, err := client.Do(req) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + responseBody, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) + err = resp.Body.Close() require.Nil(t, err) - require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) - require.Contains(t, result.MultipleUploadWithPayload[0].Name, "a.txt") - require.Equal(t, "test1", result.MultipleUploadWithPayload[0].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[0].ContentType) - require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) - require.Contains(t, result.MultipleUploadWithPayload[1].Name, "b.txt") - require.Equal(t, "test2", result.MultipleUploadWithPayload[1].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[1].ContentType) }) t.Run("valid file list upload with payload and file reuse", func(t *testing.T) { @@ -241,39 +252,32 @@ func TestFileUpload(t *testing.T) { return resp, nil } + operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` + mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` + files := []file{ + { + mapKey: "0", + name: "a.txt", + content: "test1", + contentType: "text/plain", + }, + } + test := func(uploadMaxMemory int64) { hndlr := handler.New(NewExecutableSchema(Config{Resolvers: resolver})) hndlr.AddTransport(transport.MultipartForm{MaxMemory: uploadMaxMemory}) srv := httptest.NewServer(hndlr) defer srv.Close() - gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) - - mutation := `mutation($req: [UploadFile!]!) { - multipleUploadWithPayload(req: $req) { - id - name - content - contentType - } - }` - var result struct { - MultipleUploadWithPayload []*model.File - } - - err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ - {"id": 1, "file": a1TxtFile}, - {"id": 2, "file": a1TxtFile}, - }), gqlclient.WithFiles()) + req := createUploadRequest(t, srv.URL, operations, mapData, files) + resp, err := client.Do(req) + require.Nil(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + responseBody, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"a.txt","content":"test1","contentType":"text/plain"}]}}`, string(responseBody)) + err = resp.Body.Close() require.Nil(t, err) - require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) - require.Contains(t, result.MultipleUploadWithPayload[0].Name, "a.txt") - require.Equal(t, "test1", result.MultipleUploadWithPayload[0].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[0].ContentType) - require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) - require.Contains(t, result.MultipleUploadWithPayload[1].Name, "a.txt") - require.Equal(t, "test1", result.MultipleUploadWithPayload[1].Content) - require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[1].ContentType) } t.Run("payload smaller than UploadMaxMemory, stored in memory", func(t *testing.T) { @@ -285,3 +289,39 @@ func TestFileUpload(t *testing.T) { }) }) } + +type file struct { + mapKey string + name string + content string + contentType string +} + +func createUploadRequest(t *testing.T, url, operations, mapData string, files []file) *http.Request { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + + err := bodyWriter.WriteField("operations", operations) + require.NoError(t, err) + + err = bodyWriter.WriteField("map", mapData) + require.NoError(t, err) + + for i := range files { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, files[i].mapKey, files[i].name)) + h.Set("Content-Type", files[i].contentType) + ff, err := bodyWriter.CreatePart(h) + require.NoError(t, err) + _, err = ff.Write([]byte(files[i].content)) + require.NoError(t, err) + } + err = bodyWriter.Close() + require.NoError(t, err) + + req, err := http.NewRequest("POST", fmt.Sprintf("%s/graphql", url), bodyBuf) + require.NoError(t, err) + + req.Header.Set("Content-Type", bodyWriter.FormDataContentType()) + return req +} From 8b25c9e005c44ae3730eca83445fa7f7223481d1 Mon Sep 17 00:00:00 2001 From: Hooman Yar Date: Wed, 13 Oct 2021 17:37:53 -0700 Subject: [PATCH 138/146] Add a config option to skip running "go mod tidy" on code generation (#1644) Co-authored-by: Hooman Yar --- api/generate.go | 7 +++++-- codegen/config/config.go | 1 + docs/content/config.md | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/api/generate.go b/api/generate.go index 8d4b88de69d..6a85cd941ac 100644 --- a/api/generate.go +++ b/api/generate.go @@ -77,8 +77,11 @@ func Generate(cfg *config.Config, option ...Option) error { if err = codegen.GenerateCode(data); err != nil { return fmt.Errorf("generating core failed: %w", err) } - if err = cfg.Packages.ModTidy(); err != nil { - return fmt.Errorf("tidy failed: %w", err) + + if !cfg.SkipModTidy { + if err = cfg.Packages.ModTidy(); err != nil { + return fmt.Errorf("tidy failed: %w", err) + } } for _, p := range plugins { diff --git a/codegen/config/config.go b/codegen/config/config.go index 404befada20..56bfc6090d6 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -27,6 +27,7 @@ type Config struct { Directives map[string]DirectiveConfig `yaml:"directives,omitempty"` OmitSliceElementPointers bool `yaml:"omit_slice_element_pointers,omitempty"` SkipValidation bool `yaml:"skip_validation,omitempty"` + SkipModTidy bool `yaml:"skip_mod_tidy,omitempty"` Sources []*ast.Source `yaml:"-"` Packages *code.Packages `yaml:"-"` Schema *ast.Schema `yaml:"-"` diff --git a/docs/content/config.md b/docs/content/config.md index 21cfa328ffb..6ed8c900fba 100644 --- a/docs/content/config.md +++ b/docs/content/config.md @@ -46,6 +46,9 @@ resolver: # Optional: set to speed up generation time by not performing a final validation pass. # skip_validation: true +# Optional: set to skip running `go mod tidy` when generating server code +# skip_mod_tidy: true + # gqlgen will search for any type names in the schema in these go packages # if they match it will use them, otherwise it will generate them. autobind: From 7435403cf94ce8147fdd9d473a5469d63e7e5b38 Mon Sep 17 00:00:00 2001 From: Corey Winkelmann <350215+CoreyWinkelmann@users.noreply.github.com> Date: Thu, 14 Oct 2021 07:22:10 -0600 Subject: [PATCH 139/146] Adds RootFieldInterceptor to extension interfaces (#1647) * Adds RootFieldInterceptor to extension interfaces * #1647 Regenerates the integration folder * Regenerates example folder * #1647 Adds Root Field Context separate from Field Context * Re-generate after changes Signed-off-by: Steve Coffman Co-authored-by: Steve Coffman --- codegen/object.gotpl | 122 +- codegen/testserver/generated.go | 1760 ++++++++++++++--- example/chat/generated.go | 325 ++- example/config/generated.go | 349 +++- example/dataloader/generated.go | 381 +++- .../accounts/graph/generated/generated.go | 330 +++- .../products/graph/generated/generated.go | 337 +++- .../reviews/graph/generated/generated.go | 369 +++- example/fileupload/generated.go | 331 +++- example/scalars/generated.go | 385 +++- example/selection/generated.go | 326 ++- example/starwars/generated/exec.go | 572 +++++- example/todo/generated.go | 332 +++- example/type-system-extension/generated.go | 321 ++- graphql/context_operation.go | 12 +- graphql/context_root_field.go | 25 + graphql/context_root_field_test.go | 15 + graphql/executor/executor.go | 7 +- graphql/executor/executor_test.go | 16 + graphql/executor/extensions.go | 36 + graphql/executor/testexecutor/testexecutor.go | 46 +- graphql/handler.go | 7 + graphql/handler/server.go | 5 + integration/generated.go | 372 +++- 24 files changed, 5705 insertions(+), 1076 deletions(-) create mode 100644 graphql/context_root_field.go create mode 100644 graphql/context_root_field_test.go diff --git a/codegen/object.gotpl b/codegen/object.gotpl index 33775a0b4c3..8cb9d28ced7 100644 --- a/codegen/object.gotpl +++ b/codegen/object.gotpl @@ -25,56 +25,84 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec {{- else }} func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors) - {{if $object.Root}} - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ - Object: {{$object.Name|quote}}, - }) - {{end}} - + {{- if $object.Root }} + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: {{$object.Name|quote}}, + }) + {{end}} out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString({{$object.Name|quote}}) - {{- range $field := $object.Fields }} - case "{{$field.Name}}": - {{- if $field.IsConcurrent }} - field := field - out.Concurrently(i, func() (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) - {{- if $field.TypeReference.GQL.NonNull }} - if res == graphql.Null { - {{- if $object.IsConcurrent }} - atomic.AddUint32(&invalids, 1) - {{- else }} - invalids++ - {{- end }} - } - {{- end }} - return res - }) - {{- else }} - out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) - {{- if $field.TypeReference.GQL.NonNull }} - if out.Values[i] == graphql.Null { - {{- if $object.IsConcurrent }} - atomic.AddUint32(&invalids, 1) - {{- else }} - invalids++ - {{- end }} - } - {{- end }} - {{- end }} - {{- end }} - default: - panic("unknown field " + strconv.Quote(field.Name)) - } + {{- if $object.Root }} + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + {{end}} + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString({{$object.Name|quote}}) + {{- range $field := $object.Fields }} + case "{{$field.Name}}": + {{- if $field.IsConcurrent }} + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) + {{- if $field.TypeReference.GQL.NonNull }} + if res == graphql.Null { + {{- if $object.IsConcurrent }} + atomic.AddUint32(&invalids, 1) + {{- else }} + invalids++ + {{- end }} + } + {{- end }} + return res + } + + {{if $object.Root}} + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + {{end}} + + out.Concurrently(i, func() graphql.Marshaler { + {{- if $object.Root -}} + return rrm(innerCtx) + {{- else -}} + return innerFunc(ctx) + {{end}} + }) + {{- else }} + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}}) + } + {{if $object.Root}} + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + {{else}} + out.Values[i] = innerFunc(ctx) + {{end}} + + {{- if $field.TypeReference.GQL.NonNull }} + if out.Values[i] == graphql.Null { + {{- if $object.IsConcurrent }} + atomic.AddUint32(&invalids, 1) + {{- else }} + invalids++ + {{- end }} + } + {{- end }} + {{- end }} + {{- end }} + default: + panic("unknown field " + strconv.Quote(field.Name)) + } } out.Dispatch() if invalids > 0 { return graphql.Null } diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index 2f04bf50feb..317dfdb5b1c 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -11612,7 +11612,6 @@ var aImplementors = []string{"A", "TestUnion"} func (ec *executionContext) _A(ctx context.Context, sel ast.SelectionSet, obj *A) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, aImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11620,7 +11619,12 @@ func (ec *executionContext) _A(ctx context.Context, sel ast.SelectionSet, obj *A case "__typename": out.Values[i] = graphql.MarshalString("A") case "id": - out.Values[i] = ec._A_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._A_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11639,7 +11643,6 @@ var aItImplementors = []string{"AIt"} func (ec *executionContext) _AIt(ctx context.Context, sel ast.SelectionSet, obj *AIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, aItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11647,7 +11650,12 @@ func (ec *executionContext) _AIt(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("AIt") case "id": - out.Values[i] = ec._AIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._AIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11666,7 +11674,6 @@ var abItImplementors = []string{"AbIt"} func (ec *executionContext) _AbIt(ctx context.Context, sel ast.SelectionSet, obj *AbIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, abItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11674,7 +11681,12 @@ func (ec *executionContext) _AbIt(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("AbIt") case "id": - out.Values[i] = ec._AbIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._AbIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11693,7 +11705,6 @@ var autobindImplementors = []string{"Autobind"} func (ec *executionContext) _Autobind(ctx context.Context, sel ast.SelectionSet, obj *Autobind) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, autobindImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11701,27 +11712,52 @@ func (ec *executionContext) _Autobind(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Autobind") case "int": - out.Values[i] = ec._Autobind_int(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "int32": - out.Values[i] = ec._Autobind_int32(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int32(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "int64": - out.Values[i] = ec._Autobind_int64(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int64(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "idStr": - out.Values[i] = ec._Autobind_idStr(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_idStr(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "idInt": - out.Values[i] = ec._Autobind_idInt(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_idInt(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11740,7 +11776,6 @@ var bImplementors = []string{"B", "TestUnion"} func (ec *executionContext) _B(ctx context.Context, sel ast.SelectionSet, obj *B) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, bImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11748,7 +11783,12 @@ func (ec *executionContext) _B(ctx context.Context, sel ast.SelectionSet, obj *B case "__typename": out.Values[i] = graphql.MarshalString("B") case "id": - out.Values[i] = ec._B_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._B_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11767,7 +11807,6 @@ var backedByInterfaceImplementors = []string{"BackedByInterface"} func (ec *executionContext) _BackedByInterface(ctx context.Context, sel ast.SelectionSet, obj BackedByInterface) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, backedByInterfaceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11776,7 +11815,8 @@ func (ec *executionContext) _BackedByInterface(ctx context.Context, sel ast.Sele out.Values[i] = graphql.MarshalString("BackedByInterface") case "id": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -11787,14 +11827,29 @@ func (ec *executionContext) _BackedByInterface(ctx context.Context, sel ast.Sele atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "thisShouldBind": - out.Values[i] = ec._BackedByInterface_thisShouldBind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._BackedByInterface_thisShouldBind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "thisShouldBindWithError": - out.Values[i] = ec._BackedByInterface_thisShouldBindWithError(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._BackedByInterface_thisShouldBindWithError(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -11813,7 +11868,6 @@ var catImplementors = []string{"Cat", "Animal"} func (ec *executionContext) _Cat(ctx context.Context, sel ast.SelectionSet, obj *Cat) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, catImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11821,12 +11875,22 @@ func (ec *executionContext) _Cat(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Cat") case "species": - out.Values[i] = ec._Cat_species(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Cat_species(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "catBreed": - out.Values[i] = ec._Cat_catBreed(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Cat_catBreed(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11845,7 +11909,6 @@ var checkIssue896Implementors = []string{"CheckIssue896"} func (ec *executionContext) _CheckIssue896(ctx context.Context, sel ast.SelectionSet, obj *CheckIssue896) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, checkIssue896Implementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11853,7 +11916,12 @@ func (ec *executionContext) _CheckIssue896(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("CheckIssue896") case "id": - out.Values[i] = ec._CheckIssue896_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._CheckIssue896_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -11869,7 +11937,6 @@ var circleImplementors = []string{"Circle", "Shape", "ShapeUnion"} func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, obj *Circle) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, circleImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11877,9 +11944,19 @@ func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Circle") case "radius": - out.Values[i] = ec._Circle_radius(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_radius(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "area": - out.Values[i] = ec._Circle_area(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_area(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -11895,7 +11972,6 @@ var concreteNodeAImplementors = []string{"ConcreteNodeA", "Node"} func (ec *executionContext) _ConcreteNodeA(ctx context.Context, sel ast.SelectionSet, obj *ConcreteNodeA) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, concreteNodeAImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11903,17 +11979,32 @@ func (ec *executionContext) _ConcreteNodeA(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("ConcreteNodeA") case "id": - out.Values[i] = ec._ConcreteNodeA_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "child": - out.Values[i] = ec._ConcreteNodeA_child(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_child(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec._ConcreteNodeA_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11932,7 +12023,6 @@ var concreteNodeInterfaceImplementors = []string{"ConcreteNodeInterface", "Node" func (ec *executionContext) _ConcreteNodeInterface(ctx context.Context, sel ast.SelectionSet, obj ConcreteNodeInterface) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, concreteNodeInterfaceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11940,12 +12030,22 @@ func (ec *executionContext) _ConcreteNodeInterface(ctx context.Context, sel ast. case "__typename": out.Values[i] = graphql.MarshalString("ConcreteNodeInterface") case "id": - out.Values[i] = ec._ConcreteNodeInterface_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeInterface_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "child": - out.Values[i] = ec._ConcreteNodeInterface_child(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeInterface_child(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -11964,7 +12064,6 @@ var content_PostImplementors = []string{"Content_Post", "Content_Child"} func (ec *executionContext) _Content_Post(ctx context.Context, sel ast.SelectionSet, obj *ContentPost) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, content_PostImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11972,7 +12071,12 @@ func (ec *executionContext) _Content_Post(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("Content_Post") case "foo": - out.Values[i] = ec._Content_Post_foo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Content_Post_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -11988,7 +12092,6 @@ var content_UserImplementors = []string{"Content_User", "Content_Child"} func (ec *executionContext) _Content_User(ctx context.Context, sel ast.SelectionSet, obj *ContentUser) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, content_UserImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -11996,7 +12099,12 @@ func (ec *executionContext) _Content_User(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("Content_User") case "foo": - out.Values[i] = ec._Content_User_foo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Content_User_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12012,7 +12120,6 @@ var defaultParametersMirrorImplementors = []string{"DefaultParametersMirror"} func (ec *executionContext) _DefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, obj *DefaultParametersMirror) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, defaultParametersMirrorImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12020,9 +12127,19 @@ func (ec *executionContext) _DefaultParametersMirror(ctx context.Context, sel as case "__typename": out.Values[i] = graphql.MarshalString("DefaultParametersMirror") case "falsyBoolean": - out.Values[i] = ec._DefaultParametersMirror_falsyBoolean(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DefaultParametersMirror_falsyBoolean(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "truthyBoolean": - out.Values[i] = ec._DefaultParametersMirror_truthyBoolean(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DefaultParametersMirror_truthyBoolean(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12038,7 +12155,6 @@ var dogImplementors = []string{"Dog", "Animal"} func (ec *executionContext) _Dog(ctx context.Context, sel ast.SelectionSet, obj *Dog) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, dogImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12046,12 +12162,22 @@ func (ec *executionContext) _Dog(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Dog") case "species": - out.Values[i] = ec._Dog_species(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Dog_species(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "dogBreed": - out.Values[i] = ec._Dog_dogBreed(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Dog_dogBreed(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12070,7 +12196,6 @@ var embeddedCase1Implementors = []string{"EmbeddedCase1"} func (ec *executionContext) _EmbeddedCase1(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase1) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase1Implementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12078,7 +12203,12 @@ func (ec *executionContext) _EmbeddedCase1(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("EmbeddedCase1") case "exportedEmbeddedPointerExportedMethod": - out.Values[i] = ec._EmbeddedCase1_exportedEmbeddedPointerExportedMethod(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase1_exportedEmbeddedPointerExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12097,7 +12227,6 @@ var embeddedCase2Implementors = []string{"EmbeddedCase2"} func (ec *executionContext) _EmbeddedCase2(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase2) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase2Implementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12105,7 +12234,12 @@ func (ec *executionContext) _EmbeddedCase2(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("EmbeddedCase2") case "unexportedEmbeddedPointerExportedMethod": - out.Values[i] = ec._EmbeddedCase2_unexportedEmbeddedPointerExportedMethod(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase2_unexportedEmbeddedPointerExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12124,7 +12258,6 @@ var embeddedCase3Implementors = []string{"EmbeddedCase3"} func (ec *executionContext) _EmbeddedCase3(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase3) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase3Implementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12132,7 +12265,12 @@ func (ec *executionContext) _EmbeddedCase3(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("EmbeddedCase3") case "unexportedEmbeddedInterfaceExportedMethod": - out.Values[i] = ec._EmbeddedCase3_unexportedEmbeddedInterfaceExportedMethod(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase3_unexportedEmbeddedInterfaceExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12151,7 +12289,6 @@ var embeddedDefaultScalarImplementors = []string{"EmbeddedDefaultScalar"} func (ec *executionContext) _EmbeddedDefaultScalar(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedDefaultScalar) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, embeddedDefaultScalarImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12159,7 +12296,12 @@ func (ec *executionContext) _EmbeddedDefaultScalar(ctx context.Context, sel ast. case "__typename": out.Values[i] = graphql.MarshalString("EmbeddedDefaultScalar") case "value": - out.Values[i] = ec._EmbeddedDefaultScalar_value(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedDefaultScalar_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12175,7 +12317,6 @@ var embeddedPointerImplementors = []string{"EmbeddedPointer"} func (ec *executionContext) _EmbeddedPointer(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedPointerModel) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, embeddedPointerImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12183,9 +12324,19 @@ func (ec *executionContext) _EmbeddedPointer(ctx context.Context, sel ast.Select case "__typename": out.Values[i] = graphql.MarshalString("EmbeddedPointer") case "ID": - out.Values[i] = ec._EmbeddedPointer_ID(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedPointer_ID(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "Title": - out.Values[i] = ec._EmbeddedPointer_Title(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedPointer_Title(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12201,7 +12352,6 @@ var errorImplementors = []string{"Error"} func (ec *executionContext) _Error(ctx context.Context, sel ast.SelectionSet, obj *Error) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, errorImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12209,19 +12359,39 @@ func (ec *executionContext) _Error(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("Error") case "id": - out.Values[i] = ec._Error_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "errorOnNonRequiredField": - out.Values[i] = ec._Error_errorOnNonRequiredField(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_errorOnNonRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "errorOnRequiredField": - out.Values[i] = ec._Error_errorOnRequiredField(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_errorOnRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "nilOnRequiredField": - out.Values[i] = ec._Error_nilOnRequiredField(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_nilOnRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12240,7 +12410,6 @@ var errorsImplementors = []string{"Errors"} func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, obj *Errors) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, errorsImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12249,7 +12418,8 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o out.Values[i] = graphql.MarshalString("Errors") case "a": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12260,10 +12430,16 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "b": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12274,10 +12450,16 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "c": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12288,10 +12470,16 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "d": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12302,10 +12490,16 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "e": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12316,6 +12510,11 @@ func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12332,7 +12531,6 @@ var forcedResolverImplementors = []string{"ForcedResolver"} func (ec *executionContext) _ForcedResolver(ctx context.Context, sel ast.SelectionSet, obj *ForcedResolver) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, forcedResolverImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12341,7 +12539,8 @@ func (ec *executionContext) _ForcedResolver(ctx context.Context, sel ast.Selecti out.Values[i] = graphql.MarshalString("ForcedResolver") case "field": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12349,6 +12548,11 @@ func (ec *executionContext) _ForcedResolver(ctx context.Context, sel ast.Selecti }() res = ec._ForcedResolver_field(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12365,7 +12569,6 @@ var innerObjectImplementors = []string{"InnerObject"} func (ec *executionContext) _InnerObject(ctx context.Context, sel ast.SelectionSet, obj *InnerObject) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, innerObjectImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12373,7 +12576,12 @@ func (ec *executionContext) _InnerObject(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("InnerObject") case "id": - out.Values[i] = ec._InnerObject_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InnerObject_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12392,7 +12600,6 @@ var invalidIdentifierImplementors = []string{"InvalidIdentifier"} func (ec *executionContext) _InvalidIdentifier(ctx context.Context, sel ast.SelectionSet, obj *invalid_packagename.InvalidIdentifier) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, invalidIdentifierImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12400,7 +12607,12 @@ func (ec *executionContext) _InvalidIdentifier(ctx context.Context, sel ast.Sele case "__typename": out.Values[i] = graphql.MarshalString("InvalidIdentifier") case "id": - out.Values[i] = ec._InvalidIdentifier_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InvalidIdentifier_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12419,7 +12631,6 @@ var itImplementors = []string{"It"} func (ec *executionContext) _It(ctx context.Context, sel ast.SelectionSet, obj *introspection1.It) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, itImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12427,7 +12638,12 @@ func (ec *executionContext) _It(ctx context.Context, sel ast.SelectionSet, obj * case "__typename": out.Values[i] = graphql.MarshalString("It") case "id": - out.Values[i] = ec._It_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._It_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12446,7 +12662,6 @@ var loopAImplementors = []string{"LoopA"} func (ec *executionContext) _LoopA(ctx context.Context, sel ast.SelectionSet, obj *LoopA) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, loopAImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12454,7 +12669,12 @@ func (ec *executionContext) _LoopA(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("LoopA") case "b": - out.Values[i] = ec._LoopA_b(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._LoopA_b(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12473,7 +12693,6 @@ var loopBImplementors = []string{"LoopB"} func (ec *executionContext) _LoopB(ctx context.Context, sel ast.SelectionSet, obj *LoopB) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, loopBImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12481,7 +12700,12 @@ func (ec *executionContext) _LoopB(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("LoopB") case "a": - out.Values[i] = ec._LoopB_a(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._LoopB_a(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12500,7 +12724,6 @@ var mapImplementors = []string{"Map"} func (ec *executionContext) _Map(ctx context.Context, sel ast.SelectionSet, obj *Map) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mapImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12508,7 +12731,12 @@ func (ec *executionContext) _Map(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Map") case "id": - out.Values[i] = ec._Map_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Map_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12527,7 +12755,6 @@ var mapStringInterfaceTypeImplementors = []string{"MapStringInterfaceType"} func (ec *executionContext) _MapStringInterfaceType(ctx context.Context, sel ast.SelectionSet, obj map[string]interface{}) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mapStringInterfaceTypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12535,9 +12762,19 @@ func (ec *executionContext) _MapStringInterfaceType(ctx context.Context, sel ast case "__typename": out.Values[i] = graphql.MarshalString("MapStringInterfaceType") case "a": - out.Values[i] = ec._MapStringInterfaceType_a(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MapStringInterfaceType_a(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "b": - out.Values[i] = ec._MapStringInterfaceType_b(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MapStringInterfaceType_b(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12553,7 +12790,6 @@ var modelMethodsImplementors = []string{"ModelMethods"} func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.SelectionSet, obj *ModelMethods) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, modelMethodsImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12562,7 +12798,8 @@ func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.Selection out.Values[i] = graphql.MarshalString("ModelMethods") case "resolverField": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12573,15 +12810,26 @@ func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.Selection atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "noContext": - out.Values[i] = ec._ModelMethods_noContext(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ModelMethods_noContext(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "withContext": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12592,6 +12840,11 @@ func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.Selection atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12608,7 +12861,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -12616,21 +12868,41 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "defaultInput": - out.Values[i] = ec._Mutation_defaultInput(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_defaultInput(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "updateSomething": - out.Values[i] = ec._Mutation_updateSomething(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateSomething(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "updatePtrToPtr": - out.Values[i] = ec._Mutation_updatePtrToPtr(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updatePtrToPtr(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -12649,7 +12921,6 @@ var objectDirectivesImplementors = []string{"ObjectDirectives"} func (ec *executionContext) _ObjectDirectives(ctx context.Context, sel ast.SelectionSet, obj *ObjectDirectives) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, objectDirectivesImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12657,14 +12928,29 @@ func (ec *executionContext) _ObjectDirectives(ctx context.Context, sel ast.Selec case "__typename": out.Values[i] = graphql.MarshalString("ObjectDirectives") case "text": - out.Values[i] = ec._ObjectDirectives_text(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "nullableText": - out.Values[i] = ec._ObjectDirectives_nullableText(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_nullableText(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "order": - out.Values[i] = ec._ObjectDirectives_order(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_order(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12683,7 +12969,6 @@ var objectDirectivesWithCustomGoModelImplementors = []string{"ObjectDirectivesWi func (ec *executionContext) _ObjectDirectivesWithCustomGoModel(ctx context.Context, sel ast.SelectionSet, obj *ObjectDirectivesWithCustomGoModel) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, objectDirectivesWithCustomGoModelImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12691,7 +12976,12 @@ func (ec *executionContext) _ObjectDirectivesWithCustomGoModel(ctx context.Conte case "__typename": out.Values[i] = graphql.MarshalString("ObjectDirectivesWithCustomGoModel") case "nullableText": - out.Values[i] = ec._ObjectDirectivesWithCustomGoModel_nullableText(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectivesWithCustomGoModel_nullableText(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12707,7 +12997,6 @@ var outerObjectImplementors = []string{"OuterObject"} func (ec *executionContext) _OuterObject(ctx context.Context, sel ast.SelectionSet, obj *OuterObject) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, outerObjectImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12715,7 +13004,12 @@ func (ec *executionContext) _OuterObject(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("OuterObject") case "inner": - out.Values[i] = ec._OuterObject_inner(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OuterObject_inner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12734,7 +13028,6 @@ var overlappingFieldsImplementors = []string{"OverlappingFields"} func (ec *executionContext) _OverlappingFields(ctx context.Context, sel ast.SelectionSet, obj *OverlappingFields) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, overlappingFieldsImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12742,18 +13035,29 @@ func (ec *executionContext) _OverlappingFields(ctx context.Context, sel ast.Sele case "__typename": out.Values[i] = graphql.MarshalString("OverlappingFields") case "oneFoo": - out.Values[i] = ec._OverlappingFields_oneFoo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_oneFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "twoFoo": - out.Values[i] = ec._OverlappingFields_twoFoo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_twoFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "oldFoo": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12764,14 +13068,29 @@ func (ec *executionContext) _OverlappingFields(ctx context.Context, sel ast.Sele atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "newFoo": - out.Values[i] = ec._OverlappingFields_newFoo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_newFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "new_foo": - out.Values[i] = ec._OverlappingFields_new_foo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_new_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -12790,7 +13109,6 @@ var panicsImplementors = []string{"Panics"} func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, obj *Panics) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, panicsImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12799,7 +13117,8 @@ func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, o out.Values[i] = graphql.MarshalString("Panics") case "fieldScalarMarshal": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12810,10 +13129,16 @@ func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res - }) - case "fieldFuncMarshal": + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "fieldFuncMarshal": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12824,10 +13149,16 @@ func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "argUnmarshal": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12838,6 +13169,11 @@ func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, o atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12854,7 +13190,6 @@ var primitiveImplementors = []string{"Primitive"} func (ec *executionContext) _Primitive(ctx context.Context, sel ast.SelectionSet, obj *Primitive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, primitiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12863,7 +13198,8 @@ func (ec *executionContext) _Primitive(ctx context.Context, sel ast.SelectionSet out.Values[i] = graphql.MarshalString("Primitive") case "value": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12874,9 +13210,19 @@ func (ec *executionContext) _Primitive(ctx context.Context, sel ast.SelectionSet atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "squared": - out.Values[i] = ec._Primitive_squared(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Primitive_squared(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -12895,7 +13241,6 @@ var primitiveStringImplementors = []string{"PrimitiveString"} func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.SelectionSet, obj *PrimitiveString) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, primitiveStringImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12904,7 +13249,8 @@ func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.Select out.Values[i] = graphql.MarshalString("PrimitiveString") case "value": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12915,15 +13261,26 @@ func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.Select atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "doubled": - out.Values[i] = ec._PrimitiveString_doubled(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PrimitiveString_doubled(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "len": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -12934,6 +13291,11 @@ func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.Select atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -12950,7 +13312,6 @@ var ptrToPtrInnerImplementors = []string{"PtrToPtrInner"} func (ec *executionContext) _PtrToPtrInner(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrInner) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrInnerImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12958,12 +13319,22 @@ func (ec *executionContext) _PtrToPtrInner(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("PtrToPtrInner") case "key": - out.Values[i] = ec._PtrToPtrInner_key(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrInner_key(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "value": - out.Values[i] = ec._PtrToPtrInner_value(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrInner_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -12982,7 +13353,6 @@ var ptrToPtrOuterImplementors = []string{"PtrToPtrOuter"} func (ec *executionContext) _PtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrOuter) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrOuterImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -12990,14 +13360,29 @@ func (ec *executionContext) _PtrToPtrOuter(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("PtrToPtrOuter") case "name": - out.Values[i] = ec._PtrToPtrOuter_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "inner": - out.Values[i] = ec._PtrToPtrOuter_inner(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_inner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "stupidInner": - out.Values[i] = ec._PtrToPtrOuter_stupidInner(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_stupidInner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13013,7 +13398,6 @@ var ptrToSliceContainerImplementors = []string{"PtrToSliceContainer"} func (ec *executionContext) _PtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, obj *PtrToSliceContainer) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, ptrToSliceContainerImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13021,7 +13405,12 @@ func (ec *executionContext) _PtrToSliceContainer(ctx context.Context, sel ast.Se case "__typename": out.Values[i] = graphql.MarshalString("PtrToSliceContainer") case "ptrToSlice": - out.Values[i] = ec._PtrToSliceContainer_ptrToSlice(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToSliceContainer_ptrToSlice(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13037,7 +13426,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -13045,12 +13433,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "invalidIdentifier": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13058,10 +13452,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_invalidIdentifier(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "collision": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13069,10 +13472,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_collision(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "mapInput": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13080,10 +13492,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_mapInput(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "recursive": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13091,10 +13512,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_recursive(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "nestedInputs": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13102,10 +13532,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_nestedInputs(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "nestedOutputs": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13113,10 +13552,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_nestedOutputs(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "modelMethods": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13124,10 +13572,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_modelMethods(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "user": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13138,10 +13595,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "nullableArg": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13149,10 +13615,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_nullableArg(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "inputSlice": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13163,10 +13638,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "inputNullableSlice": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13177,10 +13661,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "shapeUnion": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13191,10 +13684,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "autobind": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13202,10 +13704,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_autobind(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "deprecatedField": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13216,10 +13727,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "overlapping": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13227,10 +13747,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_overlapping(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "defaultParameters": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13241,10 +13770,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveArg": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13252,10 +13790,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveArg(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveNullableArg": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13263,10 +13810,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveNullableArg(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveInputNullable": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13274,10 +13830,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveInputNullable(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveInput": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13285,10 +13850,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveInput(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveInputType": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13296,10 +13870,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveInputType(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveObject": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13307,10 +13890,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveObject(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveObjectWithCustomGoModel": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13318,10 +13910,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveObjectWithCustomGoModel(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveFieldDef": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13332,10 +13933,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveField": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13343,10 +13953,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveField(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveDouble": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13354,10 +13973,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveDouble(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "directiveUnimplemented": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13365,10 +13993,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_directiveUnimplemented(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "embeddedCase1": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13376,10 +14013,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_embeddedCase1(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "embeddedCase2": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13387,10 +14033,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_embeddedCase2(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "embeddedCase3": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13398,10 +14053,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_embeddedCase3(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "enumInInput": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13412,10 +14076,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "shapes": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13423,10 +14096,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_shapes(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "noShape": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13434,10 +14116,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_noShape(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "node": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13448,10 +14139,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "noShapeTypedNil": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13459,10 +14159,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_noShapeTypedNil(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "animal": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13470,10 +14179,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_animal(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "notAnInterface": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13481,10 +14199,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_notAnInterface(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "issue896a": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13492,10 +14219,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_issue896a(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "mapStringInterface": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13503,10 +14239,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_mapStringInterface(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "mapNestedStringInterface": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13514,10 +14259,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_mapNestedStringInterface(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "errorBubble": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13525,10 +14279,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_errorBubble(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "errorBubbleList": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13536,10 +14299,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_errorBubbleList(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "errorList": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13547,10 +14319,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_errorList(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "errors": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13558,10 +14339,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_errors(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "valid": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13572,10 +14362,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "panics": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13583,10 +14382,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_panics(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "primitiveObject": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13597,10 +14405,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "primitiveStringObject": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13611,10 +14428,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "ptrToSliceContainer": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13625,10 +14451,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "defaultScalar": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13639,10 +14474,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "slices": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13650,10 +14494,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_slices(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "scalarSlice": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13664,10 +14517,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "fallback": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13678,10 +14540,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "optionalUnion": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13689,10 +14560,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_optionalUnion(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "vOkCaseValue": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13700,10 +14580,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_vOkCaseValue(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "vOkCaseNil": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13711,10 +14600,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_vOkCaseNil(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "validType": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13722,10 +14620,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_validType(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "wrappedStruct": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13736,10 +14643,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "wrappedScalar": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13750,10 +14666,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "wrappedMap": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13764,10 +14689,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "wrappedSlice": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13778,11 +14712,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13798,7 +14750,6 @@ var rectangleImplementors = []string{"Rectangle", "Shape", "ShapeUnion"} func (ec *executionContext) _Rectangle(ctx context.Context, sel ast.SelectionSet, obj *Rectangle) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, rectangleImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13806,11 +14757,26 @@ func (ec *executionContext) _Rectangle(ctx context.Context, sel ast.SelectionSet case "__typename": out.Values[i] = graphql.MarshalString("Rectangle") case "length": - out.Values[i] = ec._Rectangle_length(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_length(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "width": - out.Values[i] = ec._Rectangle_width(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_width(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "area": - out.Values[i] = ec._Rectangle_area(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_area(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13826,7 +14792,6 @@ var slicesImplementors = []string{"Slices"} func (ec *executionContext) _Slices(ctx context.Context, sel ast.SelectionSet, obj *Slices) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, slicesImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13834,16 +14799,36 @@ func (ec *executionContext) _Slices(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Slices") case "test1": - out.Values[i] = ec._Slices_test1(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test1(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "test2": - out.Values[i] = ec._Slices_test2(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test2(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "test3": - out.Values[i] = ec._Slices_test3(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test3(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "test4": - out.Values[i] = ec._Slices_test4(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test4(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -13894,7 +14879,6 @@ var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13902,13 +14886,19 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "id": - out.Values[i] = ec._User_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "friends": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -13919,14 +14909,29 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "created": - out.Values[i] = ec._User_created(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_created(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "updated": - out.Values[i] = ec._User_updated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_updated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13942,7 +14947,6 @@ var vOkCaseNilImplementors = []string{"VOkCaseNil"} func (ec *executionContext) _VOkCaseNil(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseNil) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseNilImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13950,7 +14954,12 @@ func (ec *executionContext) _VOkCaseNil(ctx context.Context, sel ast.SelectionSe case "__typename": out.Values[i] = graphql.MarshalString("VOkCaseNil") case "value": - out.Values[i] = ec._VOkCaseNil_value(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._VOkCaseNil_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13966,7 +14975,6 @@ var vOkCaseValueImplementors = []string{"VOkCaseValue"} func (ec *executionContext) _VOkCaseValue(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13974,7 +14982,12 @@ func (ec *executionContext) _VOkCaseValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("VOkCaseValue") case "value": - out.Values[i] = ec._VOkCaseValue_value(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._VOkCaseValue_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13990,7 +15003,6 @@ var validTypeImplementors = []string{"ValidType"} func (ec *executionContext) _ValidType(ctx context.Context, sel ast.SelectionSet, obj *ValidType) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, validTypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -13998,22 +15010,42 @@ func (ec *executionContext) _ValidType(ctx context.Context, sel ast.SelectionSet case "__typename": out.Values[i] = graphql.MarshalString("ValidType") case "differentCase": - out.Values[i] = ec._ValidType_differentCase(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_differentCase(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "different_case": - out.Values[i] = ec._ValidType_different_case(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_different_case(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "validInputKeywords": - out.Values[i] = ec._ValidType_validInputKeywords(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_validInputKeywords(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "validArgs": - out.Values[i] = ec._ValidType_validArgs(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_validArgs(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14032,7 +15064,6 @@ var wrappedMapImplementors = []string{"WrappedMap"} func (ec *executionContext) _WrappedMap(ctx context.Context, sel ast.SelectionSet, obj WrappedMap) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, wrappedMapImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14041,7 +15072,8 @@ func (ec *executionContext) _WrappedMap(ctx context.Context, sel ast.SelectionSe out.Values[i] = graphql.MarshalString("WrappedMap") case "get": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -14052,6 +15084,11 @@ func (ec *executionContext) _WrappedMap(ctx context.Context, sel ast.SelectionSe atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -14068,7 +15105,6 @@ var wrappedSliceImplementors = []string{"WrappedSlice"} func (ec *executionContext) _WrappedSlice(ctx context.Context, sel ast.SelectionSet, obj WrappedSlice) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, wrappedSliceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14077,7 +15113,8 @@ func (ec *executionContext) _WrappedSlice(ctx context.Context, sel ast.Selection out.Values[i] = graphql.MarshalString("WrappedSlice") case "get": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -14088,6 +15125,11 @@ func (ec *executionContext) _WrappedSlice(ctx context.Context, sel ast.Selection atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -14104,7 +15146,6 @@ var wrappedStructImplementors = []string{"WrappedStruct"} func (ec *executionContext) _WrappedStruct(ctx context.Context, sel ast.SelectionSet, obj *WrappedStruct) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, wrappedStructImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14112,12 +15153,22 @@ func (ec *executionContext) _WrappedStruct(ctx context.Context, sel ast.Selectio case "__typename": out.Values[i] = graphql.MarshalString("WrappedStruct") case "name": - out.Values[i] = ec._WrappedStruct_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._WrappedStruct_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "desc": - out.Values[i] = ec._WrappedStruct_desc(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._WrappedStruct_desc(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -14133,7 +15184,6 @@ var xXItImplementors = []string{"XXIt"} func (ec *executionContext) _XXIt(ctx context.Context, sel ast.SelectionSet, obj *XXIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, xXItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14141,7 +15191,12 @@ func (ec *executionContext) _XXIt(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("XXIt") case "id": - out.Values[i] = ec._XXIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._XXIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14160,7 +15215,6 @@ var xxItImplementors = []string{"XxIt"} func (ec *executionContext) _XxIt(ctx context.Context, sel ast.SelectionSet, obj *XxIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, xxItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14168,7 +15222,12 @@ func (ec *executionContext) _XxIt(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("XxIt") case "id": - out.Values[i] = ec._XxIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._XxIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14187,7 +15246,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14195,24 +15253,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14231,7 +15314,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14239,19 +15321,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -14267,7 +15369,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14275,29 +15376,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -14313,7 +15444,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14321,19 +15451,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -14349,7 +15499,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14357,21 +15506,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14390,7 +15564,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14398,26 +15571,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -14433,7 +15651,6 @@ var asdfItImplementors = []string{"asdfIt"} func (ec *executionContext) _asdfIt(ctx context.Context, sel ast.SelectionSet, obj *AsdfIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, asdfItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14441,7 +15658,12 @@ func (ec *executionContext) _asdfIt(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("asdfIt") case "id": - out.Values[i] = ec._asdfIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._asdfIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -14460,7 +15682,6 @@ var iItImplementors = []string{"iIt"} func (ec *executionContext) _iIt(ctx context.Context, sel ast.SelectionSet, obj *IIt) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, iItImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -14468,7 +15689,12 @@ func (ec *executionContext) _iIt(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("iIt") case "id": - out.Values[i] = ec._iIt_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._iIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } diff --git a/example/chat/generated.go b/example/chat/generated.go index 7ebbf06eb47..70d41c98b3c 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -2007,7 +2007,6 @@ var chatroomImplementors = []string{"Chatroom"} func (ec *executionContext) _Chatroom(ctx context.Context, sel ast.SelectionSet, obj *Chatroom) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, chatroomImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2015,12 +2014,22 @@ func (ec *executionContext) _Chatroom(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Chatroom") case "name": - out.Values[i] = ec._Chatroom_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Chatroom_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "messages": - out.Values[i] = ec._Chatroom_messages(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Chatroom_messages(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2039,7 +2048,6 @@ var messageImplementors = []string{"Message"} func (ec *executionContext) _Message(ctx context.Context, sel ast.SelectionSet, obj *Message) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, messageImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2047,22 +2055,42 @@ func (ec *executionContext) _Message(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Message") case "id": - out.Values[i] = ec._Message_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Message_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "text": - out.Values[i] = ec._Message_text(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Message_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "createdBy": - out.Values[i] = ec._Message_createdBy(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Message_createdBy(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "createdAt": - out.Values[i] = ec._Message_createdAt(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Message_createdAt(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2081,7 +2109,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -2089,11 +2116,21 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "post": - out.Values[i] = ec._Mutation_post(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_post(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -2112,7 +2149,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2120,12 +2156,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "room": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2133,11 +2175,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_room(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2173,7 +2233,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2181,24 +2240,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2217,7 +2301,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2225,19 +2308,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2253,7 +2356,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2261,29 +2363,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2299,7 +2431,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2307,19 +2438,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2335,7 +2486,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2343,21 +2493,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2376,7 +2551,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2384,26 +2558,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/config/generated.go b/example/config/generated.go index 192997e0b7d..86bfb26a2b4 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -1984,7 +1984,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -1992,11 +1991,21 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "createTodo": - out.Values[i] = ec._Mutation_createTodo(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createTodo(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -2015,7 +2024,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2023,12 +2031,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "todos": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2039,11 +2053,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2059,7 +2091,6 @@ var todoImplementors = []string{"Todo"} func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj *Todo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, todoImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2068,7 +2099,8 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj out.Values[i] = graphql.MarshalString("Todo") case "id": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2079,24 +2111,49 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "databaseId": - out.Values[i] = ec._Todo_databaseId(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_databaseId(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "text": - out.Values[i] = ec._Todo_text(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "done": - out.Values[i] = ec._Todo_done(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_done(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "user": - out.Values[i] = ec._Todo_user(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_user(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -2115,7 +2172,6 @@ var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2123,17 +2179,32 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "id": - out.Values[i] = ec._User_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec._User_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "role": - out.Values[i] = ec._User_role(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_role(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2152,7 +2223,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2160,24 +2230,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2196,7 +2291,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2204,19 +2298,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2232,7 +2346,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2240,29 +2353,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2278,7 +2421,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2286,19 +2428,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2314,7 +2476,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2322,21 +2483,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2355,7 +2541,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2363,26 +2548,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2398,7 +2628,6 @@ var roleImplementors = []string{"role"} func (ec *executionContext) _role(ctx context.Context, sel ast.SelectionSet, obj *UserRole) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, roleImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2407,7 +2636,8 @@ func (ec *executionContext) _role(ctx context.Context, sel ast.SelectionSet, obj out.Values[i] = graphql.MarshalString("role") case "name": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2418,6 +2648,11 @@ func (ec *executionContext) _role(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 7ede23b8b1a..82cd522228a 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -2117,7 +2117,6 @@ var addressImplementors = []string{"Address"} func (ec *executionContext) _Address(ctx context.Context, sel ast.SelectionSet, obj *Address) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, addressImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2125,17 +2124,32 @@ func (ec *executionContext) _Address(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Address") case "id": - out.Values[i] = ec._Address_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Address_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "street": - out.Values[i] = ec._Address_street(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Address_street(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "country": - out.Values[i] = ec._Address_country(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Address_country(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2154,7 +2168,6 @@ var customerImplementors = []string{"Customer"} func (ec *executionContext) _Customer(ctx context.Context, sel ast.SelectionSet, obj *Customer) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, customerImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2162,18 +2175,29 @@ func (ec *executionContext) _Customer(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Customer") case "id": - out.Values[i] = ec._Customer_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Customer_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "name": - out.Values[i] = ec._Customer_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Customer_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "address": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2181,10 +2205,16 @@ func (ec *executionContext) _Customer(ctx context.Context, sel ast.SelectionSet, }() res = ec._Customer_address(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "orders": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2192,6 +2222,11 @@ func (ec *executionContext) _Customer(ctx context.Context, sel ast.SelectionSet, }() res = ec._Customer_orders(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2208,7 +2243,6 @@ var itemImplementors = []string{"Item"} func (ec *executionContext) _Item(ctx context.Context, sel ast.SelectionSet, obj *Item) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, itemImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2216,7 +2250,12 @@ func (ec *executionContext) _Item(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Item") case "name": - out.Values[i] = ec._Item_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Item_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2235,7 +2274,6 @@ var orderImplementors = []string{"Order"} func (ec *executionContext) _Order(ctx context.Context, sel ast.SelectionSet, obj *Order) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, orderImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2243,23 +2281,39 @@ func (ec *executionContext) _Order(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("Order") case "id": - out.Values[i] = ec._Order_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Order_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "date": - out.Values[i] = ec._Order_date(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Order_date(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "amount": - out.Values[i] = ec._Order_amount(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Order_amount(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "items": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2267,6 +2321,11 @@ func (ec *executionContext) _Order(ctx context.Context, sel ast.SelectionSet, ob }() res = ec._Order_items(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2283,7 +2342,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2291,12 +2349,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "customers": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2304,10 +2368,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_customers(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "torture1d": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2315,10 +2388,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_torture1d(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "torture2d": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2326,11 +2408,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_torture2d(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2346,7 +2446,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2354,24 +2453,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2390,7 +2514,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2398,19 +2521,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2426,7 +2569,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2434,29 +2576,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2472,7 +2644,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2480,19 +2651,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2508,7 +2699,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2516,21 +2706,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2549,7 +2764,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2557,26 +2771,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index 395c1321a6e..388055bf2e7 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -1798,7 +1798,6 @@ var entityImplementors = []string{"Entity"} func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Entity", }) @@ -1806,12 +1805,18 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") case "findUserByID": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1822,6 +1827,14 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -1838,7 +1851,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -1846,12 +1858,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "me": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1859,10 +1877,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_me(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "_entities": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1873,10 +1900,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "_service": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1887,11 +1923,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1907,7 +1961,6 @@ var userImplementors = []string{"User", "_Entity"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *model.User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1915,12 +1968,22 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "id": - out.Values[i] = ec._User_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "username": - out.Values[i] = ec._User_username(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_username(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -1939,7 +2002,6 @@ var _ServiceImplementors = []string{"_Service"} func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1947,7 +2009,12 @@ func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("_Service") case "sdl": - out.Values[i] = ec.__Service_sdl(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.__Service_sdl(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1963,7 +2030,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1971,24 +2037,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2007,7 +2098,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2015,19 +2105,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2043,7 +2153,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2051,29 +2160,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2089,7 +2228,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2097,19 +2235,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2125,7 +2283,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2133,21 +2290,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2166,7 +2348,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2174,26 +2355,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 76e13f15460..8134be72e0a 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -1869,7 +1869,6 @@ var entityImplementors = []string{"Entity"} func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Entity", }) @@ -1877,12 +1876,18 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") case "findProductByUpc": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1893,6 +1898,14 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -1909,7 +1922,6 @@ var productImplementors = []string{"Product", "_Entity"} func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, productImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1917,17 +1929,32 @@ func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Product") case "upc": - out.Values[i] = ec._Product_upc(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_upc(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec._Product_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "price": - out.Values[i] = ec._Product_price(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_price(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -1946,7 +1973,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -1954,12 +1980,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "topProducts": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1967,10 +1999,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_topProducts(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "_entities": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1981,10 +2022,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "_service": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1995,11 +2045,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2015,7 +2083,6 @@ var _ServiceImplementors = []string{"_Service"} func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2023,7 +2090,12 @@ func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("_Service") case "sdl": - out.Values[i] = ec.__Service_sdl(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.__Service_sdl(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2039,7 +2111,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2047,24 +2118,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2083,7 +2179,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2091,19 +2186,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2119,7 +2234,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2127,29 +2241,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2165,7 +2309,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2173,19 +2316,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2201,7 +2364,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2209,21 +2371,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2242,7 +2429,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2250,26 +2436,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 30c5a3e3723..6fc2cf679fc 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -2063,7 +2063,6 @@ var entityImplementors = []string{"Entity"} func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, entityImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Entity", }) @@ -2071,12 +2070,18 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") case "findProductByUpc": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2087,10 +2092,19 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "findUserByID": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2101,6 +2115,14 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2117,7 +2139,6 @@ var productImplementors = []string{"Product", "_Entity"} func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, productImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2125,13 +2146,19 @@ func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Product") case "upc": - out.Values[i] = ec._Product_upc(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_upc(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "reviews": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2139,6 +2166,11 @@ func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, }() res = ec._Product_reviews(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2155,7 +2187,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2163,12 +2194,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "_entities": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2179,10 +2216,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "_service": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2193,11 +2239,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2213,7 +2277,6 @@ var reviewImplementors = []string{"Review"} func (ec *executionContext) _Review(ctx context.Context, sel ast.SelectionSet, obj *model.Review) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, reviewImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2221,17 +2284,32 @@ func (ec *executionContext) _Review(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Review") case "body": - out.Values[i] = ec._Review_body(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_body(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "author": - out.Values[i] = ec._Review_author(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_author(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "product": - out.Values[i] = ec._Review_product(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_product(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2250,7 +2328,6 @@ var userImplementors = []string{"User", "_Entity"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *model.User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2258,13 +2335,19 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "id": - out.Values[i] = ec._User_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "reviews": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2272,6 +2355,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj }() res = ec._User_reviews(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2288,7 +2376,6 @@ var _ServiceImplementors = []string{"_Service"} func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, obj *fedruntime.Service) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, _ServiceImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2296,7 +2383,12 @@ func (ec *executionContext) __Service(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("_Service") case "sdl": - out.Values[i] = ec.__Service_sdl(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.__Service_sdl(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2312,7 +2404,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2320,24 +2411,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2356,7 +2472,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2364,19 +2479,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2392,7 +2527,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2400,29 +2534,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2438,7 +2602,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2446,19 +2609,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2474,7 +2657,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2482,21 +2664,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2515,7 +2722,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2523,26 +2729,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/fileupload/generated.go b/example/fileupload/generated.go index 58527eb28d0..32717ad1843 100644 --- a/example/fileupload/generated.go +++ b/example/fileupload/generated.go @@ -1964,7 +1964,6 @@ var fileImplementors = []string{"File"} func (ec *executionContext) _File(ctx context.Context, sel ast.SelectionSet, obj *model.File) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, fileImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1972,22 +1971,42 @@ func (ec *executionContext) _File(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("File") case "id": - out.Values[i] = ec._File_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._File_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec._File_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._File_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "content": - out.Values[i] = ec._File_content(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._File_content(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "contentType": - out.Values[i] = ec._File_contentType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._File_contentType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2006,7 +2025,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -2014,26 +2032,51 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "singleUpload": - out.Values[i] = ec._Mutation_singleUpload(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_singleUpload(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "singleUploadWithPayload": - out.Values[i] = ec._Mutation_singleUploadWithPayload(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_singleUploadWithPayload(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "multipleUpload": - out.Values[i] = ec._Mutation_multipleUpload(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_multipleUpload(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "multipleUploadWithPayload": - out.Values[i] = ec._Mutation_multipleUploadWithPayload(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_multipleUploadWithPayload(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -2052,7 +2095,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2060,12 +2102,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "empty": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2076,11 +2124,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2096,7 +2162,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2104,24 +2169,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2140,7 +2230,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2148,19 +2237,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2176,7 +2285,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2184,29 +2292,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2222,7 +2360,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2230,19 +2367,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2258,7 +2415,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2266,21 +2422,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2299,7 +2480,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2307,26 +2487,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index 872921a1174..cd067e341cc 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -2230,7 +2230,6 @@ var addressImplementors = []string{"Address"} func (ec *executionContext) _Address(ctx context.Context, sel ast.SelectionSet, obj *model.Address) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, addressImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2238,12 +2237,22 @@ func (ec *executionContext) _Address(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Address") case "id": - out.Values[i] = ec._Address_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Address_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "location": - out.Values[i] = ec._Address_location(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Address_location(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2259,7 +2268,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2267,12 +2275,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "user": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2280,10 +2294,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_user(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "search": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2294,10 +2317,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "userByTier": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2308,11 +2340,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2328,7 +2378,6 @@ var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *model.User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2336,31 +2385,67 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "id": - out.Values[i] = ec._User_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "name": - out.Values[i] = ec._User_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "created": - out.Values[i] = ec._User_created(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_created(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "modified": - out.Values[i] = ec._User_modified(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_modified(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "valPrefs": - out.Values[i] = ec._User_valPrefs(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_valPrefs(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ptrPrefs": - out.Values[i] = ec._User_ptrPrefs(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_ptrPrefs(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isBanned": - out.Values[i] = ec._User_isBanned(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_isBanned(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "primitiveResolver": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2371,10 +2456,16 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "customResolver": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2385,11 +2476,26 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "address": - out.Values[i] = ec._User_address(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_address(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "tier": - out.Values[i] = ec._User_tier(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_tier(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2405,7 +2511,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2413,24 +2518,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2449,7 +2579,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2457,19 +2586,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2485,7 +2634,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2493,29 +2641,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2531,7 +2709,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2539,19 +2716,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2567,7 +2764,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2575,21 +2771,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2608,7 +2829,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2616,26 +2836,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/selection/generated.go b/example/selection/generated.go index bc3c24d4442..39bbdb271e1 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -1806,7 +1806,6 @@ var likeImplementors = []string{"Like", "Event"} func (ec *executionContext) _Like(ctx context.Context, sel ast.SelectionSet, obj *Like) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, likeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1814,19 +1813,39 @@ func (ec *executionContext) _Like(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Like") case "reaction": - out.Values[i] = ec._Like_reaction(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Like_reaction(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "sent": - out.Values[i] = ec._Like_sent(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Like_sent(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "selection": - out.Values[i] = ec._Like_selection(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Like_selection(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "collected": - out.Values[i] = ec._Like_collected(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Like_collected(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1842,7 +1861,6 @@ var postImplementors = []string{"Post", "Event"} func (ec *executionContext) _Post(ctx context.Context, sel ast.SelectionSet, obj *Post) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, postImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1850,19 +1868,39 @@ func (ec *executionContext) _Post(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Post") case "message": - out.Values[i] = ec._Post_message(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Post_message(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "sent": - out.Values[i] = ec._Post_sent(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Post_sent(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "selection": - out.Values[i] = ec._Post_selection(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Post_selection(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "collected": - out.Values[i] = ec._Post_collected(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Post_collected(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1878,7 +1916,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -1886,12 +1923,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "events": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1899,11 +1942,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_events(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1919,7 +1980,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1927,24 +1987,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -1963,7 +2048,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -1971,19 +2055,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1999,7 +2103,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2007,29 +2110,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2045,7 +2178,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2053,19 +2185,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2081,7 +2233,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2089,21 +2240,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2122,7 +2298,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2130,26 +2305,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index 90dc8645a2a..6052f45ceef 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -3621,7 +3621,6 @@ var droidImplementors = []string{"Droid", "Character", "SearchResult"} func (ec *executionContext) _Droid(ctx context.Context, sel ast.SelectionSet, obj *models.Droid) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, droidImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3629,18 +3628,29 @@ func (ec *executionContext) _Droid(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("Droid") case "id": - out.Values[i] = ec._Droid_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Droid_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "name": - out.Values[i] = ec._Droid_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Droid_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "friends": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3648,10 +3658,16 @@ func (ec *executionContext) _Droid(ctx context.Context, sel ast.SelectionSet, ob }() res = ec._Droid_friends(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "friendsConnection": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3662,14 +3678,29 @@ func (ec *executionContext) _Droid(ctx context.Context, sel ast.SelectionSet, ob atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "appearsIn": - out.Values[i] = ec._Droid_appearsIn(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Droid_appearsIn(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "primaryFunction": - out.Values[i] = ec._Droid_primaryFunction(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Droid_primaryFunction(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3685,7 +3716,6 @@ var friendsConnectionImplementors = []string{"FriendsConnection"} func (ec *executionContext) _FriendsConnection(ctx context.Context, sel ast.SelectionSet, obj *models.FriendsConnection) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, friendsConnectionImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3693,13 +3723,19 @@ func (ec *executionContext) _FriendsConnection(ctx context.Context, sel ast.Sele case "__typename": out.Values[i] = graphql.MarshalString("FriendsConnection") case "totalCount": - out.Values[i] = ec._FriendsConnection_totalCount(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._FriendsConnection_totalCount(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "edges": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3707,10 +3743,16 @@ func (ec *executionContext) _FriendsConnection(ctx context.Context, sel ast.Sele }() res = ec._FriendsConnection_edges(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "friends": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3718,9 +3760,19 @@ func (ec *executionContext) _FriendsConnection(ctx context.Context, sel ast.Sele }() res = ec._FriendsConnection_friends(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "pageInfo": - out.Values[i] = ec._FriendsConnection_pageInfo(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._FriendsConnection_pageInfo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -3739,7 +3791,6 @@ var friendsEdgeImplementors = []string{"FriendsEdge"} func (ec *executionContext) _FriendsEdge(ctx context.Context, sel ast.SelectionSet, obj *models.FriendsEdge) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, friendsEdgeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3747,12 +3798,22 @@ func (ec *executionContext) _FriendsEdge(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("FriendsEdge") case "cursor": - out.Values[i] = ec._FriendsEdge_cursor(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._FriendsEdge_cursor(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "node": - out.Values[i] = ec._FriendsEdge_node(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._FriendsEdge_node(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3768,7 +3829,6 @@ var humanImplementors = []string{"Human", "Character", "SearchResult"} func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, obj *models.Human) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, humanImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3776,25 +3836,46 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob case "__typename": out.Values[i] = graphql.MarshalString("Human") case "id": - out.Values[i] = ec._Human_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Human_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "name": - out.Values[i] = ec._Human_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Human_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "height": - out.Values[i] = ec._Human_height(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Human_height(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "mass": - out.Values[i] = ec._Human_mass(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Human_mass(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "friends": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3802,10 +3883,16 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob }() res = ec._Human_friends(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "friendsConnection": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3816,15 +3903,26 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "appearsIn": - out.Values[i] = ec._Human_appearsIn(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Human_appearsIn(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "starships": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3832,6 +3930,11 @@ func (ec *executionContext) _Human(ctx context.Context, sel ast.SelectionSet, ob }() res = ec._Human_starships(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -3848,7 +3951,6 @@ var mutationImplementors = []string{"Mutation"} func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Mutation", }) @@ -3856,11 +3958,21 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") case "createReview": - out.Values[i] = ec._Mutation_createReview(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createReview(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3876,7 +3988,6 @@ var pageInfoImplementors = []string{"PageInfo"} func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, obj *models.PageInfo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, pageInfoImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -3884,17 +3995,32 @@ func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("PageInfo") case "startCursor": - out.Values[i] = ec._PageInfo_startCursor(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PageInfo_startCursor(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "endCursor": - out.Values[i] = ec._PageInfo_endCursor(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PageInfo_endCursor(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "hasNextPage": - out.Values[i] = ec._PageInfo_hasNextPage(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PageInfo_hasNextPage(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -3913,7 +4039,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -3921,12 +4046,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "hero": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3934,10 +4065,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_hero(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "reviews": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3948,10 +4088,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "search": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3962,10 +4111,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "character": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3973,10 +4131,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_character(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "droid": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3984,10 +4151,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_droid(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "human": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -3995,10 +4171,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_human(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "starship": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4006,11 +4191,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_starship(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4026,7 +4229,6 @@ var reviewImplementors = []string{"Review"} func (ec *executionContext) _Review(ctx context.Context, sel ast.SelectionSet, obj *models.Review) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, reviewImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4034,14 +4236,29 @@ func (ec *executionContext) _Review(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Review") case "stars": - out.Values[i] = ec._Review_stars(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_stars(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "commentary": - out.Values[i] = ec._Review_commentary(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_commentary(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "time": - out.Values[i] = ec._Review_time(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Review_time(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4057,7 +4274,6 @@ var starshipImplementors = []string{"Starship", "SearchResult"} func (ec *executionContext) _Starship(ctx context.Context, sel ast.SelectionSet, obj *models.Starship) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, starshipImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4065,18 +4281,29 @@ func (ec *executionContext) _Starship(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("Starship") case "id": - out.Values[i] = ec._Starship_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Starship_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "name": - out.Values[i] = ec._Starship_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Starship_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "length": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -4087,9 +4314,19 @@ func (ec *executionContext) _Starship(ctx context.Context, sel ast.SelectionSet, atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "history": - out.Values[i] = ec._Starship_history(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Starship_history(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -4108,7 +4345,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4116,24 +4352,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -4152,7 +4413,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4160,19 +4420,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4188,7 +4468,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4196,29 +4475,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4234,7 +4543,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4242,19 +4550,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4270,7 +4598,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4278,21 +4605,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -4311,7 +4663,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -4319,26 +4670,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/todo/generated.go b/example/todo/generated.go index dfb1179ccab..bdf847f6fc0 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -1929,7 +1929,6 @@ var myMutationImplementors = []string{"MyMutation"} func (ec *executionContext) _MyMutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, myMutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "MyMutation", }) @@ -1937,16 +1936,31 @@ func (ec *executionContext) _MyMutation(ctx context.Context, sel ast.SelectionSe out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("MyMutation") case "createTodo": - out.Values[i] = ec._MyMutation_createTodo(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyMutation_createTodo(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } case "updateTodo": - out.Values[i] = ec._MyMutation_updateTodo(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyMutation_updateTodo(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1962,7 +1976,6 @@ var myQueryImplementors = []string{"MyQuery"} func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, myQueryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "MyQuery", }) @@ -1970,12 +1983,18 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("MyQuery") case "todo": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1983,10 +2002,19 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) }() res = ec._MyQuery_todo(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "lastTodo": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -1994,10 +2022,19 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) }() res = ec._MyQuery_lastTodo(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "todos": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2008,11 +2045,29 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._MyQuery___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyQuery___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._MyQuery___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyQuery___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2028,7 +2083,6 @@ var todoImplementors = []string{"Todo"} func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj *Todo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, todoImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2036,17 +2090,32 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Todo") case "id": - out.Values[i] = ec._Todo_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "text": - out.Values[i] = ec._Todo_text(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "done": - out.Values[i] = ec._Todo_done(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_done(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2065,7 +2134,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2073,24 +2141,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2109,7 +2202,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2117,19 +2209,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2145,7 +2257,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2153,29 +2264,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2191,7 +2332,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2199,19 +2339,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2227,7 +2387,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2235,21 +2394,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2268,7 +2452,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2276,26 +2459,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index 4c0ea402cd9..1411a10eebd 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -1988,7 +1988,6 @@ var myMutationImplementors = []string{"MyMutation"} func (ec *executionContext) _MyMutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, myMutationImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "MyMutation", }) @@ -1996,11 +1995,21 @@ func (ec *executionContext) _MyMutation(ctx context.Context, sel ast.SelectionSe out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("MyMutation") case "createTodo": - out.Values[i] = ec._MyMutation_createTodo(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyMutation_createTodo(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + if out.Values[i] == graphql.Null { invalids++ } @@ -2019,7 +2028,6 @@ var myQueryImplementors = []string{"MyQuery"} func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, myQueryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "MyQuery", }) @@ -2027,12 +2035,18 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("MyQuery") case "todos": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2043,10 +2057,19 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "todo": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2054,11 +2077,29 @@ func (ec *executionContext) _MyQuery(ctx context.Context, sel ast.SelectionSet) }() res = ec._MyQuery_todo(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._MyQuery___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyQuery___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._MyQuery___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MyQuery___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2074,7 +2115,6 @@ var todoImplementors = []string{"Todo", "Node", "Data"} func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj *Todo) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, todoImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2082,22 +2122,42 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("Todo") case "id": - out.Values[i] = ec._Todo_id(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "text": - out.Values[i] = ec._Todo_text(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "state": - out.Values[i] = ec._Todo_state(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_state(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "verified": - out.Values[i] = ec._Todo_verified(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Todo_verified(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2116,7 +2176,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2124,24 +2183,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2160,7 +2244,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2168,19 +2251,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2196,7 +2299,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2204,29 +2306,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2242,7 +2374,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2250,19 +2381,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2278,7 +2429,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2286,21 +2436,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2319,7 +2494,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2327,26 +2501,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/graphql/context_operation.go b/graphql/context_operation.go index 4f4607eab3a..bfbbc5c002f 100644 --- a/graphql/context_operation.go +++ b/graphql/context_operation.go @@ -16,10 +16,11 @@ type OperationContext struct { OperationName string Doc *ast.QueryDocument - Operation *ast.OperationDefinition - DisableIntrospection bool - RecoverFunc RecoverFunc - ResolverMiddleware FieldMiddleware + Operation *ast.OperationDefinition + DisableIntrospection bool + RecoverFunc RecoverFunc + ResolverMiddleware FieldMiddleware + RootResolverMiddleware RootFieldMiddleware Stats Stats } @@ -37,6 +38,9 @@ func (c *OperationContext) Validate(ctx context.Context) error { if c.ResolverMiddleware == nil { return errors.New("field 'ResolverMiddleware' is required") } + if c.RootResolverMiddleware == nil { + return errors.New("field 'RootResolverMiddleware' is required") + } if c.RecoverFunc == nil { c.RecoverFunc = DefaultRecover } diff --git a/graphql/context_root_field.go b/graphql/context_root_field.go new file mode 100644 index 00000000000..1bf4d13b84d --- /dev/null +++ b/graphql/context_root_field.go @@ -0,0 +1,25 @@ +package graphql + +import ( + "context" +) + +const rootResolverCtx key = "root_resolver_context" + +type RootFieldContext struct { + // The name of the type this field belongs to + Object string + // The raw field + Field CollectedField +} + +func GetRootFieldContext(ctx context.Context) *RootFieldContext { + if val, ok := ctx.Value(rootResolverCtx).(*RootFieldContext); ok { + return val + } + return nil +} + +func WithRootFieldContext(ctx context.Context, rc *RootFieldContext) context.Context { + return context.WithValue(ctx, rootResolverCtx, rc) +} diff --git a/graphql/context_root_field_test.go b/graphql/context_root_field_test.go new file mode 100644 index 00000000000..dfbb859ccb4 --- /dev/null +++ b/graphql/context_root_field_test.go @@ -0,0 +1,15 @@ +package graphql + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetRootFieldContext(t *testing.T) { + require.Nil(t, GetRootFieldContext(context.Background())) + + rc := &RootFieldContext{} + require.Equal(t, rc, GetRootFieldContext(WithRootFieldContext(context.Background(), rc))) +} diff --git a/graphql/executor/executor.go b/graphql/executor/executor.go index 44a2b04c36c..95a28031148 100644 --- a/graphql/executor/executor.go +++ b/graphql/executor/executor.go @@ -39,9 +39,10 @@ func New(es graphql.ExecutableSchema) *Executor { func (e *Executor) CreateOperationContext(ctx context.Context, params *graphql.RawParams) (*graphql.OperationContext, gqlerror.List) { rc := &graphql.OperationContext{ - DisableIntrospection: true, - RecoverFunc: e.recoverFunc, - ResolverMiddleware: e.ext.fieldMiddleware, + DisableIntrospection: true, + RecoverFunc: e.recoverFunc, + ResolverMiddleware: e.ext.fieldMiddleware, + RootResolverMiddleware: e.ext.rootFieldMiddleware, Stats: graphql.Stats{ Read: params.ReadTime, OperationStart: graphql.GetStartTime(ctx), diff --git a/graphql/executor/executor_test.go b/graphql/executor/executor_test.go index e76b68e97f7..dbd36053818 100644 --- a/graphql/executor/executor_test.go +++ b/graphql/executor/executor_test.go @@ -53,6 +53,22 @@ func TestExecutor(t *testing.T) { assert.Equal(t, []string{"first", "second"}, calls) }) + t.Run("invokes root field middleware in order", func(t *testing.T) { + var calls []string + exec.AroundRootFields(func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + calls = append(calls, "first") + return next(ctx) + }) + exec.AroundRootFields(func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + calls = append(calls, "second") + return next(ctx) + }) + + resp := query(exec, "", "{name}") + assert.Equal(t, `{"name":"test"}`, string(resp.Data)) + assert.Equal(t, []string{"first", "second"}, calls) + }) + t.Run("invokes field middleware in order", func(t *testing.T) { var calls []string exec.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { diff --git a/graphql/executor/extensions.go b/graphql/executor/extensions.go index 30a48ce809f..a8eebf110c4 100644 --- a/graphql/executor/extensions.go +++ b/graphql/executor/extensions.go @@ -17,6 +17,7 @@ func (e *Executor) Use(extension graphql.HandlerExtension) { case graphql.OperationParameterMutator, graphql.OperationContextMutator, graphql.OperationInterceptor, + graphql.RootFieldInterceptor, graphql.FieldInterceptor, graphql.ResponseInterceptor: e.extensions = append(e.extensions, extension) @@ -32,6 +33,11 @@ func (e *Executor) AroundFields(f graphql.FieldMiddleware) { e.Use(aroundFieldFunc(f)) } +// AroundRootFields is a convenience method for creating an extension that only implements root field middleware +func (e *Executor) AroundRootFields(f graphql.RootFieldMiddleware) { + e.Use(aroundRootFieldFunc(f)) +} + // AroundOperations is a convenience method for creating an extension that only implements operation middleware func (e *Executor) AroundOperations(f graphql.OperationMiddleware) { e.Use(aroundOpFunc(f)) @@ -45,6 +51,7 @@ func (e *Executor) AroundResponses(f graphql.ResponseMiddleware) { type extensions struct { operationMiddleware graphql.OperationMiddleware responseMiddleware graphql.ResponseMiddleware + rootFieldMiddleware graphql.RootFieldMiddleware fieldMiddleware graphql.FieldMiddleware operationParameterMutators []graphql.OperationParameterMutator operationContextMutators []graphql.OperationContextMutator @@ -58,6 +65,9 @@ func processExtensions(exts []graphql.HandlerExtension) extensions { responseMiddleware: func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { return next(ctx) }, + rootFieldMiddleware: func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return next(ctx) + }, fieldMiddleware: func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { return next(ctx) }, @@ -84,6 +94,15 @@ func processExtensions(exts []graphql.HandlerExtension) extensions { } } + if p, ok := p.(graphql.RootFieldInterceptor); ok { + previous := e.rootFieldMiddleware + e.rootFieldMiddleware = func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return p.InterceptRootField(ctx, func(ctx context.Context) graphql.Marshaler { + return previous(ctx, next) + }) + } + } + if p, ok := p.(graphql.FieldInterceptor); ok { previous := e.fieldMiddleware e.fieldMiddleware = func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { @@ -157,3 +176,20 @@ func (f aroundFieldFunc) Validate(schema graphql.ExecutableSchema) error { func (f aroundFieldFunc) InterceptField(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { return f(ctx, next) } + +type aroundRootFieldFunc func(ctx context.Context, next graphql.RootResolver) graphql.Marshaler + +func (f aroundRootFieldFunc) ExtensionName() string { + return "InlineRootFieldFunc" +} + +func (f aroundRootFieldFunc) Validate(schema graphql.ExecutableSchema) error { + if f == nil { + return fmt.Errorf("RootFieldFunc can not be nil") + } + return nil +} + +func (f aroundRootFieldFunc) InterceptRootField(ctx context.Context, next graphql.RootResolver) graphql.Marshaler { + return f(ctx, next) +} diff --git a/graphql/executor/testexecutor/testexecutor.go b/graphql/executor/testexecutor/testexecutor.go index 61aaa1b51cf..f0f28a2b49c 100644 --- a/graphql/executor/testexecutor/testexecutor.go +++ b/graphql/executor/testexecutor/testexecutor.go @@ -1,8 +1,11 @@ package testexecutor import ( + "bytes" "context" + "encoding/json" "fmt" + "io" "time" "github.com/99designs/gqlgen/graphql" @@ -11,6 +14,27 @@ import ( "github.com/vektah/gqlparser/v2/ast" ) +type MockResponse struct { + Name string `json:"name"` +} + +func (mr *MockResponse) UnmarshalGQL(v interface{}) error { + return nil +} + +func (mr *MockResponse) MarshalGQL(w io.Writer) { + buf := new(bytes.Buffer) + err := json.NewEncoder(buf).Encode(mr) + + if err != nil { + panic(err) + } + + ba := bytes.NewBuffer(bytes.TrimRight(buf.Bytes(), "\n")) + + fmt.Fprint(w, ba) +} + // New provides a server for use in tests that isn't relying on generated code. It isnt a perfect reproduction of // a generated server, but it aims to be good enough to test the handler package without relying on codegen. func New() *TestExecutor { @@ -55,13 +79,23 @@ func New() *TestExecutor { }, }, }) - res, err := graphql.GetOperationContext(ctx).ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return &graphql.Response{Data: []byte(`{"name":"test"}`)}, nil + data := graphql.GetOperationContext(ctx).RootResolverMiddleware(ctx, func(ctx context.Context) graphql.Marshaler { + res, err := graphql.GetOperationContext(ctx).ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + // return &graphql.Response{Data: []byte(`{"name":"test"}`)}, nil + return &MockResponse{Name: "test"}, nil + }) + + if err != nil { + panic(err) + } + + return res.(*MockResponse) }) - if err != nil { - panic(err) - } - return res.(*graphql.Response) + + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{Data: buf.Bytes()} } case ast.Mutation: return graphql.OneShot(graphql.ErrorResponse(ctx, "mutations are not supported")) diff --git a/graphql/handler.go b/graphql/handler.go index e74af2f039a..921165978c2 100644 --- a/graphql/handler.go +++ b/graphql/handler.go @@ -19,6 +19,9 @@ type ( Resolver func(ctx context.Context) (res interface{}, err error) FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error) + RootResolver func(ctx context.Context) Marshaler + RootFieldMiddleware func(ctx context.Context, next RootResolver) Marshaler + RawParams struct { Query string `json:"query"` OperationName string `json:"operationName"` @@ -76,6 +79,10 @@ type ( InterceptResponse(ctx context.Context, next ResponseHandler) *Response } + RootFieldInterceptor interface { + InterceptRootField(ctx context.Context, next RootResolver) Marshaler + } + // FieldInterceptor called around each field FieldInterceptor interface { InterceptField(ctx context.Context, next Resolver) (res interface{}, err error) diff --git a/graphql/handler/server.go b/graphql/handler/server.go index 640b2781ce3..69530bbc552 100644 --- a/graphql/handler/server.go +++ b/graphql/handler/server.go @@ -74,6 +74,11 @@ func (s *Server) AroundFields(f graphql.FieldMiddleware) { s.exec.AroundFields(f) } +// AroundRootFields is a convenience method for creating an extension that only implements field middleware +func (s *Server) AroundRootFields(f graphql.RootFieldMiddleware) { + s.exec.AroundRootFields(f) +} + // AroundOperations is a convenience method for creating an extension that only implements operation middleware func (s *Server) AroundOperations(f graphql.OperationMiddleware) { s.exec.AroundOperations(f) diff --git a/integration/generated.go b/integration/generated.go index ab711d2d507..dca5b6006ee 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -2104,7 +2104,6 @@ var elementImplementors = []string{"Element"} func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, obj *models.Element) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, elementImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2113,7 +2112,8 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, out.Values[i] = graphql.MarshalString("Element") case "child": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2124,10 +2124,16 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "error": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2138,10 +2144,16 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) case "mismatched": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2149,6 +2161,11 @@ func (ec *executionContext) _Element(ctx context.Context, sel ast.SelectionSet, }() res = ec._Element_mismatched(ctx, field, obj) return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2165,7 +2182,6 @@ var queryImplementors = []string{"Query"} func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ Object: "Query", }) @@ -2173,12 +2189,18 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Query") case "path": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2186,10 +2208,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_path(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "date": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2200,10 +2231,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "viewer": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2211,10 +2251,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr }() res = ec._Query_viewer(ctx, field) return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "jsonEncoding": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2225,10 +2274,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "error": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2239,10 +2297,19 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "complexity": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2253,11 +2320,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr atomic.AddUint32(&invalids, 1) } return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) }) case "__type": - out.Values[i] = ec._Query___type(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + case "__schema": - out.Values[i] = ec._Query___schema(ctx, field) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2273,7 +2358,6 @@ var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *remote_api.User) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2281,13 +2365,19 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj case "__typename": out.Values[i] = graphql.MarshalString("User") case "name": - out.Values[i] = ec._User_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } case "likes": field := field - out.Concurrently(i, func() (res graphql.Marshaler) { + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -2298,6 +2388,11 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj atomic.AddUint32(&invalids, 1) } return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + }) default: panic("unknown field " + strconv.Quote(field.Name)) @@ -2314,7 +2409,6 @@ var viewerImplementors = []string{"Viewer"} func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, obj *models.Viewer) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, viewerImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2322,7 +2416,12 @@ func (ec *executionContext) _Viewer(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("Viewer") case "user": - out.Values[i] = ec._Viewer_user(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Viewer_user(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2338,7 +2437,6 @@ var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2346,24 +2444,49 @@ func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__Directive") case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2382,7 +2505,6 @@ var __EnumValueImplementors = []string{"__EnumValue"} func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2390,19 +2512,39 @@ func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionS case "__typename": out.Values[i] = graphql.MarshalString("__EnumValue") case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2418,7 +2560,6 @@ var __FieldImplementors = []string{"__Field"} func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2426,29 +2567,59 @@ func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Field") case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2464,7 +2635,6 @@ var __InputValueImplementors = []string{"__InputValue"} func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2472,19 +2642,39 @@ func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.Selection case "__typename": out.Values[i] = graphql.MarshalString("__InputValue") case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2500,7 +2690,6 @@ var __SchemaImplementors = []string{"__Schema"} func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2508,21 +2697,46 @@ func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, case "__typename": out.Values[i] = graphql.MarshalString("__Schema") case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2541,7 +2755,6 @@ var __TypeImplementors = []string{"__Type"} func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - out := graphql.NewFieldSet(fields) var invalids uint32 for i, field := range fields { @@ -2549,26 +2762,71 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o case "__typename": out.Values[i] = graphql.MarshalString("__Type") case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } From 129783590c9cb8c709a2b0e9cbb7b69f022ee78a Mon Sep 17 00:00:00 2001 From: Alex Sonneveld Date: Fri, 15 Oct 2021 21:40:03 +1100 Subject: [PATCH 140/146] Update GQLgen test client to work with multipart form data (take 2) (#1661) * Update GQLgen test client to work with multipart form data Update the GQLgen to support multipart form data, like those present within the fileupload examples. - Add missing space between "unsupported encoding " and failing content-type header error (cherry picked from commit 101842f73fb79b10c1299bb40506080e08543ec6) * Add WithFiles client option for fileupload GQLgen client tests Add a `WithFiles` GQLgen client option to support the fileupload input within tests, using the core Golang `os` package and File type, which converts `os.File`s to their appropriate multipart form data within a request. - If there are no files this should just simply convert a `application/json` Content-Type to supported `multipart/form-data` (cherry picked from commit 08ef942416c98a2cadf61223308a3ff3c879d1c9) * Update fileupload test to use GQLgen test client Update the fileupload test to use the GQLgen test client and `WithFiles` option to remove the need for `createUploadRequest` helper with raw http posts - Fix setting the Content Type by using the appropriate `http` package function to dectect it + https://godoc.org/net/http#DetectContentType (cherry picked from commit 5e573d51440eba9d457adb4186772577b28ef085) * Update WithFiles option test with multipart Reader (cherry picked from commit 6dfa3cbe0647138e80a59a0c1d55dd9c900f96f2) * Update file upload tests `WithFiles` option Update the file upload tests to use the GQL test client and its `WithFiles` option to remove the need for a custom raw HTTP post request builder `createUploadRequest`. - Also update `WithFiles` option to group & map identical files; e.g. ``` { "0": ["variables.req.0.file", "variables.req.1.file"] } ``` (cherry picked from commit 486d9f1b2b200701f9ce6b386736a633547c1441) * Make sure `WithFiles` does not add duplicates to multipart form data (cherry picked from commit 0c2364d8495553051d97ab805618b006fcd9eddb) * Fix use of byte vs string in `WithFiles` tests (cherry picked from commit ba10b5b1c52a74e63e825ee57c235254e8821e0d) * Fix strict withFiles option test for race conditions Fix a problem with how strict the test's expected response was for tests with files in their request, since it always expected a strict order of files input that is somewhat random or dependent on what OS it is running the test on and/or race condition --- client/client.go | 10 +- client/client_test.go | 41 ++++ client/withfilesoption.go | 133 +++++++++++++ client/withfilesoption_test.go | 237 ++++++++++++++++++++++ example/fileupload/fileupload_test.go | 274 +++++++++++--------------- 5 files changed, 538 insertions(+), 157 deletions(-) create mode 100644 client/withfilesoption.go create mode 100644 client/withfilesoption_test.go diff --git a/client/client.go b/client/client.go index 7a2825c952b..e29c5fe5b3d 100644 --- a/client/client.go +++ b/client/client.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "regexp" "github.com/mitchellh/mapstructure" ) @@ -120,15 +121,18 @@ func (p *Client) newRequest(query string, options ...Option) (*http.Request, err option(bd) } - switch bd.HTTP.Header.Get("Content-Type") { - case "application/json": + contentType := bd.HTTP.Header.Get("Content-Type") + switch { + case regexp.MustCompile(`multipart/form-data; ?boundary=.*`).MatchString(contentType): + break + case "application/json" == contentType: requestBody, err := json.Marshal(bd) if err != nil { return nil, fmt.Errorf("encode: %w", err) } bd.HTTP.Body = ioutil.NopCloser(bytes.NewBuffer(requestBody)) default: - panic("unsupported encoding" + bd.HTTP.Header.Get("Content-Type")) + panic("unsupported encoding " + bd.HTTP.Header.Get("Content-Type")) } return bd.HTTP, nil diff --git a/client/client_test.go b/client/client_test.go index 569151cd8a2..176c48d12ae 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,9 +1,12 @@ package client_test import ( + "bytes" "encoding/json" "io/ioutil" + "mime/multipart" "net/http" + "net/textproto" "testing" "github.com/99designs/gqlgen/client" @@ -39,6 +42,44 @@ func TestClient(t *testing.T) { require.Equal(t, "bob", resp.Name) } +func TestClientMultipartFormData(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + bodyBytes, err := ioutil.ReadAll(r.Body) + require.NoError(t, err) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="operations"`) + require.Contains(t, string(bodyBytes), `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="map"`) + require.Contains(t, string(bodyBytes), `{"0":["variables.file"]}`) + require.Contains(t, string(bodyBytes), `Content-Disposition: form-data; name="0"; filename="example.txt"`) + require.Contains(t, string(bodyBytes), `Content-Type: text/plain`) + require.Contains(t, string(bodyBytes), `Hello World`) + + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + func(bd *client.Request) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + bodyWriter.WriteField("operations", `{"query":"mutation ($input: Input!) {}","variables":{"file":{}}`) + bodyWriter.WriteField("map", `{"0":["variables.file"]}`) + + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", `form-data; name="0"; filename="example.txt"`) + h.Set("Content-Type", "text/plain") + ff, _ := bodyWriter.CreatePart(h) + ff.Write([]byte("Hello World")) + bodyWriter.Close() + + bd.HTTP.Body = ioutil.NopCloser(bodyBuf) + bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) + }, + ) +} + func TestAddHeader(t *testing.T) { h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "ASDF", r.Header.Get("Test-Key")) diff --git a/client/withfilesoption.go b/client/withfilesoption.go new file mode 100644 index 00000000000..eff0d1c25f3 --- /dev/null +++ b/client/withfilesoption.go @@ -0,0 +1,133 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "mime/multipart" + "net/http" + "net/textproto" + "os" + "strings" +) + +type fileFormDataMap struct { + mapKey string + file *os.File +} + +func findFiles(parentMapKey string, variables map[string]interface{}) []*fileFormDataMap { + files := []*fileFormDataMap{} + for key, value := range variables { + if v, ok := value.(map[string]interface{}); ok { + files = append(files, findFiles(parentMapKey+"."+key, v)...) + } else if v, ok := value.([]map[string]interface{}); ok { + for i, arr := range v { + files = append(files, findFiles(fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), arr)...) + } + } else if v, ok := value.([]*os.File); ok { + for i, file := range v { + files = append(files, &fileFormDataMap{ + mapKey: fmt.Sprintf(`%s.%s.%d`, parentMapKey, key, i), + file: file, + }) + } + } else if v, ok := value.(*os.File); ok { + files = append(files, &fileFormDataMap{ + mapKey: parentMapKey + "." + key, + file: v, + }) + } + } + + return files +} + +// WithFiles encodes the outgoing request body as multipart form data for file variables +func WithFiles() Option { + return func(bd *Request) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + + //-b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="operations" + // + // {"query":"mutation ($input: Input!) {}","variables":{"input":{"file":{}}} + requestBody, _ := json.Marshal(bd) + bodyWriter.WriteField("operations", string(requestBody)) + + // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="map" + // + // `{ "0":["variables.input.file"] }` + // or + // `{ "0":["variables.input.files.0"], "1":["variables.input.files.1"] }` + // or + // `{ "0": ["variables.input.0.file"], "1": ["variables.input.1.file"] }` + // or + // `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` + mapData := "" + filesData := findFiles("variables", bd.Variables) + filesGroup := [][]*fileFormDataMap{} + for _, fd := range filesData { + foundDuplicate := false + for j, fg := range filesGroup { + f1, _ := fd.file.Stat() + f2, _ := fg[0].file.Stat() + if os.SameFile(f1, f2) { + foundDuplicate = true + filesGroup[j] = append(filesGroup[j], fd) + } + } + + if !foundDuplicate { + filesGroup = append(filesGroup, []*fileFormDataMap{fd}) + } + } + if len(filesGroup) > 0 { + mapDataFiles := []string{} + + for i, fileData := range filesGroup { + mapDataFiles = append( + mapDataFiles, + fmt.Sprintf(`"%d":[%s]`, i, strings.Join(collect(fileData, wrapMapKeyInQuotes), ",")), + ) + } + + mapData = `{` + strings.Join(mapDataFiles, ",") + `}` + } + bodyWriter.WriteField("map", mapData) + + // --b7955bd2e1d17b67ac157b9e9ddb6238888caefc6f3541920a1debad284d + // Content-Disposition: form-data; name="0"; filename="tempFile" + // Content-Type: text/plain; charset=utf-8 + // or + // Content-Type: application/octet-stream + // + for i, fileData := range filesGroup { + h := make(textproto.MIMEHeader) + h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%d"; filename="%s"`, i, fileData[0].file.Name())) + b, _ := ioutil.ReadFile(fileData[0].file.Name()) + h.Set("Content-Type", http.DetectContentType(b)) + ff, _ := bodyWriter.CreatePart(h) + ff.Write(b) + } + bodyWriter.Close() + + bd.HTTP.Body = ioutil.NopCloser(bodyBuf) + bd.HTTP.Header.Set("Content-Type", bodyWriter.FormDataContentType()) + } +} + +func collect(strArr []*fileFormDataMap, f func(s *fileFormDataMap) string) []string { + result := make([]string, len(strArr)) + for i, str := range strArr { + result[i] = f(str) + } + return result +} + +func wrapMapKeyInQuotes(s *fileFormDataMap) string { + return fmt.Sprintf("\"%s\"", s.mapKey) +} diff --git a/client/withfilesoption_test.go b/client/withfilesoption_test.go new file mode 100644 index 00000000000..48b9e09d0c4 --- /dev/null +++ b/client/withfilesoption_test.go @@ -0,0 +1,237 @@ +package client_test + +import ( + "io" + "io/ioutil" + "mime" + "mime/multipart" + "net/http" + "os" + "regexp" + "strings" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/stretchr/testify/require" +) + +func TestWithFiles(t *testing.T) { + tempFile1, _ := ioutil.TempFile(os.TempDir(), "tempFile1") + tempFile2, _ := ioutil.TempFile(os.TempDir(), "tempFile2") + tempFile3, _ := ioutil.TempFile(os.TempDir(), "tempFile3") + defer os.Remove(tempFile1.Name()) + defer os.Remove(tempFile2.Name()) + defer os.Remove(tempFile3.Name()) + tempFile1.WriteString(`The quick brown fox jumps over the lazy dog`) + tempFile2.WriteString(`hello world`) + tempFile3.WriteString(`La-Li-Lu-Le-Lo`) + + t.Run("with one file", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + + if contentDisposition == `form-data; name="operations"` { + require.EqualValues(t, `{"query":"{ id }","variables":{"file":{}}}`, slurp) + } + if contentDisposition == `form-data; name="map"` { + require.EqualValues(t, `{"0":["variables.file"]}`, slurp) + } + if regexp.MustCompile(`form-data; name="0"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.EqualValues(t, `The quick brown fox jumps over the lazy dog`, slurp) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("file", tempFile1), + client.WithFiles(), + ) + }) + + t.Run("with multiple files", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + + if contentDisposition == `form-data; name="operations"` { + require.EqualValues(t, `{"query":"{ id }","variables":{"input":{"files":[{},{}]}}}`, slurp) + } + if contentDisposition == `form-data; name="map"` { + // returns `{"0":["variables.input.files.0"],"1":["variables.input.files.1"]}` + // but the order of file inputs is unpredictable between different OS systems + require.Contains(t, string(slurp), `{"0":`) + require.Contains(t, string(slurp), `["variables.input.files.0"]`) + require.Contains(t, string(slurp), `,"1":`) + require.Contains(t, string(slurp), `["variables.input.files.1"]`) + require.Contains(t, string(slurp), `}`) + } + if regexp.MustCompile(`form-data; name="[0,1]"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Contains(t, []string{ + `The quick brown fox jumps over the lazy dog`, + `hello world`, + }, string(slurp)) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("input", map[string]interface{}{ + "files": []*os.File{tempFile1, tempFile2}, + }), + client.WithFiles(), + ) + }) + + t.Run("with multiple files across multiple variables", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + + if contentDisposition == `form-data; name="operations"` { + require.EqualValues(t, `{"query":"{ id }","variables":{"req":{"files":[{},{}],"foo":{"bar":{}}}}}`, slurp) + } + if contentDisposition == `form-data; name="map"` { + // returns `{"0":["variables.req.files.0"],"1":["variables.req.files.1"],"2":["variables.req.foo.bar"]}` + // but the order of file inputs is unpredictable between different OS systems + require.Contains(t, string(slurp), `{"0":`) + require.Contains(t, string(slurp), `["variables.req.files.0"]`) + require.Contains(t, string(slurp), `,"1":`) + require.Contains(t, string(slurp), `["variables.req.files.1"]`) + require.Contains(t, string(slurp), `,"2":`) + require.Contains(t, string(slurp), `["variables.req.foo.bar"]`) + require.Contains(t, string(slurp), `}`) + } + if regexp.MustCompile(`form-data; name="[0,1,2]"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Contains(t, []string{ + `The quick brown fox jumps over the lazy dog`, + `La-Li-Lu-Le-Lo`, + `hello world`, + }, string(slurp)) + } + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("req", map[string]interface{}{ + "files": []*os.File{tempFile1, tempFile2}, + "foo": map[string]interface{}{ + "bar": tempFile3, + }, + }), + client.WithFiles(), + ) + }) + + t.Run("with multiple files and file reuse", func(t *testing.T) { + h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mediaType, params, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + require.NoError(t, err) + require.True(t, strings.HasPrefix(mediaType, "multipart/")) + + mr := multipart.NewReader(r.Body, params["boundary"]) + for { + p, err := mr.NextPart() + if err == io.EOF { + break + } + require.NoError(t, err) + + slurp, err := ioutil.ReadAll(p) + require.NoError(t, err) + + contentDisposition := p.Header.Get("Content-Disposition") + + if contentDisposition == `form-data; name="operations"` { + require.EqualValues(t, `{"query":"{ id }","variables":{"files":[{},{},{}]}}`, slurp) + } + if contentDisposition == `form-data; name="map"` { + require.EqualValues(t, `{"0":["variables.files.0","variables.files.2"],"1":["variables.files.1"]}`, slurp) + // returns `{"0":["variables.files.0","variables.files.2"],"1":["variables.files.1"]}` + // but the order of file inputs is unpredictable between different OS systems + require.Contains(t, string(slurp), `{"0":`) + require.Contains(t, string(slurp), `["variables.files.0"`) + require.Contains(t, string(slurp), `,"1":`) + require.Contains(t, string(slurp), `"variables.files.1"]`) + require.Contains(t, string(slurp), `"variables.files.2"]`) + require.NotContains(t, string(slurp), `,"2":`) + require.Contains(t, string(slurp), `}`) + } + if regexp.MustCompile(`form-data; name="[0,1]"; filename=.*`).MatchString(contentDisposition) { + require.Equal(t, `text/plain; charset=utf-8`, p.Header.Get("Content-Type")) + require.Contains(t, []string{ + `The quick brown fox jumps over the lazy dog`, + `hello world`, + }, string(slurp)) + } + require.False(t, regexp.MustCompile(`form-data; name="2"; filename=.*`).MatchString(contentDisposition)) + } + w.Write([]byte(`{}`)) + }) + + c := client.New(h) + + var resp struct{} + c.MustPost("{ id }", &resp, + client.Var("files", []*os.File{tempFile1, tempFile2, tempFile1}), + client.WithFiles(), + ) + }) +} diff --git a/example/fileupload/fileupload_test.go b/example/fileupload/fileupload_test.go index 8d68252e009..0973e56ed97 100644 --- a/example/fileupload/fileupload_test.go +++ b/example/fileupload/fileupload_test.go @@ -2,17 +2,14 @@ package fileupload import ( - "bytes" "context" - "fmt" "io" "io/ioutil" - "mime/multipart" - "net/http" "net/http/httptest" - "net/textproto" + "os" "testing" + gqlclient "github.com/99designs/gqlgen/client" "github.com/99designs/gqlgen/example/fileupload/model" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/handler" @@ -21,10 +18,23 @@ import ( ) func TestFileUpload(t *testing.T) { - client := http.Client{} + resolver := &Stub{} + srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) + defer srv.Close() + gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) + + aTxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") + defer os.Remove(aTxtFile.Name()) + aTxtFile.WriteString(`test`) + + a1TxtFile, _ := ioutil.TempFile(os.TempDir(), "a.txt") + b1TxtFile, _ := ioutil.TempFile(os.TempDir(), "b.txt") + defer os.Remove(a1TxtFile.Name()) + defer os.Remove(b1TxtFile.Name()) + a1TxtFile.WriteString(`test1`) + b1TxtFile.WriteString(`test2`) t.Run("valid single file upload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.SingleUpload = func(ctx context.Context, file graphql.Upload) (*model.File, error) { require.NotNil(t, file) require.NotNil(t, file.File) @@ -39,34 +49,28 @@ func TestFileUpload(t *testing.T) { ContentType: file.ContentType, }, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id, name, content, contentType } }", "variables": { "file": null } }` - mapData := `{ "0": ["variables.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test", - contentType: "text/plain", - }, + mutation := `mutation ($file: Upload!) { + singleUpload(file: $file) { + id + name + content + contentType + } + }` + var result struct { + SingleUpload *model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - responseString := string(responseBody) - require.Equal(t, `{"data":{"singleUpload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, responseString) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("file", aTxtFile), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.SingleUpload.ID) + require.Contains(t, result.SingleUpload.Name, "a.txt") + require.Equal(t, "test", result.SingleUpload.Content) + require.Equal(t, "text/plain; charset=utf-8", result.SingleUpload.ContentType) }) t.Run("valid single file upload with payload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.SingleUploadWithPayload = func(ctx context.Context, req model.UploadFile) (*model.File, error) { require.Equal(t, req.ID, 1) require.NotNil(t, req.File) @@ -82,33 +86,28 @@ func TestFileUpload(t *testing.T) { ContentType: req.File.ContentType, }, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation ($req: UploadFile!) { singleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": {"file": null, "id": 1 } } }` - mapData := `{ "0": ["variables.req.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test", - contentType: "text/plain", - }, + mutation := `mutation ($req: UploadFile!) { + singleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + SingleUploadWithPayload *model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"singleUploadWithPayload":{"id":1,"name":"a.txt","content":"test","contentType":"text/plain"}}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("req", map[string]interface{}{"id": 1, "file": aTxtFile}), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.SingleUploadWithPayload.ID) + require.Contains(t, result.SingleUploadWithPayload.Name, "a.txt") + require.Equal(t, "test", result.SingleUploadWithPayload.Content) + require.Equal(t, "text/plain; charset=utf-8", result.SingleUploadWithPayload.ContentType) }) t.Run("valid file list upload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.MultipleUpload = func(ctx context.Context, files []*graphql.Upload) ([]*model.File, error) { require.Len(t, files, 2) var contents []string @@ -128,39 +127,35 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id, name, content, contentType } }", "variables": { "files": [null, null] } }` - mapData := `{ "0": ["variables.files.0"], "1": ["variables.files.1"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - { - mapKey: "1", - name: "b.txt", - content: "test2", - contentType: "text/plain", - }, + mutation := `mutation($files: [Upload!]!) { + multipleUpload(files: $files) { + id + name + content + contentType + } + }` + var result struct { + MultipleUpload []*model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUpload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("files", []*os.File{a1TxtFile, b1TxtFile}), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUpload[0].ID) + require.Equal(t, 2, result.MultipleUpload[1].ID) + for _, mu := range result.MultipleUpload { + if mu.Name == "a.txt" { + require.Equal(t, "test1", mu.Content) + } + if mu.Name == "b.txt" { + require.Equal(t, "test2", mu.Content) + } + require.Equal(t, "text/plain; charset=utf-8", mu.ContentType) + } }) t.Run("valid file list upload with payload", func(t *testing.T) { - resolver := &Stub{} resolver.MutationResolver.MultipleUploadWithPayload = func(ctx context.Context, req []*model.UploadFile) ([]*model.File, error) { require.Len(t, req, 2) var ids []int @@ -184,35 +179,35 @@ func TestFileUpload(t *testing.T) { require.ElementsMatch(t, []string{"test1", "test2"}, contents) return resp, nil } - srv := httptest.NewServer(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolver}))) - defer srv.Close() - operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` - mapData := `{ "0": ["variables.req.0.file"], "1": ["variables.req.1.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - { - mapKey: "1", - name: "b.txt", - content: "test2", - contentType: "text/plain", - }, + mutation := `mutation($req: [UploadFile!]!) { + multipleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + MultipleUploadWithPayload []*model.File } - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"b.txt","content":"test2","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ + {"id": 1, "file": a1TxtFile}, + {"id": 2, "file": b1TxtFile}, + }), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) + require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) + for _, mu := range result.MultipleUploadWithPayload { + if mu.Name == "a.txt" { + require.Equal(t, "test1", mu.Content) + } + if mu.Name == "b.txt" { + require.Equal(t, "test2", mu.Content) + } + require.Equal(t, "text/plain; charset=utf-8", mu.ContentType) + } }) t.Run("valid file list upload with payload and file reuse", func(t *testing.T) { @@ -252,32 +247,39 @@ func TestFileUpload(t *testing.T) { return resp, nil } - operations := `{ "query": "mutation($req: [UploadFile!]!) { multipleUploadWithPayload(req: $req) { id, name, content, contentType } }", "variables": { "req": [ { "id": 1, "file": null }, { "id": 2, "file": null } ] } }` - mapData := `{ "0": ["variables.req.0.file", "variables.req.1.file"] }` - files := []file{ - { - mapKey: "0", - name: "a.txt", - content: "test1", - contentType: "text/plain", - }, - } - test := func(uploadMaxMemory int64) { hndlr := handler.New(NewExecutableSchema(Config{Resolvers: resolver})) hndlr.AddTransport(transport.MultipartForm{MaxMemory: uploadMaxMemory}) srv := httptest.NewServer(hndlr) defer srv.Close() - req := createUploadRequest(t, srv.URL, operations, mapData, files) - resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusOK, resp.StatusCode) - responseBody, err := ioutil.ReadAll(resp.Body) - require.Nil(t, err) - require.Equal(t, `{"data":{"multipleUploadWithPayload":[{"id":1,"name":"a.txt","content":"test1","contentType":"text/plain"},{"id":2,"name":"a.txt","content":"test1","contentType":"text/plain"}]}}`, string(responseBody)) - err = resp.Body.Close() + gql := gqlclient.New(srv.Config.Handler, gqlclient.Path("/graphql")) + + mutation := `mutation($req: [UploadFile!]!) { + multipleUploadWithPayload(req: $req) { + id + name + content + contentType + } + }` + var result struct { + MultipleUploadWithPayload []*model.File + } + + err := gql.Post(mutation, &result, gqlclient.Var("req", []map[string]interface{}{ + {"id": 1, "file": a1TxtFile}, + {"id": 2, "file": a1TxtFile}, + }), gqlclient.WithFiles()) require.Nil(t, err) + require.Equal(t, 1, result.MultipleUploadWithPayload[0].ID) + require.Contains(t, result.MultipleUploadWithPayload[0].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUploadWithPayload[0].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[0].ContentType) + require.Equal(t, 2, result.MultipleUploadWithPayload[1].ID) + require.Contains(t, result.MultipleUploadWithPayload[1].Name, "a.txt") + require.Equal(t, "test1", result.MultipleUploadWithPayload[1].Content) + require.Equal(t, "text/plain; charset=utf-8", result.MultipleUploadWithPayload[1].ContentType) } t.Run("payload smaller than UploadMaxMemory, stored in memory", func(t *testing.T) { @@ -289,39 +291,3 @@ func TestFileUpload(t *testing.T) { }) }) } - -type file struct { - mapKey string - name string - content string - contentType string -} - -func createUploadRequest(t *testing.T, url, operations, mapData string, files []file) *http.Request { - bodyBuf := &bytes.Buffer{} - bodyWriter := multipart.NewWriter(bodyBuf) - - err := bodyWriter.WriteField("operations", operations) - require.NoError(t, err) - - err = bodyWriter.WriteField("map", mapData) - require.NoError(t, err) - - for i := range files { - h := make(textproto.MIMEHeader) - h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"; filename="%s"`, files[i].mapKey, files[i].name)) - h.Set("Content-Type", files[i].contentType) - ff, err := bodyWriter.CreatePart(h) - require.NoError(t, err) - _, err = ff.Write([]byte(files[i].content)) - require.NoError(t, err) - } - err = bodyWriter.Close() - require.NoError(t, err) - - req, err := http.NewRequest("POST", fmt.Sprintf("%s/graphql", url), bodyBuf) - require.NoError(t, err) - - req.Header.Set("Content-Type", bodyWriter.FormDataContentType()) - return req -} From 1f500016aedcb9bc35eb9964b55730efe966ef5e Mon Sep 17 00:00:00 2001 From: Kevin Beaulieu Date: Fri, 15 Oct 2021 04:08:50 -0700 Subject: [PATCH 141/146] Add follow-schema layout for exec (#1309) * Define ExecConfig separate from PackageConfig When support for writing generated code to a directory instead of a single file is added, ExecConfig will need additional fields that will not be relevant to other users of PackageConfig. * Add single-file, follow-schema layouts When `ExecLayout` is set to `follow-schema`, output generated code to a directory instead of a single file. Each file in the output directory will correspond to a single *.graphql schema file (plus a root!.generated.go file containing top-level definitions that are not specific to a single schema file). `ExecLayout` defaults to `single-file`, which is the current behavior, so this new functionality is opt-in. These layouts expose similar functionality to the `ResolverLayout`s with the same name, just applied to `exec` instead of `resolver`. Resolves issue #1265. * Rebase, regenerate Signed-off-by: Steve Coffman Co-authored-by: Steve Coffman --- codegen/args.go | 2 +- codegen/config/config.go | 4 +- codegen/config/config_test.go | 74 +- codegen/config/exec.go | 97 + codegen/data.go | 34 +- codegen/data_test.go | 68 + codegen/field.gotpl | 2 +- codegen/generate.go | 198 + codegen/generated!.gotpl | 314 +- codegen/root_.gotpl | 201 + codegen/templates/templates.go | 4 + codegen/testserver/empty.go | 3 + .../followschema/builtinscalar.generated.go | 106 + .../{ => followschema}/builtinscalar.graphql | 0 codegen/testserver/followschema/bytes.go | 27 + .../followschema/complexity.generated.go | 296 + .../{ => followschema}/complexity.graphql | 0 .../followschema/complexity_test.go | 119 + .../followschema/defaults.generated.go | 421 ++ .../{ => followschema}/defaults.graphql | 0 .../testserver/followschema/defaults_test.go | 68 + .../followschema/directive.generated.go | 707 ++ .../{ => followschema}/directive.graphql | 0 .../testserver/followschema/directive_test.go | 465 ++ .../followschema/embedded.generated.go | 253 + codegen/testserver/followschema/embedded.go | 43 + .../testserver/followschema/embedded.graphql | 17 + .../testserver/followschema/embedded_test.go | 66 + .../testserver/followschema/enum.generated.go | 83 + .../{ => followschema}/enum.graphql | 0 codegen/testserver/followschema/enums_test.go | 52 + .../testserver/followschema/generated_test.go | 80 + codegen/testserver/followschema/gqlgen.yml | 24 + codegen/testserver/followschema/input_test.go | 69 + .../followschema/interfaces.generated.go | 1060 +++ codegen/testserver/followschema/interfaces.go | 84 + .../followschema/interfaces.graphql | 62 + .../followschema/interfaces_test.go | 200 + .../{ => followschema}/introspection/it.go | 0 .../followschema/introspection_test.go | 79 + .../invalid-packagename/invalid-identifier.go | 0 .../followschema/issue896.generated.go | 206 + .../{ => followschema}/issue896.graphql | 0 .../followschema/loops.generated.go | 189 + .../{ => followschema}/loops.graphql | 0 .../testserver/followschema/maps.generated.go | 200 + .../{ => followschema}/maps.graphql | 0 codegen/testserver/followschema/maps_test.go | 73 + .../followschema/middleware_test.go | 110 + .../followschema/modelmethod_test.go | 44 + codegen/testserver/followschema/models-gen.go | 299 + codegen/testserver/followschema/models.go | 106 + .../mutation_with_custom_scalar.generated.go | 108 + .../mutation_with_custom_scalar.go | 29 + .../mutation_with_custom_scalar.graphql | 0 .../mutation_with_custom_scalar_test.go | 50 + .../followschema/nulls.generated.go | 633 ++ .../{ => followschema}/nulls.graphql | 0 codegen/testserver/followschema/nulls_test.go | 134 + .../{ => followschema}/otherpkg/model.go | 0 .../followschema/panics.generated.go | 324 + .../{ => followschema}/panics.graphql | 0 .../testserver/followschema/panics_test.go | 69 + .../followschema/prelude.generated.go | 2312 +++++++ .../primitive_objects.generated.go | 432 ++ .../primitive_objects.graphql | 0 .../followschema/primitive_objects_test.go | 73 + .../ptr_to_ptr_input.generated.go | 513 ++ .../followschema/ptr_to_ptr_input.go | 23 + .../ptr_to_ptr_input.graphql | 0 .../followschema/ptr_to_ptr_input_test.go | 174 + .../followschema/ptr_to_slice.generated.go | 114 + .../testserver/followschema/ptr_to_slice.go | 5 + .../{ => followschema}/ptr_to_slice.graphql | 0 .../followschema/ptr_to_slice_test.go | 37 + codegen/testserver/followschema/recursive.go | 5 + codegen/testserver/followschema/resolver.go | 426 ++ .../followschema/response_extension_test.go | 33 + .../followschema/root!.generated.go | 2475 +++++++ .../followschema/scalar_default.generated.go | 130 + .../{ => followschema}/scalar_default.graphql | 0 .../followschema/scalar_default_test.go | 32 + .../followschema/schema.generated.go | 6018 +++++++++++++++++ .../testserver/followschema/schema.graphql | 105 + .../followschema/slices.generated.go | 248 + .../{ => followschema}/slices.graphql | 0 .../testserver/followschema/slices_test.go | 43 + codegen/testserver/followschema/stub.go | 479 ++ .../followschema/subscription_test.go | 141 + codegen/testserver/followschema/thirdparty.go | 31 + codegen/testserver/followschema/time_test.go | 68 + .../followschema/typefallback.generated.go | 58 + .../{ => followschema}/typefallback.graphql | 0 .../followschema/typefallback_test.go | 28 + .../followschema/useptr.generated.go | 200 + .../{ => followschema}/useptr.graphql | 0 .../testserver/followschema/useptr_test.go | 14 + .../testserver/followschema/v-ok.generated.go | 179 + codegen/testserver/followschema/v-ok.go | 17 + codegen/testserver/followschema/v-ok.graphql | 12 + codegen/testserver/followschema/v-ok_test.go | 47 + .../followschema/validtypes.generated.go | 877 +++ .../{ => followschema}/validtypes.graphql | 0 .../followschema/validtypes_test.go | 36 + .../weird_type_cases.generated.go | 421 ++ .../weird_type_cases.graphql | 0 .../followschema/wrapped_type.generated.go | 407 ++ .../testserver/followschema/wrapped_type.go | 8 + .../{ => followschema}/wrapped_type.graphql | 0 .../followschema/wrapped_type_test.go | 98 + codegen/testserver/generated_test.go | 109 +- .../singlefile/builtinscalar.graphql | 8 + codegen/testserver/{ => singlefile}/bytes.go | 2 +- .../testserver/singlefile/complexity.graphql | 11 + .../{ => singlefile}/complexity_test.go | 2 +- .../testserver/singlefile/defaults.graphql | 20 + .../{ => singlefile}/defaults_test.go | 2 +- .../testserver/singlefile/directive.graphql | 54 + .../{ => singlefile}/directive_test.go | 2 +- .../testserver/{ => singlefile}/embedded.go | 2 +- .../{ => singlefile}/embedded.graphql | 6 +- .../{ => singlefile}/embedded_test.go | 2 +- codegen/testserver/singlefile/enum.graphql | 12 + .../testserver/{ => singlefile}/enums_test.go | 2 +- .../testserver/{ => singlefile}/generated.go | 478 +- .../testserver/singlefile/generated_test.go | 80 + codegen/testserver/singlefile/gqlgen.yml | 23 + .../testserver/{ => singlefile}/input_test.go | 2 +- .../testserver/{ => singlefile}/interfaces.go | 2 +- .../{ => singlefile}/interfaces.graphql | 2 +- .../{ => singlefile}/interfaces_test.go | 4 +- .../testserver/singlefile/introspection/it.go | 5 + .../{ => singlefile}/introspection_test.go | 2 +- .../invalid-packagename/invalid-identifier.go | 5 + .../testserver/singlefile/issue896.graphql | 18 + codegen/testserver/singlefile/loops.graphql | 7 + codegen/testserver/singlefile/maps.graphql | 18 + .../testserver/{ => singlefile}/maps_test.go | 2 +- .../{ => singlefile}/middleware_test.go | 2 +- .../{ => singlefile}/modelmethod_test.go | 2 +- .../testserver/{ => singlefile}/models-gen.go | 2 +- codegen/testserver/{ => singlefile}/models.go | 2 +- .../mutation_with_custom_scalar.go | 2 +- .../mutation_with_custom_scalar.graphql | 13 + .../mutation_with_custom_scalar_test.go | 2 +- codegen/testserver/singlefile/nulls.graphql | 22 + .../testserver/{ => singlefile}/nulls_test.go | 2 +- .../testserver/singlefile/otherpkg/model.go | 12 + codegen/testserver/singlefile/panics.graphql | 12 + .../{ => singlefile}/panics_test.go | 2 +- .../singlefile/primitive_objects.graphql | 15 + .../primitive_objects_test.go | 2 +- .../{ => singlefile}/ptr_to_ptr_input.go | 2 +- .../singlefile/ptr_to_ptr_input.graphql | 25 + .../{ => singlefile}/ptr_to_ptr_input_test.go | 2 +- .../{ => singlefile}/ptr_to_slice.go | 2 +- .../singlefile/ptr_to_slice.graphql | 7 + .../{ => singlefile}/ptr_to_slice_test.go | 2 +- .../testserver/{ => singlefile}/recursive.go | 2 +- .../testserver/{ => singlefile}/resolver.go | 8 +- .../response_extension_test.go | 2 +- .../singlefile/scalar_default.graphql | 10 + .../{ => singlefile}/scalar_default_test.go | 2 +- .../{ => singlefile}/schema.graphql | 4 +- codegen/testserver/singlefile/slices.graphql | 13 + .../{ => singlefile}/slices_test.go | 2 +- codegen/testserver/{ => singlefile}/stub.go | 8 +- .../{ => singlefile}/subscription_test.go | 2 +- .../testserver/{ => singlefile}/thirdparty.go | 2 +- .../testserver/{ => singlefile}/time_test.go | 2 +- .../singlefile/typefallback.graphql | 9 + .../{ => singlefile}/typefallback_test.go | 2 +- codegen/testserver/singlefile/useptr.graphql | 13 + .../{ => singlefile}/useptr_test.go | 2 +- codegen/testserver/{ => singlefile}/v-ok.go | 2 +- codegen/testserver/singlefile/v-ok.graphql | 12 + .../testserver/{ => singlefile}/v-ok_test.go | 2 +- .../testserver/singlefile/validtypes.graphql | 78 + .../{ => singlefile}/validtypes_test.go | 2 +- .../singlefile/weird_type_cases.graphql | 8 + .../{ => singlefile}/wrapped_type.go | 4 +- .../singlefile/wrapped_type.graphql | 13 + .../{ => singlefile}/wrapped_type_test.go | 4 +- codegen/testserver/v-ok.graphql | 12 - docs/content/config.md | 3 +- example/go.sum | 1 + go.mod | 1 + go.sum | 2 + testdata/gqlgen.go | 12 +- 189 files changed, 24954 insertions(+), 574 deletions(-) create mode 100644 codegen/config/exec.go create mode 100644 codegen/data_test.go create mode 100644 codegen/root_.gotpl create mode 100644 codegen/testserver/empty.go create mode 100644 codegen/testserver/followschema/builtinscalar.generated.go rename codegen/testserver/{ => followschema}/builtinscalar.graphql (100%) create mode 100644 codegen/testserver/followschema/bytes.go create mode 100644 codegen/testserver/followschema/complexity.generated.go rename codegen/testserver/{ => followschema}/complexity.graphql (100%) create mode 100644 codegen/testserver/followschema/complexity_test.go create mode 100644 codegen/testserver/followschema/defaults.generated.go rename codegen/testserver/{ => followschema}/defaults.graphql (100%) create mode 100644 codegen/testserver/followschema/defaults_test.go create mode 100644 codegen/testserver/followschema/directive.generated.go rename codegen/testserver/{ => followschema}/directive.graphql (100%) create mode 100644 codegen/testserver/followschema/directive_test.go create mode 100644 codegen/testserver/followschema/embedded.generated.go create mode 100644 codegen/testserver/followschema/embedded.go create mode 100644 codegen/testserver/followschema/embedded.graphql create mode 100644 codegen/testserver/followschema/embedded_test.go create mode 100644 codegen/testserver/followschema/enum.generated.go rename codegen/testserver/{ => followschema}/enum.graphql (100%) create mode 100644 codegen/testserver/followschema/enums_test.go create mode 100644 codegen/testserver/followschema/generated_test.go create mode 100644 codegen/testserver/followschema/gqlgen.yml create mode 100644 codegen/testserver/followschema/input_test.go create mode 100644 codegen/testserver/followschema/interfaces.generated.go create mode 100644 codegen/testserver/followschema/interfaces.go create mode 100644 codegen/testserver/followschema/interfaces.graphql create mode 100644 codegen/testserver/followschema/interfaces_test.go rename codegen/testserver/{ => followschema}/introspection/it.go (100%) create mode 100644 codegen/testserver/followschema/introspection_test.go rename codegen/testserver/{ => followschema}/invalid-packagename/invalid-identifier.go (100%) create mode 100644 codegen/testserver/followschema/issue896.generated.go rename codegen/testserver/{ => followschema}/issue896.graphql (100%) create mode 100644 codegen/testserver/followschema/loops.generated.go rename codegen/testserver/{ => followschema}/loops.graphql (100%) create mode 100644 codegen/testserver/followschema/maps.generated.go rename codegen/testserver/{ => followschema}/maps.graphql (100%) create mode 100644 codegen/testserver/followschema/maps_test.go create mode 100644 codegen/testserver/followschema/middleware_test.go create mode 100644 codegen/testserver/followschema/modelmethod_test.go create mode 100644 codegen/testserver/followschema/models-gen.go create mode 100644 codegen/testserver/followschema/models.go create mode 100644 codegen/testserver/followschema/mutation_with_custom_scalar.generated.go create mode 100644 codegen/testserver/followschema/mutation_with_custom_scalar.go rename codegen/testserver/{ => followschema}/mutation_with_custom_scalar.graphql (100%) create mode 100644 codegen/testserver/followschema/mutation_with_custom_scalar_test.go create mode 100644 codegen/testserver/followschema/nulls.generated.go rename codegen/testserver/{ => followschema}/nulls.graphql (100%) create mode 100644 codegen/testserver/followschema/nulls_test.go rename codegen/testserver/{ => followschema}/otherpkg/model.go (100%) create mode 100644 codegen/testserver/followschema/panics.generated.go rename codegen/testserver/{ => followschema}/panics.graphql (100%) create mode 100644 codegen/testserver/followschema/panics_test.go create mode 100644 codegen/testserver/followschema/prelude.generated.go create mode 100644 codegen/testserver/followschema/primitive_objects.generated.go rename codegen/testserver/{ => followschema}/primitive_objects.graphql (100%) create mode 100644 codegen/testserver/followschema/primitive_objects_test.go create mode 100644 codegen/testserver/followschema/ptr_to_ptr_input.generated.go create mode 100644 codegen/testserver/followschema/ptr_to_ptr_input.go rename codegen/testserver/{ => followschema}/ptr_to_ptr_input.graphql (100%) create mode 100644 codegen/testserver/followschema/ptr_to_ptr_input_test.go create mode 100644 codegen/testserver/followschema/ptr_to_slice.generated.go create mode 100644 codegen/testserver/followschema/ptr_to_slice.go rename codegen/testserver/{ => followschema}/ptr_to_slice.graphql (100%) create mode 100644 codegen/testserver/followschema/ptr_to_slice_test.go create mode 100644 codegen/testserver/followschema/recursive.go create mode 100644 codegen/testserver/followschema/resolver.go create mode 100644 codegen/testserver/followschema/response_extension_test.go create mode 100644 codegen/testserver/followschema/root!.generated.go create mode 100644 codegen/testserver/followschema/scalar_default.generated.go rename codegen/testserver/{ => followschema}/scalar_default.graphql (100%) create mode 100644 codegen/testserver/followschema/scalar_default_test.go create mode 100644 codegen/testserver/followschema/schema.generated.go create mode 100644 codegen/testserver/followschema/schema.graphql create mode 100644 codegen/testserver/followschema/slices.generated.go rename codegen/testserver/{ => followschema}/slices.graphql (100%) create mode 100644 codegen/testserver/followschema/slices_test.go create mode 100644 codegen/testserver/followschema/stub.go create mode 100644 codegen/testserver/followschema/subscription_test.go create mode 100644 codegen/testserver/followschema/thirdparty.go create mode 100644 codegen/testserver/followschema/time_test.go create mode 100644 codegen/testserver/followschema/typefallback.generated.go rename codegen/testserver/{ => followschema}/typefallback.graphql (100%) create mode 100644 codegen/testserver/followschema/typefallback_test.go create mode 100644 codegen/testserver/followschema/useptr.generated.go rename codegen/testserver/{ => followschema}/useptr.graphql (100%) create mode 100644 codegen/testserver/followschema/useptr_test.go create mode 100644 codegen/testserver/followschema/v-ok.generated.go create mode 100644 codegen/testserver/followschema/v-ok.go create mode 100644 codegen/testserver/followschema/v-ok.graphql create mode 100644 codegen/testserver/followschema/v-ok_test.go create mode 100644 codegen/testserver/followschema/validtypes.generated.go rename codegen/testserver/{ => followschema}/validtypes.graphql (100%) create mode 100644 codegen/testserver/followschema/validtypes_test.go create mode 100644 codegen/testserver/followschema/weird_type_cases.generated.go rename codegen/testserver/{ => followschema}/weird_type_cases.graphql (100%) create mode 100644 codegen/testserver/followschema/wrapped_type.generated.go create mode 100644 codegen/testserver/followschema/wrapped_type.go rename codegen/testserver/{ => followschema}/wrapped_type.graphql (100%) create mode 100644 codegen/testserver/followschema/wrapped_type_test.go create mode 100644 codegen/testserver/singlefile/builtinscalar.graphql rename codegen/testserver/{ => singlefile}/bytes.go (96%) create mode 100644 codegen/testserver/singlefile/complexity.graphql rename codegen/testserver/{ => singlefile}/complexity_test.go (99%) create mode 100644 codegen/testserver/singlefile/defaults.graphql rename codegen/testserver/{ => singlefile}/defaults_test.go (98%) create mode 100644 codegen/testserver/singlefile/directive.graphql rename codegen/testserver/{ => singlefile}/directive_test.go (99%) rename codegen/testserver/{ => singlefile}/embedded.go (98%) rename codegen/testserver/{ => singlefile}/embedded.graphql (60%) rename codegen/testserver/{ => singlefile}/embedded_test.go (99%) create mode 100644 codegen/testserver/singlefile/enum.graphql rename codegen/testserver/{ => singlefile}/enums_test.go (98%) rename codegen/testserver/{ => singlefile}/generated.go (94%) create mode 100644 codegen/testserver/singlefile/generated_test.go create mode 100644 codegen/testserver/singlefile/gqlgen.yml rename codegen/testserver/{ => singlefile}/input_test.go (99%) rename codegen/testserver/{ => singlefile}/interfaces.go (98%) rename codegen/testserver/{ => singlefile}/interfaces.graphql (94%) rename codegen/testserver/{ => singlefile}/interfaces_test.go (98%) create mode 100644 codegen/testserver/singlefile/introspection/it.go rename codegen/testserver/{ => singlefile}/introspection_test.go (99%) create mode 100644 codegen/testserver/singlefile/invalid-packagename/invalid-identifier.go create mode 100644 codegen/testserver/singlefile/issue896.graphql create mode 100644 codegen/testserver/singlefile/loops.graphql create mode 100644 codegen/testserver/singlefile/maps.graphql rename codegen/testserver/{ => singlefile}/maps_test.go (99%) rename codegen/testserver/{ => singlefile}/middleware_test.go (99%) rename codegen/testserver/{ => singlefile}/modelmethod_test.go (98%) rename codegen/testserver/{ => singlefile}/models-gen.go (99%) rename codegen/testserver/{ => singlefile}/models.go (98%) rename codegen/testserver/{ => singlefile}/mutation_with_custom_scalar.go (96%) create mode 100644 codegen/testserver/singlefile/mutation_with_custom_scalar.graphql rename codegen/testserver/{ => singlefile}/mutation_with_custom_scalar_test.go (98%) create mode 100644 codegen/testserver/singlefile/nulls.graphql rename codegen/testserver/{ => singlefile}/nulls_test.go (99%) create mode 100644 codegen/testserver/singlefile/otherpkg/model.go create mode 100644 codegen/testserver/singlefile/panics.graphql rename codegen/testserver/{ => singlefile}/panics_test.go (99%) create mode 100644 codegen/testserver/singlefile/primitive_objects.graphql rename codegen/testserver/{ => singlefile}/primitive_objects_test.go (99%) rename codegen/testserver/{ => singlefile}/ptr_to_ptr_input.go (95%) create mode 100644 codegen/testserver/singlefile/ptr_to_ptr_input.graphql rename codegen/testserver/{ => singlefile}/ptr_to_ptr_input_test.go (99%) rename codegen/testserver/{ => singlefile}/ptr_to_slice.go (75%) create mode 100644 codegen/testserver/singlefile/ptr_to_slice.graphql rename codegen/testserver/{ => singlefile}/ptr_to_slice_test.go (97%) rename codegen/testserver/{ => singlefile}/recursive.go (77%) rename codegen/testserver/{ => singlefile}/resolver.go (98%) rename codegen/testserver/{ => singlefile}/response_extension_test.go (97%) create mode 100644 codegen/testserver/singlefile/scalar_default.graphql rename codegen/testserver/{ => singlefile}/scalar_default_test.go (97%) rename codegen/testserver/{ => singlefile}/schema.graphql (92%) create mode 100644 codegen/testserver/singlefile/slices.graphql rename codegen/testserver/{ => singlefile}/slices_test.go (98%) rename codegen/testserver/{ => singlefile}/stub.go (99%) rename codegen/testserver/{ => singlefile}/subscription_test.go (99%) rename codegen/testserver/{ => singlefile}/thirdparty.go (96%) rename codegen/testserver/{ => singlefile}/time_test.go (98%) create mode 100644 codegen/testserver/singlefile/typefallback.graphql rename codegen/testserver/{ => singlefile}/typefallback_test.go (97%) create mode 100644 codegen/testserver/singlefile/useptr.graphql rename codegen/testserver/{ => singlefile}/useptr_test.go (92%) rename codegen/testserver/{ => singlefile}/v-ok.go (92%) create mode 100644 codegen/testserver/singlefile/v-ok.graphql rename codegen/testserver/{ => singlefile}/v-ok_test.go (98%) create mode 100644 codegen/testserver/singlefile/validtypes.graphql rename codegen/testserver/{ => singlefile}/validtypes_test.go (97%) create mode 100644 codegen/testserver/singlefile/weird_type_cases.graphql rename codegen/testserver/{ => singlefile}/wrapped_type.go (58%) create mode 100644 codegen/testserver/singlefile/wrapped_type.graphql rename codegen/testserver/{ => singlefile}/wrapped_type_test.go (96%) delete mode 100644 codegen/testserver/v-ok.graphql diff --git a/codegen/args.go b/codegen/args.go index 69af1404174..9a9c8fdbee8 100644 --- a/codegen/args.go +++ b/codegen/args.go @@ -110,7 +110,7 @@ func (a *Data) Args() map[string][]*FieldArgument { } } - for _, d := range a.Directives { + for _, d := range a.Directives() { if len(d.Args) > 0 { ret[d.ArgsFunc()] = d.Args } diff --git a/codegen/config/config.go b/codegen/config/config.go index 56bfc6090d6..d2016f4bd09 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -17,7 +17,7 @@ import ( type Config struct { SchemaFilename StringList `yaml:"schema,omitempty"` - Exec PackageConfig `yaml:"exec"` + Exec ExecConfig `yaml:"exec"` Model PackageConfig `yaml:"model,omitempty"` Federation PackageConfig `yaml:"federation,omitempty"` Resolver ResolverConfig `yaml:"resolver,omitempty"` @@ -43,7 +43,7 @@ func DefaultConfig() *Config { return &Config{ SchemaFilename: StringList{"schema.graphql"}, Model: PackageConfig{Filename: "models_gen.go"}, - Exec: PackageConfig{Filename: "generated.go"}, + Exec: ExecConfig{Filename: "generated.go"}, Directives: map[string]DirectiveConfig{}, Models: TypeMap{}, } diff --git a/codegen/config/config_test.go b/codegen/config/config_test.go index 2e7935e58d7..baa836c3ba3 100644 --- a/codegen/config/config_test.go +++ b/codegen/config/config_test.go @@ -132,41 +132,45 @@ func TestReferencedPackages(t *testing.T) { } func TestConfigCheck(t *testing.T) { - t.Run("invalid config format due to conflicting package names", func(t *testing.T) { - config := Config{ - Exec: PackageConfig{Filename: "generated/exec.go", Package: "graphql"}, - Model: PackageConfig{Filename: "generated/models.go"}, - } - - require.EqualError(t, config.check(), "exec and model define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (graphql vs generated)") - }) - - t.Run("federation must be in exec package", func(t *testing.T) { - config := Config{ - Exec: PackageConfig{Filename: "generated/exec.go"}, - Federation: PackageConfig{Filename: "anotherpkg/federation.go"}, - } - - require.EqualError(t, config.check(), "federation and exec must be in the same package") - }) - - t.Run("federation must have same package name as exec", func(t *testing.T) { - config := Config{ - Exec: PackageConfig{Filename: "generated/exec.go"}, - Federation: PackageConfig{Filename: "generated/federation.go", Package: "federation"}, - } - - require.EqualError(t, config.check(), "exec and federation define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (generated vs federation)") - }) - - t.Run("deprecated federated flag raises an error", func(t *testing.T) { - config := Config{ - Exec: PackageConfig{Filename: "generated/exec.go"}, - Federated: true, - } - - require.EqualError(t, config.check(), "federated has been removed, instead use\nfederation:\n filename: path/to/federated.go") - }) + for _, execLayout := range []ExecLayout{ExecLayoutSingleFile, ExecLayoutFollowSchema} { + t.Run(string(execLayout), func(t *testing.T) { + t.Run("invalid config format due to conflicting package names", func(t *testing.T) { + config := Config{ + Exec: ExecConfig{Layout: execLayout, Filename: "generated/exec.go", DirName: "generated", Package: "graphql"}, + Model: PackageConfig{Filename: "generated/models.go"}, + } + + require.EqualError(t, config.check(), "exec and model define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (graphql vs generated)") + }) + + t.Run("federation must be in exec package", func(t *testing.T) { + config := Config{ + Exec: ExecConfig{Layout: execLayout, Filename: "generated/exec.go", DirName: "generated"}, + Federation: PackageConfig{Filename: "anotherpkg/federation.go"}, + } + + require.EqualError(t, config.check(), "federation and exec must be in the same package") + }) + + t.Run("federation must have same package name as exec", func(t *testing.T) { + config := Config{ + Exec: ExecConfig{Layout: execLayout, Filename: "generated/exec.go", DirName: "generated"}, + Federation: PackageConfig{Filename: "generated/federation.go", Package: "federation"}, + } + + require.EqualError(t, config.check(), "exec and federation define the same import path (github.com/99designs/gqlgen/codegen/config/generated) with different package names (generated vs federation)") + }) + + t.Run("deprecated federated flag raises an error", func(t *testing.T) { + config := Config{ + Exec: ExecConfig{Layout: execLayout, Filename: "generated/exec.go", DirName: "generated"}, + Federated: true, + } + + require.EqualError(t, config.check(), "federated has been removed, instead use\nfederation:\n filename: path/to/federated.go") + }) + }) + } } func TestAutobinding(t *testing.T) { diff --git a/codegen/config/exec.go b/codegen/config/exec.go new file mode 100644 index 00000000000..fe1dccd21da --- /dev/null +++ b/codegen/config/exec.go @@ -0,0 +1,97 @@ +package config + +import ( + "fmt" + "go/types" + "path/filepath" + "strings" + + "github.com/99designs/gqlgen/internal/code" +) + +type ExecConfig struct { + Package string `yaml:"package,omitempty"` + Layout ExecLayout `yaml:"layout,omitempty"` // Default: single-file + + // Only for single-file layout: + Filename string `yaml:"filename,omitempty"` + + // Only for follow-schema layout: + FilenameTemplate string `yaml:"filename_template,omitempty"` // String template with {name} as placeholder for base name. + DirName string `yaml:"dir"` +} + +type ExecLayout string + +var ( + // Write all generated code to a single file. + ExecLayoutSingleFile ExecLayout = "single-file" + // Write generated code to a directory, generating one Go source file for each GraphQL schema file. + ExecLayoutFollowSchema ExecLayout = "follow-schema" +) + +func (r *ExecConfig) Check() error { + if r.Layout == "" { + r.Layout = ExecLayoutSingleFile + } + + switch r.Layout { + case ExecLayoutSingleFile: + if r.Filename == "" { + return fmt.Errorf("filename must be specified when using single-file layout") + } + if !strings.HasSuffix(r.Filename, ".go") { + return fmt.Errorf("filename should be path to a go source file when using single-file layout") + } + r.Filename = abs(r.Filename) + case ExecLayoutFollowSchema: + if r.DirName == "" { + return fmt.Errorf("dir must be specified when using follow-schema layout") + } + r.DirName = abs(r.DirName) + default: + return fmt.Errorf("invalid layout %s", r.Layout) + } + + if strings.ContainsAny(r.Package, "./\\") { + return fmt.Errorf("package should be the output package name only, do not include the output filename") + } + + if r.Package == "" && r.Dir() != "" { + r.Package = code.NameForDir(r.Dir()) + } + + return nil +} + +func (r *ExecConfig) ImportPath() string { + if r.Dir() == "" { + return "" + } + return code.ImportPathForDir(r.Dir()) +} + +func (r *ExecConfig) Dir() string { + switch r.Layout { + case ExecLayoutSingleFile: + if r.Filename == "" { + return "" + } + return filepath.Dir(r.Filename) + case ExecLayoutFollowSchema: + return abs(r.DirName) + default: + panic("invalid layout " + r.Layout) + } +} + +func (r *ExecConfig) Pkg() *types.Package { + if r.Dir() == "" { + return nil + } + return types.NewPackage(r.ImportPath(), r.Package) +} + +func (r *ExecConfig) IsDefined() bool { + return r.Filename != "" || r.DirName != "" +} diff --git a/codegen/data.go b/codegen/data.go index 1a92b787801..690718de3a9 100644 --- a/codegen/data.go +++ b/codegen/data.go @@ -12,9 +12,15 @@ import ( // Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement // resolvers or directives automatically (eg grpc, validation) type Data struct { - Config *config.Config - Schema *ast.Schema - Directives DirectiveList + Config *config.Config + Schema *ast.Schema + // If a schema is broken up into multiple Data instance, each representing part of the schema, + // AllDirectives should contain the directives for the entire schema. Directives() can + // then be used to get the directives that were defined in this Data instance's sources. + // If a single Data instance is used for the entire schema, AllDirectives and Directives() + // will be identical. + // AllDirectives should rarely be used directly. + AllDirectives DirectiveList Objects Objects Inputs Objects Interfaces map[string]*Interface @@ -33,6 +39,20 @@ type builder struct { Directives map[string]*Directive } +// Get only the directives which are defined in the config's sources. +func (d *Data) Directives() DirectiveList { + res := DirectiveList{} + for k, directive := range d.AllDirectives { + for _, s := range d.Config.Sources { + if directive.Position.Src.Name == s.Name { + res[k] = directive + break + } + } + } + return res +} + func BuildData(cfg *config.Config) (*Data, error) { b := builder{ Config: cfg, @@ -55,10 +75,10 @@ func BuildData(cfg *config.Config) (*Data, error) { } s := Data{ - Config: cfg, - Directives: dataDirectives, - Schema: b.Schema, - Interfaces: map[string]*Interface{}, + Config: cfg, + AllDirectives: dataDirectives, + Schema: b.Schema, + Interfaces: map[string]*Interface{}, } for _, schemaType := range b.Schema.Types { diff --git a/codegen/data_test.go b/codegen/data_test.go new file mode 100644 index 00000000000..a1ac4d3df9f --- /dev/null +++ b/codegen/data_test.go @@ -0,0 +1,68 @@ +package codegen + +import ( + "testing" + + "github.com/99designs/gqlgen/codegen/config" + "github.com/vektah/gqlparser/v2/ast" + + "github.com/stretchr/testify/assert" +) + +func TestData_Directives(t *testing.T) { + d := Data{ + Config: &config.Config{ + Sources: []*ast.Source{ + { + Name: "schema.graphql", + }, + }, + }, + AllDirectives: DirectiveList{ + "includeDirective": { + DirectiveDefinition: &ast.DirectiveDefinition{ + Name: "includeDirective", + Position: &ast.Position{ + Src: &ast.Source{ + Name: "schema.graphql", + }, + }, + }, + Name: "includeDirective", + Args: nil, + Builtin: false, + }, + "excludeDirective": { + DirectiveDefinition: &ast.DirectiveDefinition{ + Name: "excludeDirective", + Position: &ast.Position{ + Src: &ast.Source{ + Name: "anothersource.graphql", + }, + }, + }, + Name: "excludeDirective", + Args: nil, + Builtin: false, + }, + }, + } + + expected := DirectiveList{ + "includeDirective": { + DirectiveDefinition: &ast.DirectiveDefinition{ + Name: "includeDirective", + Position: &ast.Position{ + Src: &ast.Source{ + Name: "schema.graphql", + }, + }, + }, + Name: "includeDirective", + Args: nil, + Builtin: false, + }, + } + + assert.Equal(t, expected, d.Directives()) +} diff --git a/codegen/field.gotpl b/codegen/field.gotpl index 8e53772afac..0c6becaea6a 100644 --- a/codegen/field.gotpl +++ b/codegen/field.gotpl @@ -29,7 +29,7 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex } fc.Args = args {{- end }} - {{- if $.Directives.LocationDirectives "FIELD" }} + {{- if $.AllDirectives.LocationDirectives "FIELD" }} resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) { {{ template "field" $field }} }) diff --git a/codegen/generate.go b/codegen/generate.go index f1ed2ca27be..84c130a2e8f 100644 --- a/codegen/generate.go +++ b/codegen/generate.go @@ -1,10 +1,35 @@ package codegen import ( + "errors" + "fmt" + "io/ioutil" + "path/filepath" + "runtime" + "strings" + + "github.com/vektah/gqlparser/v2/ast" + + "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/codegen/templates" ) func GenerateCode(data *Data) error { + if !data.Config.Exec.IsDefined() { + return fmt.Errorf("missing exec config") + } + + switch data.Config.Exec.Layout { + case config.ExecLayoutSingleFile: + return generateSingleFile(data) + case config.ExecLayoutFollowSchema: + return generatePerSchema(data) + } + + return fmt.Errorf("unrecognized exec layout %s", data.Config.Exec.Layout) +} + +func generateSingleFile(data *Data) error { return templates.Render(templates.Options{ PackageName: data.Config.Exec.Package, Filename: data.Config.Exec.Filename, @@ -14,3 +39,176 @@ func GenerateCode(data *Data) error { Packages: data.Config.Packages, }) } + +func generatePerSchema(data *Data) error { + err := generateRootFile(data) + if err != nil { + return err + } + + builds := map[string]*Data{} + + err = addObjects(data, &builds) + if err != nil { + return err + } + + err = addInputs(data, &builds) + if err != nil { + return err + } + + err = addInterfaces(data, &builds) + if err != nil { + return err + } + + err = addReferencedTypes(data, &builds) + if err != nil { + return err + } + + for filename, build := range builds { + if filename == "" { + continue + } + + dir := data.Config.Exec.DirName + path := filepath.Join(dir, filename) + + err = templates.Render(templates.Options{ + PackageName: data.Config.Exec.Package, + Filename: path, + Data: build, + RegionTags: true, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) + if err != nil { + return err + } + } + + return nil +} + +func filename(p *ast.Position, config *config.Config) string { + name := "common!" + if p != nil && p.Src != nil { + gqlname := filepath.Base(p.Src.Name) + ext := filepath.Ext(p.Src.Name) + name = strings.TrimSuffix(gqlname, ext) + } + + filenameTempl := config.Exec.FilenameTemplate + if filenameTempl == "" { + filenameTempl = "{name}.generated.go" + } + + return strings.ReplaceAll(filenameTempl, "{name}", name) +} + +func addBuild(filename string, p *ast.Position, data *Data, builds *map[string]*Data) { + buildConfig := *data.Config + if p != nil { + buildConfig.Sources = []*ast.Source{p.Src} + } + + (*builds)[filename] = &Data{ + Config: &buildConfig, + QueryRoot: data.QueryRoot, + MutationRoot: data.MutationRoot, + SubscriptionRoot: data.SubscriptionRoot, + AllDirectives: data.AllDirectives, + } +} + +// Root file contains top-level definitions that should not be duplicated across the generated +// files for each schema file. +func generateRootFile(data *Data) error { + dir := data.Config.Exec.DirName + path := filepath.Join(dir, "root!.generated.go") + + _, thisFile, _, _ := runtime.Caller(0) + rootDir := filepath.Dir(thisFile) + templatePath := filepath.Join(rootDir, "root_.gotpl") + templateBytes, err := ioutil.ReadFile(templatePath) + if err != nil { + return err + } + template := string(templateBytes) + + return templates.Render(templates.Options{ + PackageName: data.Config.Exec.Package, + Template: template, + Filename: path, + Data: data, + RegionTags: false, + GeneratedHeader: true, + Packages: data.Config.Packages, + }) +} + +func addObjects(data *Data, builds *map[string]*Data) error { + for _, o := range data.Objects { + filename := filename(o.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, o.Position, data, builds) + } + + (*builds)[filename].Objects = append((*builds)[filename].Objects, o) + } + return nil +} + +func addInputs(data *Data, builds *map[string]*Data) error { + for _, in := range data.Inputs { + filename := filename(in.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, in.Position, data, builds) + } + + (*builds)[filename].Inputs = append((*builds)[filename].Inputs, in) + } + return nil +} + +func addInterfaces(data *Data, builds *map[string]*Data) error { + for k, inf := range data.Interfaces { + filename := filename(inf.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, inf.Position, data, builds) + } + build := (*builds)[filename] + + if build.Interfaces == nil { + build.Interfaces = map[string]*Interface{} + } + if build.Interfaces[k] != nil { + return errors.New("conflicting interface keys") + } + + build.Interfaces[k] = inf + } + return nil +} + +func addReferencedTypes(data *Data, builds *map[string]*Data) error { + for k, rt := range data.ReferencedTypes { + filename := filename(rt.Definition.Position, data.Config) + if (*builds)[filename] == nil { + addBuild(filename, rt.Definition.Position, data, builds) + } + build := (*builds)[filename] + + if build.ReferencedTypes == nil { + build.ReferencedTypes = map[string]*config.TypeReference{} + } + if build.ReferencedTypes[k] != nil { + return errors.New("conflicting referenced type keys") + } + + build.ReferencedTypes[k] = rt + } + return nil +} diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index 3e51d6434af..e72fdd08bca 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -14,49 +14,51 @@ {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} -// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. -func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { - return &executableSchema{ - resolvers: cfg.Resolvers, - directives: cfg.Directives, - complexity: cfg.Complexity, +{{ if eq .Config.Exec.Layout "single-file" }} + // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. + func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } + } + + type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot + } + + type ResolverRoot interface { + {{- range $object := .Objects -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} + {{- end }} } -} - -type Config struct { - Resolvers ResolverRoot - Directives DirectiveRoot - Complexity ComplexityRoot -} - -type ResolverRoot interface { -{{- range $object := .Objects -}} - {{ if $object.HasResolvers -}} - {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + + type DirectiveRoot struct { + {{ range $directive := .Directives }} + {{- $directive.Declaration }} {{ end }} -{{- end }} -} + } -type DirectiveRoot struct { -{{ range $directive := .Directives }} - {{- $directive.Declaration }} -{{ end }} -} - -type ComplexityRoot struct { -{{ range $object := .Objects }} - {{ if not $object.IsReserved -}} - {{ ucFirst $object.Name }} struct { - {{ range $_, $fields := $object.UniqueFields }} - {{- $field := index $fields 0 -}} - {{ if not $field.IsReserved -}} - {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} - {{ end }} + type ComplexityRoot struct { + {{ range $object := .Objects }} + {{ if not $object.IsReserved -}} + {{ ucFirst $object.Name }} struct { + {{ range $_, $fields := $object.UniqueFields }} + {{- $field := index $fields 0 -}} + {{ if not $field.IsReserved -}} + {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} + {{ end }} + {{- end }} + } {{- end }} - } - {{- end }} + {{ end }} + } {{ end }} -} {{ range $object := .Objects -}} {{ if $object.HasResolvers }} @@ -70,145 +72,147 @@ type ComplexityRoot struct { {{- end }} {{- end }} -type executableSchema struct { - resolvers ResolverRoot - directives DirectiveRoot - complexity ComplexityRoot -} +{{ if eq .Config.Exec.Layout "single-file" }} + type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot + } -func (e *executableSchema) Schema() *ast.Schema { - return parsedSchema -} + func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema + } -func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e} - _ = ec - switch typeName + "." + field { - {{ range $object := .Objects }} - {{ if not $object.IsReserved }} - {{ range $_, $fields := $object.UniqueFields }} - {{- $len := len $fields }} - {{- range $i, $field := $fields }} - {{- $last := eq (add $i 1) $len }} - {{- if not $field.IsReserved }} - {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: - if e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}} == nil { - break - } - {{ if $field.Args }} - args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) - if err != nil { - return 0, false + func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e} + _ = ec + switch typeName + "." + field { + {{ range $object := .Objects }} + {{ if not $object.IsReserved }} + {{ range $_, $fields := $object.UniqueFields }} + {{- $len := len $fields }} + {{- range $i, $field := $fields }} + {{- $last := eq (add $i 1) $len }} + {{- if not $field.IsReserved }} + {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: + if e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}} == nil { + break } + {{ if $field.Args }} + args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) + if err != nil { + return 0, false + } + {{ end }} + return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true {{ end }} - return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true - {{ end }} + {{- end }} {{- end }} - {{- end }} + {{ end }} {{ end }} {{ end }} - {{ end }} + } + return 0, false } - return 0, false -} - -func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { - rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e} - first := true - - switch rc.Operation.Operation { - {{- if .QueryRoot }} case ast.Query: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ if .Directives.LocationDirectives "QUERY" -}} - data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ - return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil - }) - {{- else -}} - data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - return &graphql.Response{ - Data: buf.Bytes(), + func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e} + first := true + + switch rc.Operation.Operation { + {{- if .QueryRoot }} case ast.Query: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "QUERY" -}} + data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } } - } - {{ end }} + {{ end }} + + {{- if .MutationRoot }} case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "MUTATION" -}} + data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) - {{- if .MutationRoot }} case ast.Mutation: - return func(ctx context.Context) *graphql.Response { - if !first { return nil } - first = false - {{ if .Directives.LocationDirectives "MUTATION" -}} - data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ - return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .SubscriptionRoot }} case ast.Subscription: + {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} + next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil }) {{- else -}} - data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) + next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) {{- end }} - var buf bytes.Buffer - data.MarshalGQL(&buf) - return &graphql.Response{ - Data: buf.Bytes(), + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next() + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } } + {{ end }} + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) } - {{ end }} - - {{- if .SubscriptionRoot }} case ast.Subscription: - {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} - next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ - return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil - }) - {{- else -}} - next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) - {{- end }} - - var buf bytes.Buffer - return func(ctx context.Context) *graphql.Response { - buf.Reset() - data := next() + } - if data == nil { - return nil - } - data.MarshalGQL(&buf) + type executionContext struct { + *graphql.OperationContext + *executableSchema + } - return &graphql.Response{ - Data: buf.Bytes(), - } + func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") } - {{ end }} - default: - return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + return introspection.WrapSchema(parsedSchema), nil } -} - -type executionContext struct { - *graphql.OperationContext - *executableSchema -} -func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") + func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil } - return introspection.WrapSchema(parsedSchema), nil -} -func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") + var sources = []*ast.Source{ + {{- range $source := .Config.Sources }} + {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, + {{- end }} } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil -} - -var sources = []*ast.Source{ -{{- range $source := .Config.Sources }} - {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, -{{- end }} -} -var parsedSchema = gqlparser.MustLoadSchema(sources...) + var parsedSchema = gqlparser.MustLoadSchema(sources...) +{{ end }} diff --git a/codegen/root_.gotpl b/codegen/root_.gotpl new file mode 100644 index 00000000000..13d77961837 --- /dev/null +++ b/codegen/root_.gotpl @@ -0,0 +1,201 @@ +{{ reserveImport "context" }} +{{ reserveImport "fmt" }} +{{ reserveImport "io" }} +{{ reserveImport "strconv" }} +{{ reserveImport "time" }} +{{ reserveImport "sync" }} +{{ reserveImport "sync/atomic" }} +{{ reserveImport "errors" }} +{{ reserveImport "bytes" }} + +{{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} +{{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql" }} +{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { +{{- range $object := .Objects -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} +{{- end }} +} + +type DirectiveRoot struct { +{{ range $directive := .Directives }} + {{- $directive.Declaration }} +{{ end }} +} + +type ComplexityRoot struct { +{{ range $object := .Objects }} + {{ if not $object.IsReserved -}} + {{ ucFirst $object.Name }} struct { + {{ range $_, $fields := $object.UniqueFields }} + {{- $field := index $fields 0 -}} + {{ if not $field.IsReserved -}} + {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} + {{ end }} + {{- end }} + } + {{- end }} +{{ end }} +} + +type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema +} + +func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e} + _ = ec + switch typeName + "." + field { + {{ range $object := .Objects }} + {{ if not $object.IsReserved }} + {{ range $_, $fields := $object.UniqueFields }} + {{- $len := len $fields }} + {{- range $i, $field := $fields }} + {{- $last := eq (add $i 1) $len }} + {{- if not $field.IsReserved }} + {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: + if e.complexity.{{ucFirst $object.Name }}.{{$field.GoFieldName}} == nil { + break + } + {{ if $field.Args }} + args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) + if err != nil { + return 0, false + } + {{ end }} + return e.complexity.{{ucFirst $object.Name}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true + {{ end }} + {{- end }} + {{- end }} + {{ end }} + {{ end }} + {{ end }} + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e} + first := true + + switch rc.Operation.Operation { + {{- if .QueryRoot }} case ast.Query: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "QUERY" -}} + data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .MutationRoot }} case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { return nil } + first = false + {{ if .Directives.LocationDirectives "MUTATION" -}} + data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil + }) + {{- else -}} + data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + + {{- if .SubscriptionRoot }} case ast.Subscription: + {{ if .Directives.LocationDirectives "SUBSCRIPTION" -}} + next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){ + return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil + }) + {{- else -}} + next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet) + {{- end }} + + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next() + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + {{ end }} + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil +} + +var sources = []*ast.Source{ +{{- range $source := .Config.Sources }} + {Name: {{$source.Name|quote}}, Input: {{$source.Input|rawQuote}}, BuiltIn: {{$source.BuiltIn}}}, +{{- end }} +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index 77bac847367..ca8f923c1f3 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -91,6 +91,10 @@ func Render(cfg Options) error { if !strings.HasSuffix(info.Name(), ".gotpl") { return nil } + // omit any templates with "_" at the end of their name, which are meant for specific contexts only + if strings.HasSuffix(info.Name(), "_.gotpl") { + return nil + } b, err := ioutil.ReadFile(path) if err != nil { return err diff --git a/codegen/testserver/empty.go b/codegen/testserver/empty.go new file mode 100644 index 00000000000..e46955dab29 --- /dev/null +++ b/codegen/testserver/empty.go @@ -0,0 +1,3 @@ +package testserver + +// Empty file to silence go build error complaining that codegen/testserver/ has no non-test Go source files. diff --git a/codegen/testserver/followschema/builtinscalar.generated.go b/codegen/testserver/followschema/builtinscalar.generated.go new file mode 100644 index 00000000000..6b58040853b --- /dev/null +++ b/codegen/testserver/followschema/builtinscalar.generated.go @@ -0,0 +1,106 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Map_id(ctx context.Context, field graphql.CollectedField, obj *Map) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Map", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var mapImplementors = []string{"Map"} + +func (ec *executionContext) _Map(ctx context.Context, sel ast.SelectionSet, obj *Map) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mapImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Map") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Map_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/builtinscalar.graphql b/codegen/testserver/followschema/builtinscalar.graphql similarity index 100% rename from codegen/testserver/builtinscalar.graphql rename to codegen/testserver/followschema/builtinscalar.graphql diff --git a/codegen/testserver/followschema/bytes.go b/codegen/testserver/followschema/bytes.go new file mode 100644 index 00000000000..10395285ae0 --- /dev/null +++ b/codegen/testserver/followschema/bytes.go @@ -0,0 +1,27 @@ +package followschema + +import ( + "fmt" + "io" + + "github.com/99designs/gqlgen/graphql" +) + +func MarshalBytes(b []byte) graphql.Marshaler { + return graphql.WriterFunc(func(w io.Writer) { + _, _ = fmt.Fprintf(w, "%q", string(b)) + }) +} + +func UnmarshalBytes(v interface{}) ([]byte, error) { + switch v := v.(type) { + case string: + return []byte(v), nil + case *string: + return []byte(*v), nil + case []byte: + return v, nil + default: + return nil, fmt.Errorf("%T is not []byte", v) + } +} diff --git a/codegen/testserver/followschema/complexity.generated.go b/codegen/testserver/followschema/complexity.generated.go new file mode 100644 index 00000000000..f39c2ebeb17 --- /dev/null +++ b/codegen/testserver/followschema/complexity.generated.go @@ -0,0 +1,296 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type OverlappingFieldsResolver interface { + OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _OverlappingFields_oneFoo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OverlappingFields", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Foo, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _OverlappingFields_twoFoo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OverlappingFields", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Foo, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _OverlappingFields_oldFoo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OverlappingFields", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.OverlappingFields().OldFoo(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _OverlappingFields_newFoo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OverlappingFields", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NewFoo, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _OverlappingFields_new_foo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OverlappingFields", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NewFoo, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var overlappingFieldsImplementors = []string{"OverlappingFields"} + +func (ec *executionContext) _OverlappingFields(ctx context.Context, sel ast.SelectionSet, obj *OverlappingFields) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, overlappingFieldsImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("OverlappingFields") + case "oneFoo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_oneFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "twoFoo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_twoFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "oldFoo": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._OverlappingFields_oldFoo(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "newFoo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_newFoo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "new_foo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OverlappingFields_new_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOverlappingFields(ctx context.Context, sel ast.SelectionSet, v *OverlappingFields) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._OverlappingFields(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/complexity.graphql b/codegen/testserver/followschema/complexity.graphql similarity index 100% rename from codegen/testserver/complexity.graphql rename to codegen/testserver/followschema/complexity.graphql diff --git a/codegen/testserver/followschema/complexity_test.go b/codegen/testserver/followschema/complexity_test.go new file mode 100644 index 00000000000..6a91e0f0005 --- /dev/null +++ b/codegen/testserver/followschema/complexity_test.go @@ -0,0 +1,119 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/extension" + "github.com/stretchr/testify/require" +) + +func TestComplexityCollisions(t *testing.T) { + resolvers := &Stub{} + + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + + c := client.New(srv) + + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + resolvers.OverlappingFieldsResolver.OldFoo = func(ctx context.Context, obj *OverlappingFields) (i int, e error) { + return obj.Foo, nil + } + + var resp struct { + Overlapping struct { + OneFoo int `json:"oneFoo"` + TwoFoo int `json:"twoFoo"` + OldFoo int `json:"oldFoo"` + NewFoo int `json:"newFoo"` + New_foo int `json:"new_foo"` + } + } + c.MustPost(`query { overlapping { oneFoo, twoFoo, oldFoo, newFoo, new_foo } }`, &resp) + require.Equal(t, 2, resp.Overlapping.OneFoo) + require.Equal(t, 2, resp.Overlapping.TwoFoo) + require.Equal(t, 2, resp.Overlapping.OldFoo) + require.Equal(t, 3, resp.Overlapping.NewFoo) + require.Equal(t, 3, resp.Overlapping.New_foo) +} + +func TestComplexityFuncs(t *testing.T) { + resolvers := &Stub{} + cfg := Config{Resolvers: resolvers} + cfg.Complexity.OverlappingFields.Foo = func(childComplexity int) int { return 1000 } + cfg.Complexity.OverlappingFields.NewFoo = func(childComplexity int) int { return 5 } + + srv := handler.NewDefaultServer(NewExecutableSchema(cfg)) + srv.Use(extension.FixedComplexityLimit(10)) + c := client.New(srv) + + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + t.Run("with high complexity limit will not run", func(t *testing.T) { + ran := false + resolvers.OverlappingFieldsResolver.OldFoo = func(ctx context.Context, obj *OverlappingFields) (i int, e error) { + ran = true + return obj.Foo, nil + } + + var resp struct { + Overlapping interface{} + } + err := c.Post(`query { overlapping { oneFoo, twoFoo, oldFoo, newFoo, new_foo } }`, &resp) + + require.EqualError(t, err, `[{"message":"operation has complexity 2012, which exceeds the limit of 10","extensions":{"code":"COMPLEXITY_LIMIT_EXCEEDED"}}]`) + require.False(t, ran) + }) + + t.Run("with low complexity will run", func(t *testing.T) { + ran := false + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + ran = true + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + var resp struct { + Overlapping interface{} + } + c.MustPost(`query { overlapping { newFoo } }`, &resp) + + require.True(t, ran) + }) + + t.Run("with multiple low complexity will not run", func(t *testing.T) { + ran := false + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + ran = true + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + var resp interface{} + err := c.Post(`query { + a: overlapping { newFoo }, + b: overlapping { newFoo }, + c: overlapping { newFoo }, + }`, &resp) + + require.EqualError(t, err, `[{"message":"operation has complexity 18, which exceeds the limit of 10","extensions":{"code":"COMPLEXITY_LIMIT_EXCEEDED"}}]`) + require.False(t, ran) + }) +} diff --git a/codegen/testserver/followschema/defaults.generated.go b/codegen/testserver/followschema/defaults.generated.go new file mode 100644 index 00000000000..a62937e031b --- /dev/null +++ b/codegen/testserver/followschema/defaults.generated.go @@ -0,0 +1,421 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type MutationResolver interface { + DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) + UpdateSomething(ctx context.Context, input SpecialInput) (string, error) + UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Mutation_defaultInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 DefaultInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Mutation_updatePtrToPtr_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 UpdatePtrToPtrOuter + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrOuter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Mutation_updateSomething_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 SpecialInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐSpecialInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _DefaultParametersMirror_falsyBoolean(ctx context.Context, field graphql.CollectedField, obj *DefaultParametersMirror) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DefaultParametersMirror", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.FalsyBoolean, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _DefaultParametersMirror_truthyBoolean(ctx context.Context, field graphql.CollectedField, obj *DefaultParametersMirror) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "DefaultParametersMirror", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TruthyBoolean, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Mutation_defaultInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_defaultInput_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DefaultInput(rctx, args["input"].(DefaultInput)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*DefaultParametersMirror) + fc.Result = res + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultParametersMirror(ctx, field.Selections, res) +} + +func (ec *executionContext) _Mutation_updateSomething(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_updateSomething_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateSomething(rctx, args["input"].(SpecialInput)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Mutation_updatePtrToPtr(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_updatePtrToPtr_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdatePtrToPtr(rctx, args["input"].(UpdatePtrToPtrOuter)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*PtrToPtrOuter) + fc.Result = res + return ec.marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrOuter(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputDefaultInput(ctx context.Context, obj interface{}) (DefaultInput, error) { + var it DefaultInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + if _, present := asMap["falsyBoolean"]; !present { + asMap["falsyBoolean"] = false + } + if _, present := asMap["truthyBoolean"]; !present { + asMap["truthyBoolean"] = true + } + + for k, v := range asMap { + switch k { + case "falsyBoolean": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("falsyBoolean")) + it.FalsyBoolean, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + case "truthyBoolean": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("truthyBoolean")) + it.TruthyBoolean, err = ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var defaultParametersMirrorImplementors = []string{"DefaultParametersMirror"} + +func (ec *executionContext) _DefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, obj *DefaultParametersMirror) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, defaultParametersMirrorImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DefaultParametersMirror") + case "falsyBoolean": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DefaultParametersMirror_falsyBoolean(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "truthyBoolean": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._DefaultParametersMirror_truthyBoolean(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var mutationImplementors = []string{"Mutation"} + +func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mutationImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Mutation", + }) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Mutation") + case "defaultInput": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_defaultInput(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "updateSomething": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updateSomething(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "updatePtrToPtr": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_updatePtrToPtr(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultInput(ctx context.Context, v interface{}) (DefaultInput, error) { + res, err := ec.unmarshalInputDefaultInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDefaultParametersMirror2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v DefaultParametersMirror) graphql.Marshaler { + return ec._DefaultParametersMirror(ctx, sel, &v) +} + +func (ec *executionContext) marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v *DefaultParametersMirror) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._DefaultParametersMirror(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/defaults.graphql b/codegen/testserver/followschema/defaults.graphql similarity index 100% rename from codegen/testserver/defaults.graphql rename to codegen/testserver/followschema/defaults.graphql diff --git a/codegen/testserver/followschema/defaults_test.go b/codegen/testserver/followschema/defaults_test.go new file mode 100644 index 00000000000..e5708a72e33 --- /dev/null +++ b/codegen/testserver/followschema/defaults_test.go @@ -0,0 +1,68 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func assertDefaults(t *testing.T, ret *DefaultParametersMirror) { + require.NotNil(t, ret) + require.NotNil(t, ret.FalsyBoolean) + require.Equal(t, *ret.FalsyBoolean, false) + require.NotNil(t, ret.TruthyBoolean) + require.Equal(t, *ret.TruthyBoolean, true) +} + +func TestDefaults(t *testing.T) { + resolvers := &Stub{} + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + c := client.New(srv) + + t.Run("default field parameters", func(t *testing.T) { + resolvers.QueryResolver.DefaultParameters = func( + ctx context.Context, + falsyBoolean, truthyBoolean *bool, + ) (*DefaultParametersMirror, error) { + return &DefaultParametersMirror{ + FalsyBoolean: falsyBoolean, + TruthyBoolean: truthyBoolean, + }, nil + } + + var resp struct{ DefaultParameters *DefaultParametersMirror } + err := c.Post(`query { + defaultParameters { + falsyBoolean + truthyBoolean + } + }`, &resp) + require.NoError(t, err) + assertDefaults(t, resp.DefaultParameters) + }) + + t.Run("default input fields", func(t *testing.T) { + resolvers.MutationResolver.DefaultInput = func( + ctx context.Context, + input DefaultInput, + ) (*DefaultParametersMirror, error) { + return &DefaultParametersMirror{ + FalsyBoolean: input.FalsyBoolean, + TruthyBoolean: input.TruthyBoolean, + }, nil + } + + var resp struct{ DefaultInput *DefaultParametersMirror } + err := c.Post(`mutation { + defaultInput(input: {}) { + falsyBoolean + truthyBoolean + } + }`, &resp) + require.NoError(t, err) + assertDefaults(t, resp.DefaultInput) + }) +} diff --git a/codegen/testserver/followschema/directive.generated.go b/codegen/testserver/followschema/directive.generated.go new file mode 100644 index 00000000000..70aecc97e4c --- /dev/null +++ b/codegen/testserver/followschema/directive.generated.go @@ -0,0 +1,707 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "errors" + "fmt" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) dir_length_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 int + if tmp, ok := rawArgs["min"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("min")) + arg0, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["min"] = arg0 + var arg1 *int + if tmp, ok := rawArgs["max"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("max")) + arg1, err = ec.unmarshalOInt2ᚖint(ctx, tmp) + if err != nil { + return nil, err + } + } + args["max"] = arg1 + var arg2 *string + if tmp, ok := rawArgs["message"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("message")) + arg2, err = ec.unmarshalOString2ᚖstring(ctx, tmp) + if err != nil { + return nil, err + } + } + args["message"] = arg2 + return args, nil +} + +func (ec *executionContext) dir_logged_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNUUID2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + +func (ec *executionContext) dir_order1_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["location"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("location")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["location"] = arg0 + return args, nil +} + +func (ec *executionContext) dir_order2_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["location"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("location")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["location"] = arg0 + return args, nil +} + +func (ec *executionContext) dir_range_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *int + if tmp, ok := rawArgs["min"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("min")) + arg0, err = ec.unmarshalOInt2ᚖint(ctx, tmp) + if err != nil { + return nil, err + } + } + args["min"] = arg0 + var arg1 *int + if tmp, ok := rawArgs["max"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("max")) + arg1, err = ec.unmarshalOInt2ᚖint(ctx, tmp) + if err != nil { + return nil, err + } + } + args["max"] = arg1 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +func (ec *executionContext) _fieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) interface{} { + fc := graphql.GetFieldContext(ctx) + for _, d := range fc.Field.Directives { + switch d.Name { + case "logged": + rawArgs := d.ArgumentMap(ec.Variables) + args, err := ec.dir_logged_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return nil + } + n := next + next = func(ctx context.Context) (interface{}, error) { + if ec.directives.Logged == nil { + return nil, errors.New("directive logged is not implemented") + } + return ec.directives.Logged(ctx, obj, n, args["id"].(string)) + } + } + } + res, err := ec.ResolverMiddleware(ctx, next) + if err != nil { + ec.Error(ctx, err) + return nil + } + return res +} + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _ObjectDirectives_text(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectives) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ObjectDirectives", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Text, nil + } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 0) + if err != nil { + return nil, err + } + max, err := ec.unmarshalOInt2ᚖint(ctx, 7) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "not valid") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, obj, directive0, min, max, message) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ObjectDirectives_nullableText(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectives) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ObjectDirectives", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NullableText, nil + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.ToNull == nil { + return nil, errors.New("directive toNull is not implemented") + } + return ec.directives.ToNull(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _ObjectDirectives_order(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectives) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ObjectDirectives", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Order, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _ObjectDirectivesWithCustomGoModel_nullableText(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectivesWithCustomGoModel) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ObjectDirectivesWithCustomGoModel", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NullableText, nil + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.ToNull == nil { + return nil, errors.New("directive toNull is not implemented") + } + return ec.directives.ToNull(ctx, obj, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputInnerDirectives(ctx context.Context, obj interface{}) (InnerDirectives, error) { + var it InnerDirectives + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "message": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("message")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 1) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "not valid") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, obj, directive0, min, nil, message) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + it.Message = data + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, obj interface{}) (InputDirectives, error) { + var it InputDirectives + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "text": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("text")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, v) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 0) + if err != nil { + return nil, err + } + max, err := ec.unmarshalOInt2ᚖint(ctx, 7) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "not valid") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, obj, directive1, min, max, message) + } + + tmp, err := directive2(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + it.Text = data + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "nullableText": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nullableText")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOString2ᚖstring(ctx, v) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { + if ec.directives.ToNull == nil { + return nil, errors.New("directive toNull is not implemented") + } + return ec.directives.ToNull(ctx, obj, directive1) + } + + tmp, err := directive2(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*string); ok { + it.NullableText = data + } else if tmp == nil { + it.NullableText = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "inner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.Inner = data + } else if tmp == nil { + it.Inner = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/followschema.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "innerNullable": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("innerNullable")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerDirectives(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + + tmp, err := directive1(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*InnerDirectives); ok { + it.InnerNullable = data + } else if tmp == nil { + it.InnerNullable = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/followschema.InnerDirectives`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + case "thirdParty": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("thirdParty")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐThirdParty(ctx, v) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive3 == nil { + return nil, errors.New("directive directive3 is not implemented") + } + return ec.directives.Directive3(ctx, obj, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 0) + if err != nil { + return nil, err + } + max, err := ec.unmarshalOInt2ᚖint(ctx, 7) + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, obj, directive1, min, max, nil) + } + + tmp, err := directive2(ctx) + if err != nil { + return it, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*ThirdParty); ok { + it.ThirdParty = data + } else if tmp == nil { + it.ThirdParty = nil + } else { + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/followschema.ThirdParty`, tmp) + return it, graphql.ErrorOnPath(ctx, err) + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var objectDirectivesImplementors = []string{"ObjectDirectives"} + +func (ec *executionContext) _ObjectDirectives(ctx context.Context, sel ast.SelectionSet, obj *ObjectDirectives) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, objectDirectivesImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ObjectDirectives") + case "text": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_text(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "nullableText": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_nullableText(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "order": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectives_order(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var objectDirectivesWithCustomGoModelImplementors = []string{"ObjectDirectivesWithCustomGoModel"} + +func (ec *executionContext) _ObjectDirectivesWithCustomGoModel(ctx context.Context, sel ast.SelectionSet, obj *ObjectDirectivesWithCustomGoModel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, objectDirectivesWithCustomGoModelImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ObjectDirectivesWithCustomGoModel") + case "nullableText": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ObjectDirectivesWithCustomGoModel_nullableText(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { + res, err := ec.unmarshalInputInnerDirectives(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputDirectives(ctx context.Context, v interface{}) (InputDirectives, error) { + res, err := ec.unmarshalInputInputDirectives(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputInnerDirectives(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputDirectives(ctx context.Context, v interface{}) (*InputDirectives, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputInputDirectives(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐObjectDirectives(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectives) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ObjectDirectives(ctx, sel, v) +} + +func (ec *executionContext) marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐObjectDirectivesWithCustomGoModel(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectivesWithCustomGoModel) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ObjectDirectivesWithCustomGoModel(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/directive.graphql b/codegen/testserver/followschema/directive.graphql similarity index 100% rename from codegen/testserver/directive.graphql rename to codegen/testserver/followschema/directive.graphql diff --git a/codegen/testserver/followschema/directive_test.go b/codegen/testserver/followschema/directive_test.go new file mode 100644 index 00000000000..e995b2721cd --- /dev/null +++ b/codegen/testserver/followschema/directive_test.go @@ -0,0 +1,465 @@ +package followschema + +import ( + "context" + "fmt" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +type ckey string + +func TestDirectives(t *testing.T) { + resolvers := &Stub{} + ok := "Ok" + resolvers.QueryResolver.DirectiveArg = func(ctx context.Context, arg string) (i *string, e error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveInput = func(ctx context.Context, arg InputDirectives) (i *string, e error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveInputNullable = func(ctx context.Context, arg *InputDirectives) (i *string, e error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveNullableArg = func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveInputType = func(ctx context.Context, arg InnerInput) (i *string, e error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveObject = func(ctx context.Context) (*ObjectDirectives, error) { + return &ObjectDirectives{ + Text: ok, + NullableText: &ok, + }, nil + } + + resolvers.QueryResolver.DirectiveObjectWithCustomGoModel = func(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) { + return &ObjectDirectivesWithCustomGoModel{ + NullableText: ok, + }, nil + } + + resolvers.QueryResolver.DirectiveField = func(ctx context.Context) (*string, error) { + if s, ok := ctx.Value(ckey("request_id")).(*string); ok { + return s, nil + } + + return nil, nil + } + + resolvers.QueryResolver.DirectiveDouble = func(ctx context.Context) (*string, error) { + return &ok, nil + } + + resolvers.QueryResolver.DirectiveUnimplemented = func(ctx context.Context) (*string, error) { + return &ok, nil + } + + okchan := func() (<-chan *string, error) { + res := make(chan *string, 1) + res <- &ok + close(res) + return res, nil + } + + resolvers.SubscriptionResolver.DirectiveArg = func(ctx context.Context, arg string) (strings <-chan *string, e error) { + return okchan() + } + + resolvers.SubscriptionResolver.DirectiveNullableArg = func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (strings <-chan *string, e error) { + return okchan() + } + + resolvers.SubscriptionResolver.DirectiveDouble = func(ctx context.Context) (strings <-chan *string, e error) { + return okchan() + } + + resolvers.SubscriptionResolver.DirectiveUnimplemented = func(ctx context.Context) (<-chan *string, error) { + return okchan() + } + srv := handler.NewDefaultServer(NewExecutableSchema(Config{ + Resolvers: resolvers, + Directives: DirectiveRoot{ + Length: func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int, message *string) (interface{}, error) { + e := func(msg string) error { + if message == nil { + return fmt.Errorf(msg) + } + return fmt.Errorf(*message) + } + res, err := next(ctx) + if err != nil { + return nil, err + } + + s := res.(string) + if len(s) < min { + return nil, e("too short") + } + if max != nil && len(s) > *max { + return nil, e("too long") + } + return res, nil + }, + Range: func(ctx context.Context, obj interface{}, next graphql.Resolver, min *int, max *int) (interface{}, error) { + res, err := next(ctx) + if err != nil { + return nil, err + } + + switch res := res.(type) { + case int: + if min != nil && res < *min { + return nil, fmt.Errorf("too small") + } + if max != nil && res > *max { + return nil, fmt.Errorf("too large") + } + return next(ctx) + + case int64: + if min != nil && int(res) < *min { + return nil, fmt.Errorf("too small") + } + if max != nil && int(res) > *max { + return nil, fmt.Errorf("too large") + } + return next(ctx) + + case *int: + if min != nil && *res < *min { + return nil, fmt.Errorf("too small") + } + if max != nil && *res > *max { + return nil, fmt.Errorf("too large") + } + return next(ctx) + } + return nil, fmt.Errorf("unsupported type %T", res) + }, + Custom: func(ctx context.Context, obj interface{}, next graphql.Resolver) (interface{}, error) { + return next(ctx) + }, + Logged: func(ctx context.Context, obj interface{}, next graphql.Resolver, id string) (interface{}, error) { + return next(context.WithValue(ctx, ckey("request_id"), &id)) + }, + ToNull: func(ctx context.Context, obj interface{}, next graphql.Resolver) (interface{}, error) { + return nil, nil + }, + Directive1: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, + Directive2: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, + Directive3: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return next(ctx) + }, + Order1: func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) { + order := []string{location} + res, err = next(ctx) + od := res.(*ObjectDirectives) + od.Order = append(order, od.Order...) + return od, err + }, + Order2: func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) { + order := []string{location} + res, err = next(ctx) + od := res.(*ObjectDirectives) + od.Order = append(order, od.Order...) + return od, err + }, + Unimplemented: nil, + }, + })) + + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) + }) + + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) + }) + + c := client.New(srv) + + t.Run("arg directives", func(t *testing.T) { + t.Run("when function errors on directives", func(t *testing.T) { + var resp struct { + DirectiveArg *string + } + + err := c.Post(`query { directiveArg(arg: "") }`, &resp) + + require.EqualError(t, err, `[{"message":"invalid length","path":["directiveArg","arg"]}]`) + require.Nil(t, resp.DirectiveArg) + }) + t.Run("when function errors on nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.Post(`query { directiveNullableArg(arg: -100) }`, &resp) + + require.EqualError(t, err, `[{"message":"too small","path":["directiveNullableArg","arg"]}]`) + require.Nil(t, resp.DirectiveNullableArg) + }) + t.Run("when function success on nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.Post(`query { directiveNullableArg }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveNullableArg) + }) + t.Run("when function success on valid nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.Post(`query { directiveNullableArg(arg: 1) }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveNullableArg) + }) + t.Run("when function success", func(t *testing.T) { + var resp struct { + DirectiveArg *string + } + + err := c.Post(`query { directiveArg(arg: "test") }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveArg) + }) + }) + t.Run("field definition directives", func(t *testing.T) { + resolvers.QueryResolver.DirectiveFieldDef = func(ctx context.Context, ret string) (i string, e error) { + return ret, nil + } + + t.Run("too short", func(t *testing.T) { + var resp struct { + DirectiveFieldDef string + } + + err := c.Post(`query { directiveFieldDef(ret: "") }`, &resp) + + require.EqualError(t, err, `[{"message":"not valid","path":["directiveFieldDef"]}]`) + }) + + t.Run("has 2 directives", func(t *testing.T) { + var resp struct { + DirectiveDouble string + } + + c.MustPost(`query { directiveDouble }`, &resp) + + require.Equal(t, "Ok", resp.DirectiveDouble) + }) + + t.Run("directive is not implemented", func(t *testing.T) { + var resp struct { + DirectiveUnimplemented string + } + + err := c.Post(`query { directiveUnimplemented }`, &resp) + + require.EqualError(t, err, `[{"message":"directive unimplemented is not implemented","path":["directiveUnimplemented"]}]`) + }) + + t.Run("ok", func(t *testing.T) { + var resp struct { + DirectiveFieldDef string + } + + c.MustPost(`query { directiveFieldDef(ret: "aaa") }`, &resp) + + require.Equal(t, "aaa", resp.DirectiveFieldDef) + }) + }) + t.Run("field directives", func(t *testing.T) { + t.Run("add field directive", func(t *testing.T) { + var resp struct { + DirectiveField string + } + + c.MustPost(`query { directiveField@logged(id:"testes_id") }`, &resp) + + require.Equal(t, resp.DirectiveField, `testes_id`) + }) + t.Run("without field directive", func(t *testing.T) { + var resp struct { + DirectiveField *string + } + + c.MustPost(`query { directiveField }`, &resp) + + require.Nil(t, resp.DirectiveField) + }) + }) + t.Run("input field directives", func(t *testing.T) { + t.Run("when function errors on directives", func(t *testing.T) { + var resp struct { + DirectiveInputNullable *string + } + + err := c.Post(`query { directiveInputNullable(arg: {text:"invalid text",inner:{message:"123"}}) }`, &resp) + + require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable","arg","text"]}]`) + require.Nil(t, resp.DirectiveInputNullable) + }) + t.Run("when function errors on inner directives", func(t *testing.T) { + var resp struct { + DirectiveInputNullable *string + } + + err := c.Post(`query { directiveInputNullable(arg: {text:"2",inner:{message:""}}) }`, &resp) + + require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable","arg","inner","message"]}]`) + require.Nil(t, resp.DirectiveInputNullable) + }) + t.Run("when function errors on nullable inner directives", func(t *testing.T) { + var resp struct { + DirectiveInputNullable *string + } + + err := c.Post(`query { directiveInputNullable(arg: {text:"success",inner:{message:"1"},innerNullable:{message:""}}) }`, &resp) + + require.EqualError(t, err, `[{"message":"not valid","path":["directiveInputNullable","arg","innerNullable","message"]}]`) + require.Nil(t, resp.DirectiveInputNullable) + }) + t.Run("when function success", func(t *testing.T) { + var resp struct { + DirectiveInputNullable *string + } + + err := c.Post(`query { directiveInputNullable(arg: {text:"23",inner:{message:"1"}}) }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveInputNullable) + }) + t.Run("when function inner nullable success", func(t *testing.T) { + var resp struct { + DirectiveInputNullable *string + } + + err := c.Post(`query { directiveInputNullable(arg: {text:"23",nullableText:"23",inner:{message:"1"},innerNullable:{message:"success"}}) }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveInputNullable) + }) + t.Run("when arg has directive", func(t *testing.T) { + var resp struct { + DirectiveInputType *string + } + + err := c.Post(`query { directiveInputType(arg: {id: 1}) }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveInputType) + }) + }) + t.Run("object field directives", func(t *testing.T) { + t.Run("when function success", func(t *testing.T) { + var resp struct { + DirectiveObject *struct { + Text string + NullableText *string + Order []string + } + } + + err := c.Post(`query { directiveObject{ text nullableText order} }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", resp.DirectiveObject.Text) + require.True(t, resp.DirectiveObject.NullableText == nil) + require.Equal(t, "Query_field", resp.DirectiveObject.Order[0]) + require.Equal(t, "order2_1", resp.DirectiveObject.Order[1]) + require.Equal(t, "order1_2", resp.DirectiveObject.Order[2]) + require.Equal(t, "order1_1", resp.DirectiveObject.Order[3]) + }) + t.Run("when directive returns nil & custom go field is not nilable", func(t *testing.T) { + var resp struct { + DirectiveObjectWithCustomGoModel *struct { + NullableText *string + } + } + + err := c.Post(`query { directiveObjectWithCustomGoModel{ nullableText } }`, &resp) + + require.Nil(t, err) + require.True(t, resp.DirectiveObjectWithCustomGoModel.NullableText == nil) + }) + }) + + t.Run("Subscription directives", func(t *testing.T) { + t.Run("arg directives", func(t *testing.T) { + t.Run("when function errors on directives", func(t *testing.T) { + var resp struct { + DirectiveArg *string + } + + err := c.WebsocketOnce(`subscription { directiveArg(arg: "") }`, &resp) + + require.EqualError(t, err, `[{"message":"invalid length","path":["directiveArg","arg"]}]`) + require.Nil(t, resp.DirectiveArg) + }) + t.Run("when function errors on nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.WebsocketOnce(`subscription { directiveNullableArg(arg: -100) }`, &resp) + + require.EqualError(t, err, `[{"message":"too small","path":["directiveNullableArg","arg"]}]`) + require.Nil(t, resp.DirectiveNullableArg) + }) + t.Run("when function success on nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.WebsocketOnce(`subscription { directiveNullableArg }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveNullableArg) + }) + t.Run("when function success on valid nullable arg directives", func(t *testing.T) { + var resp struct { + DirectiveNullableArg *string + } + + err := c.WebsocketOnce(`subscription { directiveNullableArg(arg: 1) }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveNullableArg) + }) + t.Run("when function success", func(t *testing.T) { + var resp struct { + DirectiveArg *string + } + + err := c.WebsocketOnce(`subscription { directiveArg(arg: "test") }`, &resp) + + require.Nil(t, err) + require.Equal(t, "Ok", *resp.DirectiveArg) + }) + }) + }) +} diff --git a/codegen/testserver/followschema/embedded.generated.go b/codegen/testserver/followschema/embedded.generated.go new file mode 100644 index 00000000000..0263b49735f --- /dev/null +++ b/codegen/testserver/followschema/embedded.generated.go @@ -0,0 +1,253 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _EmbeddedCase1_exportedEmbeddedPointerExportedMethod(ctx context.Context, field graphql.CollectedField, obj *EmbeddedCase1) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedCase1", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExportedEmbeddedPointerExportedMethod(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _EmbeddedCase2_unexportedEmbeddedPointerExportedMethod(ctx context.Context, field graphql.CollectedField, obj *EmbeddedCase2) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedCase2", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.UnexportedEmbeddedPointerExportedMethod(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _EmbeddedCase3_unexportedEmbeddedInterfaceExportedMethod(ctx context.Context, field graphql.CollectedField, obj *EmbeddedCase3) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedCase3", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.UnexportedEmbeddedInterfaceExportedMethod(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var embeddedCase1Implementors = []string{"EmbeddedCase1"} + +func (ec *executionContext) _EmbeddedCase1(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase1) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase1Implementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmbeddedCase1") + case "exportedEmbeddedPointerExportedMethod": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase1_exportedEmbeddedPointerExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var embeddedCase2Implementors = []string{"EmbeddedCase2"} + +func (ec *executionContext) _EmbeddedCase2(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase2) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase2Implementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmbeddedCase2") + case "unexportedEmbeddedPointerExportedMethod": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase2_unexportedEmbeddedPointerExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var embeddedCase3Implementors = []string{"EmbeddedCase3"} + +func (ec *executionContext) _EmbeddedCase3(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedCase3) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, embeddedCase3Implementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmbeddedCase3") + case "unexportedEmbeddedInterfaceExportedMethod": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedCase3_unexportedEmbeddedInterfaceExportedMethod(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase1(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase1) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._EmbeddedCase1(ctx, sel, v) +} + +func (ec *executionContext) marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase2(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase2) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._EmbeddedCase2(ctx, sel, v) +} + +func (ec *executionContext) marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase3(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase3) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._EmbeddedCase3(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/embedded.go b/codegen/testserver/followschema/embedded.go new file mode 100644 index 00000000000..f22f83b592d --- /dev/null +++ b/codegen/testserver/followschema/embedded.go @@ -0,0 +1,43 @@ +package followschema + +// EmbeddedCase1 model +type EmbeddedCase1 struct { + Empty + *ExportedEmbeddedPointerAfterInterface +} + +// Empty interface +type Empty interface{} + +// ExportedEmbeddedPointerAfterInterface model +type ExportedEmbeddedPointerAfterInterface struct{} + +// ExportedEmbeddedPointerExportedMethod method +func (*ExportedEmbeddedPointerAfterInterface) ExportedEmbeddedPointerExportedMethod() string { + return "ExportedEmbeddedPointerExportedMethodResponse" +} + +// EmbeddedCase2 model +type EmbeddedCase2 struct { + *unexportedEmbeddedPointer +} + +type unexportedEmbeddedPointer struct{} + +// UnexportedEmbeddedPointerExportedMethod method +func (*unexportedEmbeddedPointer) UnexportedEmbeddedPointerExportedMethod() string { + return "UnexportedEmbeddedPointerExportedMethodResponse" +} + +// EmbeddedCase3 model +type EmbeddedCase3 struct { + unexportedEmbeddedInterface +} + +type unexportedEmbeddedInterface interface { + nestedInterface +} + +type nestedInterface interface { + UnexportedEmbeddedInterfaceExportedMethod() string +} diff --git a/codegen/testserver/followschema/embedded.graphql b/codegen/testserver/followschema/embedded.graphql new file mode 100644 index 00000000000..e707a236031 --- /dev/null +++ b/codegen/testserver/followschema/embedded.graphql @@ -0,0 +1,17 @@ +extend type Query { + embeddedCase1: EmbeddedCase1 + embeddedCase2: EmbeddedCase2 + embeddedCase3: EmbeddedCase3 +} + +type EmbeddedCase1 @goModel(model:"followschema.EmbeddedCase1") { + exportedEmbeddedPointerExportedMethod: String! +} + +type EmbeddedCase2 @goModel(model:"followschema.EmbeddedCase2") { + unexportedEmbeddedPointerExportedMethod: String! +} + +type EmbeddedCase3 @goModel(model:"followschema.EmbeddedCase3") { + unexportedEmbeddedInterfaceExportedMethod: String! +} diff --git a/codegen/testserver/followschema/embedded_test.go b/codegen/testserver/followschema/embedded_test.go new file mode 100644 index 00000000000..b5e1575bac3 --- /dev/null +++ b/codegen/testserver/followschema/embedded_test.go @@ -0,0 +1,66 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +type fakeUnexportedEmbeddedInterface struct{} + +func (*fakeUnexportedEmbeddedInterface) UnexportedEmbeddedInterfaceExportedMethod() string { + return "UnexportedEmbeddedInterfaceExportedMethod" +} + +func TestEmbedded(t *testing.T) { + resolver := &Stub{} + resolver.QueryResolver.EmbeddedCase1 = func(ctx context.Context) (*EmbeddedCase1, error) { + return &EmbeddedCase1{}, nil + } + resolver.QueryResolver.EmbeddedCase2 = func(ctx context.Context) (*EmbeddedCase2, error) { + return &EmbeddedCase2{&unexportedEmbeddedPointer{}}, nil + } + resolver.QueryResolver.EmbeddedCase3 = func(ctx context.Context) (*EmbeddedCase3, error) { + return &EmbeddedCase3{&fakeUnexportedEmbeddedInterface{}}, nil + } + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolver}), + )) + + t.Run("embedded case 1", func(t *testing.T) { + var resp struct { + EmbeddedCase1 struct { + ExportedEmbeddedPointerExportedMethod string + } + } + err := c.Post(`query { embeddedCase1 { exportedEmbeddedPointerExportedMethod } }`, &resp) + require.NoError(t, err) + require.Equal(t, resp.EmbeddedCase1.ExportedEmbeddedPointerExportedMethod, "ExportedEmbeddedPointerExportedMethodResponse") + }) + + t.Run("embedded case 2", func(t *testing.T) { + var resp struct { + EmbeddedCase2 struct { + UnexportedEmbeddedPointerExportedMethod string + } + } + err := c.Post(`query { embeddedCase2 { unexportedEmbeddedPointerExportedMethod } }`, &resp) + require.NoError(t, err) + require.Equal(t, resp.EmbeddedCase2.UnexportedEmbeddedPointerExportedMethod, "UnexportedEmbeddedPointerExportedMethodResponse") + }) + + t.Run("embedded case 3", func(t *testing.T) { + var resp struct { + EmbeddedCase3 struct { + UnexportedEmbeddedInterfaceExportedMethod string + } + } + err := c.Post(`query { embeddedCase3 { unexportedEmbeddedInterfaceExportedMethod } }`, &resp) + require.NoError(t, err) + require.Equal(t, resp.EmbeddedCase3.UnexportedEmbeddedInterfaceExportedMethod, "UnexportedEmbeddedInterfaceExportedMethod") + }) +} diff --git a/codegen/testserver/followschema/enum.generated.go b/codegen/testserver/followschema/enum.generated.go new file mode 100644 index 00000000000..59752873f91 --- /dev/null +++ b/codegen/testserver/followschema/enum.generated.go @@ -0,0 +1,83 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputInputWithEnumValue(ctx context.Context, obj interface{}) (InputWithEnumValue, error) { + var it InputWithEnumValue + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "enum": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("enum")) + it.Enum, err = ec.unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEnumTest(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEnumTest(ctx context.Context, v interface{}) (EnumTest, error) { + var res EnumTest + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEnumTest(ctx context.Context, sel ast.SelectionSet, v EnumTest) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputWithEnumValue(ctx context.Context, v interface{}) (*InputWithEnumValue, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputInputWithEnumValue(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/enum.graphql b/codegen/testserver/followschema/enum.graphql similarity index 100% rename from codegen/testserver/enum.graphql rename to codegen/testserver/followschema/enum.graphql diff --git a/codegen/testserver/followschema/enums_test.go b/codegen/testserver/followschema/enums_test.go new file mode 100644 index 00000000000..4f4f1c76d8f --- /dev/null +++ b/codegen/testserver/followschema/enums_test.go @@ -0,0 +1,52 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestEnumsResolver(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.EnumInInput = func(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) { + return input.Enum, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("input with valid enum value", func(t *testing.T) { + var resp struct { + EnumInInput EnumTest + } + c.MustPost(`query { + enumInInput(input: {enum: OK}) + } + `, &resp) + require.Equal(t, resp.EnumInInput, EnumTestOk) + }) + + t.Run("input with invalid enum value", func(t *testing.T) { + var resp struct { + EnumInInput EnumTest + } + err := c.Post(`query { + enumInInput(input: {enum: INVALID}) + } + `, &resp) + require.EqualError(t, err, `http 422: {"errors":[{"message":"Expected type EnumTest!, found INVALID.","locations":[{"line":2,"column":30}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`) + }) + + t.Run("input with invalid enum value via vars", func(t *testing.T) { + var resp struct { + EnumInInput EnumTest + } + err := c.Post(`query ($input: InputWithEnumValue) { + enumInInput(input: $input) + } + `, &resp, client.Var("input", map[string]interface{}{"enum": "INVALID"})) + require.EqualError(t, err, `http 422: {"errors":[{"message":"INVALID is not a valid EnumTest","path":["variable","input","enum"],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`) + }) +} diff --git a/codegen/testserver/followschema/generated_test.go b/codegen/testserver/followschema/generated_test.go new file mode 100644 index 00000000000..9d10cde2c35 --- /dev/null +++ b/codegen/testserver/followschema/generated_test.go @@ -0,0 +1,80 @@ +//go:generate rm -f resolver.go +//go:generate go run ../../../testdata/gqlgen.go -config gqlgen.yml -stub stub.go + +package followschema + +import ( + "context" + "reflect" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestForcedResolverFieldIsPointer(t *testing.T) { + field, ok := reflect.TypeOf((*ForcedResolverResolver)(nil)).Elem().MethodByName("Field") + require.True(t, ok) + require.Equal(t, "*followschema.Circle", field.Type.Out(0).String()) +} + +func TestEnums(t *testing.T) { + t.Run("list of enums", func(t *testing.T) { + require.Equal(t, StatusOk, AllStatus[0]) + require.Equal(t, StatusError, AllStatus[1]) + }) + + t.Run("invalid enum values", func(t *testing.T) { + require.Equal(t, StatusOk, AllStatus[0]) + require.Equal(t, StatusError, AllStatus[1]) + }) +} + +func TestUnionFragments(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.ShapeUnion = func(ctx context.Context) (ShapeUnion, error) { + return &Circle{Radius: 32}, nil + } + + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + c := client.New(srv) + + t.Run("inline fragment on union", func(t *testing.T) { + var resp struct { + ShapeUnion struct { + Radius float64 + } + } + c.MustPost(`query { + shapeUnion { + ... on Circle { + radius + } + } + } + `, &resp) + require.NotEmpty(t, resp.ShapeUnion.Radius) + }) + + t.Run("named fragment", func(t *testing.T) { + var resp struct { + ShapeUnion struct { + Radius float64 + } + } + c.MustPost(`query { + shapeUnion { + ...C + } + } + + fragment C on ShapeUnion { + ... on Circle { + radius + } + } + `, &resp) + require.NotEmpty(t, resp.ShapeUnion.Radius) + }) +} diff --git a/codegen/testserver/followschema/gqlgen.yml b/codegen/testserver/followschema/gqlgen.yml new file mode 100644 index 00000000000..02f25a0d120 --- /dev/null +++ b/codegen/testserver/followschema/gqlgen.yml @@ -0,0 +1,24 @@ +schema: + - "*.graphql" +skip_validation: true +exec: + layout: follow-schema + dir: . + package: followschema +model: + filename: models-gen.go + package: followschema +resolver: + filename: resolver.go + package: followschema + type: Resolver + +autobind: + - "github.com/99designs/gqlgen/codegen/testserver" + - "github.com/99designs/gqlgen/codegen/testserver/followschema" + - "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" + - "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" + +models: + Email: + model: "github.com/99designs/gqlgen/codegen/testserver/followschema.Email" diff --git a/codegen/testserver/followschema/input_test.go b/codegen/testserver/followschema/input_test.go new file mode 100644 index 00000000000..b4417a010af --- /dev/null +++ b/codegen/testserver/followschema/input_test.go @@ -0,0 +1,69 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestInput(t *testing.T) { + resolvers := &Stub{} + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + c := client.New(srv) + + t.Run("when function errors on directives", func(t *testing.T) { + resolvers.QueryResolver.InputSlice = func(ctx context.Context, arg []string) (b bool, e error) { + return true, nil + } + + var resp struct { + DirectiveArg *string + } + + err := c.Post(`query { inputSlice(arg: ["ok", 1, 2, "ok"]) }`, &resp) + + require.EqualError(t, err, `http 422: {"errors":[{"message":"Expected type String!, found 1.","locations":[{"line":1,"column":32}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}},{"message":"Expected type String!, found 2.","locations":[{"line":1,"column":35}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}],"data":null}`) + require.Nil(t, resp.DirectiveArg) + }) + + t.Run("when input slice nullable", func(t *testing.T) { + resolvers.QueryResolver.InputNullableSlice = func(ctx context.Context, arg []string) (b bool, e error) { + return arg == nil, nil + } + + var resp struct { + InputNullableSlice bool + } + var err error + err = c.Post(`query { inputNullableSlice(arg: null) }`, &resp) + require.NoError(t, err) + require.True(t, resp.InputNullableSlice) + + err = c.Post(`query { inputNullableSlice(arg: []) }`, &resp) + require.NoError(t, err) + require.False(t, resp.InputNullableSlice) + }) + + t.Run("coerce single value to slice", func(t *testing.T) { + check := func(ctx context.Context, arg []string) (b bool, e error) { + return len(arg) == 1 && arg[0] == "coerced", nil + } + resolvers.QueryResolver.InputSlice = check + resolvers.QueryResolver.InputNullableSlice = check + + var resp struct { + Coerced bool + } + var err error + err = c.Post(`query { coerced: inputSlice(arg: "coerced") }`, &resp) + require.NoError(t, err) + require.True(t, resp.Coerced) + + err = c.Post(`query { coerced: inputNullableSlice(arg: "coerced") }`, &resp) + require.NoError(t, err) + require.True(t, resp.Coerced) + }) +} diff --git a/codegen/testserver/followschema/interfaces.generated.go b/codegen/testserver/followschema/interfaces.generated.go new file mode 100644 index 00000000000..5d139fc5d65 --- /dev/null +++ b/codegen/testserver/followschema/interfaces.generated.go @@ -0,0 +1,1060 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type BackedByInterfaceResolver interface { + ID(ctx context.Context, obj BackedByInterface) (string, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _BackedByInterface_id(ctx context.Context, field graphql.CollectedField, obj BackedByInterface) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "BackedByInterface", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.BackedByInterface().ID(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _BackedByInterface_thisShouldBind(ctx context.Context, field graphql.CollectedField, obj BackedByInterface) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "BackedByInterface", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ThisShouldBind(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _BackedByInterface_thisShouldBindWithError(ctx context.Context, field graphql.CollectedField, obj BackedByInterface) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "BackedByInterface", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ThisShouldBindWithError() + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Cat_species(ctx context.Context, field graphql.CollectedField, obj *Cat) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Cat", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Species, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Cat_catBreed(ctx context.Context, field graphql.CollectedField, obj *Cat) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Cat", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CatBreed, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Circle_radius(ctx context.Context, field graphql.CollectedField, obj *Circle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Circle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Radius, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalOFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Circle_area(ctx context.Context, field graphql.CollectedField, obj *Circle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Circle", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Area(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalOFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _ConcreteNodeA_id(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ConcreteNodeA", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ConcreteNodeA_child(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ConcreteNodeA", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Child() + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(Node) + fc.Result = res + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNode(ctx, field.Selections, res) +} + +func (ec *executionContext) _ConcreteNodeA_name(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ConcreteNodeA", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ConcreteNodeInterface_id(ctx context.Context, field graphql.CollectedField, obj ConcreteNodeInterface) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ConcreteNodeInterface", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ConcreteNodeInterface_child(ctx context.Context, field graphql.CollectedField, obj ConcreteNodeInterface) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ConcreteNodeInterface", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Child() + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(Node) + fc.Result = res + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNode(ctx, field.Selections, res) +} + +func (ec *executionContext) _Dog_species(ctx context.Context, field graphql.CollectedField, obj *Dog) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Dog", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Species, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Dog_dogBreed(ctx context.Context, field graphql.CollectedField, obj *Dog) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Dog", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DogBreed, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Rectangle_length(ctx context.Context, field graphql.CollectedField, obj *Rectangle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Rectangle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Length, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalOFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Rectangle_width(ctx context.Context, field graphql.CollectedField, obj *Rectangle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Rectangle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Width, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalOFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Rectangle_area(ctx context.Context, field graphql.CollectedField, obj *Rectangle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Rectangle", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Area(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalOFloat2float64(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _Animal(ctx context.Context, sel ast.SelectionSet, obj Animal) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case Dog: + return ec._Dog(ctx, sel, &obj) + case *Dog: + if obj == nil { + return graphql.Null + } + return ec._Dog(ctx, sel, obj) + case Cat: + return ec._Cat(ctx, sel, &obj) + case *Cat: + if obj == nil { + return graphql.Null + } + return ec._Cat(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj Node) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case *ConcreteNodeA: + if obj == nil { + return graphql.Null + } + return ec._ConcreteNodeA(ctx, sel, obj) + case ConcreteNodeInterface: + if obj == nil { + return graphql.Null + } + return ec._ConcreteNodeInterface(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) _Shape(ctx context.Context, sel ast.SelectionSet, obj Shape) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case *Circle: + if obj == nil { + return graphql.Null + } + return ec._Circle(ctx, sel, obj) + case *Rectangle: + if obj == nil { + return graphql.Null + } + return ec._Rectangle(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) _ShapeUnion(ctx context.Context, sel ast.SelectionSet, obj ShapeUnion) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case *Circle: + if obj == nil { + return graphql.Null + } + return ec._Circle(ctx, sel, obj) + case *Rectangle: + if obj == nil { + return graphql.Null + } + return ec._Rectangle(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var backedByInterfaceImplementors = []string{"BackedByInterface"} + +func (ec *executionContext) _BackedByInterface(ctx context.Context, sel ast.SelectionSet, obj BackedByInterface) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, backedByInterfaceImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("BackedByInterface") + case "id": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._BackedByInterface_id(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "thisShouldBind": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._BackedByInterface_thisShouldBind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "thisShouldBindWithError": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._BackedByInterface_thisShouldBindWithError(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var catImplementors = []string{"Cat", "Animal"} + +func (ec *executionContext) _Cat(ctx context.Context, sel ast.SelectionSet, obj *Cat) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, catImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Cat") + case "species": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Cat_species(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "catBreed": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Cat_catBreed(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var circleImplementors = []string{"Circle", "Shape", "ShapeUnion"} + +func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, obj *Circle) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, circleImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Circle") + case "radius": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_radius(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "area": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_area(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var concreteNodeAImplementors = []string{"ConcreteNodeA", "Node"} + +func (ec *executionContext) _ConcreteNodeA(ctx context.Context, sel ast.SelectionSet, obj *ConcreteNodeA) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, concreteNodeAImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ConcreteNodeA") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "child": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_child(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeA_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var concreteNodeInterfaceImplementors = []string{"ConcreteNodeInterface", "Node"} + +func (ec *executionContext) _ConcreteNodeInterface(ctx context.Context, sel ast.SelectionSet, obj ConcreteNodeInterface) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, concreteNodeInterfaceImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ConcreteNodeInterface") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeInterface_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "child": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ConcreteNodeInterface_child(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var dogImplementors = []string{"Dog", "Animal"} + +func (ec *executionContext) _Dog(ctx context.Context, sel ast.SelectionSet, obj *Dog) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, dogImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Dog") + case "species": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Dog_species(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "dogBreed": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Dog_dogBreed(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var rectangleImplementors = []string{"Rectangle", "Shape", "ShapeUnion"} + +func (ec *executionContext) _Rectangle(ctx context.Context, sel ast.SelectionSet, obj *Rectangle) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, rectangleImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Rectangle") + case "length": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_length(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "width": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_width(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "area": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_area(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNode(ctx context.Context, sel ast.SelectionSet, v Node) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._Node(ctx, sel, v) +} + +func (ec *executionContext) marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShapeUnion(ctx context.Context, sel ast.SelectionSet, v ShapeUnion) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._ShapeUnion(ctx, sel, v) +} + +func (ec *executionContext) marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐAnimal(ctx context.Context, sel ast.SelectionSet, v Animal) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Animal(ctx, sel, v) +} + +func (ec *executionContext) marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐBackedByInterface(ctx context.Context, sel ast.SelectionSet, v BackedByInterface) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._BackedByInterface(ctx, sel, v) +} + +func (ec *executionContext) marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCircle(ctx context.Context, sel ast.SelectionSet, v *Circle) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Circle(ctx, sel, v) +} + +func (ec *executionContext) marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx context.Context, sel ast.SelectionSet, v Shape) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Shape(ctx, sel, v) +} + +func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx context.Context, sel ast.SelectionSet, v []Shape) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/interfaces.go b/codegen/testserver/followschema/interfaces.go new file mode 100644 index 00000000000..39d908e4c24 --- /dev/null +++ b/codegen/testserver/followschema/interfaces.go @@ -0,0 +1,84 @@ +package followschema + +import "math" + +type Shape interface { + Area() float64 + isShape() +} + +type ShapeUnion interface { + Area() float64 + isShapeUnion() +} + +type Circle struct { + Radius float64 +} + +func (c *Circle) Area() float64 { + return c.Radius * math.Pi * math.Pi +} + +func (c *Circle) isShapeUnion() {} +func (c *Circle) isShape() {} + +type Rectangle struct { + Length, Width float64 +} + +func (r *Rectangle) Area() float64 { + return r.Length * r.Width +} +func (r *Rectangle) isShapeUnion() {} +func (r *Rectangle) isShape() {} + +type Node interface { + Child() (Node, error) +} + +type ConcreteNodeA struct { + ID string + Name string + child Node +} + +func (n *ConcreteNodeA) Child() (Node, error) { + return n.child, nil +} + +// Implements the Node interface with another interface +type ConcreteNodeInterface interface { + Node + ID() string +} + +type ConcreteNodeInterfaceImplementor struct{} + +func (c ConcreteNodeInterfaceImplementor) ID() string { + return "CNII" +} + +func (c ConcreteNodeInterfaceImplementor) Child() (Node, error) { + return &ConcreteNodeA{ + ID: "Child", + Name: "child", + }, nil +} + +type BackedByInterface interface { + ThisShouldBind() string + ThisShouldBindWithError() (string, error) +} + +type BackedByInterfaceImpl struct { + Value string + Error error +} + +func (b *BackedByInterfaceImpl) ThisShouldBind() string { + return b.Value +} +func (b *BackedByInterfaceImpl) ThisShouldBindWithError() (string, error) { + return b.Value, b.Error +} diff --git a/codegen/testserver/followschema/interfaces.graphql b/codegen/testserver/followschema/interfaces.graphql new file mode 100644 index 00000000000..4dc320f9a29 --- /dev/null +++ b/codegen/testserver/followschema/interfaces.graphql @@ -0,0 +1,62 @@ +extend type Query { + shapes: [Shape] + noShape: Shape @makeNil + node: Node! + noShapeTypedNil: Shape @makeTypedNil + animal: Animal @makeTypedNil + notAnInterface: BackedByInterface +} + +interface Animal { + species: String! +} + +type BackedByInterface { + id: String! + thisShouldBind: String! + thisShouldBindWithError: String! +} + +type Dog implements Animal { + species: String! + dogBreed: String! +} + +type Cat implements Animal { + species: String! + catBreed: String! +} + +interface Shape { + area: Float +} +type Circle implements Shape { + radius: Float + area: Float +} +type Rectangle implements Shape { + length: Float + width: Float + area: Float +} +union ShapeUnion @goModel(model:"followschema.ShapeUnion") = Circle | Rectangle + +directive @makeNil on FIELD_DEFINITION +directive @makeTypedNil on FIELD_DEFINITION + +interface Node { + id: ID! + child: Node! +} + +type ConcreteNodeA implements Node { + id: ID! + child: Node! + name: String! +} + +""" Implements the Node interface with another interface """ +type ConcreteNodeInterface implements Node { + id: ID! + child: Node! +} diff --git a/codegen/testserver/followschema/interfaces_test.go b/codegen/testserver/followschema/interfaces_test.go new file mode 100644 index 00000000000..c2fae2ff9ad --- /dev/null +++ b/codegen/testserver/followschema/interfaces_test.go @@ -0,0 +1,200 @@ +package followschema + +import ( + "context" + "fmt" + "reflect" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestInterfaces(t *testing.T) { + t.Run("slices of interfaces are not pointers", func(t *testing.T) { + field, ok := reflect.TypeOf((*QueryResolver)(nil)).Elem().MethodByName("Shapes") + require.True(t, ok) + require.Equal(t, "[]followschema.Shape", field.Type.Out(0).String()) + }) + + t.Run("models returning interfaces", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Node = func(ctx context.Context) (node Node, err error) { + return &ConcreteNodeA{ + ID: "1234", + Name: "asdf", + child: &ConcreteNodeA{ + ID: "5678", + Name: "hjkl", + child: nil, + }, + }, nil + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{ + Resolvers: resolvers, + }), + ) + + c := client.New(srv) + + var resp struct { + Node struct { + ID string + Child struct { + ID string + } + } + } + c.MustPost(`{ node { id, child { id } } }`, &resp) + require.Equal(t, "1234", resp.Node.ID) + require.Equal(t, "5678", resp.Node.Child.ID) + }) + + t.Run("interfaces can be nil", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.NoShape = func(ctx context.Context) (shapes Shape, e error) { + return nil, nil + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{ + Resolvers: resolvers, + Directives: DirectiveRoot{ + MakeNil: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + return nil, nil + }, + }, + }), + ) + + c := client.New(srv) + + var resp interface{} + c.MustPost(`{ noShape { area } }`, &resp) + }) + + t.Run("interfaces can be typed nil", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.NoShapeTypedNil = func(ctx context.Context) (shapes Shape, e error) { + panic("should not be called") + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{ + Resolvers: resolvers, + Directives: DirectiveRoot{ + MakeTypedNil: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + var circle *Circle + return circle, nil + }, + }, + }), + ) + + c := client.New(srv) + + var resp interface{} + c.MustPost(`{ noShapeTypedNil { area } }`, &resp) + }) + + t.Run("interfaces can be nil (test with code-generated resolver)", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Animal = func(ctx context.Context) (animal Animal, e error) { + panic("should not be called") + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{ + Resolvers: resolvers, + Directives: DirectiveRoot{ + MakeTypedNil: func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) { + var dog *Dog // return a typed nil, not just nil + return dog, nil + }, + }, + }), + ) + + c := client.New(srv) + + var resp interface{} + c.MustPost(`{ animal { species } }`, &resp) + }) + + t.Run("can bind to interfaces even when the graphql is not", func(t *testing.T) { + resolvers := &Stub{} + resolvers.BackedByInterfaceResolver.ID = func(ctx context.Context, obj BackedByInterface) (s string, err error) { + return "ID:" + obj.ThisShouldBind(), nil + } + resolvers.QueryResolver.NotAnInterface = func(ctx context.Context) (byInterface BackedByInterface, err error) { + return &BackedByInterfaceImpl{ + Value: "A", + Error: nil, + }, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + var resp struct { + NotAnInterface struct { + ID string + ThisShouldBind string + ThisShouldBindWithError string + } + } + c.MustPost(`{ notAnInterface { id, thisShouldBind, thisShouldBindWithError } }`, &resp) + require.Equal(t, "ID:A", resp.NotAnInterface.ID) + require.Equal(t, "A", resp.NotAnInterface.ThisShouldBind) + require.Equal(t, "A", resp.NotAnInterface.ThisShouldBindWithError) + }) + + t.Run("can return errors from interface funcs", func(t *testing.T) { + resolvers := &Stub{} + resolvers.BackedByInterfaceResolver.ID = func(ctx context.Context, obj BackedByInterface) (s string, err error) { + return "ID:" + obj.ThisShouldBind(), nil + } + resolvers.QueryResolver.NotAnInterface = func(ctx context.Context) (byInterface BackedByInterface, err error) { + return &BackedByInterfaceImpl{ + Value: "A", + Error: fmt.Errorf("boom"), + }, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + var resp struct { + NotAnInterface struct { + ID string + ThisShouldBind string + ThisShouldBindWithError string + } + } + err := c.Post(`{ notAnInterface { id, thisShouldBind, thisShouldBindWithError } }`, &resp) + require.EqualError(t, err, `[{"message":"boom","path":["notAnInterface","thisShouldBindWithError"]}]`) + }) + + t.Run("interfaces can implement other interfaces", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Node = func(ctx context.Context) (node Node, err error) { + return ConcreteNodeInterfaceImplementor{}, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + var resp struct { + Node struct { + ID string + Child struct { + ID string + } + } + } + c.MustPost(`{ node { id, child { id } } }`, &resp) + require.Equal(t, "CNII", resp.Node.ID) + require.Equal(t, "Child", resp.Node.Child.ID) + }) +} diff --git a/codegen/testserver/introspection/it.go b/codegen/testserver/followschema/introspection/it.go similarity index 100% rename from codegen/testserver/introspection/it.go rename to codegen/testserver/followschema/introspection/it.go diff --git a/codegen/testserver/followschema/introspection_test.go b/codegen/testserver/followschema/introspection_test.go new file mode 100644 index 00000000000..ef2bfafb53b --- /dev/null +++ b/codegen/testserver/followschema/introspection_test.go @@ -0,0 +1,79 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/stretchr/testify/require" +) + +func TestIntrospection(t *testing.T) { + t.Run("disabled when creating your own server", func(t *testing.T) { + resolvers := &Stub{} + + srv := handler.New(NewExecutableSchema(Config{Resolvers: resolvers})) + srv.AddTransport(transport.POST{}) + c := client.New(srv) + + var resp interface{} + err := c.Post(introspection.Query, &resp) + require.EqualError(t, err, "[{\"message\":\"introspection disabled\",\"path\":[\"__schema\"]}]") + }) + + t.Run("enabled by default", func(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolvers}), + )) + + var resp interface{} + err := c.Post(introspection.Query, &resp) + require.NoError(t, err) + + t.Run("does not return empty deprecation strings", func(t *testing.T) { + q := `{ + __type(name:"InnerObject") { + fields { + name + deprecationReason + } + } + }` + + var resp struct { + Type struct { + Fields []struct { + Name string + DeprecationReason *string + } + } `json:"__type"` + } + err := c.Post(q, &resp) + require.NoError(t, err) + + require.Equal(t, "id", resp.Type.Fields[0].Name) + require.Nil(t, resp.Type.Fields[0].DeprecationReason) + }) + }) + + t.Run("disabled by middleware", func(t *testing.T) { + resolvers := &Stub{} + + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler { + graphql.GetOperationContext(ctx).DisableIntrospection = true + return next(ctx) + }) + c := client.New(srv) + + var resp interface{} + err := c.Post(introspection.Query, &resp) + require.EqualError(t, err, "[{\"message\":\"introspection disabled\",\"path\":[\"__schema\"]}]") + }) +} diff --git a/codegen/testserver/invalid-packagename/invalid-identifier.go b/codegen/testserver/followschema/invalid-packagename/invalid-identifier.go similarity index 100% rename from codegen/testserver/invalid-packagename/invalid-identifier.go rename to codegen/testserver/followschema/invalid-packagename/invalid-identifier.go diff --git a/codegen/testserver/followschema/issue896.generated.go b/codegen/testserver/followschema/issue896.generated.go new file mode 100644 index 00000000000..43591226e8f --- /dev/null +++ b/codegen/testserver/followschema/issue896.generated.go @@ -0,0 +1,206 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _CheckIssue896_id(ctx context.Context, field graphql.CollectedField, obj *CheckIssue896) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "CheckIssue896", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*int) + fc.Result = res + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var checkIssue896Implementors = []string{"CheckIssue896"} + +func (ec *executionContext) _CheckIssue896(ctx context.Context, sel ast.SelectionSet, obj *CheckIssue896) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, checkIssue896Implementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CheckIssue896") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._CheckIssue896_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._CheckIssue896(ctx, sel, v) +} + +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896ᚄ(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._CheckIssue896(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/issue896.graphql b/codegen/testserver/followschema/issue896.graphql similarity index 100% rename from codegen/testserver/issue896.graphql rename to codegen/testserver/followschema/issue896.graphql diff --git a/codegen/testserver/followschema/loops.generated.go b/codegen/testserver/followschema/loops.generated.go new file mode 100644 index 00000000000..b90f1fa7ef6 --- /dev/null +++ b/codegen/testserver/followschema/loops.generated.go @@ -0,0 +1,189 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _LoopA_b(ctx context.Context, field graphql.CollectedField, obj *LoopA) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "LoopA", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.B, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*LoopB) + fc.Result = res + return ec.marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐLoopB(ctx, field.Selections, res) +} + +func (ec *executionContext) _LoopB_a(ctx context.Context, field graphql.CollectedField, obj *LoopB) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "LoopB", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.A, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*LoopA) + fc.Result = res + return ec.marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐLoopA(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var loopAImplementors = []string{"LoopA"} + +func (ec *executionContext) _LoopA(ctx context.Context, sel ast.SelectionSet, obj *LoopA) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, loopAImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LoopA") + case "b": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._LoopA_b(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var loopBImplementors = []string{"LoopB"} + +func (ec *executionContext) _LoopB(ctx context.Context, sel ast.SelectionSet, obj *LoopB) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, loopBImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LoopB") + case "a": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._LoopB_a(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐLoopA(ctx context.Context, sel ast.SelectionSet, v *LoopA) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._LoopA(ctx, sel, v) +} + +func (ec *executionContext) marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐLoopB(ctx context.Context, sel ast.SelectionSet, v *LoopB) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._LoopB(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/loops.graphql b/codegen/testserver/followschema/loops.graphql similarity index 100% rename from codegen/testserver/loops.graphql rename to codegen/testserver/followschema/loops.graphql diff --git a/codegen/testserver/followschema/maps.generated.go b/codegen/testserver/followschema/maps.generated.go new file mode 100644 index 00000000000..d82085836b7 --- /dev/null +++ b/codegen/testserver/followschema/maps.generated.go @@ -0,0 +1,200 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "fmt" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _MapStringInterfaceType_a(ctx context.Context, field graphql.CollectedField, obj map[string]interface{}) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "MapStringInterfaceType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + switch v := obj["a"].(type) { + case *string: + return v, nil + case string: + return &v, nil + case nil: + return (*string)(nil), nil + default: + return nil, fmt.Errorf("unexpected type %T for field %s", v, "a") + } + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _MapStringInterfaceType_b(ctx context.Context, field graphql.CollectedField, obj map[string]interface{}) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "MapStringInterfaceType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + switch v := obj["b"].(type) { + case *int: + return v, nil + case int: + return &v, nil + case nil: + return (*int)(nil), nil + default: + return nil, fmt.Errorf("unexpected type %T for field %s", v, "b") + } + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*int) + fc.Result = res + return ec.marshalOInt2ᚖint(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputNestedMapInput(ctx context.Context, obj interface{}) (NestedMapInput, error) { + var it NestedMapInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "map": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("map")) + it.Map, err = ec.unmarshalOMapStringInterfaceInput2map(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var mapStringInterfaceTypeImplementors = []string{"MapStringInterfaceType"} + +func (ec *executionContext) _MapStringInterfaceType(ctx context.Context, sel ast.SelectionSet, obj map[string]interface{}) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mapStringInterfaceTypeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("MapStringInterfaceType") + case "a": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MapStringInterfaceType_a(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "b": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._MapStringInterfaceType_b(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalOMapStringInterfaceInput2map(ctx context.Context, v interface{}) (map[string]interface{}, error) { + if v == nil { + return nil, nil + } + return v.(map[string]interface{}), nil +} + +func (ec *executionContext) marshalOMapStringInterfaceType2map(ctx context.Context, sel ast.SelectionSet, v map[string]interface{}) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._MapStringInterfaceType(ctx, sel, v) +} + +func (ec *executionContext) unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNestedMapInput(ctx context.Context, v interface{}) (*NestedMapInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputNestedMapInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/maps.graphql b/codegen/testserver/followschema/maps.graphql similarity index 100% rename from codegen/testserver/maps.graphql rename to codegen/testserver/followschema/maps.graphql diff --git a/codegen/testserver/followschema/maps_test.go b/codegen/testserver/followschema/maps_test.go new file mode 100644 index 00000000000..fe9750450fb --- /dev/null +++ b/codegen/testserver/followschema/maps_test.go @@ -0,0 +1,73 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestMaps(t *testing.T) { + resolver := &Stub{} + resolver.QueryResolver.MapStringInterface = func(ctx context.Context, in map[string]interface{}) (i map[string]interface{}, e error) { + return in, nil + } + resolver.QueryResolver.MapNestedStringInterface = func(ctx context.Context, in *NestedMapInput) (i map[string]interface{}, e error) { + if in == nil { + return nil, nil + } + return in.Map, nil + } + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolver}), + )) + t.Run("unset", func(t *testing.T) { + var resp struct { + MapStringInterface map[string]interface{} + } + err := c.Post(`query { mapStringInterface { a, b } }`, &resp) + require.NoError(t, err) + require.Nil(t, resp.MapStringInterface) + }) + + t.Run("nil", func(t *testing.T) { + var resp struct { + MapStringInterface map[string]interface{} + } + err := c.Post(`query { mapStringInterface(in: null) { a, b } }`, &resp) + require.NoError(t, err) + require.Nil(t, resp.MapStringInterface) + }) + + t.Run("values", func(t *testing.T) { + var resp struct { + MapStringInterface map[string]interface{} + } + err := c.Post(`query { mapStringInterface(in: { a: "a", b: null }) { a, b } }`, &resp) + require.NoError(t, err) + require.Equal(t, "a", resp.MapStringInterface["a"]) + require.Nil(t, resp.MapStringInterface["b"]) + }) + + t.Run("nested", func(t *testing.T) { + var resp struct { + MapNestedStringInterface map[string]interface{} + } + err := c.Post(`query { mapNestedStringInterface(in: { map: { a: "a", b: null } }) { a, b } }`, &resp) + require.NoError(t, err) + require.Equal(t, "a", resp.MapNestedStringInterface["a"]) + require.Nil(t, resp.MapNestedStringInterface["b"]) + }) + + t.Run("nested nil", func(t *testing.T) { + var resp struct { + MapNestedStringInterface map[string]interface{} + } + err := c.Post(`query { mapNestedStringInterface(in: { map: null }) { a, b } }`, &resp) + require.NoError(t, err) + require.Nil(t, resp.MapNestedStringInterface) + }) +} diff --git a/codegen/testserver/followschema/middleware_test.go b/codegen/testserver/followschema/middleware_test.go new file mode 100644 index 00000000000..843ca806f88 --- /dev/null +++ b/codegen/testserver/followschema/middleware_test.go @@ -0,0 +1,110 @@ +package followschema + +import ( + "context" + "sync" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestMiddleware(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.ErrorBubble = func(ctx context.Context) (i *Error, e error) { + return &Error{ID: "E1234"}, nil + } + + resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) { + return &User{ID: 1}, nil + } + + resolvers.UserResolver.Friends = func(ctx context.Context, obj *User) (users []*User, e error) { + return []*User{{ID: 1}}, nil + } + + resolvers.QueryResolver.ModelMethods = func(ctx context.Context) (methods *ModelMethods, e error) { + return &ModelMethods{}, nil + } + + var mu sync.Mutex + areMethods := map[string]bool{} + areResolvers := map[string]bool{} + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolvers}), + ) + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) + }) + + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) + }) + + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + fc := graphql.GetFieldContext(ctx) + mu.Lock() + areMethods[fc.Field.Name] = fc.IsMethod + areResolvers[fc.Field.Name] = fc.IsResolver + mu.Unlock() + return next(ctx) + }) + + c := client.New(srv) + + var resp struct { + User struct { + ID int + Friends []struct { + ID int + } + } + ModelMethods struct { + NoContext bool + } + } + + called := false + resolvers.UserResolver.Friends = func(ctx context.Context, obj *User) ([]*User, error) { + assert.Equal(t, []int{1, 2, 1, 2}, ctx.Value(ckey("path"))) + called = true + return []*User{}, nil + } + + err := c.Post(`query { + user(id: 1) { + id, + friends { + id + } + } + modelMethods { + noContext + } + }`, &resp) + + assert.Equal(t, map[string]bool{ + "user": true, + "id": false, + "friends": true, + "modelMethods": true, + "noContext": true, + }, areMethods) + assert.Equal(t, map[string]bool{ + "user": true, + "id": false, + "friends": true, + "modelMethods": true, + "noContext": false, + }, areResolvers) + + require.NoError(t, err) + require.True(t, called) + +} diff --git a/codegen/testserver/followschema/modelmethod_test.go b/codegen/testserver/followschema/modelmethod_test.go new file mode 100644 index 00000000000..4cf1803729e --- /dev/null +++ b/codegen/testserver/followschema/modelmethod_test.go @@ -0,0 +1,44 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestModelMethods(t *testing.T) { + resolver := &Stub{} + resolver.QueryResolver.ModelMethods = func(ctx context.Context) (methods *ModelMethods, e error) { + return &ModelMethods{}, nil + } + resolver.ModelMethodsResolver.ResolverField = func(ctx context.Context, obj *ModelMethods) (b bool, e error) { + return true, nil + } + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolver}), + )) + t.Run("without context", func(t *testing.T) { + var resp struct { + ModelMethods struct { + NoContext bool + } + } + err := c.Post(`query { modelMethods{ noContext } }`, &resp) + require.NoError(t, err) + require.True(t, resp.ModelMethods.NoContext) + }) + t.Run("with context", func(t *testing.T) { + var resp struct { + ModelMethods struct { + WithContext bool + } + } + err := c.Post(`query { modelMethods{ withContext } }`, &resp) + require.NoError(t, err) + require.True(t, resp.ModelMethods.WithContext) + }) +} diff --git a/codegen/testserver/followschema/models-gen.go b/codegen/testserver/followschema/models-gen.go new file mode 100644 index 00000000000..7e24f2aa394 --- /dev/null +++ b/codegen/testserver/followschema/models-gen.go @@ -0,0 +1,299 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "fmt" + "io" + "strconv" + "time" +) + +type Animal interface { + IsAnimal() +} + +type ContentChild interface { + IsContentChild() +} + +type TestUnion interface { + IsTestUnion() +} + +type A struct { + ID string `json:"id"` +} + +func (A) IsTestUnion() {} + +type AIt struct { + ID string `json:"id"` +} + +type AbIt struct { + ID string `json:"id"` +} + +type B struct { + ID string `json:"id"` +} + +func (B) IsTestUnion() {} + +type Cat struct { + Species string `json:"species"` + CatBreed string `json:"catBreed"` +} + +func (Cat) IsAnimal() {} + +type CheckIssue896 struct { + ID *int `json:"id"` +} + +type ContentPost struct { + Foo *string `json:"foo"` +} + +func (ContentPost) IsContentChild() {} + +type ContentUser struct { + Foo *string `json:"foo"` +} + +func (ContentUser) IsContentChild() {} + +type DefaultInput struct { + FalsyBoolean *bool `json:"falsyBoolean"` + TruthyBoolean *bool `json:"truthyBoolean"` +} + +type DefaultParametersMirror struct { + FalsyBoolean *bool `json:"falsyBoolean"` + TruthyBoolean *bool `json:"truthyBoolean"` +} + +type Dog struct { + Species string `json:"species"` + DogBreed string `json:"dogBreed"` +} + +func (Dog) IsAnimal() {} + +type EmbeddedDefaultScalar struct { + Value *string `json:"value"` +} + +type InnerDirectives struct { + Message string `json:"message"` +} + +type InnerInput struct { + ID int `json:"id"` +} + +type InnerObject struct { + ID int `json:"id"` +} + +type InputDirectives struct { + Text string `json:"text"` + NullableText *string `json:"nullableText"` + Inner *InnerDirectives `json:"inner"` + InnerNullable *InnerDirectives `json:"innerNullable"` + ThirdParty *ThirdParty `json:"thirdParty"` +} + +type InputWithEnumValue struct { + Enum EnumTest `json:"enum"` +} + +type LoopA struct { + B *LoopB `json:"b"` +} + +type LoopB struct { + A *LoopA `json:"a"` +} + +// Since gqlgen defines default implementation for a Map scalar, this tests that the builtin is _not_ +// added to the TypeMap +type Map struct { + ID string `json:"id"` +} + +type NestedInput struct { + Field Email `json:"field"` +} + +type NestedMapInput struct { + Map map[string]interface{} `json:"map"` +} + +type ObjectDirectives struct { + Text string `json:"text"` + NullableText *string `json:"nullableText"` + Order []string `json:"order"` +} + +type OuterInput struct { + Inner *InnerInput `json:"inner"` +} + +type OuterObject struct { + Inner *InnerObject `json:"inner"` +} + +type Slices struct { + Test1 []*string `json:"test1"` + Test2 []string `json:"test2"` + Test3 []*string `json:"test3"` + Test4 []string `json:"test4"` +} + +type SpecialInput struct { + Nesting *NestedInput `json:"nesting"` +} + +type User struct { + ID int `json:"id"` + Friends []*User `json:"friends"` + Created time.Time `json:"created"` + Updated *time.Time `json:"updated"` +} + +type ValidInput struct { + Break string `json:"break"` + Default string `json:"default"` + Func string `json:"func"` + Interface string `json:"interface"` + Select string `json:"select"` + Case string `json:"case"` + Defer string `json:"defer"` + Go string `json:"go"` + Map string `json:"map"` + Struct string `json:"struct"` + Chan string `json:"chan"` + Else string `json:"else"` + Goto string `json:"goto"` + Package string `json:"package"` + Switch string `json:"switch"` + Const string `json:"const"` + Fallthrough string `json:"fallthrough"` + If string `json:"if"` + Range string `json:"range"` + Type string `json:"type"` + Continue string `json:"continue"` + For string `json:"for"` + Import string `json:"import"` + Return string `json:"return"` + Var string `json:"var"` + Underscore string `json:"_"` +} + +// These things are all valid, but without care generate invalid go code +type ValidType struct { + DifferentCase string `json:"differentCase"` + DifferentCaseOld string `json:"different_case"` + ValidInputKeywords bool `json:"validInputKeywords"` + ValidArgs bool `json:"validArgs"` +} + +type XXIt struct { + ID string `json:"id"` +} + +type XxIt struct { + ID string `json:"id"` +} + +type AsdfIt struct { + ID string `json:"id"` +} + +type IIt struct { + ID string `json:"id"` +} + +type EnumTest string + +const ( + EnumTestOk EnumTest = "OK" + EnumTestNg EnumTest = "NG" +) + +var AllEnumTest = []EnumTest{ + EnumTestOk, + EnumTestNg, +} + +func (e EnumTest) IsValid() bool { + switch e { + case EnumTestOk, EnumTestNg: + return true + } + return false +} + +func (e EnumTest) String() string { + return string(e) +} + +func (e *EnumTest) UnmarshalGQL(v interface{}) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = EnumTest(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid EnumTest", str) + } + return nil +} + +func (e EnumTest) MarshalGQL(w io.Writer) { + fmt.Fprint(w, strconv.Quote(e.String())) +} + +type Status string + +const ( + StatusOk Status = "OK" + StatusError Status = "ERROR" +) + +var AllStatus = []Status{ + StatusOk, + StatusError, +} + +func (e Status) IsValid() bool { + switch e { + case StatusOk, StatusError: + return true + } + return false +} + +func (e Status) String() string { + return string(e) +} + +func (e *Status) UnmarshalGQL(v interface{}) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = Status(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid Status", str) + } + return nil +} + +func (e Status) MarshalGQL(w io.Writer) { + fmt.Fprint(w, strconv.Quote(e.String())) +} diff --git a/codegen/testserver/followschema/models.go b/codegen/testserver/followschema/models.go new file mode 100644 index 00000000000..66fa415d75c --- /dev/null +++ b/codegen/testserver/followschema/models.go @@ -0,0 +1,106 @@ +package followschema + +import ( + "context" + "fmt" + "io" +) + +type ForcedResolver struct { + Field Circle +} + +type ModelMethods struct { +} + +func (m ModelMethods) NoContext() bool { + return true +} + +func (m ModelMethods) WithContext(_ context.Context) bool { + return true +} + +type Errors struct{} + +type Error struct { + ID string +} + +func (Error) ErrorOnRequiredField() (string, error) { + return "", fmt.Errorf("boom") +} + +func (Error) ErrorOnNonRequiredField() (string, error) { + return "", fmt.Errorf("boom") +} + +func (Error) NilOnRequiredField() *string { + return nil +} + +type EmbeddedPointerModel struct { + *EmbeddedPointer + ID string +} + +type EmbeddedPointer struct { + Title string +} + +type MarshalPanic string + +func (m *MarshalPanic) UnmarshalGQL(v interface{}) error { + panic("BOOM") +} + +func (m MarshalPanic) MarshalGQL(w io.Writer) { + panic("BOOM") +} + +type Panics struct { +} + +func (p *Panics) FieldFuncMarshal(ctx context.Context, u []MarshalPanic) []MarshalPanic { + return []MarshalPanic{MarshalPanic("aa"), MarshalPanic("bb")} +} + +type Autobind struct { + Int int + Int32 int32 + Int64 int64 + + IdStr string + IdInt int +} + +type OverlappingFields struct { + Foo int + NewFoo int +} + +type ObjectDirectivesWithCustomGoModel struct { + NullableText string // not *string, but schema is `String @toNull` type. +} + +type FallbackToStringEncoding string + +const ( + FallbackToStringEncodingA FallbackToStringEncoding = "A" + FallbackToStringEncodingB FallbackToStringEncoding = "B" + FallbackToStringEncodingC FallbackToStringEncoding = "C" +) + +type Primitive int + +func (p Primitive) Squared() int { + return int(p) * int(p) +} + +type PrimitiveString string + +func (s PrimitiveString) Doubled() string { + return string(s) + string(s) +} + +type Bytes []byte diff --git a/codegen/testserver/followschema/mutation_with_custom_scalar.generated.go b/codegen/testserver/followschema/mutation_with_custom_scalar.generated.go new file mode 100644 index 00000000000..c0d4d0bd93f --- /dev/null +++ b/codegen/testserver/followschema/mutation_with_custom_scalar.generated.go @@ -0,0 +1,108 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputNestedInput(ctx context.Context, obj interface{}) (NestedInput, error) { + var it NestedInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "field": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + it.Field, err = ec.unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmail(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputSpecialInput(ctx context.Context, obj interface{}) (SpecialInput, error) { + var it SpecialInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "nesting": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nesting")) + it.Nesting, err = ec.unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNestedInput(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmail(ctx context.Context, v interface{}) (Email, error) { + var res Email + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmail(ctx context.Context, sel ast.SelectionSet, v Email) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNestedInput(ctx context.Context, v interface{}) (*NestedInput, error) { + res, err := ec.unmarshalInputNestedInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐSpecialInput(ctx context.Context, v interface{}) (SpecialInput, error) { + res, err := ec.unmarshalInputSpecialInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/mutation_with_custom_scalar.go b/codegen/testserver/followschema/mutation_with_custom_scalar.go new file mode 100644 index 00000000000..6245a5fc9b1 --- /dev/null +++ b/codegen/testserver/followschema/mutation_with_custom_scalar.go @@ -0,0 +1,29 @@ +package followschema + +import ( + "encoding/json" + "fmt" + "io" + "regexp" +) + +var re = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$") + +type Email string + +func (value *Email) UnmarshalGQL(v interface{}) error { + input, ok := v.(string) + if !ok { + return fmt.Errorf("email expects a string value") + } + if !re.MatchString(input) { + return fmt.Errorf("invalid email format") + } + *value = Email(input) + return nil +} + +func (value Email) MarshalGQL(w io.Writer) { + output, _ := json.Marshal(string(value)) + w.Write(output) +} diff --git a/codegen/testserver/mutation_with_custom_scalar.graphql b/codegen/testserver/followschema/mutation_with_custom_scalar.graphql similarity index 100% rename from codegen/testserver/mutation_with_custom_scalar.graphql rename to codegen/testserver/followschema/mutation_with_custom_scalar.graphql diff --git a/codegen/testserver/followschema/mutation_with_custom_scalar_test.go b/codegen/testserver/followschema/mutation_with_custom_scalar_test.go new file mode 100644 index 00000000000..2f46c3ad4d0 --- /dev/null +++ b/codegen/testserver/followschema/mutation_with_custom_scalar_test.go @@ -0,0 +1,50 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestErrorInsideMutationArgument(t *testing.T) { + resolvers := &Stub{} + resolvers.MutationResolver.UpdateSomething = func(_ context.Context, input SpecialInput) (s string, err error) { + return "Hello world", nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("mutation with correct input doesn't return error", func(t *testing.T) { + var resp map[string]interface{} + input := map[string]interface{}{ + "nesting": map[string]interface{}{ + "field": "email@example.com", + }, + } + err := c.Post( + `mutation TestMutation($input: SpecialInput!) { updateSomething(input: $input) }`, + &resp, + client.Var("input", input), + ) + require.Equal(t, resp["updateSomething"], "Hello world") + require.NoError(t, err) + }) + + t.Run("mutation with incorrect input returns full path", func(t *testing.T) { + var resp map[string]interface{} + input := map[string]interface{}{ + "nesting": map[string]interface{}{ + "field": "not-an-email", + }, + } + err := c.Post( + `mutation TestMutation($input: SpecialInput!) { updateSomething(input: $input) }`, + &resp, + client.Var("input", input), + ) + require.EqualError(t, err, `[{"message":"invalid email format","path":["updateSomething","input","nesting","field"]}]`) + }) +} diff --git a/codegen/testserver/followschema/nulls.generated.go b/codegen/testserver/followschema/nulls.generated.go new file mode 100644 index 00000000000..33cec45379c --- /dev/null +++ b/codegen/testserver/followschema/nulls.generated.go @@ -0,0 +1,633 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type ErrorsResolver interface { + A(ctx context.Context, obj *Errors) (*Error, error) + B(ctx context.Context, obj *Errors) (*Error, error) + C(ctx context.Context, obj *Errors) (*Error, error) + D(ctx context.Context, obj *Errors) (*Error, error) + E(ctx context.Context, obj *Errors) (*Error, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Error_id(ctx context.Context, field graphql.CollectedField, obj *Error) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Error", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Error_errorOnNonRequiredField(ctx context.Context, field graphql.CollectedField, obj *Error) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Error", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ErrorOnNonRequiredField() + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Error_errorOnRequiredField(ctx context.Context, field graphql.CollectedField, obj *Error) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Error", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ErrorOnRequiredField() + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Error_nilOnRequiredField(ctx context.Context, field graphql.CollectedField, obj *Error) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Error", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NilOnRequiredField(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalNString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Errors_a(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Errors", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Errors().A(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Errors_b(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Errors", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Errors().B(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Errors_c(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Errors", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Errors().C(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Errors_d(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Errors", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Errors().D(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Errors_e(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Errors", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Errors().E(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var errorImplementors = []string{"Error"} + +func (ec *executionContext) _Error(ctx context.Context, sel ast.SelectionSet, obj *Error) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, errorImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Error") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "errorOnNonRequiredField": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_errorOnNonRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "errorOnRequiredField": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_errorOnRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "nilOnRequiredField": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Error_nilOnRequiredField(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var errorsImplementors = []string{"Errors"} + +func (ec *executionContext) _Errors(ctx context.Context, sel ast.SelectionSet, obj *Errors) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, errorsImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Errors") + case "a": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Errors_a(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "b": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Errors_b(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "c": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Errors_c(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "d": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Errors_d(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "e": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Errors_e(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNError2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx context.Context, sel ast.SelectionSet, v Error) graphql.Marshaler { + return ec._Error(ctx, sel, &v) +} + +func (ec *executionContext) marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._Error(ctx, sel, v) +} + +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐErrorᚄ(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Error(ctx, sel, v) +} + +func (ec *executionContext) marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐErrors(ctx context.Context, sel ast.SelectionSet, v *Errors) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Errors(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/nulls.graphql b/codegen/testserver/followschema/nulls.graphql similarity index 100% rename from codegen/testserver/nulls.graphql rename to codegen/testserver/followschema/nulls.graphql diff --git a/codegen/testserver/followschema/nulls_test.go b/codegen/testserver/followschema/nulls_test.go new file mode 100644 index 00000000000..ef586e01c93 --- /dev/null +++ b/codegen/testserver/followschema/nulls_test.go @@ -0,0 +1,134 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestNullBubbling(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Valid = func(ctx context.Context) (s string, e error) { + return "Ok", nil + } + resolvers.QueryResolver.Errors = func(ctx context.Context) (errors *Errors, e error) { + return &Errors{}, nil + } + resolvers.QueryResolver.ErrorBubble = func(ctx context.Context) (i *Error, e error) { + return &Error{ID: "E1234"}, nil + } + resolvers.QueryResolver.ErrorBubbleList = func(ctx context.Context) (i []*Error, e error) { + return []*Error{nil}, nil + } + resolvers.QueryResolver.ErrorList = func(ctx context.Context) (i []*Error, e error) { + return []*Error{nil}, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("when function errors on non required field", func(t *testing.T) { + var resp struct { + Valid string + ErrorBubble *struct { + Id string + ErrorOnNonRequiredField *string + } + } + err := c.Post(`query { valid, errorBubble { id, errorOnNonRequiredField } }`, &resp) + + require.EqualError(t, err, `[{"message":"boom","path":["errorBubble","errorOnNonRequiredField"]}]`) + require.Equal(t, "E1234", resp.ErrorBubble.Id) + require.Nil(t, resp.ErrorBubble.ErrorOnNonRequiredField) + require.Equal(t, "Ok", resp.Valid) + }) + + t.Run("when function errors", func(t *testing.T) { + var resp struct { + Valid string + ErrorBubble *struct { + NilOnRequiredField string + } + } + err := c.Post(`query { valid, errorBubble { id, errorOnRequiredField } }`, &resp) + + require.EqualError(t, err, `[{"message":"boom","path":["errorBubble","errorOnRequiredField"]}]`) + require.Nil(t, resp.ErrorBubble) + require.Equal(t, "Ok", resp.Valid) + }) + + t.Run("when user returns null on required field", func(t *testing.T) { + var resp struct { + Valid string + ErrorBubble *struct { + NilOnRequiredField string + } + } + err := c.Post(`query { valid, errorBubble { id, nilOnRequiredField } }`, &resp) + + require.EqualError(t, err, `[{"message":"must not be null","path":["errorBubble","nilOnRequiredField"]}]`) + require.Nil(t, resp.ErrorBubble) + require.Equal(t, "Ok", resp.Valid) + }) + + t.Run("when list element is null", func(t *testing.T) { + var resp struct { + Valid string + ErrorList []*struct{} + } + err := c.Post(`query { valid, errorList { id } }`, &resp) + + require.Nil(t, err) + require.Equal(t, len(resp.ErrorList), 1) + require.Nil(t, resp.ErrorList[0]) + require.Equal(t, "Ok", resp.Valid) + }) + + t.Run("when non-null list element is null", func(t *testing.T) { + var resp struct { + Valid string + ErrorBubbleList []*struct{} + } + err := c.Post(`query { valid, errorBubbleList { id } }`, &resp) + + require.EqualError(t, err, `[{"message":"must not be null","path":["errorBubbleList",0]}]`) + require.Nil(t, resp.ErrorBubbleList) + require.Equal(t, "Ok", resp.Valid) + }) + + t.Run("null args", func(t *testing.T) { + var resp struct { + NullableArg *string + } + resolvers.QueryResolver.NullableArg = func(ctx context.Context, arg *int) (i *string, e error) { + v := "Ok" + return &v, nil + } + + err := c.Post(`query { nullableArg(arg: null) }`, &resp) + require.Nil(t, err) + require.Equal(t, "Ok", *resp.NullableArg) + }) + + t.Run("concurrent null detection", func(t *testing.T) { + var resp interface{} + resolvers.ErrorsResolver.A = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } + resolvers.ErrorsResolver.B = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } + resolvers.ErrorsResolver.C = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } + resolvers.ErrorsResolver.D = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } + resolvers.ErrorsResolver.E = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil } + + err := c.Post(`{ errors { + a { id }, + b { id }, + c { id }, + d { id }, + e { id }, + } }`, &resp) + + require.Error(t, err) + require.Contains(t, err.Error(), "must not be null") + }) +} diff --git a/codegen/testserver/otherpkg/model.go b/codegen/testserver/followschema/otherpkg/model.go similarity index 100% rename from codegen/testserver/otherpkg/model.go rename to codegen/testserver/followschema/otherpkg/model.go diff --git a/codegen/testserver/followschema/panics.generated.go b/codegen/testserver/followschema/panics.generated.go new file mode 100644 index 00000000000..1aa80a17b03 --- /dev/null +++ b/codegen/testserver/followschema/panics.generated.go @@ -0,0 +1,324 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type PanicsResolver interface { + FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) + + ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Panics_argUnmarshal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []MarshalPanic + if tmp, ok := rawArgs["u"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("u")) + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["u"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Panics_fieldFuncMarshal_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []MarshalPanic + if tmp, ok := rawArgs["u"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("u")) + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["u"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Panics_fieldScalarMarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Panics", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Panics().FieldScalarMarshal(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]MarshalPanic) + fc.Result = res + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Panics_fieldFuncMarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Panics", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Panics_fieldFuncMarshal_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.FieldFuncMarshal(ctx, args["u"].([]MarshalPanic)), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]MarshalPanic) + fc.Result = res + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Panics_argUnmarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Panics", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Panics_argUnmarshal_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Panics().ArgUnmarshal(rctx, obj, args["u"].([]MarshalPanic)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var panicsImplementors = []string{"Panics"} + +func (ec *executionContext) _Panics(ctx context.Context, sel ast.SelectionSet, obj *Panics) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, panicsImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Panics") + case "fieldScalarMarshal": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_fieldScalarMarshal(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "fieldFuncMarshal": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_fieldFuncMarshal(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "argUnmarshal": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Panics_argUnmarshal(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanic(ctx context.Context, v interface{}) (MarshalPanic, error) { + var res MarshalPanic + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanic(ctx context.Context, sel ast.SelectionSet, v MarshalPanic) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx context.Context, v interface{}) ([]MarshalPanic, error) { + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]MarshalPanic, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanic(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanicᚄ(ctx context.Context, sel ast.SelectionSet, v []MarshalPanic) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐMarshalPanic(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPanics(ctx context.Context, sel ast.SelectionSet, v *Panics) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Panics(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/panics.graphql b/codegen/testserver/followschema/panics.graphql similarity index 100% rename from codegen/testserver/panics.graphql rename to codegen/testserver/followschema/panics.graphql diff --git a/codegen/testserver/followschema/panics_test.go b/codegen/testserver/followschema/panics_test.go new file mode 100644 index 00000000000..4433aad01a3 --- /dev/null +++ b/codegen/testserver/followschema/panics_test.go @@ -0,0 +1,69 @@ +package followschema + +import ( + "context" + "fmt" + "testing" + + "github.com/99designs/gqlgen/graphql" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" + "github.com/vektah/gqlparser/v2/gqlerror" +) + +func TestPanics(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Panics = func(ctx context.Context) (panics *Panics, e error) { + return &Panics{}, nil + } + resolvers.PanicsResolver.ArgUnmarshal = func(ctx context.Context, obj *Panics, u []MarshalPanic) (b bool, e error) { + return true, nil + } + resolvers.PanicsResolver.FieldScalarMarshal = func(ctx context.Context, obj *Panics) (marshalPanic []MarshalPanic, e error) { + return []MarshalPanic{MarshalPanic("aa"), MarshalPanic("bb")}, nil + } + + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + srv.SetRecoverFunc(func(ctx context.Context, err interface{}) (userMessage error) { + return fmt.Errorf("panic: %v", err) + }) + + srv.SetErrorPresenter(func(ctx context.Context, err error) *gqlerror.Error { + return &gqlerror.Error{ + Message: "presented: " + err.Error(), + Path: graphql.GetPath(ctx), + } + }) + + c := client.New(srv) + + t.Run("panics in marshallers will not kill server", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldScalarMarshal } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"presented: panic: BOOM\"}],\"data\":null}") + }) + + t.Run("panics in unmarshalers will not kill server", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { argUnmarshal(u: ["aa", "bb"]) } }`, &resp) + + require.EqualError(t, err, "[{\"message\":\"presented: input: panics.argUnmarshal panic: BOOM\",\"path\":[\"panics\",\"argUnmarshal\"]}]") + }) + + t.Run("panics in funcs unmarshal return errors", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldFuncMarshal(u: ["aa", "bb"]) } }`, &resp) + + require.EqualError(t, err, "[{\"message\":\"presented: input: panics.fieldFuncMarshal panic: BOOM\",\"path\":[\"panics\",\"fieldFuncMarshal\"]}]") + }) + + t.Run("panics in funcs marshal return errors", func(t *testing.T) { + var resp interface{} + err := c.Post(`query { panics { fieldFuncMarshal(u: []) } }`, &resp) + + require.EqualError(t, err, "http 422: {\"errors\":[{\"message\":\"presented: panic: BOOM\"}],\"data\":null}") + }) +} diff --git a/codegen/testserver/followschema/prelude.generated.go b/codegen/testserver/followschema/prelude.generated.go new file mode 100644 index 00000000000..2a306d304e2 --- /dev/null +++ b/codegen/testserver/followschema/prelude.generated.go @@ -0,0 +1,2312 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Directive", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Field", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Schema", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field___Type_fields_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(args["includeDeprecated"].(bool)), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field___Type_enumValues_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(args["includeDeprecated"].(bool)), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "__Type", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "locations": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_locations(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "args": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "isRepeatable": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Directive_isRepeatable(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "isDeprecated": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "deprecationReason": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___EnumValue_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "args": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_args(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "type": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "isDeprecated": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_isDeprecated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "deprecationReason": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Field_deprecationReason(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "type": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_type(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "defaultValue": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___InputValue_defaultValue(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "types": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_types(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "queryType": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_queryType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "mutationType": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_mutationType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "subscriptionType": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_subscriptionType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "directives": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Schema_directives(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_kind(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "description": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_description(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "fields": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_fields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "interfaces": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_interfaces(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "possibleTypes": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_possibleTypes(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "enumValues": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_enumValues(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "inputFields": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_inputFields(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "ofType": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec.___Type_ofType(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) { + res, err := graphql.UnmarshalIntID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + res := graphql.MarshalIntID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int32(ctx context.Context, v interface{}) (int32, error) { + res, err := graphql.UnmarshalInt32(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int32(ctx context.Context, sel ast.SelectionSet, v int32) graphql.Marshaler { + res := graphql.MarshalInt32(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int64(ctx context.Context, v interface{}) (int64, error) { + res, err := graphql.UnmarshalInt64(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int64(ctx context.Context, sel ast.SelectionSet, v int64) graphql.Marshaler { + res := graphql.MarshalInt64(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNString2ᚕᚖstring(ctx context.Context, v interface{}) ([]*string, error) { + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]*string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalOString2ᚖstring(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNString2ᚕᚖstring(ctx context.Context, sel ast.SelectionSet, v []*string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalOString2ᚖstring(ctx, sel, v[i]) + } + + return ret +} + +func (ec *executionContext) unmarshalNString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := graphql.MarshalString(*v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler { + return ec.___Type(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + return graphql.MarshalBoolean(v) +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalBoolean(*v) +} + +func (ec *executionContext) unmarshalOFloat2float64(ctx context.Context, v interface{}) (float64, error) { + res, err := graphql.UnmarshalFloat(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + return graphql.MarshalFloat(v) +} + +func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v interface{}) (*int, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalInt(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.SelectionSet, v *int) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalInt(*v) +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + return graphql.MarshalString(v) +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚕᚖstring(ctx context.Context, v interface{}) ([]*string, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]*string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalOString2ᚖstring(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕᚖstring(ctx context.Context, sel ast.SelectionSet, v []*string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalOString2ᚖstring(ctx, sel, v[i]) + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalString(*v) +} + +func (ec *executionContext) unmarshalOString2ᚖᚕstringᚄ(ctx context.Context, v interface{}) (*[]string, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v *[]string) graphql.Marshaler { + return ec.marshalOString2ᚕstringᚄ(ctx, sel, *v) +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Schema(ctx, sel, v) +} + +func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/primitive_objects.generated.go b/codegen/testserver/followschema/primitive_objects.generated.go new file mode 100644 index 00000000000..715910f0d2e --- /dev/null +++ b/codegen/testserver/followschema/primitive_objects.generated.go @@ -0,0 +1,432 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type PrimitiveResolver interface { + Value(ctx context.Context, obj *Primitive) (int, error) +} +type PrimitiveStringResolver interface { + Value(ctx context.Context, obj *PrimitiveString) (string, error) + + Len(ctx context.Context, obj *PrimitiveString) (int, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Primitive_value(ctx context.Context, field graphql.CollectedField, obj *Primitive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Primitive", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Primitive().Value(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _Primitive_squared(ctx context.Context, field graphql.CollectedField, obj *Primitive) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Primitive", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Squared(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _PrimitiveString_value(ctx context.Context, field graphql.CollectedField, obj *PrimitiveString) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PrimitiveString", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.PrimitiveString().Value(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PrimitiveString_doubled(ctx context.Context, field graphql.CollectedField, obj *PrimitiveString) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PrimitiveString", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Doubled(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PrimitiveString_len(ctx context.Context, field graphql.CollectedField, obj *PrimitiveString) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PrimitiveString", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.PrimitiveString().Len(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var primitiveImplementors = []string{"Primitive"} + +func (ec *executionContext) _Primitive(ctx context.Context, sel ast.SelectionSet, obj *Primitive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, primitiveImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Primitive") + case "value": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Primitive_value(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "squared": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Primitive_squared(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var primitiveStringImplementors = []string{"PrimitiveString"} + +func (ec *executionContext) _PrimitiveString(ctx context.Context, sel ast.SelectionSet, obj *PrimitiveString) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, primitiveStringImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PrimitiveString") + case "value": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PrimitiveString_value(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "doubled": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PrimitiveString_doubled(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "len": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PrimitiveString_len(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitive(ctx context.Context, sel ast.SelectionSet, v Primitive) graphql.Marshaler { + return ec._Primitive(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveᚄ(ctx context.Context, sel ast.SelectionSet, v []Primitive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitive(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveString(ctx context.Context, sel ast.SelectionSet, v PrimitiveString) graphql.Marshaler { + return ec._PrimitiveString(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveStringᚄ(ctx context.Context, sel ast.SelectionSet, v []PrimitiveString) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveString(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/primitive_objects.graphql b/codegen/testserver/followschema/primitive_objects.graphql similarity index 100% rename from codegen/testserver/primitive_objects.graphql rename to codegen/testserver/followschema/primitive_objects.graphql diff --git a/codegen/testserver/followschema/primitive_objects_test.go b/codegen/testserver/followschema/primitive_objects_test.go new file mode 100644 index 00000000000..87de88bb452 --- /dev/null +++ b/codegen/testserver/followschema/primitive_objects_test.go @@ -0,0 +1,73 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/assert" +) + +func TestPrimitiveObjects(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.PrimitiveObject = func(ctx context.Context) (out []Primitive, e error) { + return []Primitive{2, 4}, nil + } + + resolvers.PrimitiveResolver.Value = func(ctx context.Context, obj *Primitive) (i int, e error) { + return int(*obj), nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("can fetch value", func(t *testing.T) { + var resp struct { + PrimitiveObject []struct { + Value int + Squared int + } + } + c.MustPost(`query { primitiveObject { value, squared } }`, &resp) + + assert.Equal(t, 2, resp.PrimitiveObject[0].Value) + assert.Equal(t, 4, resp.PrimitiveObject[0].Squared) + assert.Equal(t, 4, resp.PrimitiveObject[1].Value) + assert.Equal(t, 16, resp.PrimitiveObject[1].Squared) + }) +} + +func TestPrimitiveStringObjects(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.PrimitiveStringObject = func(ctx context.Context) (out []PrimitiveString, e error) { + return []PrimitiveString{"hello", "world"}, nil + } + + resolvers.PrimitiveStringResolver.Value = func(ctx context.Context, obj *PrimitiveString) (i string, e error) { + return string(*obj), nil + } + + resolvers.PrimitiveStringResolver.Len = func(ctx context.Context, obj *PrimitiveString) (i int, e error) { + return len(string(*obj)), nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("can fetch value", func(t *testing.T) { + var resp struct { + PrimitiveStringObject []struct { + Value string + Doubled string + Len int + } + } + c.MustPost(`query { primitiveStringObject { value, doubled, len } }`, &resp) + + assert.Equal(t, "hello", resp.PrimitiveStringObject[0].Value) + assert.Equal(t, "hellohello", resp.PrimitiveStringObject[0].Doubled) + assert.Equal(t, 5, resp.PrimitiveStringObject[0].Len) + assert.Equal(t, "world", resp.PrimitiveStringObject[1].Value) + assert.Equal(t, "worldworld", resp.PrimitiveStringObject[1].Doubled) + assert.Equal(t, 5, resp.PrimitiveStringObject[1].Len) + }) +} diff --git a/codegen/testserver/followschema/ptr_to_ptr_input.generated.go b/codegen/testserver/followschema/ptr_to_ptr_input.generated.go new file mode 100644 index 00000000000..0b51b80a79f --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_ptr_input.generated.go @@ -0,0 +1,513 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _PtrToPtrInner_key(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrInner) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrInner", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Key, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrInner_value(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrInner) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrInner", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_name(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_inner(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Inner, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*PtrToPtrInner) + fc.Result = res + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, field.Selections, res) +} + +func (ec *executionContext) _PtrToPtrOuter_stupidInner(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToPtrOuter", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StupidInner, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*******PtrToPtrInner) + fc.Result = res + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputUpdatePtrToPtrInner(ctx context.Context, obj interface{}) (UpdatePtrToPtrInner, error) { + var it UpdatePtrToPtrInner + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "key": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + it.Key, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "value": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("value")) + it.Value, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputUpdatePtrToPtrOuter(ctx context.Context, obj interface{}) (UpdatePtrToPtrOuter, error) { + var it UpdatePtrToPtrOuter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + it.Name, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "inner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) + it.Inner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return it, err + } + case "stupidInner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("stupidInner")) + it.StupidInner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var ptrToPtrInnerImplementors = []string{"PtrToPtrInner"} + +func (ec *executionContext) _PtrToPtrInner(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrInner) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrInnerImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToPtrInner") + case "key": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrInner_key(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "value": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrInner_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var ptrToPtrOuterImplementors = []string{"PtrToPtrOuter"} + +func (ec *executionContext) _PtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, obj *PtrToPtrOuter) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToPtrOuterImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToPtrOuter") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "inner": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_inner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "stupidInner": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToPtrOuter_stupidInner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNPtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v PtrToPtrOuter) graphql.Marshaler { + return ec._PtrToPtrOuter(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrOuter) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._PtrToPtrOuter(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrOuter(ctx context.Context, v interface{}) (UpdatePtrToPtrOuter, error) { + res, err := ec.unmarshalInputUpdatePtrToPtrOuter(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._PtrToPtrInner(ctx, sel, v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v **PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ***PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ****PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *****PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ******PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *******PtrToPtrInner) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToPtrInner(ctx, sel, *v) +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*UpdatePtrToPtrInner, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputUpdatePtrToPtrInner(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (**UpdatePtrToPtrInner, error) { + var pres *UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (***UpdatePtrToPtrInner, error) { + var pres **UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (****UpdatePtrToPtrInner, error) { + var pres ***UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*****UpdatePtrToPtrInner, error) { + var pres ****UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (******UpdatePtrToPtrInner, error) { + var pres *****UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*******UpdatePtrToPtrInner, error) { + var pres ******UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (********UpdatePtrToPtrInner, error) { + var pres *******UpdatePtrToPtrInner + if v != nil { + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUpdatePtrToPtrInner(ctx, v) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + pres = res + } + return &pres, nil +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/ptr_to_ptr_input.go b/codegen/testserver/followschema/ptr_to_ptr_input.go new file mode 100644 index 00000000000..c4c082b75ec --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_ptr_input.go @@ -0,0 +1,23 @@ +package followschema + +type PtrToPtrOuter struct { + Name string + Inner *PtrToPtrInner + StupidInner *******PtrToPtrInner +} + +type PtrToPtrInner struct { + Key string + Value string +} + +type UpdatePtrToPtrOuter struct { + Name *string + Inner **UpdatePtrToPtrInner + StupidInner ********UpdatePtrToPtrInner +} + +type UpdatePtrToPtrInner struct { + Key *string + Value *string +} diff --git a/codegen/testserver/ptr_to_ptr_input.graphql b/codegen/testserver/followschema/ptr_to_ptr_input.graphql similarity index 100% rename from codegen/testserver/ptr_to_ptr_input.graphql rename to codegen/testserver/followschema/ptr_to_ptr_input.graphql diff --git a/codegen/testserver/followschema/ptr_to_ptr_input_test.go b/codegen/testserver/followschema/ptr_to_ptr_input_test.go new file mode 100644 index 00000000000..bb644e492b4 --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_ptr_input_test.go @@ -0,0 +1,174 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +type UpdatePtrToPtrResults struct { + UpdatedPtrToPtr PtrToPtrOuter `json:"updatePtrToPtr"` +} + +func TestPtrToPtr(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.MutationResolver.UpdatePtrToPtr = func(ctx context.Context, in UpdatePtrToPtrOuter) (ret *PtrToPtrOuter, err error) { + ret = &PtrToPtrOuter{ + Name: "oldName", + Inner: &PtrToPtrInner{ + Key: "oldKey", + Value: "oldValue", + }, + StupidInner: nest7(&PtrToPtrInner{ + Key: "oldStupidKey", + Value: "oldStupidValue", + }), + } + + if in.Name != nil { + ret.Name = *in.Name + } + + if in.Inner != nil { + inner := *in.Inner + if inner == nil { + ret.Inner = nil + } else { + if in.Inner == nil { + ret.Inner = &PtrToPtrInner{} + } + if inner.Key != nil { + ret.Inner.Key = *inner.Key + } + if inner.Value != nil { + ret.Inner.Value = *inner.Value + } + } + } + + if in.StupidInner != nil { + si := *in.StupidInner + if si == nil { + ret.StupidInner = nil + } else { + deepIn := ******si + deepOut := ******ret.StupidInner + if deepIn.Key != nil { + deepOut.Key = *deepIn.Key + } + if deepIn.Value != nil { + deepOut.Value = *deepIn.Value + } + } + } + return + } + + t.Run("pointer to pointer input missing", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { name: "newName" }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "newName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("pointer to pointer input non-null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { + updatePtrToPtr(input: { + inner: { + key: "newKey" + value: "newValue" + } + }) + { name, inner { key, value }, stupidInner { key, value }} + }`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "newKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "newValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("pointer to pointer input null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { inner: null }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.Nil(t, resp.UpdatedPtrToPtr.Inner) + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "oldStupidKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "oldStupidValue") + }) + + t.Run("many pointers input non-null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { + updatePtrToPtr(input: { + stupidInner: { + key: "newKey" + value: "newValue" + } + }) + { name, inner { key, value }, stupidInner { key, value }} + }`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.NotNil(t, resp.UpdatedPtrToPtr.StupidInner) + require.NotNil(t, ******resp.UpdatedPtrToPtr.StupidInner) + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Key, "newKey") + require.Equal(t, (******resp.UpdatedPtrToPtr.StupidInner).Value, "newValue") + }) + + t.Run("many pointers input null", func(t *testing.T) { + var resp UpdatePtrToPtrResults + + err := c.Post(`mutation { updatePtrToPtr(input: { stupidInner: null }) { name, inner { key, value }, stupidInner { key, value }}}`, &resp) + require.NoError(t, err) + + require.Equal(t, resp.UpdatedPtrToPtr.Name, "oldName") + require.NotNil(t, resp.UpdatedPtrToPtr.Inner) + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Key, "oldKey") + require.Equal(t, resp.UpdatedPtrToPtr.Inner.Value, "oldValue") + require.Nil(t, resp.UpdatedPtrToPtr.StupidInner) + }) +} + +func nest7(in *PtrToPtrInner) *******PtrToPtrInner { + si2 := &in + si3 := &si2 + si4 := &si3 + si5 := &si4 + si6 := &si5 + si7 := &si6 + + return si7 +} diff --git a/codegen/testserver/followschema/ptr_to_slice.generated.go b/codegen/testserver/followschema/ptr_to_slice.generated.go new file mode 100644 index 00000000000..0ead7386453 --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_slice.generated.go @@ -0,0 +1,114 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _PtrToSliceContainer_ptrToSlice(ctx context.Context, field graphql.CollectedField, obj *PtrToSliceContainer) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "PtrToSliceContainer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PtrToSlice, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*[]string) + fc.Result = res + return ec.marshalOString2ᚖᚕstringᚄ(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var ptrToSliceContainerImplementors = []string{"PtrToSliceContainer"} + +func (ec *executionContext) _PtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, obj *PtrToSliceContainer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, ptrToSliceContainerImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PtrToSliceContainer") + case "ptrToSlice": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._PtrToSliceContainer_ptrToSlice(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNPtrToSliceContainer2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v PtrToSliceContainer) graphql.Marshaler { + return ec._PtrToSliceContainer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v *PtrToSliceContainer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._PtrToSliceContainer(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/ptr_to_slice.go b/codegen/testserver/followschema/ptr_to_slice.go new file mode 100644 index 00000000000..8cdd22d7c8a --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_slice.go @@ -0,0 +1,5 @@ +package followschema + +type PtrToSliceContainer struct { + PtrToSlice *[]string +} diff --git a/codegen/testserver/ptr_to_slice.graphql b/codegen/testserver/followschema/ptr_to_slice.graphql similarity index 100% rename from codegen/testserver/ptr_to_slice.graphql rename to codegen/testserver/followschema/ptr_to_slice.graphql diff --git a/codegen/testserver/followschema/ptr_to_slice_test.go b/codegen/testserver/followschema/ptr_to_slice_test.go new file mode 100644 index 00000000000..ba7fbb3eed9 --- /dev/null +++ b/codegen/testserver/followschema/ptr_to_slice_test.go @@ -0,0 +1,37 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestPtrToSlice(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.PtrToSliceContainer = func(ctx context.Context) (wrappedStruct *PtrToSliceContainer, e error) { + ptrToSliceContainer := PtrToSliceContainer{ + PtrToSlice: &[]string{"hello"}, + } + return &ptrToSliceContainer, nil + } + + t.Run("pointer to slice", func(t *testing.T) { + var resp struct { + PtrToSliceContainer struct { + PtrToSlice []string + } + } + + err := c.Post(`query { ptrToSliceContainer { ptrToSlice }}`, &resp) + require.NoError(t, err) + + require.Equal(t, []string{"hello"}, resp.PtrToSliceContainer.PtrToSlice) + + }) +} diff --git a/codegen/testserver/followschema/recursive.go b/codegen/testserver/followschema/recursive.go new file mode 100644 index 00000000000..b5c096ff757 --- /dev/null +++ b/codegen/testserver/followschema/recursive.go @@ -0,0 +1,5 @@ +package followschema + +type RecursiveInputSlice struct { + Self []RecursiveInputSlice +} diff --git a/codegen/testserver/followschema/resolver.go b/codegen/testserver/followschema/resolver.go new file mode 100644 index 00000000000..7cf60b2455e --- /dev/null +++ b/codegen/testserver/followschema/resolver.go @@ -0,0 +1,426 @@ +package followschema + +// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. + +import ( + "context" + + introspection1 "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" +) + +type Resolver struct{} + +func (r *backedByInterfaceResolver) ID(ctx context.Context, obj BackedByInterface) (string, error) { + panic("not implemented") +} + +func (r *errorsResolver) A(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) B(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) C(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) D(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *errorsResolver) E(ctx context.Context, obj *Errors) (*Error, error) { + panic("not implemented") +} + +func (r *forcedResolverResolver) Field(ctx context.Context, obj *ForcedResolver) (*Circle, error) { + panic("not implemented") +} + +func (r *modelMethodsResolver) ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) { + panic("not implemented") +} + +func (r *mutationResolver) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { + panic("not implemented") +} + +func (r *mutationResolver) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { + panic("not implemented") +} + +func (r *mutationResolver) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { + panic("not implemented") +} + +func (r *overlappingFieldsResolver) OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) { + panic("not implemented") +} + +func (r *panicsResolver) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { + panic("not implemented") +} + +func (r *panicsResolver) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { + panic("not implemented") +} + +func (r *primitiveResolver) Value(ctx context.Context, obj *Primitive) (int, error) { + panic("not implemented") +} + +func (r *primitiveStringResolver) Value(ctx context.Context, obj *PrimitiveString) (string, error) { + panic("not implemented") +} + +func (r *primitiveStringResolver) Len(ctx context.Context, obj *PrimitiveString) (int, error) { + panic("not implemented") +} + +func (r *queryResolver) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { + panic("not implemented") +} + +func (r *queryResolver) Collision(ctx context.Context) (*introspection1.It, error) { + panic("not implemented") +} + +func (r *queryResolver) MapInput(ctx context.Context, input map[string]interface{}) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) { + panic("not implemented") +} + +func (r *queryResolver) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { + panic("not implemented") +} + +func (r *queryResolver) ModelMethods(ctx context.Context) (*ModelMethods, error) { + panic("not implemented") +} + +func (r *queryResolver) User(ctx context.Context, id int) (*User, error) { + panic("not implemented") +} + +func (r *queryResolver) NullableArg(ctx context.Context, arg *int) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) InputSlice(ctx context.Context, arg []string) (bool, error) { + panic("not implemented") +} + +func (r *queryResolver) InputNullableSlice(ctx context.Context, arg []string) (bool, error) { + panic("not implemented") +} + +func (r *queryResolver) ShapeUnion(ctx context.Context) (ShapeUnion, error) { + panic("not implemented") +} + +func (r *queryResolver) Autobind(ctx context.Context) (*Autobind, error) { + panic("not implemented") +} + +func (r *queryResolver) DeprecatedField(ctx context.Context) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Overlapping(ctx context.Context) (*OverlappingFields, error) { + panic("not implemented") +} + +func (r *queryResolver) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveArg(ctx context.Context, arg string) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveInputType(ctx context.Context, arg InnerInput) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveObject(ctx context.Context) (*ObjectDirectives, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveObjectWithCustomGoModel(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveFieldDef(ctx context.Context, ret string) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveField(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveDouble(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) DirectiveUnimplemented(ctx context.Context) (*string, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase1(ctx context.Context) (*EmbeddedCase1, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase2(ctx context.Context) (*EmbeddedCase2, error) { + panic("not implemented") +} + +func (r *queryResolver) EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) { + panic("not implemented") +} + +func (r *queryResolver) EnumInInput(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) { + panic("not implemented") +} + +func (r *queryResolver) Shapes(ctx context.Context) ([]Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) NoShape(ctx context.Context) (Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) Node(ctx context.Context) (Node, error) { + panic("not implemented") +} + +func (r *queryResolver) NoShapeTypedNil(ctx context.Context) (Shape, error) { + panic("not implemented") +} + +func (r *queryResolver) Animal(ctx context.Context) (Animal, error) { + panic("not implemented") +} + +func (r *queryResolver) NotAnInterface(ctx context.Context) (BackedByInterface, error) { + panic("not implemented") +} + +func (r *queryResolver) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { + panic("not implemented") +} + +func (r *queryResolver) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { + panic("not implemented") +} + +func (r *queryResolver) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorBubble(ctx context.Context) (*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorBubbleList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) ErrorList(ctx context.Context) ([]*Error, error) { + panic("not implemented") +} + +func (r *queryResolver) Errors(ctx context.Context) (*Errors, error) { + panic("not implemented") +} + +func (r *queryResolver) Valid(ctx context.Context) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Panics(ctx context.Context) (*Panics, error) { + panic("not implemented") +} + +func (r *queryResolver) PrimitiveObject(ctx context.Context) ([]Primitive, error) { + panic("not implemented") +} + +func (r *queryResolver) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) { + panic("not implemented") +} + +func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { + panic("not implemented") +} + +func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { + panic("not implemented") +} + +func (r *queryResolver) Slices(ctx context.Context) (*Slices, error) { + panic("not implemented") +} + +func (r *queryResolver) ScalarSlice(ctx context.Context) ([]byte, error) { + panic("not implemented") +} + +func (r *queryResolver) Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) { + panic("not implemented") +} + +func (r *queryResolver) OptionalUnion(ctx context.Context) (TestUnion, error) { + panic("not implemented") +} + +func (r *queryResolver) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { + panic("not implemented") +} + +func (r *queryResolver) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { + panic("not implemented") +} + +func (r *queryResolver) ValidType(ctx context.Context) (*ValidType, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedStruct(ctx context.Context) (*WrappedStruct, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedMap(ctx context.Context) (WrappedMap, error) { + panic("not implemented") +} + +func (r *queryResolver) WrappedSlice(ctx context.Context) (WrappedSlice, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) Updated(ctx context.Context) (<-chan string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) InitPayload(ctx context.Context) (<-chan string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveArg(ctx context.Context, arg string) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveDouble(ctx context.Context) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { + panic("not implemented") +} + +func (r *subscriptionResolver) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { + panic("not implemented") +} + +func (r *userResolver) Friends(ctx context.Context, obj *User) ([]*User, error) { + panic("not implemented") +} + +func (r *wrappedMapResolver) Get(ctx context.Context, obj WrappedMap, key string) (string, error) { + panic("not implemented") +} + +func (r *wrappedSliceResolver) Get(ctx context.Context, obj WrappedSlice, idx int) (string, error) { + panic("not implemented") +} + +// BackedByInterface returns BackedByInterfaceResolver implementation. +func (r *Resolver) BackedByInterface() BackedByInterfaceResolver { + return &backedByInterfaceResolver{r} +} + +// Errors returns ErrorsResolver implementation. +func (r *Resolver) Errors() ErrorsResolver { return &errorsResolver{r} } + +// ForcedResolver returns ForcedResolverResolver implementation. +func (r *Resolver) ForcedResolver() ForcedResolverResolver { return &forcedResolverResolver{r} } + +// ModelMethods returns ModelMethodsResolver implementation. +func (r *Resolver) ModelMethods() ModelMethodsResolver { return &modelMethodsResolver{r} } + +// Mutation returns MutationResolver implementation. +func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} } + +// OverlappingFields returns OverlappingFieldsResolver implementation. +func (r *Resolver) OverlappingFields() OverlappingFieldsResolver { + return &overlappingFieldsResolver{r} +} + +// Panics returns PanicsResolver implementation. +func (r *Resolver) Panics() PanicsResolver { return &panicsResolver{r} } + +// Primitive returns PrimitiveResolver implementation. +func (r *Resolver) Primitive() PrimitiveResolver { return &primitiveResolver{r} } + +// PrimitiveString returns PrimitiveStringResolver implementation. +func (r *Resolver) PrimitiveString() PrimitiveStringResolver { return &primitiveStringResolver{r} } + +// Query returns QueryResolver implementation. +func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } + +// Subscription returns SubscriptionResolver implementation. +func (r *Resolver) Subscription() SubscriptionResolver { return &subscriptionResolver{r} } + +// User returns UserResolver implementation. +func (r *Resolver) User() UserResolver { return &userResolver{r} } + +// WrappedMap returns WrappedMapResolver implementation. +func (r *Resolver) WrappedMap() WrappedMapResolver { return &wrappedMapResolver{r} } + +// WrappedSlice returns WrappedSliceResolver implementation. +func (r *Resolver) WrappedSlice() WrappedSliceResolver { return &wrappedSliceResolver{r} } + +type backedByInterfaceResolver struct{ *Resolver } +type errorsResolver struct{ *Resolver } +type forcedResolverResolver struct{ *Resolver } +type modelMethodsResolver struct{ *Resolver } +type mutationResolver struct{ *Resolver } +type overlappingFieldsResolver struct{ *Resolver } +type panicsResolver struct{ *Resolver } +type primitiveResolver struct{ *Resolver } +type primitiveStringResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } +type subscriptionResolver struct{ *Resolver } +type userResolver struct{ *Resolver } +type wrappedMapResolver struct{ *Resolver } +type wrappedSliceResolver struct{ *Resolver } diff --git a/codegen/testserver/followschema/response_extension_test.go b/codegen/testserver/followschema/response_extension_test.go new file mode 100644 index 00000000000..4ee1b5749f8 --- /dev/null +++ b/codegen/testserver/followschema/response_extension_test.go @@ -0,0 +1,33 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestResponseExtension(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Valid = func(ctx context.Context) (s string, e error) { + return "Ok", nil + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolvers}), + ) + + srv.AroundResponses(func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response { + graphql.RegisterExtension(ctx, "example", "value") + + return next(ctx) + }) + + c := client.New(srv) + + raw, _ := c.RawPost(`query { valid }`) + require.Equal(t, raw.Extensions["example"], "value") +} diff --git a/codegen/testserver/followschema/root!.generated.go b/codegen/testserver/followschema/root!.generated.go new file mode 100644 index 00000000000..c5bd0aeb35e --- /dev/null +++ b/codegen/testserver/followschema/root!.generated.go @@ -0,0 +1,2475 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "bytes" + "context" + "errors" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" +) + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + BackedByInterface() BackedByInterfaceResolver + Errors() ErrorsResolver + ForcedResolver() ForcedResolverResolver + ModelMethods() ModelMethodsResolver + Mutation() MutationResolver + OverlappingFields() OverlappingFieldsResolver + Panics() PanicsResolver + Primitive() PrimitiveResolver + PrimitiveString() PrimitiveStringResolver + Query() QueryResolver + Subscription() SubscriptionResolver + User() UserResolver + WrappedMap() WrappedMapResolver + WrappedSlice() WrappedSliceResolver +} + +type DirectiveRoot struct { + Custom func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Directive1 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Directive2 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Directive3 func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Length func(ctx context.Context, obj interface{}, next graphql.Resolver, min int, max *int, message *string) (res interface{}, err error) + Logged func(ctx context.Context, obj interface{}, next graphql.Resolver, id string) (res interface{}, err error) + MakeNil func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + MakeTypedNil func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Order1 func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) + Order2 func(ctx context.Context, obj interface{}, next graphql.Resolver, location string) (res interface{}, err error) + Range func(ctx context.Context, obj interface{}, next graphql.Resolver, min *int, max *int) (res interface{}, err error) + ToNull func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) + Unimplemented func(ctx context.Context, obj interface{}, next graphql.Resolver) (res interface{}, err error) +} + +type ComplexityRoot struct { + A struct { + ID func(childComplexity int) int + } + + AIt struct { + ID func(childComplexity int) int + } + + AbIt struct { + ID func(childComplexity int) int + } + + Autobind struct { + IdInt func(childComplexity int) int + IdStr func(childComplexity int) int + Int func(childComplexity int) int + Int32 func(childComplexity int) int + Int64 func(childComplexity int) int + } + + B struct { + ID func(childComplexity int) int + } + + BackedByInterface struct { + ID func(childComplexity int) int + ThisShouldBind func(childComplexity int) int + ThisShouldBindWithError func(childComplexity int) int + } + + Cat struct { + CatBreed func(childComplexity int) int + Species func(childComplexity int) int + } + + CheckIssue896 struct { + ID func(childComplexity int) int + } + + Circle struct { + Area func(childComplexity int) int + Radius func(childComplexity int) int + } + + ConcreteNodeA struct { + Child func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + } + + ConcreteNodeInterface struct { + Child func(childComplexity int) int + ID func(childComplexity int) int + } + + Content_Post struct { + Foo func(childComplexity int) int + } + + Content_User struct { + Foo func(childComplexity int) int + } + + DefaultParametersMirror struct { + FalsyBoolean func(childComplexity int) int + TruthyBoolean func(childComplexity int) int + } + + Dog struct { + DogBreed func(childComplexity int) int + Species func(childComplexity int) int + } + + EmbeddedCase1 struct { + ExportedEmbeddedPointerExportedMethod func(childComplexity int) int + } + + EmbeddedCase2 struct { + UnexportedEmbeddedPointerExportedMethod func(childComplexity int) int + } + + EmbeddedCase3 struct { + UnexportedEmbeddedInterfaceExportedMethod func(childComplexity int) int + } + + EmbeddedDefaultScalar struct { + Value func(childComplexity int) int + } + + EmbeddedPointer struct { + ID func(childComplexity int) int + Title func(childComplexity int) int + } + + Error struct { + ErrorOnNonRequiredField func(childComplexity int) int + ErrorOnRequiredField func(childComplexity int) int + ID func(childComplexity int) int + NilOnRequiredField func(childComplexity int) int + } + + Errors struct { + A func(childComplexity int) int + B func(childComplexity int) int + C func(childComplexity int) int + D func(childComplexity int) int + E func(childComplexity int) int + } + + ForcedResolver struct { + Field func(childComplexity int) int + } + + InnerObject struct { + ID func(childComplexity int) int + } + + InvalidIdentifier struct { + ID func(childComplexity int) int + } + + It struct { + ID func(childComplexity int) int + } + + LoopA struct { + B func(childComplexity int) int + } + + LoopB struct { + A func(childComplexity int) int + } + + Map struct { + ID func(childComplexity int) int + } + + MapStringInterfaceType struct { + A func(childComplexity int) int + B func(childComplexity int) int + } + + ModelMethods struct { + NoContext func(childComplexity int) int + ResolverField func(childComplexity int) int + WithContext func(childComplexity int) int + } + + Mutation struct { + DefaultInput func(childComplexity int, input DefaultInput) int + UpdatePtrToPtr func(childComplexity int, input UpdatePtrToPtrOuter) int + UpdateSomething func(childComplexity int, input SpecialInput) int + } + + ObjectDirectives struct { + NullableText func(childComplexity int) int + Order func(childComplexity int) int + Text func(childComplexity int) int + } + + ObjectDirectivesWithCustomGoModel struct { + NullableText func(childComplexity int) int + } + + OuterObject struct { + Inner func(childComplexity int) int + } + + OverlappingFields struct { + Foo func(childComplexity int) int + NewFoo func(childComplexity int) int + OldFoo func(childComplexity int) int + } + + Panics struct { + ArgUnmarshal func(childComplexity int, u []MarshalPanic) int + FieldFuncMarshal func(childComplexity int, u []MarshalPanic) int + FieldScalarMarshal func(childComplexity int) int + } + + Primitive struct { + Squared func(childComplexity int) int + Value func(childComplexity int) int + } + + PrimitiveString struct { + Doubled func(childComplexity int) int + Len func(childComplexity int) int + Value func(childComplexity int) int + } + + PtrToPtrInner struct { + Key func(childComplexity int) int + Value func(childComplexity int) int + } + + PtrToPtrOuter struct { + Inner func(childComplexity int) int + Name func(childComplexity int) int + StupidInner func(childComplexity int) int + } + + PtrToSliceContainer struct { + PtrToSlice func(childComplexity int) int + } + + Query struct { + Animal func(childComplexity int) int + Autobind func(childComplexity int) int + Collision func(childComplexity int) int + DefaultParameters func(childComplexity int, falsyBoolean *bool, truthyBoolean *bool) int + DefaultScalar func(childComplexity int, arg string) int + DeprecatedField func(childComplexity int) int + DirectiveArg func(childComplexity int, arg string) int + DirectiveDouble func(childComplexity int) int + DirectiveField func(childComplexity int) int + DirectiveFieldDef func(childComplexity int, ret string) int + DirectiveInput func(childComplexity int, arg InputDirectives) int + DirectiveInputNullable func(childComplexity int, arg *InputDirectives) int + DirectiveInputType func(childComplexity int, arg InnerInput) int + DirectiveNullableArg func(childComplexity int, arg *int, arg2 *int, arg3 *string) int + DirectiveObject func(childComplexity int) int + DirectiveObjectWithCustomGoModel func(childComplexity int) int + DirectiveUnimplemented func(childComplexity int) int + EmbeddedCase1 func(childComplexity int) int + EmbeddedCase2 func(childComplexity int) int + EmbeddedCase3 func(childComplexity int) int + EnumInInput func(childComplexity int, input *InputWithEnumValue) int + ErrorBubble func(childComplexity int) int + ErrorBubbleList func(childComplexity int) int + ErrorList func(childComplexity int) int + Errors func(childComplexity int) int + Fallback func(childComplexity int, arg FallbackToStringEncoding) int + InputNullableSlice func(childComplexity int, arg []string) int + InputSlice func(childComplexity int, arg []string) int + InvalidIdentifier func(childComplexity int) int + Issue896a func(childComplexity int) int + MapInput func(childComplexity int, input map[string]interface{}) int + MapNestedStringInterface func(childComplexity int, in *NestedMapInput) int + MapStringInterface func(childComplexity int, in map[string]interface{}) int + ModelMethods func(childComplexity int) int + NestedInputs func(childComplexity int, input [][]*OuterInput) int + NestedOutputs func(childComplexity int) int + NoShape func(childComplexity int) int + NoShapeTypedNil func(childComplexity int) int + Node func(childComplexity int) int + NotAnInterface func(childComplexity int) int + NullableArg func(childComplexity int, arg *int) int + OptionalUnion func(childComplexity int) int + Overlapping func(childComplexity int) int + Panics func(childComplexity int) int + PrimitiveObject func(childComplexity int) int + PrimitiveStringObject func(childComplexity int) int + PtrToSliceContainer func(childComplexity int) int + Recursive func(childComplexity int, input *RecursiveInputSlice) int + ScalarSlice func(childComplexity int) int + ShapeUnion func(childComplexity int) int + Shapes func(childComplexity int) int + Slices func(childComplexity int) int + User func(childComplexity int, id int) int + VOkCaseNil func(childComplexity int) int + VOkCaseValue func(childComplexity int) int + Valid func(childComplexity int) int + ValidType func(childComplexity int) int + WrappedMap func(childComplexity int) int + WrappedScalar func(childComplexity int) int + WrappedSlice func(childComplexity int) int + WrappedStruct func(childComplexity int) int + } + + Rectangle struct { + Area func(childComplexity int) int + Length func(childComplexity int) int + Width func(childComplexity int) int + } + + Slices struct { + Test1 func(childComplexity int) int + Test2 func(childComplexity int) int + Test3 func(childComplexity int) int + Test4 func(childComplexity int) int + } + + Subscription struct { + DirectiveArg func(childComplexity int, arg string) int + DirectiveDouble func(childComplexity int) int + DirectiveNullableArg func(childComplexity int, arg *int, arg2 *int, arg3 *string) int + DirectiveUnimplemented func(childComplexity int) int + InitPayload func(childComplexity int) int + Issue896b func(childComplexity int) int + Updated func(childComplexity int) int + } + + User struct { + Created func(childComplexity int) int + Friends func(childComplexity int) int + ID func(childComplexity int) int + Updated func(childComplexity int) int + } + + VOkCaseNil struct { + Value func(childComplexity int) int + } + + VOkCaseValue struct { + Value func(childComplexity int) int + } + + ValidType struct { + DifferentCase func(childComplexity int) int + DifferentCaseOld func(childComplexity int) int + ValidArgs func(childComplexity int, breakArg string, defaultArg string, funcArg string, interfaceArg string, selectArg string, caseArg string, deferArg string, goArg string, mapArg string, structArg string, chanArg string, elseArg string, gotoArg string, packageArg string, switchArg string, constArg string, fallthroughArg string, ifArg string, rangeArg string, typeArg string, continueArg string, forArg string, importArg string, returnArg string, varArg string, _ string) int + ValidInputKeywords func(childComplexity int, input *ValidInput) int + } + + WrappedMap struct { + Get func(childComplexity int, key string) int + } + + WrappedSlice struct { + Get func(childComplexity int, idx int) int + } + + WrappedStruct struct { + Desc func(childComplexity int) int + Name func(childComplexity int) int + } + + XXIt struct { + ID func(childComplexity int) int + } + + XxIt struct { + ID func(childComplexity int) int + } + + AsdfIt struct { + ID func(childComplexity int) int + } + + IIt struct { + ID func(childComplexity int) int + } +} + +type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema +} + +func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e} + _ = ec + switch typeName + "." + field { + + case "A.id": + if e.complexity.A.ID == nil { + break + } + + return e.complexity.A.ID(childComplexity), true + + case "AIt.id": + if e.complexity.AIt.ID == nil { + break + } + + return e.complexity.AIt.ID(childComplexity), true + + case "AbIt.id": + if e.complexity.AbIt.ID == nil { + break + } + + return e.complexity.AbIt.ID(childComplexity), true + + case "Autobind.idInt": + if e.complexity.Autobind.IdInt == nil { + break + } + + return e.complexity.Autobind.IdInt(childComplexity), true + + case "Autobind.idStr": + if e.complexity.Autobind.IdStr == nil { + break + } + + return e.complexity.Autobind.IdStr(childComplexity), true + + case "Autobind.int": + if e.complexity.Autobind.Int == nil { + break + } + + return e.complexity.Autobind.Int(childComplexity), true + + case "Autobind.int32": + if e.complexity.Autobind.Int32 == nil { + break + } + + return e.complexity.Autobind.Int32(childComplexity), true + + case "Autobind.int64": + if e.complexity.Autobind.Int64 == nil { + break + } + + return e.complexity.Autobind.Int64(childComplexity), true + + case "B.id": + if e.complexity.B.ID == nil { + break + } + + return e.complexity.B.ID(childComplexity), true + + case "BackedByInterface.id": + if e.complexity.BackedByInterface.ID == nil { + break + } + + return e.complexity.BackedByInterface.ID(childComplexity), true + + case "BackedByInterface.thisShouldBind": + if e.complexity.BackedByInterface.ThisShouldBind == nil { + break + } + + return e.complexity.BackedByInterface.ThisShouldBind(childComplexity), true + + case "BackedByInterface.thisShouldBindWithError": + if e.complexity.BackedByInterface.ThisShouldBindWithError == nil { + break + } + + return e.complexity.BackedByInterface.ThisShouldBindWithError(childComplexity), true + + case "Cat.catBreed": + if e.complexity.Cat.CatBreed == nil { + break + } + + return e.complexity.Cat.CatBreed(childComplexity), true + + case "Cat.species": + if e.complexity.Cat.Species == nil { + break + } + + return e.complexity.Cat.Species(childComplexity), true + + case "CheckIssue896.id": + if e.complexity.CheckIssue896.ID == nil { + break + } + + return e.complexity.CheckIssue896.ID(childComplexity), true + + case "Circle.area": + if e.complexity.Circle.Area == nil { + break + } + + return e.complexity.Circle.Area(childComplexity), true + + case "Circle.radius": + if e.complexity.Circle.Radius == nil { + break + } + + return e.complexity.Circle.Radius(childComplexity), true + + case "ConcreteNodeA.child": + if e.complexity.ConcreteNodeA.Child == nil { + break + } + + return e.complexity.ConcreteNodeA.Child(childComplexity), true + + case "ConcreteNodeA.id": + if e.complexity.ConcreteNodeA.ID == nil { + break + } + + return e.complexity.ConcreteNodeA.ID(childComplexity), true + + case "ConcreteNodeA.name": + if e.complexity.ConcreteNodeA.Name == nil { + break + } + + return e.complexity.ConcreteNodeA.Name(childComplexity), true + + case "ConcreteNodeInterface.child": + if e.complexity.ConcreteNodeInterface.Child == nil { + break + } + + return e.complexity.ConcreteNodeInterface.Child(childComplexity), true + + case "ConcreteNodeInterface.id": + if e.complexity.ConcreteNodeInterface.ID == nil { + break + } + + return e.complexity.ConcreteNodeInterface.ID(childComplexity), true + + case "Content_Post.foo": + if e.complexity.Content_Post.Foo == nil { + break + } + + return e.complexity.Content_Post.Foo(childComplexity), true + + case "Content_User.foo": + if e.complexity.Content_User.Foo == nil { + break + } + + return e.complexity.Content_User.Foo(childComplexity), true + + case "DefaultParametersMirror.falsyBoolean": + if e.complexity.DefaultParametersMirror.FalsyBoolean == nil { + break + } + + return e.complexity.DefaultParametersMirror.FalsyBoolean(childComplexity), true + + case "DefaultParametersMirror.truthyBoolean": + if e.complexity.DefaultParametersMirror.TruthyBoolean == nil { + break + } + + return e.complexity.DefaultParametersMirror.TruthyBoolean(childComplexity), true + + case "Dog.dogBreed": + if e.complexity.Dog.DogBreed == nil { + break + } + + return e.complexity.Dog.DogBreed(childComplexity), true + + case "Dog.species": + if e.complexity.Dog.Species == nil { + break + } + + return e.complexity.Dog.Species(childComplexity), true + + case "EmbeddedCase1.exportedEmbeddedPointerExportedMethod": + if e.complexity.EmbeddedCase1.ExportedEmbeddedPointerExportedMethod == nil { + break + } + + return e.complexity.EmbeddedCase1.ExportedEmbeddedPointerExportedMethod(childComplexity), true + + case "EmbeddedCase2.unexportedEmbeddedPointerExportedMethod": + if e.complexity.EmbeddedCase2.UnexportedEmbeddedPointerExportedMethod == nil { + break + } + + return e.complexity.EmbeddedCase2.UnexportedEmbeddedPointerExportedMethod(childComplexity), true + + case "EmbeddedCase3.unexportedEmbeddedInterfaceExportedMethod": + if e.complexity.EmbeddedCase3.UnexportedEmbeddedInterfaceExportedMethod == nil { + break + } + + return e.complexity.EmbeddedCase3.UnexportedEmbeddedInterfaceExportedMethod(childComplexity), true + + case "EmbeddedDefaultScalar.value": + if e.complexity.EmbeddedDefaultScalar.Value == nil { + break + } + + return e.complexity.EmbeddedDefaultScalar.Value(childComplexity), true + + case "EmbeddedPointer.ID": + if e.complexity.EmbeddedPointer.ID == nil { + break + } + + return e.complexity.EmbeddedPointer.ID(childComplexity), true + + case "EmbeddedPointer.Title": + if e.complexity.EmbeddedPointer.Title == nil { + break + } + + return e.complexity.EmbeddedPointer.Title(childComplexity), true + + case "Error.errorOnNonRequiredField": + if e.complexity.Error.ErrorOnNonRequiredField == nil { + break + } + + return e.complexity.Error.ErrorOnNonRequiredField(childComplexity), true + + case "Error.errorOnRequiredField": + if e.complexity.Error.ErrorOnRequiredField == nil { + break + } + + return e.complexity.Error.ErrorOnRequiredField(childComplexity), true + + case "Error.id": + if e.complexity.Error.ID == nil { + break + } + + return e.complexity.Error.ID(childComplexity), true + + case "Error.nilOnRequiredField": + if e.complexity.Error.NilOnRequiredField == nil { + break + } + + return e.complexity.Error.NilOnRequiredField(childComplexity), true + + case "Errors.a": + if e.complexity.Errors.A == nil { + break + } + + return e.complexity.Errors.A(childComplexity), true + + case "Errors.b": + if e.complexity.Errors.B == nil { + break + } + + return e.complexity.Errors.B(childComplexity), true + + case "Errors.c": + if e.complexity.Errors.C == nil { + break + } + + return e.complexity.Errors.C(childComplexity), true + + case "Errors.d": + if e.complexity.Errors.D == nil { + break + } + + return e.complexity.Errors.D(childComplexity), true + + case "Errors.e": + if e.complexity.Errors.E == nil { + break + } + + return e.complexity.Errors.E(childComplexity), true + + case "ForcedResolver.field": + if e.complexity.ForcedResolver.Field == nil { + break + } + + return e.complexity.ForcedResolver.Field(childComplexity), true + + case "InnerObject.id": + if e.complexity.InnerObject.ID == nil { + break + } + + return e.complexity.InnerObject.ID(childComplexity), true + + case "InvalidIdentifier.id": + if e.complexity.InvalidIdentifier.ID == nil { + break + } + + return e.complexity.InvalidIdentifier.ID(childComplexity), true + + case "It.id": + if e.complexity.It.ID == nil { + break + } + + return e.complexity.It.ID(childComplexity), true + + case "LoopA.b": + if e.complexity.LoopA.B == nil { + break + } + + return e.complexity.LoopA.B(childComplexity), true + + case "LoopB.a": + if e.complexity.LoopB.A == nil { + break + } + + return e.complexity.LoopB.A(childComplexity), true + + case "Map.id": + if e.complexity.Map.ID == nil { + break + } + + return e.complexity.Map.ID(childComplexity), true + + case "MapStringInterfaceType.a": + if e.complexity.MapStringInterfaceType.A == nil { + break + } + + return e.complexity.MapStringInterfaceType.A(childComplexity), true + + case "MapStringInterfaceType.b": + if e.complexity.MapStringInterfaceType.B == nil { + break + } + + return e.complexity.MapStringInterfaceType.B(childComplexity), true + + case "ModelMethods.noContext": + if e.complexity.ModelMethods.NoContext == nil { + break + } + + return e.complexity.ModelMethods.NoContext(childComplexity), true + + case "ModelMethods.resolverField": + if e.complexity.ModelMethods.ResolverField == nil { + break + } + + return e.complexity.ModelMethods.ResolverField(childComplexity), true + + case "ModelMethods.withContext": + if e.complexity.ModelMethods.WithContext == nil { + break + } + + return e.complexity.ModelMethods.WithContext(childComplexity), true + + case "Mutation.defaultInput": + if e.complexity.Mutation.DefaultInput == nil { + break + } + + args, err := ec.field_Mutation_defaultInput_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DefaultInput(childComplexity, args["input"].(DefaultInput)), true + + case "Mutation.updatePtrToPtr": + if e.complexity.Mutation.UpdatePtrToPtr == nil { + break + } + + args, err := ec.field_Mutation_updatePtrToPtr_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdatePtrToPtr(childComplexity, args["input"].(UpdatePtrToPtrOuter)), true + + case "Mutation.updateSomething": + if e.complexity.Mutation.UpdateSomething == nil { + break + } + + args, err := ec.field_Mutation_updateSomething_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateSomething(childComplexity, args["input"].(SpecialInput)), true + + case "ObjectDirectives.nullableText": + if e.complexity.ObjectDirectives.NullableText == nil { + break + } + + return e.complexity.ObjectDirectives.NullableText(childComplexity), true + + case "ObjectDirectives.order": + if e.complexity.ObjectDirectives.Order == nil { + break + } + + return e.complexity.ObjectDirectives.Order(childComplexity), true + + case "ObjectDirectives.text": + if e.complexity.ObjectDirectives.Text == nil { + break + } + + return e.complexity.ObjectDirectives.Text(childComplexity), true + + case "ObjectDirectivesWithCustomGoModel.nullableText": + if e.complexity.ObjectDirectivesWithCustomGoModel.NullableText == nil { + break + } + + return e.complexity.ObjectDirectivesWithCustomGoModel.NullableText(childComplexity), true + + case "OuterObject.inner": + if e.complexity.OuterObject.Inner == nil { + break + } + + return e.complexity.OuterObject.Inner(childComplexity), true + + case "OverlappingFields.oneFoo", "OverlappingFields.twoFoo": + if e.complexity.OverlappingFields.Foo == nil { + break + } + + return e.complexity.OverlappingFields.Foo(childComplexity), true + + case "OverlappingFields.newFoo", "OverlappingFields.new_foo": + if e.complexity.OverlappingFields.NewFoo == nil { + break + } + + return e.complexity.OverlappingFields.NewFoo(childComplexity), true + + case "OverlappingFields.oldFoo": + if e.complexity.OverlappingFields.OldFoo == nil { + break + } + + return e.complexity.OverlappingFields.OldFoo(childComplexity), true + + case "Panics.argUnmarshal": + if e.complexity.Panics.ArgUnmarshal == nil { + break + } + + args, err := ec.field_Panics_argUnmarshal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Panics.ArgUnmarshal(childComplexity, args["u"].([]MarshalPanic)), true + + case "Panics.fieldFuncMarshal": + if e.complexity.Panics.FieldFuncMarshal == nil { + break + } + + args, err := ec.field_Panics_fieldFuncMarshal_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Panics.FieldFuncMarshal(childComplexity, args["u"].([]MarshalPanic)), true + + case "Panics.fieldScalarMarshal": + if e.complexity.Panics.FieldScalarMarshal == nil { + break + } + + return e.complexity.Panics.FieldScalarMarshal(childComplexity), true + + case "Primitive.squared": + if e.complexity.Primitive.Squared == nil { + break + } + + return e.complexity.Primitive.Squared(childComplexity), true + + case "Primitive.value": + if e.complexity.Primitive.Value == nil { + break + } + + return e.complexity.Primitive.Value(childComplexity), true + + case "PrimitiveString.doubled": + if e.complexity.PrimitiveString.Doubled == nil { + break + } + + return e.complexity.PrimitiveString.Doubled(childComplexity), true + + case "PrimitiveString.len": + if e.complexity.PrimitiveString.Len == nil { + break + } + + return e.complexity.PrimitiveString.Len(childComplexity), true + + case "PrimitiveString.value": + if e.complexity.PrimitiveString.Value == nil { + break + } + + return e.complexity.PrimitiveString.Value(childComplexity), true + + case "PtrToPtrInner.key": + if e.complexity.PtrToPtrInner.Key == nil { + break + } + + return e.complexity.PtrToPtrInner.Key(childComplexity), true + + case "PtrToPtrInner.value": + if e.complexity.PtrToPtrInner.Value == nil { + break + } + + return e.complexity.PtrToPtrInner.Value(childComplexity), true + + case "PtrToPtrOuter.inner": + if e.complexity.PtrToPtrOuter.Inner == nil { + break + } + + return e.complexity.PtrToPtrOuter.Inner(childComplexity), true + + case "PtrToPtrOuter.name": + if e.complexity.PtrToPtrOuter.Name == nil { + break + } + + return e.complexity.PtrToPtrOuter.Name(childComplexity), true + + case "PtrToPtrOuter.stupidInner": + if e.complexity.PtrToPtrOuter.StupidInner == nil { + break + } + + return e.complexity.PtrToPtrOuter.StupidInner(childComplexity), true + + case "PtrToSliceContainer.ptrToSlice": + if e.complexity.PtrToSliceContainer.PtrToSlice == nil { + break + } + + return e.complexity.PtrToSliceContainer.PtrToSlice(childComplexity), true + + case "Query.animal": + if e.complexity.Query.Animal == nil { + break + } + + return e.complexity.Query.Animal(childComplexity), true + + case "Query.autobind": + if e.complexity.Query.Autobind == nil { + break + } + + return e.complexity.Query.Autobind(childComplexity), true + + case "Query.collision": + if e.complexity.Query.Collision == nil { + break + } + + return e.complexity.Query.Collision(childComplexity), true + + case "Query.defaultParameters": + if e.complexity.Query.DefaultParameters == nil { + break + } + + args, err := ec.field_Query_defaultParameters_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DefaultParameters(childComplexity, args["falsyBoolean"].(*bool), args["truthyBoolean"].(*bool)), true + + case "Query.defaultScalar": + if e.complexity.Query.DefaultScalar == nil { + break + } + + args, err := ec.field_Query_defaultScalar_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DefaultScalar(childComplexity, args["arg"].(string)), true + + case "Query.deprecatedField": + if e.complexity.Query.DeprecatedField == nil { + break + } + + return e.complexity.Query.DeprecatedField(childComplexity), true + + case "Query.directiveArg": + if e.complexity.Query.DirectiveArg == nil { + break + } + + args, err := ec.field_Query_directiveArg_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveArg(childComplexity, args["arg"].(string)), true + + case "Query.directiveDouble": + if e.complexity.Query.DirectiveDouble == nil { + break + } + + return e.complexity.Query.DirectiveDouble(childComplexity), true + + case "Query.directiveField": + if e.complexity.Query.DirectiveField == nil { + break + } + + return e.complexity.Query.DirectiveField(childComplexity), true + + case "Query.directiveFieldDef": + if e.complexity.Query.DirectiveFieldDef == nil { + break + } + + args, err := ec.field_Query_directiveFieldDef_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveFieldDef(childComplexity, args["ret"].(string)), true + + case "Query.directiveInput": + if e.complexity.Query.DirectiveInput == nil { + break + } + + args, err := ec.field_Query_directiveInput_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveInput(childComplexity, args["arg"].(InputDirectives)), true + + case "Query.directiveInputNullable": + if e.complexity.Query.DirectiveInputNullable == nil { + break + } + + args, err := ec.field_Query_directiveInputNullable_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveInputNullable(childComplexity, args["arg"].(*InputDirectives)), true + + case "Query.directiveInputType": + if e.complexity.Query.DirectiveInputType == nil { + break + } + + args, err := ec.field_Query_directiveInputType_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveInputType(childComplexity, args["arg"].(InnerInput)), true + + case "Query.directiveNullableArg": + if e.complexity.Query.DirectiveNullableArg == nil { + break + } + + args, err := ec.field_Query_directiveNullableArg_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.DirectiveNullableArg(childComplexity, args["arg"].(*int), args["arg2"].(*int), args["arg3"].(*string)), true + + case "Query.directiveObject": + if e.complexity.Query.DirectiveObject == nil { + break + } + + return e.complexity.Query.DirectiveObject(childComplexity), true + + case "Query.directiveObjectWithCustomGoModel": + if e.complexity.Query.DirectiveObjectWithCustomGoModel == nil { + break + } + + return e.complexity.Query.DirectiveObjectWithCustomGoModel(childComplexity), true + + case "Query.directiveUnimplemented": + if e.complexity.Query.DirectiveUnimplemented == nil { + break + } + + return e.complexity.Query.DirectiveUnimplemented(childComplexity), true + + case "Query.embeddedCase1": + if e.complexity.Query.EmbeddedCase1 == nil { + break + } + + return e.complexity.Query.EmbeddedCase1(childComplexity), true + + case "Query.embeddedCase2": + if e.complexity.Query.EmbeddedCase2 == nil { + break + } + + return e.complexity.Query.EmbeddedCase2(childComplexity), true + + case "Query.embeddedCase3": + if e.complexity.Query.EmbeddedCase3 == nil { + break + } + + return e.complexity.Query.EmbeddedCase3(childComplexity), true + + case "Query.enumInInput": + if e.complexity.Query.EnumInInput == nil { + break + } + + args, err := ec.field_Query_enumInInput_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.EnumInInput(childComplexity, args["input"].(*InputWithEnumValue)), true + + case "Query.errorBubble": + if e.complexity.Query.ErrorBubble == nil { + break + } + + return e.complexity.Query.ErrorBubble(childComplexity), true + + case "Query.errorBubbleList": + if e.complexity.Query.ErrorBubbleList == nil { + break + } + + return e.complexity.Query.ErrorBubbleList(childComplexity), true + + case "Query.errorList": + if e.complexity.Query.ErrorList == nil { + break + } + + return e.complexity.Query.ErrorList(childComplexity), true + + case "Query.errors": + if e.complexity.Query.Errors == nil { + break + } + + return e.complexity.Query.Errors(childComplexity), true + + case "Query.fallback": + if e.complexity.Query.Fallback == nil { + break + } + + args, err := ec.field_Query_fallback_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Fallback(childComplexity, args["arg"].(FallbackToStringEncoding)), true + + case "Query.inputNullableSlice": + if e.complexity.Query.InputNullableSlice == nil { + break + } + + args, err := ec.field_Query_inputNullableSlice_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.InputNullableSlice(childComplexity, args["arg"].([]string)), true + + case "Query.inputSlice": + if e.complexity.Query.InputSlice == nil { + break + } + + args, err := ec.field_Query_inputSlice_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.InputSlice(childComplexity, args["arg"].([]string)), true + + case "Query.invalidIdentifier": + if e.complexity.Query.InvalidIdentifier == nil { + break + } + + return e.complexity.Query.InvalidIdentifier(childComplexity), true + + case "Query.issue896a": + if e.complexity.Query.Issue896a == nil { + break + } + + return e.complexity.Query.Issue896a(childComplexity), true + + case "Query.mapInput": + if e.complexity.Query.MapInput == nil { + break + } + + args, err := ec.field_Query_mapInput_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.MapInput(childComplexity, args["input"].(map[string]interface{})), true + + case "Query.mapNestedStringInterface": + if e.complexity.Query.MapNestedStringInterface == nil { + break + } + + args, err := ec.field_Query_mapNestedStringInterface_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.MapNestedStringInterface(childComplexity, args["in"].(*NestedMapInput)), true + + case "Query.mapStringInterface": + if e.complexity.Query.MapStringInterface == nil { + break + } + + args, err := ec.field_Query_mapStringInterface_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.MapStringInterface(childComplexity, args["in"].(map[string]interface{})), true + + case "Query.modelMethods": + if e.complexity.Query.ModelMethods == nil { + break + } + + return e.complexity.Query.ModelMethods(childComplexity), true + + case "Query.nestedInputs": + if e.complexity.Query.NestedInputs == nil { + break + } + + args, err := ec.field_Query_nestedInputs_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.NestedInputs(childComplexity, args["input"].([][]*OuterInput)), true + + case "Query.nestedOutputs": + if e.complexity.Query.NestedOutputs == nil { + break + } + + return e.complexity.Query.NestedOutputs(childComplexity), true + + case "Query.noShape": + if e.complexity.Query.NoShape == nil { + break + } + + return e.complexity.Query.NoShape(childComplexity), true + + case "Query.noShapeTypedNil": + if e.complexity.Query.NoShapeTypedNil == nil { + break + } + + return e.complexity.Query.NoShapeTypedNil(childComplexity), true + + case "Query.node": + if e.complexity.Query.Node == nil { + break + } + + return e.complexity.Query.Node(childComplexity), true + + case "Query.notAnInterface": + if e.complexity.Query.NotAnInterface == nil { + break + } + + return e.complexity.Query.NotAnInterface(childComplexity), true + + case "Query.nullableArg": + if e.complexity.Query.NullableArg == nil { + break + } + + args, err := ec.field_Query_nullableArg_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.NullableArg(childComplexity, args["arg"].(*int)), true + + case "Query.optionalUnion": + if e.complexity.Query.OptionalUnion == nil { + break + } + + return e.complexity.Query.OptionalUnion(childComplexity), true + + case "Query.overlapping": + if e.complexity.Query.Overlapping == nil { + break + } + + return e.complexity.Query.Overlapping(childComplexity), true + + case "Query.panics": + if e.complexity.Query.Panics == nil { + break + } + + return e.complexity.Query.Panics(childComplexity), true + + case "Query.primitiveObject": + if e.complexity.Query.PrimitiveObject == nil { + break + } + + return e.complexity.Query.PrimitiveObject(childComplexity), true + + case "Query.primitiveStringObject": + if e.complexity.Query.PrimitiveStringObject == nil { + break + } + + return e.complexity.Query.PrimitiveStringObject(childComplexity), true + + case "Query.ptrToSliceContainer": + if e.complexity.Query.PtrToSliceContainer == nil { + break + } + + return e.complexity.Query.PtrToSliceContainer(childComplexity), true + + case "Query.recursive": + if e.complexity.Query.Recursive == nil { + break + } + + args, err := ec.field_Query_recursive_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Recursive(childComplexity, args["input"].(*RecursiveInputSlice)), true + + case "Query.scalarSlice": + if e.complexity.Query.ScalarSlice == nil { + break + } + + return e.complexity.Query.ScalarSlice(childComplexity), true + + case "Query.shapeUnion": + if e.complexity.Query.ShapeUnion == nil { + break + } + + return e.complexity.Query.ShapeUnion(childComplexity), true + + case "Query.shapes": + if e.complexity.Query.Shapes == nil { + break + } + + return e.complexity.Query.Shapes(childComplexity), true + + case "Query.slices": + if e.complexity.Query.Slices == nil { + break + } + + return e.complexity.Query.Slices(childComplexity), true + + case "Query.user": + if e.complexity.Query.User == nil { + break + } + + args, err := ec.field_Query_user_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.User(childComplexity, args["id"].(int)), true + + case "Query.vOkCaseNil": + if e.complexity.Query.VOkCaseNil == nil { + break + } + + return e.complexity.Query.VOkCaseNil(childComplexity), true + + case "Query.vOkCaseValue": + if e.complexity.Query.VOkCaseValue == nil { + break + } + + return e.complexity.Query.VOkCaseValue(childComplexity), true + + case "Query.valid": + if e.complexity.Query.Valid == nil { + break + } + + return e.complexity.Query.Valid(childComplexity), true + + case "Query.validType": + if e.complexity.Query.ValidType == nil { + break + } + + return e.complexity.Query.ValidType(childComplexity), true + + case "Query.wrappedMap": + if e.complexity.Query.WrappedMap == nil { + break + } + + return e.complexity.Query.WrappedMap(childComplexity), true + + case "Query.wrappedScalar": + if e.complexity.Query.WrappedScalar == nil { + break + } + + return e.complexity.Query.WrappedScalar(childComplexity), true + + case "Query.wrappedSlice": + if e.complexity.Query.WrappedSlice == nil { + break + } + + return e.complexity.Query.WrappedSlice(childComplexity), true + + case "Query.wrappedStruct": + if e.complexity.Query.WrappedStruct == nil { + break + } + + return e.complexity.Query.WrappedStruct(childComplexity), true + + case "Rectangle.area": + if e.complexity.Rectangle.Area == nil { + break + } + + return e.complexity.Rectangle.Area(childComplexity), true + + case "Rectangle.length": + if e.complexity.Rectangle.Length == nil { + break + } + + return e.complexity.Rectangle.Length(childComplexity), true + + case "Rectangle.width": + if e.complexity.Rectangle.Width == nil { + break + } + + return e.complexity.Rectangle.Width(childComplexity), true + + case "Slices.test1": + if e.complexity.Slices.Test1 == nil { + break + } + + return e.complexity.Slices.Test1(childComplexity), true + + case "Slices.test2": + if e.complexity.Slices.Test2 == nil { + break + } + + return e.complexity.Slices.Test2(childComplexity), true + + case "Slices.test3": + if e.complexity.Slices.Test3 == nil { + break + } + + return e.complexity.Slices.Test3(childComplexity), true + + case "Slices.test4": + if e.complexity.Slices.Test4 == nil { + break + } + + return e.complexity.Slices.Test4(childComplexity), true + + case "Subscription.directiveArg": + if e.complexity.Subscription.DirectiveArg == nil { + break + } + + args, err := ec.field_Subscription_directiveArg_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Subscription.DirectiveArg(childComplexity, args["arg"].(string)), true + + case "Subscription.directiveDouble": + if e.complexity.Subscription.DirectiveDouble == nil { + break + } + + return e.complexity.Subscription.DirectiveDouble(childComplexity), true + + case "Subscription.directiveNullableArg": + if e.complexity.Subscription.DirectiveNullableArg == nil { + break + } + + args, err := ec.field_Subscription_directiveNullableArg_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Subscription.DirectiveNullableArg(childComplexity, args["arg"].(*int), args["arg2"].(*int), args["arg3"].(*string)), true + + case "Subscription.directiveUnimplemented": + if e.complexity.Subscription.DirectiveUnimplemented == nil { + break + } + + return e.complexity.Subscription.DirectiveUnimplemented(childComplexity), true + + case "Subscription.initPayload": + if e.complexity.Subscription.InitPayload == nil { + break + } + + return e.complexity.Subscription.InitPayload(childComplexity), true + + case "Subscription.issue896b": + if e.complexity.Subscription.Issue896b == nil { + break + } + + return e.complexity.Subscription.Issue896b(childComplexity), true + + case "Subscription.updated": + if e.complexity.Subscription.Updated == nil { + break + } + + return e.complexity.Subscription.Updated(childComplexity), true + + case "User.created": + if e.complexity.User.Created == nil { + break + } + + return e.complexity.User.Created(childComplexity), true + + case "User.friends": + if e.complexity.User.Friends == nil { + break + } + + return e.complexity.User.Friends(childComplexity), true + + case "User.id": + if e.complexity.User.ID == nil { + break + } + + return e.complexity.User.ID(childComplexity), true + + case "User.updated": + if e.complexity.User.Updated == nil { + break + } + + return e.complexity.User.Updated(childComplexity), true + + case "VOkCaseNil.value": + if e.complexity.VOkCaseNil.Value == nil { + break + } + + return e.complexity.VOkCaseNil.Value(childComplexity), true + + case "VOkCaseValue.value": + if e.complexity.VOkCaseValue.Value == nil { + break + } + + return e.complexity.VOkCaseValue.Value(childComplexity), true + + case "ValidType.differentCase": + if e.complexity.ValidType.DifferentCase == nil { + break + } + + return e.complexity.ValidType.DifferentCase(childComplexity), true + + case "ValidType.different_case": + if e.complexity.ValidType.DifferentCaseOld == nil { + break + } + + return e.complexity.ValidType.DifferentCaseOld(childComplexity), true + + case "ValidType.validArgs": + if e.complexity.ValidType.ValidArgs == nil { + break + } + + args, err := ec.field_ValidType_validArgs_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.ValidType.ValidArgs(childComplexity, args["break"].(string), args["default"].(string), args["func"].(string), args["interface"].(string), args["select"].(string), args["case"].(string), args["defer"].(string), args["go"].(string), args["map"].(string), args["struct"].(string), args["chan"].(string), args["else"].(string), args["goto"].(string), args["package"].(string), args["switch"].(string), args["const"].(string), args["fallthrough"].(string), args["if"].(string), args["range"].(string), args["type"].(string), args["continue"].(string), args["for"].(string), args["import"].(string), args["return"].(string), args["var"].(string), args["_"].(string)), true + + case "ValidType.validInputKeywords": + if e.complexity.ValidType.ValidInputKeywords == nil { + break + } + + args, err := ec.field_ValidType_validInputKeywords_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.ValidType.ValidInputKeywords(childComplexity, args["input"].(*ValidInput)), true + + case "WrappedMap.get": + if e.complexity.WrappedMap.Get == nil { + break + } + + args, err := ec.field_WrappedMap_get_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.WrappedMap.Get(childComplexity, args["key"].(string)), true + + case "WrappedSlice.get": + if e.complexity.WrappedSlice.Get == nil { + break + } + + args, err := ec.field_WrappedSlice_get_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.WrappedSlice.Get(childComplexity, args["idx"].(int)), true + + case "WrappedStruct.desc": + if e.complexity.WrappedStruct.Desc == nil { + break + } + + return e.complexity.WrappedStruct.Desc(childComplexity), true + + case "WrappedStruct.name": + if e.complexity.WrappedStruct.Name == nil { + break + } + + return e.complexity.WrappedStruct.Name(childComplexity), true + + case "XXIt.id": + if e.complexity.XXIt.ID == nil { + break + } + + return e.complexity.XXIt.ID(childComplexity), true + + case "XxIt.id": + if e.complexity.XxIt.ID == nil { + break + } + + return e.complexity.XxIt.ID(childComplexity), true + + case "asdfIt.id": + if e.complexity.AsdfIt.ID == nil { + break + } + + return e.complexity.AsdfIt.ID(childComplexity), true + + case "iIt.id": + if e.complexity.IIt.ID == nil { + break + } + + return e.complexity.IIt.ID(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e} + first := true + + switch rc.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + if !first { + return nil + } + first = false + data := ec._Query(ctx, rc.Operation.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + case ast.Mutation: + return func(ctx context.Context) *graphql.Response { + if !first { + return nil + } + first = false + data := ec._Mutation(ctx, rc.Operation.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + case ast.Subscription: + next := ec._Subscription(ctx, rc.Operation.SelectionSet) + + var buf bytes.Buffer + return func(ctx context.Context) *graphql.Response { + buf.Reset() + data := next() + + if data == nil { + return nil + } + data.MarshalGQL(&buf) + + return &graphql.Response{ + Data: buf.Bytes(), + } + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "builtinscalar.graphql", Input: ` +""" +Since gqlgen defines default implementation for a Map scalar, this tests that the builtin is _not_ +added to the TypeMap +""" +type Map { + id: ID! +} +`, BuiltIn: false}, + {Name: "complexity.graphql", Input: `extend type Query { + overlapping: OverlappingFields +} + +type OverlappingFields { + oneFoo: Int! @goField(name: "foo") + twoFoo: Int! @goField(name: "foo") + oldFoo: Int! @goField(name: "foo", forceResolver: true) + newFoo: Int! + new_foo: Int! +} +`, BuiltIn: false}, + {Name: "defaults.graphql", Input: `extend type Query { + defaultParameters( + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true + ): DefaultParametersMirror! +} + +extend type Mutation { + defaultInput(input: DefaultInput!): DefaultParametersMirror! +} + +input DefaultInput { + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true +} + +type DefaultParametersMirror { + falsyBoolean: Boolean + truthyBoolean: Boolean +} +`, BuiltIn: false}, + {Name: "directive.graphql", Input: `directive @length(min: Int!, max: Int, message: String) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION +directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION +directive @custom on ARGUMENT_DEFINITION +directive @logged(id: UUID!) on FIELD +directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION +directive @directive1 on FIELD_DEFINITION +directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT +directive @unimplemented on FIELD_DEFINITION +directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT +directive @order2(location: String!) on OBJECT + +extend type Query { + directiveArg(arg: String! @length(min:1, max: 255, message: "invalid length")): String + directiveNullableArg(arg: Int @range(min:0), arg2: Int @range, arg3: String @toNull): String + directiveInputNullable(arg: InputDirectives): String + directiveInput(arg: InputDirectives!): String + directiveInputType(arg: InnerInput! @custom): String + directiveObject: ObjectDirectives @order1(location: "Query_field") + directiveObjectWithCustomGoModel: ObjectDirectivesWithCustomGoModel + directiveFieldDef(ret: String!): String! @length(min: 1, message: "not valid") + directiveField: String + directiveDouble: String @directive1 @directive2 + directiveUnimplemented: String @unimplemented +} + +extend type Subscription { + directiveArg(arg: String! @length(min:1, max: 255, message: "invalid length")): String + directiveNullableArg(arg: Int @range(min:0), arg2: Int @range, arg3: String @toNull): String + directiveDouble: String @directive1 @directive2 + directiveUnimplemented: String @unimplemented +} + +input InputDirectives @directive3 { + text: String! @length(min: 0, max: 7, message: "not valid") + nullableText: String @toNull + inner: InnerDirectives! + innerNullable: InnerDirectives + thirdParty: ThirdParty @length(min: 0, max: 7) +} + +input InnerDirectives { + message: String! @length(min: 1, message: "not valid") +} + +type ObjectDirectives @order1(location: "order1_1") @order1(location: "order1_2") @order2(location: "order2_1") { + text: String! @length(min: 0, max: 7, message: "not valid") + nullableText: String @toNull + order: [String!]! +} + +type ObjectDirectivesWithCustomGoModel { + nullableText: String @toNull +} +`, BuiltIn: false}, + {Name: "embedded.graphql", Input: `extend type Query { + embeddedCase1: EmbeddedCase1 + embeddedCase2: EmbeddedCase2 + embeddedCase3: EmbeddedCase3 +} + +type EmbeddedCase1 @goModel(model:"followschema.EmbeddedCase1") { + exportedEmbeddedPointerExportedMethod: String! +} + +type EmbeddedCase2 @goModel(model:"followschema.EmbeddedCase2") { + unexportedEmbeddedPointerExportedMethod: String! +} + +type EmbeddedCase3 @goModel(model:"followschema.EmbeddedCase3") { + unexportedEmbeddedInterfaceExportedMethod: String! +} +`, BuiltIn: false}, + {Name: "enum.graphql", Input: `enum EnumTest { + OK + NG +} + +input InputWithEnumValue { + enum: EnumTest! +} + +extend type Query { + enumInInput(input: InputWithEnumValue): EnumTest! +} +`, BuiltIn: false}, + {Name: "interfaces.graphql", Input: `extend type Query { + shapes: [Shape] + noShape: Shape @makeNil + node: Node! + noShapeTypedNil: Shape @makeTypedNil + animal: Animal @makeTypedNil + notAnInterface: BackedByInterface +} + +interface Animal { + species: String! +} + +type BackedByInterface { + id: String! + thisShouldBind: String! + thisShouldBindWithError: String! +} + +type Dog implements Animal { + species: String! + dogBreed: String! +} + +type Cat implements Animal { + species: String! + catBreed: String! +} + +interface Shape { + area: Float +} +type Circle implements Shape { + radius: Float + area: Float +} +type Rectangle implements Shape { + length: Float + width: Float + area: Float +} +union ShapeUnion @goModel(model:"followschema.ShapeUnion") = Circle | Rectangle + +directive @makeNil on FIELD_DEFINITION +directive @makeTypedNil on FIELD_DEFINITION + +interface Node { + id: ID! + child: Node! +} + +type ConcreteNodeA implements Node { + id: ID! + child: Node! + name: String! +} + +""" Implements the Node interface with another interface """ +type ConcreteNodeInterface implements Node { + id: ID! + child: Node! +} +`, BuiltIn: false}, + {Name: "issue896.graphql", Input: `# This example should build stable output. If the file content starts +# alternating nondeterministically between two outputs, then see +# https://github.com/99designs/gqlgen/issues/896. + +extend schema { + query: Query + subscription: Subscription +} + +type CheckIssue896 {id: Int} + +extend type Query { + issue896a: [CheckIssue896!] # Note the "!" or lack thereof. +} + +extend type Subscription { + issue896b: [CheckIssue896] # Note the "!" or lack thereof. +} +`, BuiltIn: false}, + {Name: "loops.graphql", Input: `type LoopA { + b: LoopB! +} + +type LoopB { + a: LoopA! +} +`, BuiltIn: false}, + {Name: "maps.graphql", Input: `extend type Query { + mapStringInterface(in: MapStringInterfaceInput): MapStringInterfaceType + mapNestedStringInterface(in: NestedMapInput): MapStringInterfaceType +} + +type MapStringInterfaceType @goModel(model: "map[string]interface{}") { + a: String + b: Int +} + +input MapStringInterfaceInput @goModel(model: "map[string]interface{}") { + a: String + b: Int +} + +input NestedMapInput { + map: MapStringInterfaceInput +} +`, BuiltIn: false}, + {Name: "mutation_with_custom_scalar.graphql", Input: `extend type Mutation { + updateSomething(input: SpecialInput!): String! +} + +scalar Email + +input SpecialInput { + nesting: NestedInput! +} + +input NestedInput { + field: Email! +} +`, BuiltIn: false}, + {Name: "nulls.graphql", Input: `extend type Query { + errorBubble: Error + errorBubbleList: [Error!] + errorList: [Error] + errors: Errors + valid: String! +} + +type Errors { + a: Error! + b: Error! + c: Error! + d: Error! + e: Error! +} + +type Error { + id: ID! + errorOnNonRequiredField: String + errorOnRequiredField: String! + nilOnRequiredField: String! +} +`, BuiltIn: false}, + {Name: "panics.graphql", Input: `extend type Query { + panics: Panics +} + +type Panics { + fieldScalarMarshal: [MarshalPanic!]! + fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]! + argUnmarshal(u: [MarshalPanic!]!): Boolean! + +} + +scalar MarshalPanic +`, BuiltIn: false}, + {Name: "primitive_objects.graphql", Input: `extend type Query { + primitiveObject: [Primitive!]! + primitiveStringObject: [PrimitiveString!]! +} + +type Primitive { + value: Int! + squared: Int! +} + +type PrimitiveString { + value: String! + doubled: String! + len: Int! +} +`, BuiltIn: false}, + {Name: "ptr_to_ptr_input.graphql", Input: `type PtrToPtrOuter { + name: String! + inner: PtrToPtrInner + stupidInner: PtrToPtrInner +} + +type PtrToPtrInner { + key: String! + value: String! +} + +input UpdatePtrToPtrOuter { + name: String + inner: UpdatePtrToPtrInner + stupidInner: UpdatePtrToPtrInner +} + +input UpdatePtrToPtrInner { + key: String + value: String +} + +extend type Mutation { + updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter! +} +`, BuiltIn: false}, + {Name: "ptr_to_slice.graphql", Input: `type PtrToSliceContainer { + ptrToSlice: [String!] +} + +extend type Query { + ptrToSliceContainer: PtrToSliceContainer! +} +`, BuiltIn: false}, + {Name: "scalar_default.graphql", Input: `extend type Query { + defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation! +} + +""" This doesnt have an implementation in the typemap, so it should act like a string """ +scalar DefaultScalarImplementation + +type EmbeddedDefaultScalar { + value: DefaultScalarImplementation +} +`, BuiltIn: false}, + {Name: "schema.graphql", Input: `directive @goModel( + model: String + models: [String!] +) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION +directive @goField( + forceResolver: Boolean + name: String +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + +type Query { + invalidIdentifier: InvalidIdentifier + collision: It + mapInput(input: Changes): Boolean + recursive(input: RecursiveInputSlice): Boolean + nestedInputs(input: [[OuterInput]] = [[{ inner: { id: 1 } }]]): Boolean + nestedOutputs: [[OuterObject]] + modelMethods: ModelMethods + user(id: Int!): User! + nullableArg(arg: Int = 123): String + inputSlice(arg: [String!]!): Boolean! + inputNullableSlice(arg: [String!]): Boolean! + shapeUnion: ShapeUnion! + autobind: Autobind + deprecatedField: String! @deprecated(reason: "test deprecated directive") +} + +type Subscription { + updated: String! + initPayload: String! +} + +type User { + id: Int! + friends: [User!]! @goField(forceResolver: true) + created: Time! + updated: Time +} + +type Autobind { + int: Int! + int32: Int! + int64: Int! + + idStr: ID! + idInt: ID! +} + +type ModelMethods { + resolverField: Boolean! + noContext: Boolean! + withContext: Boolean! +} + +type InvalidIdentifier { + id: Int! +} + +type It { + id: ID! +} + +input Changes @goModel(model: "map[string]interface{}") { + a: Int + b: Int +} + +input RecursiveInputSlice { + self: [RecursiveInputSlice!] +} + +input InnerInput { + id: Int! +} + +input OuterInput { + inner: InnerInput! +} + +scalar ThirdParty @goModel(model:"followschema.ThirdParty") + +type OuterObject { + inner: InnerObject! +} + +type InnerObject { + id: Int! +} + +type ForcedResolver { + field: Circle @goField(forceResolver: true) +} + +type EmbeddedPointer @goModel(model:"followschema.EmbeddedPointerModel") { + ID: String + Title: String +} + +scalar UUID + +enum Status { + OK + ERROR +} + +scalar Time +`, BuiltIn: false}, + {Name: "slices.graphql", Input: `extend type Query { + slices: Slices + scalarSlice: Bytes! +} + +type Slices { + test1: [String] + test2: [String!] + test3: [String]! + test4: [String!]! +} + +scalar Bytes +`, BuiltIn: false}, + {Name: "typefallback.graphql", Input: `extend type Query { + fallback(arg: FallbackToStringEncoding!): FallbackToStringEncoding! +} + +enum FallbackToStringEncoding { + A + B + C +} +`, BuiltIn: false}, + {Name: "useptr.graphql", Input: `type A { + id: ID! +} + +type B { + id: ID! +} + +union TestUnion = A | B + +extend type Query { + optionalUnion: TestUnion +} +`, BuiltIn: false}, + {Name: "v-ok.graphql", Input: `extend type Query { + vOkCaseValue: VOkCaseValue + vOkCaseNil: VOkCaseNil +} + +type VOkCaseValue @goModel(model:"followschema.VOkCaseValue") { + value: String +} + +type VOkCaseNil @goModel(model:"followschema.VOkCaseNil") { + value: String +} +`, BuiltIn: false}, + {Name: "validtypes.graphql", Input: `extend type Query { + validType: ValidType +} + +""" These things are all valid, but without care generate invalid go code """ +type ValidType { + differentCase: String! + different_case: String! @goField(name:"DifferentCaseOld") + validInputKeywords(input: ValidInput): Boolean! + validArgs( + break: String!, + default: String!, + func: String!, + interface: String!, + select: String!, + case: String!, + defer: String!, + go: String!, + map: String!, + struct: String!, + chan: String!, + else: String!, + goto: String!, + package: String!, + switch: String!, + const: String!, + fallthrough: String!, + if: String!, + range: String!, + type: String!, + continue: String!, + for: String!, + import: String!, + return: String!, + var: String!, + _: String!, + ): Boolean! +} + +input ValidInput { + break: String! + default: String! + func: String! + interface: String! + select: String! + case: String! + defer: String! + go: String! + map: String! + struct: String! + chan: String! + else: String! + goto: String! + package: String! + switch: String! + const: String! + fallthrough: String! + if: String! + range: String! + type: String! + continue: String! + for: String! + import: String! + return: String! + var: String! + _: String! @goField(name: "Underscore") +} + +# see https://github.com/99designs/gqlgen/issues/694 +type Content_User { + foo: String +} + +type Content_Post { + foo: String +} + +union Content_Child = Content_User | Content_Post +`, BuiltIn: false}, + {Name: "weird_type_cases.graphql", Input: `# regression test for https://github.com/99designs/gqlgen/issues/583 + +type asdfIt { id: ID! } +type iIt { id: ID! } +type AIt { id: ID! } +type XXIt { id: ID! } +type AbIt { id: ID! } +type XxIt { id: ID! } +`, BuiltIn: false}, + {Name: "wrapped_type.graphql", Input: `# regression test for https://github.com/99designs/gqlgen/issues/721 + +extend type Query { + wrappedStruct: WrappedStruct! + wrappedScalar: WrappedScalar! + wrappedMap: WrappedMap! + wrappedSlice: WrappedSlice! +} + +type WrappedStruct { name: WrappedScalar!, desc: WrappedScalar } +scalar WrappedScalar +type WrappedMap { get(key: String!): String! } +type WrappedSlice { get(idx: Int!): String! } +`, BuiltIn: false}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) diff --git a/codegen/testserver/followschema/scalar_default.generated.go b/codegen/testserver/followschema/scalar_default.generated.go new file mode 100644 index 00000000000..dcbd4dc63cf --- /dev/null +++ b/codegen/testserver/followschema/scalar_default.generated.go @@ -0,0 +1,130 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _EmbeddedDefaultScalar_value(ctx context.Context, field graphql.CollectedField, obj *EmbeddedDefaultScalar) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedDefaultScalar", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalODefaultScalarImplementation2ᚖstring(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var embeddedDefaultScalarImplementors = []string{"EmbeddedDefaultScalar"} + +func (ec *executionContext) _EmbeddedDefaultScalar(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedDefaultScalar) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, embeddedDefaultScalarImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmbeddedDefaultScalar") + case "value": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedDefaultScalar_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNDefaultScalarImplementation2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNDefaultScalarImplementation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalODefaultScalarImplementation2ᚖstring(ctx context.Context, v interface{}) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalODefaultScalarImplementation2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalString(*v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/scalar_default.graphql b/codegen/testserver/followschema/scalar_default.graphql similarity index 100% rename from codegen/testserver/scalar_default.graphql rename to codegen/testserver/followschema/scalar_default.graphql diff --git a/codegen/testserver/followschema/scalar_default_test.go b/codegen/testserver/followschema/scalar_default_test.go new file mode 100644 index 00000000000..f6fc05cb09e --- /dev/null +++ b/codegen/testserver/followschema/scalar_default_test.go @@ -0,0 +1,32 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestDefaultScalarImplementation(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.DefaultScalar = func(ctx context.Context, arg string) (i string, e error) { + return arg, nil + } + + t.Run("with arg value", func(t *testing.T) { + var resp struct{ DefaultScalar string } + c.MustPost(`query { defaultScalar(arg: "fff") }`, &resp) + require.Equal(t, "fff", resp.DefaultScalar) + }) + + t.Run("with default value", func(t *testing.T) { + var resp struct{ DefaultScalar string } + c.MustPost(`query { defaultScalar }`, &resp) + require.Equal(t, "default", resp.DefaultScalar) + }) +} diff --git a/codegen/testserver/followschema/schema.generated.go b/codegen/testserver/followschema/schema.generated.go new file mode 100644 index 00000000000..3d27d92643d --- /dev/null +++ b/codegen/testserver/followschema/schema.generated.go @@ -0,0 +1,6018 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "errors" + "fmt" + "io" + "strconv" + "sync" + "sync/atomic" + "time" + + introspection1 "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type ForcedResolverResolver interface { + Field(ctx context.Context, obj *ForcedResolver) (*Circle, error) +} +type ModelMethodsResolver interface { + ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) +} +type QueryResolver interface { + InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) + Collision(ctx context.Context) (*introspection1.It, error) + MapInput(ctx context.Context, input map[string]interface{}) (*bool, error) + Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) + NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) + NestedOutputs(ctx context.Context) ([][]*OuterObject, error) + ModelMethods(ctx context.Context) (*ModelMethods, error) + User(ctx context.Context, id int) (*User, error) + NullableArg(ctx context.Context, arg *int) (*string, error) + InputSlice(ctx context.Context, arg []string) (bool, error) + InputNullableSlice(ctx context.Context, arg []string) (bool, error) + ShapeUnion(ctx context.Context) (ShapeUnion, error) + Autobind(ctx context.Context) (*Autobind, error) + DeprecatedField(ctx context.Context) (string, error) + Overlapping(ctx context.Context) (*OverlappingFields, error) + DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) + DirectiveArg(ctx context.Context, arg string) (*string, error) + DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) + DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) + DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) + DirectiveInputType(ctx context.Context, arg InnerInput) (*string, error) + DirectiveObject(ctx context.Context) (*ObjectDirectives, error) + DirectiveObjectWithCustomGoModel(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) + DirectiveFieldDef(ctx context.Context, ret string) (string, error) + DirectiveField(ctx context.Context) (*string, error) + DirectiveDouble(ctx context.Context) (*string, error) + DirectiveUnimplemented(ctx context.Context) (*string, error) + EmbeddedCase1(ctx context.Context) (*EmbeddedCase1, error) + EmbeddedCase2(ctx context.Context) (*EmbeddedCase2, error) + EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) + EnumInInput(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) + Shapes(ctx context.Context) ([]Shape, error) + NoShape(ctx context.Context) (Shape, error) + Node(ctx context.Context) (Node, error) + NoShapeTypedNil(ctx context.Context) (Shape, error) + Animal(ctx context.Context) (Animal, error) + NotAnInterface(ctx context.Context) (BackedByInterface, error) + Issue896a(ctx context.Context) ([]*CheckIssue896, error) + MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) + MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) + ErrorBubble(ctx context.Context) (*Error, error) + ErrorBubbleList(ctx context.Context) ([]*Error, error) + ErrorList(ctx context.Context) ([]*Error, error) + Errors(ctx context.Context) (*Errors, error) + Valid(ctx context.Context) (string, error) + Panics(ctx context.Context) (*Panics, error) + PrimitiveObject(ctx context.Context) ([]Primitive, error) + PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) + PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) + DefaultScalar(ctx context.Context, arg string) (string, error) + Slices(ctx context.Context) (*Slices, error) + ScalarSlice(ctx context.Context) ([]byte, error) + Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) + OptionalUnion(ctx context.Context) (TestUnion, error) + VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) + VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) + ValidType(ctx context.Context) (*ValidType, error) + WrappedStruct(ctx context.Context) (*WrappedStruct, error) + WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) + WrappedMap(ctx context.Context) (WrappedMap, error) + WrappedSlice(ctx context.Context) (WrappedSlice, error) +} +type SubscriptionResolver interface { + Updated(ctx context.Context) (<-chan string, error) + InitPayload(ctx context.Context) (<-chan string, error) + DirectiveArg(ctx context.Context, arg string) (<-chan *string, error) + DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) + DirectiveDouble(ctx context.Context) (<-chan *string, error) + DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) + Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) +} +type UserResolver interface { + Friends(ctx context.Context, obj *User) ([]*User, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["name"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["name"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_defaultParameters_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *bool + if tmp, ok := rawArgs["falsyBoolean"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("falsyBoolean")) + arg0, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["falsyBoolean"] = arg0 + var arg1 *bool + if tmp, ok := rawArgs["truthyBoolean"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("truthyBoolean")) + arg1, err = ec.unmarshalOBoolean2ᚖbool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["truthyBoolean"] = arg1 + return args, nil +} + +func (ec *executionContext) field_Query_defaultScalar_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalNDefaultScalarImplementation2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 1) + if err != nil { + return nil, err + } + max, err := ec.unmarshalOInt2ᚖint(ctx, 255) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "invalid length") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, rawArgs, directive0, min, max, message) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + arg0 = data + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp)) + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveFieldDef_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["ret"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ret")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["ret"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveInputNullable_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *InputDirectives + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputDirectives(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveInputType_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 InnerInput + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + directive0 := func(ctx context.Context) (interface{}, error) { + return ec.unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerInput(ctx, tmp) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Custom == nil { + return nil, errors.New("directive custom is not implemented") + } + return ec.directives.Custom(ctx, rawArgs, directive0) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(InnerInput); ok { + arg0 = data + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/followschema.InnerInput`, tmp)) + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 InputDirectives + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputDirectives(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_directiveNullableArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *int + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOInt2ᚖint(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalOInt2ᚖint(ctx, 0) + if err != nil { + return nil, err + } + if ec.directives.Range == nil { + return nil, errors.New("directive range is not implemented") + } + return ec.directives.Range(ctx, rawArgs, directive0, min, nil) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*int); ok { + arg0 = data + } else if tmp == nil { + arg0 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *int`, tmp)) + } + } + args["arg"] = arg0 + var arg1 *int + if tmp, ok := rawArgs["arg2"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg2")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOInt2ᚖint(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalOInt2ᚖint(ctx, 0) + if err != nil { + return nil, err + } + if ec.directives.Range == nil { + return nil, errors.New("directive range is not implemented") + } + return ec.directives.Range(ctx, rawArgs, directive0, min, nil) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*int); ok { + arg1 = data + } else if tmp == nil { + arg1 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *int`, tmp)) + } + } + args["arg2"] = arg1 + var arg2 *string + if tmp, ok := rawArgs["arg3"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg3")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOString2ᚖstring(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.ToNull == nil { + return nil, errors.New("directive toNull is not implemented") + } + return ec.directives.ToNull(ctx, rawArgs, directive0) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*string); ok { + arg2 = data + } else if tmp == nil { + arg2 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp)) + } + } + args["arg3"] = arg2 + return args, nil +} + +func (ec *executionContext) field_Query_enumInInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *InputWithEnumValue + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInputWithEnumValue(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_fallback_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 FallbackToStringEncoding + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐFallbackToStringEncoding(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_inputNullableSlice_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []string + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalOString2ᚕstringᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_inputSlice_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 []string + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalNString2ᚕstringᚄ(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_mapInput_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 map[string]interface{} + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalOChanges2map(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_mapNestedStringInterface_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *NestedMapInput + if tmp, ok := rawArgs["in"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("in")) + arg0, err = ec.unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNestedMapInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["in"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_mapStringInterface_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 map[string]interface{} + if tmp, ok := rawArgs["in"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("in")) + arg0, err = ec.unmarshalOMapStringInterfaceInput2map(ctx, tmp) + if err != nil { + return nil, err + } + } + args["in"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_nestedInputs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 [][]*OuterInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_nullableArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *int + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + arg0, err = ec.unmarshalOInt2ᚖint(ctx, tmp) + if err != nil { + return nil, err + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_recursive_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *RecursiveInputSlice + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSlice(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 int + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Subscription_directiveArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalNString2string(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 1) + if err != nil { + return nil, err + } + max, err := ec.unmarshalOInt2ᚖint(ctx, 255) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "invalid length") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, rawArgs, directive0, min, max, message) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(string); ok { + arg0 = data + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp)) + } + } + args["arg"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Subscription_directiveNullableArg_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *int + if tmp, ok := rawArgs["arg"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOInt2ᚖint(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalOInt2ᚖint(ctx, 0) + if err != nil { + return nil, err + } + if ec.directives.Range == nil { + return nil, errors.New("directive range is not implemented") + } + return ec.directives.Range(ctx, rawArgs, directive0, min, nil) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*int); ok { + arg0 = data + } else if tmp == nil { + arg0 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *int`, tmp)) + } + } + args["arg"] = arg0 + var arg1 *int + if tmp, ok := rawArgs["arg2"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg2")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOInt2ᚖint(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalOInt2ᚖint(ctx, 0) + if err != nil { + return nil, err + } + if ec.directives.Range == nil { + return nil, errors.New("directive range is not implemented") + } + return ec.directives.Range(ctx, rawArgs, directive0, min, nil) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*int); ok { + arg1 = data + } else if tmp == nil { + arg1 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *int`, tmp)) + } + } + args["arg2"] = arg1 + var arg2 *string + if tmp, ok := rawArgs["arg3"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg3")) + directive0 := func(ctx context.Context) (interface{}, error) { return ec.unmarshalOString2ᚖstring(ctx, tmp) } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.ToNull == nil { + return nil, errors.New("directive toNull is not implemented") + } + return ec.directives.ToNull(ctx, rawArgs, directive0) + } + + tmp, err = directive1(ctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if data, ok := tmp.(*string); ok { + arg2 = data + } else if tmp == nil { + arg2 = nil + } else { + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp)) + } + } + args["arg3"] = arg2 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Autobind_int(ctx context.Context, field graphql.CollectedField, obj *Autobind) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Autobind", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Int, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _Autobind_int32(ctx context.Context, field graphql.CollectedField, obj *Autobind) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Autobind", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Int32, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int32) + fc.Result = res + return ec.marshalNInt2int32(ctx, field.Selections, res) +} + +func (ec *executionContext) _Autobind_int64(ctx context.Context, field graphql.CollectedField, obj *Autobind) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Autobind", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Int64, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int64) + fc.Result = res + return ec.marshalNInt2int64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Autobind_idStr(ctx context.Context, field graphql.CollectedField, obj *Autobind) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Autobind", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IdStr, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Autobind_idInt(ctx context.Context, field graphql.CollectedField, obj *Autobind) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Autobind", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IdInt, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNID2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _EmbeddedPointer_ID(ctx context.Context, field graphql.CollectedField, obj *EmbeddedPointerModel) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedPointer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _EmbeddedPointer_Title(ctx context.Context, field graphql.CollectedField, obj *EmbeddedPointerModel) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmbeddedPointer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Title, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ForcedResolver_field(ctx context.Context, field graphql.CollectedField, obj *ForcedResolver) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ForcedResolver", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.ForcedResolver().Field(rctx, obj) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Circle) + fc.Result = res + return ec.marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCircle(ctx, field.Selections, res) +} + +func (ec *executionContext) _InnerObject_id(ctx context.Context, field graphql.CollectedField, obj *InnerObject) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "InnerObject", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _InvalidIdentifier_id(ctx context.Context, field graphql.CollectedField, obj *invalid_packagename.InvalidIdentifier) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "InvalidIdentifier", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _It_id(ctx context.Context, field graphql.CollectedField, obj *introspection1.It) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "It", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ModelMethods_resolverField(ctx context.Context, field graphql.CollectedField, obj *ModelMethods) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ModelMethods", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.ModelMethods().ResolverField(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _ModelMethods_noContext(ctx context.Context, field graphql.CollectedField, obj *ModelMethods) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ModelMethods", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.NoContext(), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _ModelMethods_withContext(ctx context.Context, field graphql.CollectedField, obj *ModelMethods) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ModelMethods", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.WithContext(ctx), nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _OuterObject_inner(ctx context.Context, field graphql.CollectedField, obj *OuterObject) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "OuterObject", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Inner, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*InnerObject) + fc.Result = res + return ec.marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerObject(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_invalidIdentifier(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().InvalidIdentifier(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*invalid_packagename.InvalidIdentifier) + fc.Result = res + return ec.marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_collision(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Collision(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection1.It) + fc.Result = res + return ec.marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋintrospectionᚐIt(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_mapInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_mapInput_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().MapInput(rctx, args["input"].(map[string]interface{})) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_recursive(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_recursive_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Recursive(rctx, args["input"].(*RecursiveInputSlice)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_nestedInputs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_nestedInputs_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NestedInputs(rctx, args["input"].([][]*OuterInput)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_nestedOutputs(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NestedOutputs(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([][]*OuterObject) + fc.Result = res + return ec.marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_modelMethods(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ModelMethods(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*ModelMethods) + fc.Result = res + return ec.marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐModelMethods(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_user_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().User(rctx, args["id"].(int)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*User) + fc.Result = res + return ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUser(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_nullableArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_nullableArg_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NullableArg(rctx, args["arg"].(*int)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_inputSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_inputSlice_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().InputSlice(rctx, args["arg"].([]string)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_inputNullableSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_inputNullableSlice_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().InputNullableSlice(rctx, args["arg"].([]string)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_shapeUnion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ShapeUnion(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(ShapeUnion) + fc.Result = res + return ec.marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShapeUnion(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_autobind(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Autobind(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Autobind) + fc.Result = res + return ec.marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐAutobind(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_deprecatedField(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DeprecatedField(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_overlapping(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Overlapping(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*OverlappingFields) + fc.Result = res + return ec.marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOverlappingFields(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_defaultParameters(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_defaultParameters_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DefaultParameters(rctx, args["falsyBoolean"].(*bool), args["truthyBoolean"].(*bool)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*DefaultParametersMirror) + fc.Result = res + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐDefaultParametersMirror(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveArg_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveArg(rctx, args["arg"].(string)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveNullableArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveNullableArg_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveNullableArg(rctx, args["arg"].(*int), args["arg2"].(*int), args["arg3"].(*string)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveInputNullable(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveInputNullable_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveInputNullable(rctx, args["arg"].(*InputDirectives)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveInput_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveInput(rctx, args["arg"].(InputDirectives)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveInputType(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveInputType_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveInputType(rctx, args["arg"].(InnerInput)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveObject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveObject(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + location, err := ec.unmarshalNString2string(ctx, "order1_1") + if err != nil { + return nil, err + } + if ec.directives.Order1 == nil { + return nil, errors.New("directive order1 is not implemented") + } + return ec.directives.Order1(ctx, nil, directive0, location) + } + directive2 := func(ctx context.Context) (interface{}, error) { + location, err := ec.unmarshalNString2string(ctx, "order1_2") + if err != nil { + return nil, err + } + if ec.directives.Order1 == nil { + return nil, errors.New("directive order1 is not implemented") + } + return ec.directives.Order1(ctx, nil, directive1, location) + } + directive3 := func(ctx context.Context) (interface{}, error) { + location, err := ec.unmarshalNString2string(ctx, "order2_1") + if err != nil { + return nil, err + } + if ec.directives.Order2 == nil { + return nil, errors.New("directive order2 is not implemented") + } + return ec.directives.Order2(ctx, nil, directive2, location) + } + directive4 := func(ctx context.Context) (interface{}, error) { + location, err := ec.unmarshalNString2string(ctx, "Query_field") + if err != nil { + return nil, err + } + if ec.directives.Order1 == nil { + return nil, errors.New("directive order1 is not implemented") + } + return ec.directives.Order1(ctx, nil, directive3, location) + } + + tmp, err := directive4(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*ObjectDirectives); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/followschema.ObjectDirectives`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*ObjectDirectives) + fc.Result = res + return ec.marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐObjectDirectives(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveObjectWithCustomGoModel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveObjectWithCustomGoModel(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*ObjectDirectivesWithCustomGoModel) + fc.Result = res + return ec.marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐObjectDirectivesWithCustomGoModel(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveFieldDef(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_directiveFieldDef_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveFieldDef(rctx, args["ret"].(string)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + min, err := ec.unmarshalNInt2int(ctx, 1) + if err != nil { + return nil, err + } + message, err := ec.unmarshalOString2ᚖstring(ctx, "not valid") + if err != nil { + return nil, err + } + if ec.directives.Length == nil { + return nil, errors.New("directive length is not implemented") + } + return ec.directives.Length(ctx, nil, directive0, min, nil, message) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be string`, tmp) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveField(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveField(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveDouble(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveDouble(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive1 == nil { + return nil, errors.New("directive directive1 is not implemented") + } + return ec.directives.Directive1(ctx, nil, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive2 == nil { + return nil, errors.New("directive directive2 is not implemented") + } + return ec.directives.Directive2(ctx, nil, directive1) + } + + tmp, err := directive2(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_directiveUnimplemented(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DirectiveUnimplemented(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Unimplemented == nil { + return nil, errors.New("directive unimplemented is not implemented") + } + return ec.directives.Unimplemented(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(*string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be *string`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_embeddedCase1(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().EmbeddedCase1(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*EmbeddedCase1) + fc.Result = res + return ec.marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase1(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_embeddedCase2(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().EmbeddedCase2(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*EmbeddedCase2) + fc.Result = res + return ec.marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase2(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_embeddedCase3(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().EmbeddedCase3(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*EmbeddedCase3) + fc.Result = res + return ec.marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEmbeddedCase3(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_enumInInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_enumInInput_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().EnumInInput(rctx, args["input"].(*InputWithEnumValue)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(EnumTest) + fc.Result = res + return ec.marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐEnumTest(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_shapes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Shapes(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]Shape) + fc.Result = res + return ec.marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_noShape(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NoShape(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.MakeNil == nil { + return nil, errors.New("directive makeNil is not implemented") + } + return ec.directives.MakeNil(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(Shape); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/followschema.Shape`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Shape) + fc.Result = res + return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_node(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Node(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(Node) + fc.Result = res + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNode(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_noShapeTypedNil(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NoShapeTypedNil(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.MakeTypedNil == nil { + return nil, errors.New("directive makeTypedNil is not implemented") + } + return ec.directives.MakeTypedNil(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(Shape); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/followschema.Shape`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Shape) + fc.Result = res + return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_animal(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Animal(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.MakeTypedNil == nil { + return nil, errors.New("directive makeTypedNil is not implemented") + } + return ec.directives.MakeTypedNil(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(Animal); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/followschema.Animal`, tmp) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Animal) + fc.Result = res + return ec.marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐAnimal(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_notAnInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().NotAnInterface(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(BackedByInterface) + fc.Result = res + return ec.marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐBackedByInterface(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_issue896a(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Issue896a(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*CheckIssue896) + fc.Result = res + return ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896ᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_mapStringInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_mapStringInterface_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().MapStringInterface(rctx, args["in"].(map[string]interface{})) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(map[string]interface{}) + fc.Result = res + return ec.marshalOMapStringInterfaceType2map(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_mapNestedStringInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_mapNestedStringInterface_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().MapNestedStringInterface(rctx, args["in"].(*NestedMapInput)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(map[string]interface{}) + fc.Result = res + return ec.marshalOMapStringInterfaceType2map(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_errorBubble(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ErrorBubble(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Error) + fc.Result = res + return ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_errorBubbleList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ErrorBubbleList(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*Error) + fc.Result = res + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐErrorᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_errorList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ErrorList(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*Error) + fc.Result = res + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐError(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_errors(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Errors(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Errors) + fc.Result = res + return ec.marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐErrors(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_valid(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Valid(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_panics(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Panics(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Panics) + fc.Result = res + return ec.marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPanics(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_primitiveObject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PrimitiveObject(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]Primitive) + fc.Result = res + return ec.marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_primitiveStringObject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PrimitiveStringObject(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]PrimitiveString) + fc.Result = res + return ec.marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPrimitiveStringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PtrToSliceContainer(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*PtrToSliceContainer) + fc.Result = res + return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToSliceContainer(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_defaultScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_defaultScalar_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().DefaultScalar(rctx, args["arg"].(string)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNDefaultScalarImplementation2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_slices(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Slices(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*Slices) + fc.Result = res + return ec.marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐSlices(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_scalarSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ScalarSlice(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]byte) + fc.Result = res + return ec.marshalNBytes2ᚕbyte(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_fallback(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_fallback_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Fallback(rctx, args["arg"].(FallbackToStringEncoding)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(FallbackToStringEncoding) + fc.Result = res + return ec.marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐFallbackToStringEncoding(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_optionalUnion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().OptionalUnion(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(TestUnion) + fc.Result = res + return ec.marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐTestUnion(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_vOkCaseValue(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().VOkCaseValue(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*VOkCaseValue) + fc.Result = res + return ec.marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐVOkCaseValue(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_vOkCaseNil(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().VOkCaseNil(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*VOkCaseNil) + fc.Result = res + return ec.marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐVOkCaseNil(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_validType(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ValidType(rctx) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*ValidType) + fc.Result = res + return ec.marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐValidType(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_wrappedStruct(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().WrappedStruct(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*WrappedStruct) + fc.Result = res + return ec.marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedStruct(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_wrappedScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().WrappedScalar(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(otherpkg.Scalar) + fc.Result = res + return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_wrappedMap(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().WrappedMap(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(WrappedMap) + fc.Result = res + return ec.marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedMap(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_wrappedSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().WrappedSlice(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(WrappedSlice) + fc.Result = res + return ec.marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedSlice(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query___type_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(args["name"].(string)) + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) _Subscription_updated(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().Updated(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalNString2string(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_initPayload(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().InitPayload(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalNString2string(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_directiveArg(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Subscription_directiveArg_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return nil + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().DirectiveArg(rctx, args["arg"].(string)) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan *string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOString2ᚖstring(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_directiveNullableArg(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Subscription_directiveNullableArg_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return nil + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().DirectiveNullableArg(rctx, args["arg"].(*int), args["arg2"].(*int), args["arg3"].(*string)) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan *string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOString2ᚖstring(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_directiveDouble(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().DirectiveDouble(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive1 == nil { + return nil, errors.New("directive directive1 is not implemented") + } + return ec.directives.Directive1(ctx, nil, directive0) + } + directive2 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Directive2 == nil { + return nil, errors.New("directive directive2 is not implemented") + } + return ec.directives.Directive2(ctx, nil, directive1) + } + + tmp, err := directive2(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(<-chan *string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be <-chan *string`, tmp) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan *string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOString2ᚖstring(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_directiveUnimplemented(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().DirectiveUnimplemented(rctx) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Unimplemented == nil { + return nil, errors.New("directive unimplemented is not implemented") + } + return ec.directives.Unimplemented(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, graphql.ErrorOnPath(ctx, err) + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(<-chan *string); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be <-chan *string`, tmp) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan *string) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOString2ᚖstring(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _Subscription_issue896b(ctx context.Context, field graphql.CollectedField) (ret func() graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + fc := &graphql.FieldContext{ + Object: "Subscription", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Subscription().Issue896b(rctx) + }) + + if resTmp == nil { + return nil + } + return func() graphql.Marshaler { + res, ok := <-resTmp.(<-chan []*CheckIssue896) + if !ok { + return nil + } + return graphql.WriterFunc(func(w io.Writer) { + w.Write([]byte{'{'}) + graphql.MarshalString(field.Alias).MarshalGQL(w) + w.Write([]byte{':'}) + ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCheckIssue896(ctx, field.Selections, res).MarshalGQL(w) + w.Write([]byte{'}'}) + }) + } +} + +func (ec *executionContext) _User_id(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) _User_friends(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.User().Friends(rctx, obj) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*User) + fc.Result = res + return ec.marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUserᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _User_created(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Created, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(time.Time) + fc.Result = res + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) +} + +func (ec *executionContext) _User_updated(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Updated, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*time.Time) + fc.Result = res + return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputInnerInput(ctx context.Context, obj interface{}) (InnerInput, error) { + var it InnerInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNInt2int(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, obj interface{}) (OuterInput, error) { + var it OuterInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "inner": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) + it.Inner, err = ec.unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerInput(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Context, obj interface{}) (RecursiveInputSlice, error) { + var it RecursiveInputSlice + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "self": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("self")) + it.Self, err = ec.unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSliceᚄ(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var autobindImplementors = []string{"Autobind"} + +func (ec *executionContext) _Autobind(ctx context.Context, sel ast.SelectionSet, obj *Autobind) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, autobindImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Autobind") + case "int": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "int32": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int32(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "int64": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_int64(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "idStr": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_idStr(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "idInt": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Autobind_idInt(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var embeddedPointerImplementors = []string{"EmbeddedPointer"} + +func (ec *executionContext) _EmbeddedPointer(ctx context.Context, sel ast.SelectionSet, obj *EmbeddedPointerModel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, embeddedPointerImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmbeddedPointer") + case "ID": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedPointer_ID(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "Title": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmbeddedPointer_Title(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var forcedResolverImplementors = []string{"ForcedResolver"} + +func (ec *executionContext) _ForcedResolver(ctx context.Context, sel ast.SelectionSet, obj *ForcedResolver) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, forcedResolverImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ForcedResolver") + case "field": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._ForcedResolver_field(ctx, field, obj) + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var innerObjectImplementors = []string{"InnerObject"} + +func (ec *executionContext) _InnerObject(ctx context.Context, sel ast.SelectionSet, obj *InnerObject) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, innerObjectImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("InnerObject") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InnerObject_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var invalidIdentifierImplementors = []string{"InvalidIdentifier"} + +func (ec *executionContext) _InvalidIdentifier(ctx context.Context, sel ast.SelectionSet, obj *invalid_packagename.InvalidIdentifier) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, invalidIdentifierImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("InvalidIdentifier") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._InvalidIdentifier_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var itImplementors = []string{"It"} + +func (ec *executionContext) _It(ctx context.Context, sel ast.SelectionSet, obj *introspection1.It) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, itImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("It") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._It_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var modelMethodsImplementors = []string{"ModelMethods"} + +func (ec *executionContext) _ModelMethods(ctx context.Context, sel ast.SelectionSet, obj *ModelMethods) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, modelMethodsImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ModelMethods") + case "resolverField": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._ModelMethods_resolverField(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "noContext": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ModelMethods_noContext(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "withContext": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._ModelMethods_withContext(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var outerObjectImplementors = []string{"OuterObject"} + +func (ec *executionContext) _OuterObject(ctx context.Context, sel ast.SelectionSet, obj *OuterObject) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, outerObjectImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("OuterObject") + case "inner": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._OuterObject_inner(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "invalidIdentifier": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_invalidIdentifier(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "collision": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_collision(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "mapInput": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_mapInput(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "recursive": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_recursive(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "nestedInputs": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_nestedInputs(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "nestedOutputs": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_nestedOutputs(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "modelMethods": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_modelMethods(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "user": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_user(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "nullableArg": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_nullableArg(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "inputSlice": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_inputSlice(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "inputNullableSlice": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_inputNullableSlice(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "shapeUnion": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_shapeUnion(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "autobind": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_autobind(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "deprecatedField": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_deprecatedField(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "overlapping": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_overlapping(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "defaultParameters": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_defaultParameters(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveArg": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveArg(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveNullableArg": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveNullableArg(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveInputNullable": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveInputNullable(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveInput": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveInput(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveInputType": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveInputType(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveObject": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveObject(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveObjectWithCustomGoModel": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveObjectWithCustomGoModel(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveFieldDef": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveFieldDef(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveField": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveField(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveDouble": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveDouble(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "directiveUnimplemented": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_directiveUnimplemented(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "embeddedCase1": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_embeddedCase1(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "embeddedCase2": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_embeddedCase2(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "embeddedCase3": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_embeddedCase3(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "enumInInput": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_enumInInput(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "shapes": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_shapes(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "noShape": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_noShape(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "node": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_node(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "noShapeTypedNil": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_noShapeTypedNil(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "animal": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_animal(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "notAnInterface": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_notAnInterface(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "issue896a": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_issue896a(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "mapStringInterface": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_mapStringInterface(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "mapNestedStringInterface": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_mapNestedStringInterface(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "errorBubble": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errorBubble(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "errorBubbleList": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errorBubbleList(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "errorList": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errorList(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "errors": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_errors(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "valid": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_valid(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "panics": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_panics(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "primitiveObject": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_primitiveObject(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "primitiveStringObject": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_primitiveStringObject(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "ptrToSliceContainer": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_ptrToSliceContainer(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "defaultScalar": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_defaultScalar(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "slices": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_slices(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "scalarSlice": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_scalarSlice(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "fallback": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_fallback(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "optionalUnion": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_optionalUnion(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "vOkCaseValue": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_vOkCaseValue(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "vOkCaseNil": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_vOkCaseNil(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "validType": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_validType(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "wrappedStruct": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_wrappedStruct(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "wrappedScalar": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_wrappedScalar(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "wrappedMap": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_wrappedMap(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "wrappedSlice": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_wrappedSlice(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "__type": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + + case "__schema": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + } + + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, innerFunc) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var subscriptionImplementors = []string{"Subscription"} + +func (ec *executionContext) _Subscription(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, subscriptionImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Subscription", + }) + if len(fields) != 1 { + ec.Errorf(ctx, "must subscribe to exactly one stream") + return nil + } + + switch fields[0].Name { + case "updated": + return ec._Subscription_updated(ctx, fields[0]) + case "initPayload": + return ec._Subscription_initPayload(ctx, fields[0]) + case "directiveArg": + return ec._Subscription_directiveArg(ctx, fields[0]) + case "directiveNullableArg": + return ec._Subscription_directiveNullableArg(ctx, fields[0]) + case "directiveDouble": + return ec._Subscription_directiveDouble(ctx, fields[0]) + case "directiveUnimplemented": + return ec._Subscription_directiveUnimplemented(ctx, fields[0]) + case "issue896b": + return ec._Subscription_issue896b(ctx, fields[0]) + default: + panic("unknown field " + strconv.Quote(fields[0].Name)) + } +} + +var userImplementors = []string{"User"} + +func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *User) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, userImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("User") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "friends": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._User_friends(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + case "created": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_created(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "updated": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_updated(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerInput(ctx context.Context, v interface{}) (InnerInput, error) { + res, err := ec.unmarshalInputInnerInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerInput(ctx context.Context, v interface{}) (*InnerInput, error) { + res, err := ec.unmarshalInputInnerInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐInnerObject(ctx context.Context, sel ast.SelectionSet, v *InnerObject) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._InnerObject(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { + res, err := ec.unmarshalInputRecursiveInputSlice(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalNTime2timeᚐTime(ctx context.Context, v interface{}) (time.Time, error) { + res, err := graphql.UnmarshalTime(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context, sel ast.SelectionSet, v time.Time) graphql.Marshaler { + res := graphql.MarshalTime(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) unmarshalNUUID2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNUUID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) marshalNUser2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUser(ctx context.Context, sel ast.SelectionSet, v User) graphql.Marshaler { + return ec._User(ctx, sel, &v) +} + +func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*User) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUser(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐUser(ctx context.Context, sel ast.SelectionSet, v *User) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._User(ctx, sel, v) +} + +func (ec *executionContext) marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐAutobind(ctx context.Context, sel ast.SelectionSet, v *Autobind) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Autobind(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOChanges2map(ctx context.Context, v interface{}) (map[string]interface{}, error) { + if v == nil { + return nil, nil + } + return v.(map[string]interface{}), nil +} + +func (ec *executionContext) marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx context.Context, sel ast.SelectionSet, v *invalid_packagename.InvalidIdentifier) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._InvalidIdentifier(ctx, sel, v) +} + +func (ec *executionContext) marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋintrospectionᚐIt(ctx context.Context, sel ast.SelectionSet, v *introspection1.It) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._It(ctx, sel, v) +} + +func (ec *executionContext) marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐModelMethods(ctx context.Context, sel ast.SelectionSet, v *ModelMethods) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ModelMethods(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx context.Context, v interface{}) ([][]*OuterInput, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([][]*OuterInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx context.Context, v interface{}) ([]*OuterInput, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]*OuterInput, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterInput(ctx context.Context, v interface{}) (*OuterInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputOuterInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v [][]*OuterObject) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v []*OuterObject) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v *OuterObject) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._OuterObject(ctx, sel, v) +} + +func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSliceᚄ(ctx context.Context, v interface{}) ([]RecursiveInputSlice, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + if tmp1, ok := v.([]interface{}); ok { + vSlice = tmp1 + } else { + vSlice = []interface{}{v} + } + } + var err error + res := make([]RecursiveInputSlice, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSlice(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐRecursiveInputSlice(ctx context.Context, v interface{}) (*RecursiveInputSlice, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputRecursiveInputSlice(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐThirdParty(ctx context.Context, v interface{}) (*ThirdParty, error) { + if v == nil { + return nil, nil + } + res, err := UnmarshalThirdParty(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐThirdParty(ctx context.Context, sel ast.SelectionSet, v *ThirdParty) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return MarshalThirdParty(*v) +} + +func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalTime(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel ast.SelectionSet, v *time.Time) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalTime(*v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/schema.graphql b/codegen/testserver/followschema/schema.graphql new file mode 100644 index 00000000000..ceef6891ca8 --- /dev/null +++ b/codegen/testserver/followschema/schema.graphql @@ -0,0 +1,105 @@ +directive @goModel( + model: String + models: [String!] +) on OBJECT | INPUT_OBJECT | SCALAR | ENUM | INTERFACE | UNION +directive @goField( + forceResolver: Boolean + name: String +) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION + +type Query { + invalidIdentifier: InvalidIdentifier + collision: It + mapInput(input: Changes): Boolean + recursive(input: RecursiveInputSlice): Boolean + nestedInputs(input: [[OuterInput]] = [[{ inner: { id: 1 } }]]): Boolean + nestedOutputs: [[OuterObject]] + modelMethods: ModelMethods + user(id: Int!): User! + nullableArg(arg: Int = 123): String + inputSlice(arg: [String!]!): Boolean! + inputNullableSlice(arg: [String!]): Boolean! + shapeUnion: ShapeUnion! + autobind: Autobind + deprecatedField: String! @deprecated(reason: "test deprecated directive") +} + +type Subscription { + updated: String! + initPayload: String! +} + +type User { + id: Int! + friends: [User!]! @goField(forceResolver: true) + created: Time! + updated: Time +} + +type Autobind { + int: Int! + int32: Int! + int64: Int! + + idStr: ID! + idInt: ID! +} + +type ModelMethods { + resolverField: Boolean! + noContext: Boolean! + withContext: Boolean! +} + +type InvalidIdentifier { + id: Int! +} + +type It { + id: ID! +} + +input Changes @goModel(model: "map[string]interface{}") { + a: Int + b: Int +} + +input RecursiveInputSlice { + self: [RecursiveInputSlice!] +} + +input InnerInput { + id: Int! +} + +input OuterInput { + inner: InnerInput! +} + +scalar ThirdParty @goModel(model:"followschema.ThirdParty") + +type OuterObject { + inner: InnerObject! +} + +type InnerObject { + id: Int! +} + +type ForcedResolver { + field: Circle @goField(forceResolver: true) +} + +type EmbeddedPointer @goModel(model:"followschema.EmbeddedPointerModel") { + ID: String + Title: String +} + +scalar UUID + +enum Status { + OK + ERROR +} + +scalar Time diff --git a/codegen/testserver/followschema/slices.generated.go b/codegen/testserver/followschema/slices.generated.go new file mode 100644 index 00000000000..5a37fee0baa --- /dev/null +++ b/codegen/testserver/followschema/slices.generated.go @@ -0,0 +1,248 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Slices_test1(ctx context.Context, field graphql.CollectedField, obj *Slices) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Slices", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Test1, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*string) + fc.Result = res + return ec.marshalOString2ᚕᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Slices_test2(ctx context.Context, field graphql.CollectedField, obj *Slices) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Slices", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Test2, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Slices_test3(ctx context.Context, field graphql.CollectedField, obj *Slices) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Slices", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Test3, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*string) + fc.Result = res + return ec.marshalNString2ᚕᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Slices_test4(ctx context.Context, field graphql.CollectedField, obj *Slices) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Slices", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Test4, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalNString2ᚕstringᚄ(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var slicesImplementors = []string{"Slices"} + +func (ec *executionContext) _Slices(ctx context.Context, sel ast.SelectionSet, obj *Slices) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, slicesImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Slices") + case "test1": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test1(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "test2": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test2(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + case "test3": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test3(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "test4": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Slices_test4(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBytes2ᚕbyte(ctx context.Context, v interface{}) ([]byte, error) { + res, err := UnmarshalBytes(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBytes2ᚕbyte(ctx context.Context, sel ast.SelectionSet, v []byte) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := MarshalBytes(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐSlices(ctx context.Context, sel ast.SelectionSet, v *Slices) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Slices(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/slices.graphql b/codegen/testserver/followschema/slices.graphql similarity index 100% rename from codegen/testserver/slices.graphql rename to codegen/testserver/followschema/slices.graphql diff --git a/codegen/testserver/followschema/slices_test.go b/codegen/testserver/followschema/slices_test.go new file mode 100644 index 00000000000..19df15816ba --- /dev/null +++ b/codegen/testserver/followschema/slices_test.go @@ -0,0 +1,43 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestSlices(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("nulls vs empty slices", func(t *testing.T) { + resolvers.QueryResolver.Slices = func(ctx context.Context) (slices *Slices, e error) { + return &Slices{}, nil + } + + var resp struct { + Slices Slices + } + c.MustPost(`query { slices { test1, test2, test3, test4 }}`, &resp) + require.Nil(t, resp.Slices.Test1) + require.Nil(t, resp.Slices.Test2) + require.NotNil(t, resp.Slices.Test3) + require.NotNil(t, resp.Slices.Test4) + }) + + t.Run("custom scalars to slices work", func(t *testing.T) { + resolvers.QueryResolver.ScalarSlice = func(ctx context.Context) ([]byte, error) { + return []byte("testing"), nil + } + + var resp struct { + ScalarSlice string + } + c.MustPost(`query { scalarSlice }`, &resp) + require.Equal(t, "testing", resp.ScalarSlice) + }) +} diff --git a/codegen/testserver/followschema/stub.go b/codegen/testserver/followschema/stub.go new file mode 100644 index 00000000000..20491526095 --- /dev/null +++ b/codegen/testserver/followschema/stub.go @@ -0,0 +1,479 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + + introspection1 "github.com/99designs/gqlgen/codegen/testserver/followschema/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/followschema/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" +) + +type Stub struct { + BackedByInterfaceResolver struct { + ID func(ctx context.Context, obj BackedByInterface) (string, error) + } + ErrorsResolver struct { + A func(ctx context.Context, obj *Errors) (*Error, error) + B func(ctx context.Context, obj *Errors) (*Error, error) + C func(ctx context.Context, obj *Errors) (*Error, error) + D func(ctx context.Context, obj *Errors) (*Error, error) + E func(ctx context.Context, obj *Errors) (*Error, error) + } + ForcedResolverResolver struct { + Field func(ctx context.Context, obj *ForcedResolver) (*Circle, error) + } + ModelMethodsResolver struct { + ResolverField func(ctx context.Context, obj *ModelMethods) (bool, error) + } + MutationResolver struct { + DefaultInput func(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) + UpdateSomething func(ctx context.Context, input SpecialInput) (string, error) + UpdatePtrToPtr func(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) + } + OverlappingFieldsResolver struct { + OldFoo func(ctx context.Context, obj *OverlappingFields) (int, error) + } + PanicsResolver struct { + FieldScalarMarshal func(ctx context.Context, obj *Panics) ([]MarshalPanic, error) + ArgUnmarshal func(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) + } + PrimitiveResolver struct { + Value func(ctx context.Context, obj *Primitive) (int, error) + } + PrimitiveStringResolver struct { + Value func(ctx context.Context, obj *PrimitiveString) (string, error) + Len func(ctx context.Context, obj *PrimitiveString) (int, error) + } + QueryResolver struct { + InvalidIdentifier func(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) + Collision func(ctx context.Context) (*introspection1.It, error) + MapInput func(ctx context.Context, input map[string]interface{}) (*bool, error) + Recursive func(ctx context.Context, input *RecursiveInputSlice) (*bool, error) + NestedInputs func(ctx context.Context, input [][]*OuterInput) (*bool, error) + NestedOutputs func(ctx context.Context) ([][]*OuterObject, error) + ModelMethods func(ctx context.Context) (*ModelMethods, error) + User func(ctx context.Context, id int) (*User, error) + NullableArg func(ctx context.Context, arg *int) (*string, error) + InputSlice func(ctx context.Context, arg []string) (bool, error) + InputNullableSlice func(ctx context.Context, arg []string) (bool, error) + ShapeUnion func(ctx context.Context) (ShapeUnion, error) + Autobind func(ctx context.Context) (*Autobind, error) + DeprecatedField func(ctx context.Context) (string, error) + Overlapping func(ctx context.Context) (*OverlappingFields, error) + DefaultParameters func(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) + DirectiveArg func(ctx context.Context, arg string) (*string, error) + DirectiveNullableArg func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) + DirectiveInputNullable func(ctx context.Context, arg *InputDirectives) (*string, error) + DirectiveInput func(ctx context.Context, arg InputDirectives) (*string, error) + DirectiveInputType func(ctx context.Context, arg InnerInput) (*string, error) + DirectiveObject func(ctx context.Context) (*ObjectDirectives, error) + DirectiveObjectWithCustomGoModel func(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) + DirectiveFieldDef func(ctx context.Context, ret string) (string, error) + DirectiveField func(ctx context.Context) (*string, error) + DirectiveDouble func(ctx context.Context) (*string, error) + DirectiveUnimplemented func(ctx context.Context) (*string, error) + EmbeddedCase1 func(ctx context.Context) (*EmbeddedCase1, error) + EmbeddedCase2 func(ctx context.Context) (*EmbeddedCase2, error) + EmbeddedCase3 func(ctx context.Context) (*EmbeddedCase3, error) + EnumInInput func(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) + Shapes func(ctx context.Context) ([]Shape, error) + NoShape func(ctx context.Context) (Shape, error) + Node func(ctx context.Context) (Node, error) + NoShapeTypedNil func(ctx context.Context) (Shape, error) + Animal func(ctx context.Context) (Animal, error) + NotAnInterface func(ctx context.Context) (BackedByInterface, error) + Issue896a func(ctx context.Context) ([]*CheckIssue896, error) + MapStringInterface func(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) + MapNestedStringInterface func(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) + ErrorBubble func(ctx context.Context) (*Error, error) + ErrorBubbleList func(ctx context.Context) ([]*Error, error) + ErrorList func(ctx context.Context) ([]*Error, error) + Errors func(ctx context.Context) (*Errors, error) + Valid func(ctx context.Context) (string, error) + Panics func(ctx context.Context) (*Panics, error) + PrimitiveObject func(ctx context.Context) ([]Primitive, error) + PrimitiveStringObject func(ctx context.Context) ([]PrimitiveString, error) + PtrToSliceContainer func(ctx context.Context) (*PtrToSliceContainer, error) + DefaultScalar func(ctx context.Context, arg string) (string, error) + Slices func(ctx context.Context) (*Slices, error) + ScalarSlice func(ctx context.Context) ([]byte, error) + Fallback func(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) + OptionalUnion func(ctx context.Context) (TestUnion, error) + VOkCaseValue func(ctx context.Context) (*VOkCaseValue, error) + VOkCaseNil func(ctx context.Context) (*VOkCaseNil, error) + ValidType func(ctx context.Context) (*ValidType, error) + WrappedStruct func(ctx context.Context) (*WrappedStruct, error) + WrappedScalar func(ctx context.Context) (otherpkg.Scalar, error) + WrappedMap func(ctx context.Context) (WrappedMap, error) + WrappedSlice func(ctx context.Context) (WrappedSlice, error) + } + SubscriptionResolver struct { + Updated func(ctx context.Context) (<-chan string, error) + InitPayload func(ctx context.Context) (<-chan string, error) + DirectiveArg func(ctx context.Context, arg string) (<-chan *string, error) + DirectiveNullableArg func(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) + DirectiveDouble func(ctx context.Context) (<-chan *string, error) + DirectiveUnimplemented func(ctx context.Context) (<-chan *string, error) + Issue896b func(ctx context.Context) (<-chan []*CheckIssue896, error) + } + UserResolver struct { + Friends func(ctx context.Context, obj *User) ([]*User, error) + } + WrappedMapResolver struct { + Get func(ctx context.Context, obj WrappedMap, key string) (string, error) + } + WrappedSliceResolver struct { + Get func(ctx context.Context, obj WrappedSlice, idx int) (string, error) + } +} + +func (r *Stub) BackedByInterface() BackedByInterfaceResolver { + return &stubBackedByInterface{r} +} +func (r *Stub) Errors() ErrorsResolver { + return &stubErrors{r} +} +func (r *Stub) ForcedResolver() ForcedResolverResolver { + return &stubForcedResolver{r} +} +func (r *Stub) ModelMethods() ModelMethodsResolver { + return &stubModelMethods{r} +} +func (r *Stub) Mutation() MutationResolver { + return &stubMutation{r} +} +func (r *Stub) OverlappingFields() OverlappingFieldsResolver { + return &stubOverlappingFields{r} +} +func (r *Stub) Panics() PanicsResolver { + return &stubPanics{r} +} +func (r *Stub) Primitive() PrimitiveResolver { + return &stubPrimitive{r} +} +func (r *Stub) PrimitiveString() PrimitiveStringResolver { + return &stubPrimitiveString{r} +} +func (r *Stub) Query() QueryResolver { + return &stubQuery{r} +} +func (r *Stub) Subscription() SubscriptionResolver { + return &stubSubscription{r} +} +func (r *Stub) User() UserResolver { + return &stubUser{r} +} +func (r *Stub) WrappedMap() WrappedMapResolver { + return &stubWrappedMap{r} +} +func (r *Stub) WrappedSlice() WrappedSliceResolver { + return &stubWrappedSlice{r} +} + +type stubBackedByInterface struct{ *Stub } + +func (r *stubBackedByInterface) ID(ctx context.Context, obj BackedByInterface) (string, error) { + return r.BackedByInterfaceResolver.ID(ctx, obj) +} + +type stubErrors struct{ *Stub } + +func (r *stubErrors) A(ctx context.Context, obj *Errors) (*Error, error) { + return r.ErrorsResolver.A(ctx, obj) +} +func (r *stubErrors) B(ctx context.Context, obj *Errors) (*Error, error) { + return r.ErrorsResolver.B(ctx, obj) +} +func (r *stubErrors) C(ctx context.Context, obj *Errors) (*Error, error) { + return r.ErrorsResolver.C(ctx, obj) +} +func (r *stubErrors) D(ctx context.Context, obj *Errors) (*Error, error) { + return r.ErrorsResolver.D(ctx, obj) +} +func (r *stubErrors) E(ctx context.Context, obj *Errors) (*Error, error) { + return r.ErrorsResolver.E(ctx, obj) +} + +type stubForcedResolver struct{ *Stub } + +func (r *stubForcedResolver) Field(ctx context.Context, obj *ForcedResolver) (*Circle, error) { + return r.ForcedResolverResolver.Field(ctx, obj) +} + +type stubModelMethods struct{ *Stub } + +func (r *stubModelMethods) ResolverField(ctx context.Context, obj *ModelMethods) (bool, error) { + return r.ModelMethodsResolver.ResolverField(ctx, obj) +} + +type stubMutation struct{ *Stub } + +func (r *stubMutation) DefaultInput(ctx context.Context, input DefaultInput) (*DefaultParametersMirror, error) { + return r.MutationResolver.DefaultInput(ctx, input) +} +func (r *stubMutation) UpdateSomething(ctx context.Context, input SpecialInput) (string, error) { + return r.MutationResolver.UpdateSomething(ctx, input) +} +func (r *stubMutation) UpdatePtrToPtr(ctx context.Context, input UpdatePtrToPtrOuter) (*PtrToPtrOuter, error) { + return r.MutationResolver.UpdatePtrToPtr(ctx, input) +} + +type stubOverlappingFields struct{ *Stub } + +func (r *stubOverlappingFields) OldFoo(ctx context.Context, obj *OverlappingFields) (int, error) { + return r.OverlappingFieldsResolver.OldFoo(ctx, obj) +} + +type stubPanics struct{ *Stub } + +func (r *stubPanics) FieldScalarMarshal(ctx context.Context, obj *Panics) ([]MarshalPanic, error) { + return r.PanicsResolver.FieldScalarMarshal(ctx, obj) +} +func (r *stubPanics) ArgUnmarshal(ctx context.Context, obj *Panics, u []MarshalPanic) (bool, error) { + return r.PanicsResolver.ArgUnmarshal(ctx, obj, u) +} + +type stubPrimitive struct{ *Stub } + +func (r *stubPrimitive) Value(ctx context.Context, obj *Primitive) (int, error) { + return r.PrimitiveResolver.Value(ctx, obj) +} + +type stubPrimitiveString struct{ *Stub } + +func (r *stubPrimitiveString) Value(ctx context.Context, obj *PrimitiveString) (string, error) { + return r.PrimitiveStringResolver.Value(ctx, obj) +} +func (r *stubPrimitiveString) Len(ctx context.Context, obj *PrimitiveString) (int, error) { + return r.PrimitiveStringResolver.Len(ctx, obj) +} + +type stubQuery struct{ *Stub } + +func (r *stubQuery) InvalidIdentifier(ctx context.Context) (*invalid_packagename.InvalidIdentifier, error) { + return r.QueryResolver.InvalidIdentifier(ctx) +} +func (r *stubQuery) Collision(ctx context.Context) (*introspection1.It, error) { + return r.QueryResolver.Collision(ctx) +} +func (r *stubQuery) MapInput(ctx context.Context, input map[string]interface{}) (*bool, error) { + return r.QueryResolver.MapInput(ctx, input) +} +func (r *stubQuery) Recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) { + return r.QueryResolver.Recursive(ctx, input) +} +func (r *stubQuery) NestedInputs(ctx context.Context, input [][]*OuterInput) (*bool, error) { + return r.QueryResolver.NestedInputs(ctx, input) +} +func (r *stubQuery) NestedOutputs(ctx context.Context) ([][]*OuterObject, error) { + return r.QueryResolver.NestedOutputs(ctx) +} +func (r *stubQuery) ModelMethods(ctx context.Context) (*ModelMethods, error) { + return r.QueryResolver.ModelMethods(ctx) +} +func (r *stubQuery) User(ctx context.Context, id int) (*User, error) { + return r.QueryResolver.User(ctx, id) +} +func (r *stubQuery) NullableArg(ctx context.Context, arg *int) (*string, error) { + return r.QueryResolver.NullableArg(ctx, arg) +} +func (r *stubQuery) InputSlice(ctx context.Context, arg []string) (bool, error) { + return r.QueryResolver.InputSlice(ctx, arg) +} +func (r *stubQuery) InputNullableSlice(ctx context.Context, arg []string) (bool, error) { + return r.QueryResolver.InputNullableSlice(ctx, arg) +} +func (r *stubQuery) ShapeUnion(ctx context.Context) (ShapeUnion, error) { + return r.QueryResolver.ShapeUnion(ctx) +} +func (r *stubQuery) Autobind(ctx context.Context) (*Autobind, error) { + return r.QueryResolver.Autobind(ctx) +} +func (r *stubQuery) DeprecatedField(ctx context.Context) (string, error) { + return r.QueryResolver.DeprecatedField(ctx) +} +func (r *stubQuery) Overlapping(ctx context.Context) (*OverlappingFields, error) { + return r.QueryResolver.Overlapping(ctx) +} +func (r *stubQuery) DefaultParameters(ctx context.Context, falsyBoolean *bool, truthyBoolean *bool) (*DefaultParametersMirror, error) { + return r.QueryResolver.DefaultParameters(ctx, falsyBoolean, truthyBoolean) +} +func (r *stubQuery) DirectiveArg(ctx context.Context, arg string) (*string, error) { + return r.QueryResolver.DirectiveArg(ctx, arg) +} +func (r *stubQuery) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (*string, error) { + return r.QueryResolver.DirectiveNullableArg(ctx, arg, arg2, arg3) +} +func (r *stubQuery) DirectiveInputNullable(ctx context.Context, arg *InputDirectives) (*string, error) { + return r.QueryResolver.DirectiveInputNullable(ctx, arg) +} +func (r *stubQuery) DirectiveInput(ctx context.Context, arg InputDirectives) (*string, error) { + return r.QueryResolver.DirectiveInput(ctx, arg) +} +func (r *stubQuery) DirectiveInputType(ctx context.Context, arg InnerInput) (*string, error) { + return r.QueryResolver.DirectiveInputType(ctx, arg) +} +func (r *stubQuery) DirectiveObject(ctx context.Context) (*ObjectDirectives, error) { + return r.QueryResolver.DirectiveObject(ctx) +} +func (r *stubQuery) DirectiveObjectWithCustomGoModel(ctx context.Context) (*ObjectDirectivesWithCustomGoModel, error) { + return r.QueryResolver.DirectiveObjectWithCustomGoModel(ctx) +} +func (r *stubQuery) DirectiveFieldDef(ctx context.Context, ret string) (string, error) { + return r.QueryResolver.DirectiveFieldDef(ctx, ret) +} +func (r *stubQuery) DirectiveField(ctx context.Context) (*string, error) { + return r.QueryResolver.DirectiveField(ctx) +} +func (r *stubQuery) DirectiveDouble(ctx context.Context) (*string, error) { + return r.QueryResolver.DirectiveDouble(ctx) +} +func (r *stubQuery) DirectiveUnimplemented(ctx context.Context) (*string, error) { + return r.QueryResolver.DirectiveUnimplemented(ctx) +} +func (r *stubQuery) EmbeddedCase1(ctx context.Context) (*EmbeddedCase1, error) { + return r.QueryResolver.EmbeddedCase1(ctx) +} +func (r *stubQuery) EmbeddedCase2(ctx context.Context) (*EmbeddedCase2, error) { + return r.QueryResolver.EmbeddedCase2(ctx) +} +func (r *stubQuery) EmbeddedCase3(ctx context.Context) (*EmbeddedCase3, error) { + return r.QueryResolver.EmbeddedCase3(ctx) +} +func (r *stubQuery) EnumInInput(ctx context.Context, input *InputWithEnumValue) (EnumTest, error) { + return r.QueryResolver.EnumInInput(ctx, input) +} +func (r *stubQuery) Shapes(ctx context.Context) ([]Shape, error) { + return r.QueryResolver.Shapes(ctx) +} +func (r *stubQuery) NoShape(ctx context.Context) (Shape, error) { + return r.QueryResolver.NoShape(ctx) +} +func (r *stubQuery) Node(ctx context.Context) (Node, error) { + return r.QueryResolver.Node(ctx) +} +func (r *stubQuery) NoShapeTypedNil(ctx context.Context) (Shape, error) { + return r.QueryResolver.NoShapeTypedNil(ctx) +} +func (r *stubQuery) Animal(ctx context.Context) (Animal, error) { + return r.QueryResolver.Animal(ctx) +} +func (r *stubQuery) NotAnInterface(ctx context.Context) (BackedByInterface, error) { + return r.QueryResolver.NotAnInterface(ctx) +} +func (r *stubQuery) Issue896a(ctx context.Context) ([]*CheckIssue896, error) { + return r.QueryResolver.Issue896a(ctx) +} +func (r *stubQuery) MapStringInterface(ctx context.Context, in map[string]interface{}) (map[string]interface{}, error) { + return r.QueryResolver.MapStringInterface(ctx, in) +} +func (r *stubQuery) MapNestedStringInterface(ctx context.Context, in *NestedMapInput) (map[string]interface{}, error) { + return r.QueryResolver.MapNestedStringInterface(ctx, in) +} +func (r *stubQuery) ErrorBubble(ctx context.Context) (*Error, error) { + return r.QueryResolver.ErrorBubble(ctx) +} +func (r *stubQuery) ErrorBubbleList(ctx context.Context) ([]*Error, error) { + return r.QueryResolver.ErrorBubbleList(ctx) +} +func (r *stubQuery) ErrorList(ctx context.Context) ([]*Error, error) { + return r.QueryResolver.ErrorList(ctx) +} +func (r *stubQuery) Errors(ctx context.Context) (*Errors, error) { + return r.QueryResolver.Errors(ctx) +} +func (r *stubQuery) Valid(ctx context.Context) (string, error) { + return r.QueryResolver.Valid(ctx) +} +func (r *stubQuery) Panics(ctx context.Context) (*Panics, error) { + return r.QueryResolver.Panics(ctx) +} +func (r *stubQuery) PrimitiveObject(ctx context.Context) ([]Primitive, error) { + return r.QueryResolver.PrimitiveObject(ctx) +} +func (r *stubQuery) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) { + return r.QueryResolver.PrimitiveStringObject(ctx) +} +func (r *stubQuery) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { + return r.QueryResolver.PtrToSliceContainer(ctx) +} +func (r *stubQuery) DefaultScalar(ctx context.Context, arg string) (string, error) { + return r.QueryResolver.DefaultScalar(ctx, arg) +} +func (r *stubQuery) Slices(ctx context.Context) (*Slices, error) { + return r.QueryResolver.Slices(ctx) +} +func (r *stubQuery) ScalarSlice(ctx context.Context) ([]byte, error) { + return r.QueryResolver.ScalarSlice(ctx) +} +func (r *stubQuery) Fallback(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) { + return r.QueryResolver.Fallback(ctx, arg) +} +func (r *stubQuery) OptionalUnion(ctx context.Context) (TestUnion, error) { + return r.QueryResolver.OptionalUnion(ctx) +} +func (r *stubQuery) VOkCaseValue(ctx context.Context) (*VOkCaseValue, error) { + return r.QueryResolver.VOkCaseValue(ctx) +} +func (r *stubQuery) VOkCaseNil(ctx context.Context) (*VOkCaseNil, error) { + return r.QueryResolver.VOkCaseNil(ctx) +} +func (r *stubQuery) ValidType(ctx context.Context) (*ValidType, error) { + return r.QueryResolver.ValidType(ctx) +} +func (r *stubQuery) WrappedStruct(ctx context.Context) (*WrappedStruct, error) { + return r.QueryResolver.WrappedStruct(ctx) +} +func (r *stubQuery) WrappedScalar(ctx context.Context) (otherpkg.Scalar, error) { + return r.QueryResolver.WrappedScalar(ctx) +} +func (r *stubQuery) WrappedMap(ctx context.Context) (WrappedMap, error) { + return r.QueryResolver.WrappedMap(ctx) +} +func (r *stubQuery) WrappedSlice(ctx context.Context) (WrappedSlice, error) { + return r.QueryResolver.WrappedSlice(ctx) +} + +type stubSubscription struct{ *Stub } + +func (r *stubSubscription) Updated(ctx context.Context) (<-chan string, error) { + return r.SubscriptionResolver.Updated(ctx) +} +func (r *stubSubscription) InitPayload(ctx context.Context) (<-chan string, error) { + return r.SubscriptionResolver.InitPayload(ctx) +} +func (r *stubSubscription) DirectiveArg(ctx context.Context, arg string) (<-chan *string, error) { + return r.SubscriptionResolver.DirectiveArg(ctx, arg) +} +func (r *stubSubscription) DirectiveNullableArg(ctx context.Context, arg *int, arg2 *int, arg3 *string) (<-chan *string, error) { + return r.SubscriptionResolver.DirectiveNullableArg(ctx, arg, arg2, arg3) +} +func (r *stubSubscription) DirectiveDouble(ctx context.Context) (<-chan *string, error) { + return r.SubscriptionResolver.DirectiveDouble(ctx) +} +func (r *stubSubscription) DirectiveUnimplemented(ctx context.Context) (<-chan *string, error) { + return r.SubscriptionResolver.DirectiveUnimplemented(ctx) +} +func (r *stubSubscription) Issue896b(ctx context.Context) (<-chan []*CheckIssue896, error) { + return r.SubscriptionResolver.Issue896b(ctx) +} + +type stubUser struct{ *Stub } + +func (r *stubUser) Friends(ctx context.Context, obj *User) ([]*User, error) { + return r.UserResolver.Friends(ctx, obj) +} + +type stubWrappedMap struct{ *Stub } + +func (r *stubWrappedMap) Get(ctx context.Context, obj WrappedMap, key string) (string, error) { + return r.WrappedMapResolver.Get(ctx, obj, key) +} + +type stubWrappedSlice struct{ *Stub } + +func (r *stubWrappedSlice) Get(ctx context.Context, obj WrappedSlice, idx int) (string, error) { + return r.WrappedSliceResolver.Get(ctx, obj, idx) +} diff --git a/codegen/testserver/followschema/subscription_test.go b/codegen/testserver/followschema/subscription_test.go new file mode 100644 index 00000000000..221cbe27288 --- /dev/null +++ b/codegen/testserver/followschema/subscription_test.go @@ -0,0 +1,141 @@ +package followschema + +import ( + "context" + "fmt" + "runtime" + "sort" + "testing" + "time" + + "github.com/99designs/gqlgen/graphql/handler/transport" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestSubscriptions(t *testing.T) { + tick := make(chan string, 1) + + resolvers := &Stub{} + + resolvers.SubscriptionResolver.InitPayload = func(ctx context.Context) (strings <-chan string, e error) { + payload := transport.GetInitPayload(ctx) + channel := make(chan string, len(payload)+1) + + go func() { + <-ctx.Done() + close(channel) + }() + + // Test the helper function separately + auth := payload.Authorization() + if auth != "" { + channel <- "AUTH:" + auth + } else { + channel <- "AUTH:NONE" + } + + // Send them over the channel in alphabetic order + keys := make([]string, 0, len(payload)) + for key := range payload { + keys = append(keys, key) + } + sort.Strings(keys) + for _, key := range keys { + channel <- fmt.Sprintf("%s = %#+v", key, payload[key]) + } + + return channel, nil + } + + resolvers.SubscriptionResolver.Updated = func(ctx context.Context) (<-chan string, error) { + res := make(chan string, 1) + + go func() { + for { + select { + case t := <-tick: + res <- t + case <-ctx.Done(): + close(res) + return + } + } + }() + return res, nil + } + + srv := handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolvers}), + ) + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 1))) + }) + + srv.AroundFields(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { + path, _ := ctx.Value(ckey("path")).([]int) + return next(context.WithValue(ctx, ckey("path"), append(path, 2))) + }) + + c := client.New(srv) + + t.Run("wont leak goroutines", func(t *testing.T) { + runtime.GC() // ensure no go-routines left from preceding tests + initialGoroutineCount := runtime.NumGoroutine() + + sub := c.Websocket(`subscription { updated }`) + + tick <- "message" + + var msg struct { + resp struct { + Updated string + } + } + + err := sub.Next(&msg.resp) + require.NoError(t, err) + require.Equal(t, "message", msg.resp.Updated) + sub.Close() + + // need a little bit of time for goroutines to settle + start := time.Now() + for time.Since(start).Seconds() < 2 && initialGoroutineCount != runtime.NumGoroutine() { + time.Sleep(5 * time.Millisecond) + } + + require.Equal(t, initialGoroutineCount, runtime.NumGoroutine()) + }) + + t.Run("will parse init payload", func(t *testing.T) { + sub := c.WebsocketWithPayload(`subscription { initPayload }`, map[string]interface{}{ + "Authorization": "Bearer of the curse", + "number": 32, + "strings": []string{"hello", "world"}, + }) + + var msg struct { + resp struct { + InitPayload string + } + } + + err := sub.Next(&msg.resp) + require.NoError(t, err) + require.Equal(t, "AUTH:Bearer of the curse", msg.resp.InitPayload) + err = sub.Next(&msg.resp) + require.NoError(t, err) + require.Equal(t, "Authorization = \"Bearer of the curse\"", msg.resp.InitPayload) + err = sub.Next(&msg.resp) + require.NoError(t, err) + require.Equal(t, "number = 32", msg.resp.InitPayload) + err = sub.Next(&msg.resp) + require.NoError(t, err) + require.Equal(t, "strings = []interface {}{\"hello\", \"world\"}", msg.resp.InitPayload) + sub.Close() + }) +} diff --git a/codegen/testserver/followschema/thirdparty.go b/codegen/testserver/followschema/thirdparty.go new file mode 100644 index 00000000000..615196d7d61 --- /dev/null +++ b/codegen/testserver/followschema/thirdparty.go @@ -0,0 +1,31 @@ +package followschema + +import ( + "fmt" + "io" + "strconv" + + "github.com/99designs/gqlgen/graphql" +) + +type ThirdParty struct { + str string +} + +func MarshalThirdParty(tp ThirdParty) graphql.Marshaler { + return graphql.WriterFunc(func(w io.Writer) { + _, err := io.WriteString(w, strconv.Quote(tp.str)) + if err != nil { + panic(err) + } + }) +} + +func UnmarshalThirdParty(input interface{}) (ThirdParty, error) { + switch input := input.(type) { + case string: + return ThirdParty{str: input}, nil + default: + return ThirdParty{}, fmt.Errorf("unknown type for input: %s", input) + } +} diff --git a/codegen/testserver/followschema/time_test.go b/codegen/testserver/followschema/time_test.go new file mode 100644 index 00000000000..8b33b29041d --- /dev/null +++ b/codegen/testserver/followschema/time_test.go @@ -0,0 +1,68 @@ +package followschema + +import ( + "context" + "testing" + "time" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestTime(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) { + return &User{}, nil + } + + t.Run("zero value in nullable field", func(t *testing.T) { + var resp struct { + User struct { + Updated *string + } + } + + err := c.Post(`query { user(id: 1) { updated } }`, &resp) + require.NoError(t, err) + + require.Nil(t, resp.User.Updated) + }) + + t.Run("zero value in non nullable field", func(t *testing.T) { + var resp struct { + User struct { + Created *string + } + } + + err := c.Post(`query { user(id: 1) { created } }`, &resp) + require.EqualError(t, err, `[{"message":"must not be null","path":["user","created"]}]`) + }) + + t.Run("with values", func(t *testing.T) { + resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) { + updated := time.Date(2010, 1, 1, 0, 0, 20, 1, time.UTC) + return &User{ + Created: time.Date(2010, 1, 1, 0, 0, 10, 1, time.UTC), + Updated: &updated, + }, nil + } + + var resp struct { + User struct { + Created string + Updated string + } + } + + err := c.Post(`query { user(id: 1) { created, updated } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "2010-01-01T00:00:10.000000001Z", resp.User.Created) + require.Equal(t, "2010-01-01T00:00:20.000000001Z", resp.User.Updated) + }) +} diff --git a/codegen/testserver/followschema/typefallback.generated.go b/codegen/testserver/followschema/typefallback.generated.go new file mode 100644 index 00000000000..143f5c46e75 --- /dev/null +++ b/codegen/testserver/followschema/typefallback.generated.go @@ -0,0 +1,58 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐFallbackToStringEncoding(ctx context.Context, v interface{}) (FallbackToStringEncoding, error) { + tmp, err := graphql.UnmarshalString(v) + res := FallbackToStringEncoding(tmp) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐFallbackToStringEncoding(ctx context.Context, sel ast.SelectionSet, v FallbackToStringEncoding) graphql.Marshaler { + res := graphql.MarshalString(string(v)) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/typefallback.graphql b/codegen/testserver/followschema/typefallback.graphql similarity index 100% rename from codegen/testserver/typefallback.graphql rename to codegen/testserver/followschema/typefallback.graphql diff --git a/codegen/testserver/followschema/typefallback_test.go b/codegen/testserver/followschema/typefallback_test.go new file mode 100644 index 00000000000..764661f84b8 --- /dev/null +++ b/codegen/testserver/followschema/typefallback_test.go @@ -0,0 +1,28 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestTypeFallback(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.Fallback = func(ctx context.Context, arg FallbackToStringEncoding) (FallbackToStringEncoding, error) { + return arg, nil + } + + t.Run("fallback to string passthrough", func(t *testing.T) { + var resp struct { + Fallback string + } + c.MustPost(`query { fallback(arg: A) }`, &resp) + require.Equal(t, "A", resp.Fallback) + }) +} diff --git a/codegen/testserver/followschema/useptr.generated.go b/codegen/testserver/followschema/useptr.generated.go new file mode 100644 index 00000000000..8d480352d4e --- /dev/null +++ b/codegen/testserver/followschema/useptr.generated.go @@ -0,0 +1,200 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "fmt" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _A_id(ctx context.Context, field graphql.CollectedField, obj *A) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "A", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _B_id(ctx context.Context, field graphql.CollectedField, obj *B) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "B", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _TestUnion(ctx context.Context, sel ast.SelectionSet, obj TestUnion) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case A: + return ec._A(ctx, sel, &obj) + case *A: + if obj == nil { + return graphql.Null + } + return ec._A(ctx, sel, obj) + case B: + return ec._B(ctx, sel, &obj) + case *B: + if obj == nil { + return graphql.Null + } + return ec._B(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var aImplementors = []string{"A", "TestUnion"} + +func (ec *executionContext) _A(ctx context.Context, sel ast.SelectionSet, obj *A) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, aImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("A") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._A_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var bImplementors = []string{"B", "TestUnion"} + +func (ec *executionContext) _B(ctx context.Context, sel ast.SelectionSet, obj *B) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, bImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("B") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._B_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐTestUnion(ctx context.Context, sel ast.SelectionSet, v TestUnion) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._TestUnion(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/useptr.graphql b/codegen/testserver/followschema/useptr.graphql similarity index 100% rename from codegen/testserver/useptr.graphql rename to codegen/testserver/followschema/useptr.graphql diff --git a/codegen/testserver/followschema/useptr_test.go b/codegen/testserver/followschema/useptr_test.go new file mode 100644 index 00000000000..6fdf35c606a --- /dev/null +++ b/codegen/testserver/followschema/useptr_test.go @@ -0,0 +1,14 @@ +package followschema + +import ( + "reflect" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestUserPtr(t *testing.T) { + s := &Stub{} + r := reflect.TypeOf(s.QueryResolver.OptionalUnion) + require.True(t, r.Out(0).Kind() == reflect.Interface) +} diff --git a/codegen/testserver/followschema/v-ok.generated.go b/codegen/testserver/followschema/v-ok.generated.go new file mode 100644 index 00000000000..a495f3fc6ab --- /dev/null +++ b/codegen/testserver/followschema/v-ok.generated.go @@ -0,0 +1,179 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _VOkCaseNil_value(ctx context.Context, field graphql.CollectedField, obj *VOkCaseNil) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "VOkCaseNil", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + v, ok := obj.Value() + if !ok { + return nil, nil + } + return v, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _VOkCaseValue_value(ctx context.Context, field graphql.CollectedField, obj *VOkCaseValue) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "VOkCaseValue", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + v, ok := obj.Value() + if !ok { + return nil, nil + } + return v, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalOString2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var vOkCaseNilImplementors = []string{"VOkCaseNil"} + +func (ec *executionContext) _VOkCaseNil(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseNil) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseNilImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VOkCaseNil") + case "value": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._VOkCaseNil_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var vOkCaseValueImplementors = []string{"VOkCaseValue"} + +func (ec *executionContext) _VOkCaseValue(ctx context.Context, sel ast.SelectionSet, obj *VOkCaseValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, vOkCaseValueImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("VOkCaseValue") + case "value": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._VOkCaseValue_value(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐVOkCaseNil(ctx context.Context, sel ast.SelectionSet, v *VOkCaseNil) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._VOkCaseNil(ctx, sel, v) +} + +func (ec *executionContext) marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐVOkCaseValue(ctx context.Context, sel ast.SelectionSet, v *VOkCaseValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._VOkCaseValue(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/v-ok.go b/codegen/testserver/followschema/v-ok.go new file mode 100644 index 00000000000..7e2aab62dc9 --- /dev/null +++ b/codegen/testserver/followschema/v-ok.go @@ -0,0 +1,17 @@ +package followschema + +// VOkCaseValue model +type VOkCaseValue struct { +} + +func (v VOkCaseValue) Value() (string, bool) { + return "hi", true +} + +// VOkCaseNil model +type VOkCaseNil struct { +} + +func (v VOkCaseNil) Value() (string, bool) { + return "", false +} diff --git a/codegen/testserver/followschema/v-ok.graphql b/codegen/testserver/followschema/v-ok.graphql new file mode 100644 index 00000000000..9139cf8aa91 --- /dev/null +++ b/codegen/testserver/followschema/v-ok.graphql @@ -0,0 +1,12 @@ +extend type Query { + vOkCaseValue: VOkCaseValue + vOkCaseNil: VOkCaseNil +} + +type VOkCaseValue @goModel(model:"followschema.VOkCaseValue") { + value: String +} + +type VOkCaseNil @goModel(model:"followschema.VOkCaseNil") { + value: String +} diff --git a/codegen/testserver/followschema/v-ok_test.go b/codegen/testserver/followschema/v-ok_test.go new file mode 100644 index 00000000000..6c22368fda2 --- /dev/null +++ b/codegen/testserver/followschema/v-ok_test.go @@ -0,0 +1,47 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" +) + +func TestOk(t *testing.T) { + resolver := &Stub{} + resolver.QueryResolver.VOkCaseValue = func(ctx context.Context) (*VOkCaseValue, error) { + return &VOkCaseValue{}, nil + } + resolver.QueryResolver.VOkCaseNil = func(ctx context.Context) (*VOkCaseNil, error) { + return &VOkCaseNil{}, nil + } + + c := client.New(handler.NewDefaultServer( + NewExecutableSchema(Config{Resolvers: resolver}), + )) + + t.Run("v ok case value", func(t *testing.T) { + var resp struct { + VOkCaseValue struct { + Value string + } + } + err := c.Post(`query { vOkCaseValue { value } }`, &resp) + require.NoError(t, err) + require.Equal(t, resp.VOkCaseValue.Value, "hi") + }) + + t.Run("v ok case nil", func(t *testing.T) { + var resp struct { + VOkCaseNil struct { + Value *string + } + } + err := c.Post(`query { vOkCaseNil { value } }`, &resp) + require.NoError(t, err) + require.Equal(t, true, resp.VOkCaseNil.Value == nil) + }) +} diff --git a/codegen/testserver/followschema/validtypes.generated.go b/codegen/testserver/followschema/validtypes.generated.go new file mode 100644 index 00000000000..2f9e0117a3a --- /dev/null +++ b/codegen/testserver/followschema/validtypes.generated.go @@ -0,0 +1,877 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "fmt" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_ValidType_validArgs_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["break"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("break")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["break"] = arg0 + var arg1 string + if tmp, ok := rawArgs["default"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("default")) + arg1, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["default"] = arg1 + var arg2 string + if tmp, ok := rawArgs["func"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("func")) + arg2, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["func"] = arg2 + var arg3 string + if tmp, ok := rawArgs["interface"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("interface")) + arg3, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["interface"] = arg3 + var arg4 string + if tmp, ok := rawArgs["select"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("select")) + arg4, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["select"] = arg4 + var arg5 string + if tmp, ok := rawArgs["case"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("case")) + arg5, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["case"] = arg5 + var arg6 string + if tmp, ok := rawArgs["defer"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("defer")) + arg6, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["defer"] = arg6 + var arg7 string + if tmp, ok := rawArgs["go"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("go")) + arg7, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["go"] = arg7 + var arg8 string + if tmp, ok := rawArgs["map"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("map")) + arg8, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["map"] = arg8 + var arg9 string + if tmp, ok := rawArgs["struct"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("struct")) + arg9, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["struct"] = arg9 + var arg10 string + if tmp, ok := rawArgs["chan"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("chan")) + arg10, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["chan"] = arg10 + var arg11 string + if tmp, ok := rawArgs["else"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("else")) + arg11, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["else"] = arg11 + var arg12 string + if tmp, ok := rawArgs["goto"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("goto")) + arg12, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["goto"] = arg12 + var arg13 string + if tmp, ok := rawArgs["package"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("package")) + arg13, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["package"] = arg13 + var arg14 string + if tmp, ok := rawArgs["switch"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("switch")) + arg14, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["switch"] = arg14 + var arg15 string + if tmp, ok := rawArgs["const"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("const")) + arg15, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["const"] = arg15 + var arg16 string + if tmp, ok := rawArgs["fallthrough"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fallthrough")) + arg16, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["fallthrough"] = arg16 + var arg17 string + if tmp, ok := rawArgs["if"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("if")) + arg17, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["if"] = arg17 + var arg18 string + if tmp, ok := rawArgs["range"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("range")) + arg18, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["range"] = arg18 + var arg19 string + if tmp, ok := rawArgs["type"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type")) + arg19, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["type"] = arg19 + var arg20 string + if tmp, ok := rawArgs["continue"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("continue")) + arg20, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["continue"] = arg20 + var arg21 string + if tmp, ok := rawArgs["for"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("for")) + arg21, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["for"] = arg21 + var arg22 string + if tmp, ok := rawArgs["import"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("import")) + arg22, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["import"] = arg22 + var arg23 string + if tmp, ok := rawArgs["return"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("return")) + arg23, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["return"] = arg23 + var arg24 string + if tmp, ok := rawArgs["var"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("var")) + arg24, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["var"] = arg24 + var arg25 string + if tmp, ok := rawArgs["_"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("_")) + arg25, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["_"] = arg25 + return args, nil +} + +func (ec *executionContext) field_ValidType_validInputKeywords_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *ValidInput + if tmp, ok := rawArgs["input"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) + arg0, err = ec.unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐValidInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["input"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Content_Post_foo(ctx context.Context, field graphql.CollectedField, obj *ContentPost) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Content_Post", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Foo, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _Content_User_foo(ctx context.Context, field graphql.CollectedField, obj *ContentUser) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Content_User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Foo, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_differentCase(ctx context.Context, field graphql.CollectedField, obj *ValidType) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ValidType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DifferentCase, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_different_case(ctx context.Context, field graphql.CollectedField, obj *ValidType) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ValidType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DifferentCaseOld, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_validInputKeywords(ctx context.Context, field graphql.CollectedField, obj *ValidType) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ValidType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_ValidType_validInputKeywords_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidInputKeywords, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _ValidType_validArgs(ctx context.Context, field graphql.CollectedField, obj *ValidType) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "ValidType", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_ValidType_validArgs_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ValidArgs, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputValidInput(ctx context.Context, obj interface{}) (ValidInput, error) { + var it ValidInput + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "break": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("break")) + it.Break, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "default": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("default")) + it.Default, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "func": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("func")) + it.Func, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "interface": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("interface")) + it.Interface, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "select": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("select")) + it.Select, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "case": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("case")) + it.Case, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "defer": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("defer")) + it.Defer, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "go": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("go")) + it.Go, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "map": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("map")) + it.Map, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "struct": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("struct")) + it.Struct, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "chan": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("chan")) + it.Chan, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "else": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("else")) + it.Else, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "goto": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("goto")) + it.Goto, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "package": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("package")) + it.Package, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "switch": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("switch")) + it.Switch, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "const": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("const")) + it.Const, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "fallthrough": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("fallthrough")) + it.Fallthrough, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "if": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("if")) + it.If, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "range": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("range")) + it.Range, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "type": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type")) + it.Type, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "continue": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("continue")) + it.Continue, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "for": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("for")) + it.For, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "import": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("import")) + it.Import, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "return": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("return")) + it.Return, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "var": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("var")) + it.Var, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "_": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("_")) + it.Underscore, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _Content_Child(ctx context.Context, sel ast.SelectionSet, obj ContentChild) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case ContentUser: + return ec._Content_User(ctx, sel, &obj) + case *ContentUser: + if obj == nil { + return graphql.Null + } + return ec._Content_User(ctx, sel, obj) + case ContentPost: + return ec._Content_Post(ctx, sel, &obj) + case *ContentPost: + if obj == nil { + return graphql.Null + } + return ec._Content_Post(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var content_PostImplementors = []string{"Content_Post", "Content_Child"} + +func (ec *executionContext) _Content_Post(ctx context.Context, sel ast.SelectionSet, obj *ContentPost) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, content_PostImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Content_Post") + case "foo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Content_Post_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var content_UserImplementors = []string{"Content_User", "Content_Child"} + +func (ec *executionContext) _Content_User(ctx context.Context, sel ast.SelectionSet, obj *ContentUser) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, content_UserImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Content_User") + case "foo": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Content_User_foo(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var validTypeImplementors = []string{"ValidType"} + +func (ec *executionContext) _ValidType(ctx context.Context, sel ast.SelectionSet, obj *ValidType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, validTypeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ValidType") + case "differentCase": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_differentCase(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "different_case": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_different_case(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "validInputKeywords": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_validInputKeywords(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "validArgs": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._ValidType_validArgs(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐValidInput(ctx context.Context, v interface{}) (*ValidInput, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputValidInput(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐValidType(ctx context.Context, sel ast.SelectionSet, v *ValidType) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._ValidType(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/validtypes.graphql b/codegen/testserver/followschema/validtypes.graphql similarity index 100% rename from codegen/testserver/validtypes.graphql rename to codegen/testserver/followschema/validtypes.graphql diff --git a/codegen/testserver/followschema/validtypes_test.go b/codegen/testserver/followschema/validtypes_test.go new file mode 100644 index 00000000000..2c0e67942a0 --- /dev/null +++ b/codegen/testserver/followschema/validtypes_test.go @@ -0,0 +1,36 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestValidType(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.ValidType = func(ctx context.Context) (validType *ValidType, e error) { + return &ValidType{ + DifferentCase: "new", + DifferentCaseOld: "old", + }, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + t.Run("fields with differing cases can be distinguished", func(t *testing.T) { + var resp struct { + ValidType struct { + New string `json:"differentCase"` + Old string `json:"different_case"` + } + } + err := c.Post(`query { validType { differentCase, different_case } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "new", resp.ValidType.New) + require.Equal(t, "old", resp.ValidType.Old) + }) +} diff --git a/codegen/testserver/followschema/weird_type_cases.generated.go b/codegen/testserver/followschema/weird_type_cases.generated.go new file mode 100644 index 00000000000..181cb582158 --- /dev/null +++ b/codegen/testserver/followschema/weird_type_cases.generated.go @@ -0,0 +1,421 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _AIt_id(ctx context.Context, field graphql.CollectedField, obj *AIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "AIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _AbIt_id(ctx context.Context, field graphql.CollectedField, obj *AbIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "AbIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _XXIt_id(ctx context.Context, field graphql.CollectedField, obj *XXIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "XXIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _XxIt_id(ctx context.Context, field graphql.CollectedField, obj *XxIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "XxIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _asdfIt_id(ctx context.Context, field graphql.CollectedField, obj *AsdfIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "asdfIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _iIt_id(ctx context.Context, field graphql.CollectedField, obj *IIt) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "iIt", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var aItImplementors = []string{"AIt"} + +func (ec *executionContext) _AIt(ctx context.Context, sel ast.SelectionSet, obj *AIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, aItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("AIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._AIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var abItImplementors = []string{"AbIt"} + +func (ec *executionContext) _AbIt(ctx context.Context, sel ast.SelectionSet, obj *AbIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, abItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("AbIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._AbIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var xXItImplementors = []string{"XXIt"} + +func (ec *executionContext) _XXIt(ctx context.Context, sel ast.SelectionSet, obj *XXIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, xXItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("XXIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._XXIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var xxItImplementors = []string{"XxIt"} + +func (ec *executionContext) _XxIt(ctx context.Context, sel ast.SelectionSet, obj *XxIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, xxItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("XxIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._XxIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var asdfItImplementors = []string{"asdfIt"} + +func (ec *executionContext) _asdfIt(ctx context.Context, sel ast.SelectionSet, obj *AsdfIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, asdfItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("asdfIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._asdfIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var iItImplementors = []string{"iIt"} + +func (ec *executionContext) _iIt(ctx context.Context, sel ast.SelectionSet, obj *IIt) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, iItImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("iIt") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._iIt_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/weird_type_cases.graphql b/codegen/testserver/followschema/weird_type_cases.graphql similarity index 100% rename from codegen/testserver/weird_type_cases.graphql rename to codegen/testserver/followschema/weird_type_cases.graphql diff --git a/codegen/testserver/followschema/wrapped_type.generated.go b/codegen/testserver/followschema/wrapped_type.generated.go new file mode 100644 index 00000000000..c3a4c80ecf3 --- /dev/null +++ b/codegen/testserver/followschema/wrapped_type.generated.go @@ -0,0 +1,407 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + "strconv" + "sync/atomic" + + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +type WrappedMapResolver interface { + Get(ctx context.Context, obj WrappedMap, key string) (string, error) +} +type WrappedSliceResolver interface { + Get(ctx context.Context, obj WrappedSlice, idx int) (string, error) +} + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_WrappedMap_get_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["key"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("key")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["key"] = arg0 + return args, nil +} + +func (ec *executionContext) field_WrappedSlice_get_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 int + if tmp, ok := rawArgs["idx"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("idx")) + arg0, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["idx"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _WrappedMap_get(ctx context.Context, field graphql.CollectedField, obj WrappedMap) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "WrappedMap", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_WrappedMap_get_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.WrappedMap().Get(rctx, obj, args["key"].(string)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _WrappedSlice_get(ctx context.Context, field graphql.CollectedField, obj WrappedSlice) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "WrappedSlice", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_WrappedSlice_get_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.WrappedSlice().Get(rctx, obj, args["idx"].(int)) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _WrappedStruct_name(ctx context.Context, field graphql.CollectedField, obj *WrappedStruct) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "WrappedStruct", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(otherpkg.Scalar) + fc.Result = res + return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx, field.Selections, res) +} + +func (ec *executionContext) _WrappedStruct_desc(ctx context.Context, field graphql.CollectedField, obj *WrappedStruct) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "WrappedStruct", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Desc, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*otherpkg.Scalar) + fc.Result = res + return ec.marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx, field.Selections, res) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var wrappedMapImplementors = []string{"WrappedMap"} + +func (ec *executionContext) _WrappedMap(ctx context.Context, sel ast.SelectionSet, obj WrappedMap) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, wrappedMapImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("WrappedMap") + case "get": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._WrappedMap_get(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var wrappedSliceImplementors = []string{"WrappedSlice"} + +func (ec *executionContext) _WrappedSlice(ctx context.Context, sel ast.SelectionSet, obj WrappedSlice) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, wrappedSliceImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("WrappedSlice") + case "get": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._WrappedSlice_get(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + out.Concurrently(i, func() graphql.Marshaler { + return innerFunc(ctx) + + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var wrappedStructImplementors = []string{"WrappedStruct"} + +func (ec *executionContext) _WrappedStruct(ctx context.Context, sel ast.SelectionSet, obj *WrappedStruct) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, wrappedStructImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("WrappedStruct") + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._WrappedStruct_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "desc": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._WrappedStruct_desc(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedMap(ctx context.Context, sel ast.SelectionSet, v WrappedMap) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._WrappedMap(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (otherpkg.Scalar, error) { + tmp, err := graphql.UnmarshalString(v) + res := otherpkg.Scalar(tmp) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v otherpkg.Scalar) graphql.Marshaler { + res := graphql.MarshalString(string(v)) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + +func (ec *executionContext) marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedSlice(ctx context.Context, sel ast.SelectionSet, v WrappedSlice) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._WrappedSlice(ctx, sel, v) +} + +func (ec *executionContext) marshalNWrappedStruct2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v WrappedStruct) graphql.Marshaler { + return ec._WrappedStruct(ctx, sel, &v) +} + +func (ec *executionContext) marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v *WrappedStruct) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._WrappedStruct(ctx, sel, v) +} + +func (ec *executionContext) unmarshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (*otherpkg.Scalar, error) { + if v == nil { + return nil, nil + } + tmp, err := graphql.UnmarshalString(v) + res := otherpkg.Scalar(tmp) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v *otherpkg.Scalar) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return graphql.MarshalString(string(*v)) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/wrapped_type.go b/codegen/testserver/followschema/wrapped_type.go new file mode 100644 index 00000000000..911bf27ebb1 --- /dev/null +++ b/codegen/testserver/followschema/wrapped_type.go @@ -0,0 +1,8 @@ +package followschema + +import "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" + +type WrappedScalar = otherpkg.Scalar +type WrappedStruct otherpkg.Struct +type WrappedMap otherpkg.Map +type WrappedSlice otherpkg.Slice diff --git a/codegen/testserver/wrapped_type.graphql b/codegen/testserver/followschema/wrapped_type.graphql similarity index 100% rename from codegen/testserver/wrapped_type.graphql rename to codegen/testserver/followschema/wrapped_type.graphql diff --git a/codegen/testserver/followschema/wrapped_type_test.go b/codegen/testserver/followschema/wrapped_type_test.go new file mode 100644 index 00000000000..95280b3d952 --- /dev/null +++ b/codegen/testserver/followschema/wrapped_type_test.go @@ -0,0 +1,98 @@ +package followschema + +import ( + "context" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/codegen/testserver/followschema/otherpkg" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestWrappedTypes(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.WrappedScalar = func(ctx context.Context) (scalar WrappedScalar, e error) { + return "hello", nil + } + + resolvers.QueryResolver.WrappedStruct = func(ctx context.Context) (wrappedStruct *WrappedStruct, e error) { + wrapped := WrappedStruct(otherpkg.Struct{ + Name: "hello", + }) + return &wrapped, nil + } + + resolvers.QueryResolver.WrappedMap = func(ctx context.Context) (wrappedMap WrappedMap, e error) { + wrapped := WrappedMap(map[string]string{ + "name": "hello", + }) + return wrapped, nil + } + + resolvers.QueryResolver.WrappedSlice = func(ctx context.Context) (slice WrappedSlice, err error) { + wrapped := WrappedSlice([]string{"hello"}) + return wrapped, nil + } + + resolvers.WrappedMapResolver.Get = func(ctx context.Context, obj WrappedMap, key string) (s string, err error) { + return obj[key], nil + } + + resolvers.WrappedSliceResolver.Get = func(ctx context.Context, obj WrappedSlice, idx int) (s string, err error) { + return obj[idx], nil + } + + t.Run("wrapped struct", func(t *testing.T) { + var resp struct { + WrappedStruct struct { + Name string + } + } + + err := c.Post(`query { wrappedStruct { name } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "hello", resp.WrappedStruct.Name) + }) + + t.Run("wrapped scalar", func(t *testing.T) { + var resp struct { + WrappedScalar string + } + + err := c.Post(`query { wrappedScalar }`, &resp) + require.NoError(t, err) + + require.Equal(t, "hello", resp.WrappedScalar) + }) + + t.Run("wrapped map", func(t *testing.T) { + var resp struct { + WrappedMap struct { + Name string + } + } + + err := c.Post(`query { wrappedMap { name: get(key: "name") } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "hello", resp.WrappedMap.Name) + }) + + t.Run("wrapped slice", func(t *testing.T) { + var resp struct { + WrappedSlice struct { + First string + } + } + + err := c.Post(`query { wrappedSlice { first: get(idx: 0) } }`, &resp) + require.NoError(t, err) + + require.Equal(t, "hello", resp.WrappedSlice.First) + }) +} diff --git a/codegen/testserver/generated_test.go b/codegen/testserver/generated_test.go index edc961a8f26..5270830df9d 100644 --- a/codegen/testserver/generated_test.go +++ b/codegen/testserver/generated_test.go @@ -1,80 +1,65 @@ -//go:generate rm -f resolver.go -//go:generate go run ../../testdata/gqlgen.go -stub stub.go - package testserver import ( - "context" - "reflect" + "fmt" + "go/ast" + "go/parser" + "go/token" + "io/ioutil" + "os" + "path/filepath" + "strings" "testing" - "github.com/99designs/gqlgen/client" - "github.com/99designs/gqlgen/graphql/handler" + eqgo "github.com/kevinmbeaulieu/eq-go/eq-go" "github.com/stretchr/testify/require" ) -func TestForcedResolverFieldIsPointer(t *testing.T) { - field, ok := reflect.TypeOf((*ForcedResolverResolver)(nil)).Elem().MethodByName("Field") - require.True(t, ok) - require.Equal(t, "*testserver.Circle", field.Type.Out(0).String()) -} +func TestLayouts(t *testing.T) { + singlefileFSet := token.NewFileSet() + singlefilePkg := loadPackage("singlefile", singlefileFSet) -func TestEnums(t *testing.T) { - t.Run("list of enums", func(t *testing.T) { - require.Equal(t, StatusOk, AllStatus[0]) - require.Equal(t, StatusError, AllStatus[1]) - }) + followschemaFSet := token.NewFileSet() + followschemaPkg := loadPackage("followschema", followschemaFSet) - t.Run("invalid enum values", func(t *testing.T) { - require.Equal(t, StatusOk, AllStatus[0]) - require.Equal(t, StatusError, AllStatus[1]) - }) + eq, msg := eqgo.PackagesEquivalent(singlefilePkg, singlefileFSet, followschemaPkg, followschemaFSet, nil) + if !eq { + // When msg is too long, require.True(...) omits it entirely. + // Therefore use fmt.Fprintln to print it manually instead. + fmt.Fprintln(os.Stderr, msg) + require.Fail(t, "Packages not equivalent") + } } -func TestUnionFragments(t *testing.T) { - resolvers := &Stub{} - resolvers.QueryResolver.ShapeUnion = func(ctx context.Context) (ShapeUnion, error) { - return &Circle{Radius: 32}, nil +func loadPackage(name string, fset *token.FileSet) *ast.Package { + path, err := filepath.Abs(name) + if err != nil { + panic(err) + } + files, err := ioutil.ReadDir(path) + if err != nil { + panic(err) } - srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) - c := client.New(srv) - - t.Run("inline fragment on union", func(t *testing.T) { - var resp struct { - ShapeUnion struct { - Radius float64 - } - } - c.MustPost(`query { - shapeUnion { - ... on Circle { - radius - } - } - } - `, &resp) - require.NotEmpty(t, resp.ShapeUnion.Radius) - }) - - t.Run("named fragment", func(t *testing.T) { - var resp struct { - ShapeUnion struct { - Radius float64 - } - } - c.MustPost(`query { - shapeUnion { - ...C + pkg := ast.Package{ + Name: name, + Files: make(map[string]*ast.File), + } + for _, f := range files { + // Only compare generated files. + if strings.HasSuffix(f.Name(), ".generated.go") || + f.Name() == "generated.go" || + f.Name() == "resolver.go" || + f.Name() == "stub.go" || + f.Name() == "models-gen.go" { + filename := filepath.Join(path, f.Name()) + src, err := parser.ParseFile(fset, filename, nil, parser.AllErrors) + if err != nil { + panic(err) } + pkg.Files[filename] = src } + } - fragment C on ShapeUnion { - ... on Circle { - radius - } - } - `, &resp) - require.NotEmpty(t, resp.ShapeUnion.Radius) - }) + return &pkg } diff --git a/codegen/testserver/singlefile/builtinscalar.graphql b/codegen/testserver/singlefile/builtinscalar.graphql new file mode 100644 index 00000000000..deb8a9f6242 --- /dev/null +++ b/codegen/testserver/singlefile/builtinscalar.graphql @@ -0,0 +1,8 @@ + +""" +Since gqlgen defines default implementation for a Map scalar, this tests that the builtin is _not_ +added to the TypeMap +""" +type Map { + id: ID! +} diff --git a/codegen/testserver/bytes.go b/codegen/testserver/singlefile/bytes.go similarity index 96% rename from codegen/testserver/bytes.go rename to codegen/testserver/singlefile/bytes.go index 42a4541f9d4..9a2414b422d 100644 --- a/codegen/testserver/bytes.go +++ b/codegen/testserver/singlefile/bytes.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "fmt" diff --git a/codegen/testserver/singlefile/complexity.graphql b/codegen/testserver/singlefile/complexity.graphql new file mode 100644 index 00000000000..c6a1868a8e6 --- /dev/null +++ b/codegen/testserver/singlefile/complexity.graphql @@ -0,0 +1,11 @@ +extend type Query { + overlapping: OverlappingFields +} + +type OverlappingFields { + oneFoo: Int! @goField(name: "foo") + twoFoo: Int! @goField(name: "foo") + oldFoo: Int! @goField(name: "foo", forceResolver: true) + newFoo: Int! + new_foo: Int! +} diff --git a/codegen/testserver/complexity_test.go b/codegen/testserver/singlefile/complexity_test.go similarity index 99% rename from codegen/testserver/complexity_test.go rename to codegen/testserver/singlefile/complexity_test.go index 26e1d85f8de..ac8e05a8c35 100644 --- a/codegen/testserver/complexity_test.go +++ b/codegen/testserver/singlefile/complexity_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/defaults.graphql b/codegen/testserver/singlefile/defaults.graphql new file mode 100644 index 00000000000..1c9a9ebf03d --- /dev/null +++ b/codegen/testserver/singlefile/defaults.graphql @@ -0,0 +1,20 @@ +extend type Query { + defaultParameters( + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true + ): DefaultParametersMirror! +} + +extend type Mutation { + defaultInput(input: DefaultInput!): DefaultParametersMirror! +} + +input DefaultInput { + falsyBoolean: Boolean = false + truthyBoolean: Boolean = true +} + +type DefaultParametersMirror { + falsyBoolean: Boolean + truthyBoolean: Boolean +} diff --git a/codegen/testserver/defaults_test.go b/codegen/testserver/singlefile/defaults_test.go similarity index 98% rename from codegen/testserver/defaults_test.go rename to codegen/testserver/singlefile/defaults_test.go index 2bb1f85de6c..4b403ad1515 100644 --- a/codegen/testserver/defaults_test.go +++ b/codegen/testserver/singlefile/defaults_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/directive.graphql b/codegen/testserver/singlefile/directive.graphql new file mode 100644 index 00000000000..8cf2470986e --- /dev/null +++ b/codegen/testserver/singlefile/directive.graphql @@ -0,0 +1,54 @@ +directive @length(min: Int!, max: Int, message: String) on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION +directive @range(min: Int = 0, max: Int) on ARGUMENT_DEFINITION +directive @custom on ARGUMENT_DEFINITION +directive @logged(id: UUID!) on FIELD +directive @toNull on ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | FIELD_DEFINITION +directive @directive1 on FIELD_DEFINITION +directive @directive2 on FIELD_DEFINITION +directive @directive3 on INPUT_OBJECT +directive @unimplemented on FIELD_DEFINITION +directive @order1(location: String!) repeatable on FIELD_DEFINITION | OBJECT +directive @order2(location: String!) on OBJECT + +extend type Query { + directiveArg(arg: String! @length(min:1, max: 255, message: "invalid length")): String + directiveNullableArg(arg: Int @range(min:0), arg2: Int @range, arg3: String @toNull): String + directiveInputNullable(arg: InputDirectives): String + directiveInput(arg: InputDirectives!): String + directiveInputType(arg: InnerInput! @custom): String + directiveObject: ObjectDirectives @order1(location: "Query_field") + directiveObjectWithCustomGoModel: ObjectDirectivesWithCustomGoModel + directiveFieldDef(ret: String!): String! @length(min: 1, message: "not valid") + directiveField: String + directiveDouble: String @directive1 @directive2 + directiveUnimplemented: String @unimplemented +} + +extend type Subscription { + directiveArg(arg: String! @length(min:1, max: 255, message: "invalid length")): String + directiveNullableArg(arg: Int @range(min:0), arg2: Int @range, arg3: String @toNull): String + directiveDouble: String @directive1 @directive2 + directiveUnimplemented: String @unimplemented +} + +input InputDirectives @directive3 { + text: String! @length(min: 0, max: 7, message: "not valid") + nullableText: String @toNull + inner: InnerDirectives! + innerNullable: InnerDirectives + thirdParty: ThirdParty @length(min: 0, max: 7) +} + +input InnerDirectives { + message: String! @length(min: 1, message: "not valid") +} + +type ObjectDirectives @order1(location: "order1_1") @order1(location: "order1_2") @order2(location: "order2_1") { + text: String! @length(min: 0, max: 7, message: "not valid") + nullableText: String @toNull + order: [String!]! +} + +type ObjectDirectivesWithCustomGoModel { + nullableText: String @toNull +} diff --git a/codegen/testserver/directive_test.go b/codegen/testserver/singlefile/directive_test.go similarity index 99% rename from codegen/testserver/directive_test.go rename to codegen/testserver/singlefile/directive_test.go index a35a2889884..69f9bab337d 100644 --- a/codegen/testserver/directive_test.go +++ b/codegen/testserver/singlefile/directive_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/embedded.go b/codegen/testserver/singlefile/embedded.go similarity index 98% rename from codegen/testserver/embedded.go rename to codegen/testserver/singlefile/embedded.go index 2052281d884..76206737b92 100644 --- a/codegen/testserver/embedded.go +++ b/codegen/testserver/singlefile/embedded.go @@ -1,4 +1,4 @@ -package testserver +package singlefile // EmbeddedCase1 model type EmbeddedCase1 struct { diff --git a/codegen/testserver/embedded.graphql b/codegen/testserver/singlefile/embedded.graphql similarity index 60% rename from codegen/testserver/embedded.graphql rename to codegen/testserver/singlefile/embedded.graphql index 99cbd61c7c3..8445c056b6a 100644 --- a/codegen/testserver/embedded.graphql +++ b/codegen/testserver/singlefile/embedded.graphql @@ -4,14 +4,14 @@ extend type Query { embeddedCase3: EmbeddedCase3 } -type EmbeddedCase1 @goModel(model:"testserver.EmbeddedCase1") { +type EmbeddedCase1 @goModel(model:"singlefile.EmbeddedCase1") { exportedEmbeddedPointerExportedMethod: String! } -type EmbeddedCase2 @goModel(model:"testserver.EmbeddedCase2") { +type EmbeddedCase2 @goModel(model:"singlefile.EmbeddedCase2") { unexportedEmbeddedPointerExportedMethod: String! } -type EmbeddedCase3 @goModel(model:"testserver.EmbeddedCase3") { +type EmbeddedCase3 @goModel(model:"singlefile.EmbeddedCase3") { unexportedEmbeddedInterfaceExportedMethod: String! } diff --git a/codegen/testserver/embedded_test.go b/codegen/testserver/singlefile/embedded_test.go similarity index 99% rename from codegen/testserver/embedded_test.go rename to codegen/testserver/singlefile/embedded_test.go index 7760375fb7f..dd9ededd14a 100644 --- a/codegen/testserver/embedded_test.go +++ b/codegen/testserver/singlefile/embedded_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/enum.graphql b/codegen/testserver/singlefile/enum.graphql new file mode 100644 index 00000000000..08559b65c6f --- /dev/null +++ b/codegen/testserver/singlefile/enum.graphql @@ -0,0 +1,12 @@ +enum EnumTest { + OK + NG +} + +input InputWithEnumValue { + enum: EnumTest! +} + +extend type Query { + enumInInput(input: InputWithEnumValue): EnumTest! +} diff --git a/codegen/testserver/enums_test.go b/codegen/testserver/singlefile/enums_test.go similarity index 98% rename from codegen/testserver/enums_test.go rename to codegen/testserver/singlefile/enums_test.go index e16c34c849b..af13aa1a49a 100644 --- a/codegen/testserver/enums_test.go +++ b/codegen/testserver/singlefile/enums_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/generated.go b/codegen/testserver/singlefile/generated.go similarity index 94% rename from codegen/testserver/generated.go rename to codegen/testserver/singlefile/generated.go index 317dfdb5b1c..768095f2535 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/singlefile/generated.go @@ -1,6 +1,6 @@ // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. -package testserver +package singlefile import ( "bytes" @@ -13,9 +13,9 @@ import ( "sync/atomic" "time" - introspection1 "github.com/99designs/gqlgen/codegen/testserver/introspection" - invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/invalid-packagename" - "github.com/99designs/gqlgen/codegen/testserver/otherpkg" + introspection1 "github.com/99designs/gqlgen/codegen/testserver/singlefile/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/singlefile/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg" "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" gqlparser "github.com/vektah/gqlparser/v2" @@ -2097,15 +2097,15 @@ type ObjectDirectivesWithCustomGoModel { embeddedCase3: EmbeddedCase3 } -type EmbeddedCase1 @goModel(model:"testserver.EmbeddedCase1") { +type EmbeddedCase1 @goModel(model:"singlefile.EmbeddedCase1") { exportedEmbeddedPointerExportedMethod: String! } -type EmbeddedCase2 @goModel(model:"testserver.EmbeddedCase2") { +type EmbeddedCase2 @goModel(model:"singlefile.EmbeddedCase2") { unexportedEmbeddedPointerExportedMethod: String! } -type EmbeddedCase3 @goModel(model:"testserver.EmbeddedCase3") { +type EmbeddedCase3 @goModel(model:"singlefile.EmbeddedCase3") { unexportedEmbeddedInterfaceExportedMethod: String! } `, BuiltIn: false}, @@ -2163,7 +2163,7 @@ type Rectangle implements Shape { width: Float area: Float } -union ShapeUnion @goModel(model:"testserver.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model:"singlefile.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION @@ -2420,7 +2420,7 @@ input OuterInput { inner: InnerInput! } -scalar ThirdParty @goModel(model: "testserver.ThirdParty") +scalar ThirdParty @goModel(model:"singlefile.ThirdParty") type OuterObject { inner: InnerObject! @@ -2434,7 +2434,7 @@ type ForcedResolver { field: Circle @goField(forceResolver: true) } -type EmbeddedPointer @goModel(model: "testserver.EmbeddedPointerModel") { +type EmbeddedPointer @goModel(model:"singlefile.EmbeddedPointerModel") { ID: String Title: String } @@ -2491,11 +2491,11 @@ extend type Query { vOkCaseNil: VOkCaseNil } -type VOkCaseValue @goModel(model:"testserver.VOkCaseValue") { +type VOkCaseValue @goModel(model:"singlefile.VOkCaseValue") { value: String } -type VOkCaseNil @goModel(model:"testserver.VOkCaseNil") { +type VOkCaseNil @goModel(model:"singlefile.VOkCaseNil") { value: String } `, BuiltIn: false}, @@ -2716,7 +2716,7 @@ func (ec *executionContext) field_Mutation_defaultInput_args(ctx context.Context var arg0 DefaultInput if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultInput(ctx, tmp) + arg0, err = ec.unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultInput(ctx, tmp) if err != nil { return nil, err } @@ -2731,7 +2731,7 @@ func (ec *executionContext) field_Mutation_updatePtrToPtr_args(ctx context.Conte var arg0 UpdatePtrToPtrOuter if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrOuter(ctx, tmp) + arg0, err = ec.unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrOuter(ctx, tmp) if err != nil { return nil, err } @@ -2746,7 +2746,7 @@ func (ec *executionContext) field_Mutation_updateSomething_args(ctx context.Cont var arg0 SpecialInput if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐSpecialInput(ctx, tmp) + arg0, err = ec.unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐSpecialInput(ctx, tmp) if err != nil { return nil, err } @@ -2761,7 +2761,7 @@ func (ec *executionContext) field_Panics_argUnmarshal_args(ctx context.Context, var arg0 []MarshalPanic if tmp, ok := rawArgs["u"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("u")) - arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx, tmp) + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx, tmp) if err != nil { return nil, err } @@ -2776,7 +2776,7 @@ func (ec *executionContext) field_Panics_fieldFuncMarshal_args(ctx context.Conte var arg0 []MarshalPanic if tmp, ok := rawArgs["u"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("u")) - arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx, tmp) + arg0, err = ec.unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx, tmp) if err != nil { return nil, err } @@ -2900,7 +2900,7 @@ func (ec *executionContext) field_Query_directiveInputNullable_args(ctx context. var arg0 *InputDirectives if tmp, ok := rawArgs["arg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) - arg0, err = ec.unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputDirectives(ctx, tmp) + arg0, err = ec.unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputDirectives(ctx, tmp) if err != nil { return nil, err } @@ -2916,7 +2916,7 @@ func (ec *executionContext) field_Query_directiveInputType_args(ctx context.Cont if tmp, ok := rawArgs["arg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) directive0 := func(ctx context.Context) (interface{}, error) { - return ec.unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx, tmp) + return ec.unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerInput(ctx, tmp) } directive1 := func(ctx context.Context) (interface{}, error) { if ec.directives.Custom == nil { @@ -2932,7 +2932,7 @@ func (ec *executionContext) field_Query_directiveInputType_args(ctx context.Cont if data, ok := tmp.(InnerInput); ok { arg0 = data } else { - return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver.InnerInput`, tmp)) + return nil, graphql.ErrorOnPath(ctx, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/singlefile.InnerInput`, tmp)) } } args["arg"] = arg0 @@ -2945,7 +2945,7 @@ func (ec *executionContext) field_Query_directiveInput_args(ctx context.Context, var arg0 InputDirectives if tmp, ok := rawArgs["arg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) - arg0, err = ec.unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputDirectives(ctx, tmp) + arg0, err = ec.unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputDirectives(ctx, tmp) if err != nil { return nil, err } @@ -3046,7 +3046,7 @@ func (ec *executionContext) field_Query_enumInInput_args(ctx context.Context, ra var arg0 *InputWithEnumValue if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputWithEnumValue(ctx, tmp) + arg0, err = ec.unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputWithEnumValue(ctx, tmp) if err != nil { return nil, err } @@ -3061,7 +3061,7 @@ func (ec *executionContext) field_Query_fallback_args(ctx context.Context, rawAr var arg0 FallbackToStringEncoding if tmp, ok := rawArgs["arg"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("arg")) - arg0, err = ec.unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐFallbackToStringEncoding(ctx, tmp) + arg0, err = ec.unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐFallbackToStringEncoding(ctx, tmp) if err != nil { return nil, err } @@ -3121,7 +3121,7 @@ func (ec *executionContext) field_Query_mapNestedStringInterface_args(ctx contex var arg0 *NestedMapInput if tmp, ok := rawArgs["in"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("in")) - arg0, err = ec.unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNestedMapInput(ctx, tmp) + arg0, err = ec.unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNestedMapInput(ctx, tmp) if err != nil { return nil, err } @@ -3151,7 +3151,7 @@ func (ec *executionContext) field_Query_nestedInputs_args(ctx context.Context, r var arg0 [][]*OuterInput if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx, tmp) + arg0, err = ec.unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx, tmp) if err != nil { return nil, err } @@ -3181,7 +3181,7 @@ func (ec *executionContext) field_Query_recursive_args(ctx context.Context, rawA var arg0 *RecursiveInputSlice if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, tmp) + arg0, err = ec.unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSlice(ctx, tmp) if err != nil { return nil, err } @@ -3577,7 +3577,7 @@ func (ec *executionContext) field_ValidType_validInputKeywords_args(ctx context. var arg0 *ValidInput if tmp, ok := rawArgs["input"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("input")) - arg0, err = ec.unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx, tmp) + arg0, err = ec.unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐValidInput(ctx, tmp) if err != nil { return nil, err } @@ -4278,7 +4278,7 @@ func (ec *executionContext) _ConcreteNodeA_child(ctx context.Context, field grap } res := resTmp.(Node) fc.Result = res - return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNode(ctx, field.Selections, res) + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNode(ctx, field.Selections, res) } func (ec *executionContext) _ConcreteNodeA_name(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { @@ -4374,7 +4374,7 @@ func (ec *executionContext) _ConcreteNodeInterface_child(ctx context.Context, fi } res := resTmp.(Node) fc.Result = res - return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNode(ctx, field.Selections, res) + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNode(ctx, field.Selections, res) } func (ec *executionContext) _Content_Post_foo(ctx context.Context, field graphql.CollectedField, obj *ContentPost) (ret graphql.Marshaler) { @@ -4894,7 +4894,7 @@ func (ec *executionContext) _Errors_a(ctx context.Context, field graphql.Collect } res := resTmp.(*Error) fc.Result = res - return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Errors_b(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { @@ -4926,7 +4926,7 @@ func (ec *executionContext) _Errors_b(ctx context.Context, field graphql.Collect } res := resTmp.(*Error) fc.Result = res - return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Errors_c(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { @@ -4958,7 +4958,7 @@ func (ec *executionContext) _Errors_c(ctx context.Context, field graphql.Collect } res := resTmp.(*Error) fc.Result = res - return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Errors_d(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { @@ -4990,7 +4990,7 @@ func (ec *executionContext) _Errors_d(ctx context.Context, field graphql.Collect } res := resTmp.(*Error) fc.Result = res - return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Errors_e(ctx context.Context, field graphql.CollectedField, obj *Errors) (ret graphql.Marshaler) { @@ -5022,7 +5022,7 @@ func (ec *executionContext) _Errors_e(ctx context.Context, field graphql.Collect } res := resTmp.(*Error) fc.Result = res - return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _ForcedResolver_field(ctx context.Context, field graphql.CollectedField, obj *ForcedResolver) (ret graphql.Marshaler) { @@ -5051,7 +5051,7 @@ func (ec *executionContext) _ForcedResolver_field(ctx context.Context, field gra } res := resTmp.(*Circle) fc.Result = res - return ec.marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCircle(ctx, field.Selections, res) + return ec.marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCircle(ctx, field.Selections, res) } func (ec *executionContext) _InnerObject_id(ctx context.Context, field graphql.CollectedField, obj *InnerObject) (ret graphql.Marshaler) { @@ -5179,7 +5179,7 @@ func (ec *executionContext) _LoopA_b(ctx context.Context, field graphql.Collecte } res := resTmp.(*LoopB) fc.Result = res - return ec.marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐLoopB(ctx, field.Selections, res) + return ec.marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐLoopB(ctx, field.Selections, res) } func (ec *executionContext) _LoopB_a(ctx context.Context, field graphql.CollectedField, obj *LoopB) (ret graphql.Marshaler) { @@ -5211,7 +5211,7 @@ func (ec *executionContext) _LoopB_a(ctx context.Context, field graphql.Collecte } res := resTmp.(*LoopA) fc.Result = res - return ec.marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐLoopA(ctx, field.Selections, res) + return ec.marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐLoopA(ctx, field.Selections, res) } func (ec *executionContext) _Map_id(ctx context.Context, field graphql.CollectedField, obj *Map) (ret graphql.Marshaler) { @@ -5454,7 +5454,7 @@ func (ec *executionContext) _Mutation_defaultInput(ctx context.Context, field gr } res := resTmp.(*DefaultParametersMirror) fc.Result = res - return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx, field.Selections, res) + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultParametersMirror(ctx, field.Selections, res) } func (ec *executionContext) _Mutation_updateSomething(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -5532,7 +5532,7 @@ func (ec *executionContext) _Mutation_updatePtrToPtr(ctx context.Context, field } res := resTmp.(*PtrToPtrOuter) fc.Result = res - return ec.marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx, field.Selections, res) + return ec.marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrOuter(ctx, field.Selections, res) } func (ec *executionContext) _ObjectDirectives_text(ctx context.Context, field graphql.CollectedField, obj *ObjectDirectives) (ret graphql.Marshaler) { @@ -5758,7 +5758,7 @@ func (ec *executionContext) _OuterObject_inner(ctx context.Context, field graphq } res := resTmp.(*InnerObject) fc.Result = res - return ec.marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerObject(ctx, field.Selections, res) + return ec.marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerObject(ctx, field.Selections, res) } func (ec *executionContext) _OverlappingFields_oneFoo(ctx context.Context, field graphql.CollectedField, obj *OverlappingFields) (ret graphql.Marshaler) { @@ -5950,7 +5950,7 @@ func (ec *executionContext) _Panics_fieldScalarMarshal(ctx context.Context, fiel } res := resTmp.([]MarshalPanic) fc.Result = res - return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx, field.Selections, res) + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Panics_fieldFuncMarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) (ret graphql.Marshaler) { @@ -5989,7 +5989,7 @@ func (ec *executionContext) _Panics_fieldFuncMarshal(ctx context.Context, field } res := resTmp.([]MarshalPanic) fc.Result = res - return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx, field.Selections, res) + return ec.marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Panics_argUnmarshal(ctx context.Context, field graphql.CollectedField, obj *Panics) (ret graphql.Marshaler) { @@ -6313,7 +6313,7 @@ func (ec *executionContext) _PtrToPtrOuter_inner(ctx context.Context, field grap } res := resTmp.(*PtrToPtrInner) fc.Result = res - return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, field.Selections, res) + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, field.Selections, res) } func (ec *executionContext) _PtrToPtrOuter_stupidInner(ctx context.Context, field graphql.CollectedField, obj *PtrToPtrOuter) (ret graphql.Marshaler) { @@ -6342,7 +6342,7 @@ func (ec *executionContext) _PtrToPtrOuter_stupidInner(ctx context.Context, fiel } res := resTmp.(*******PtrToPtrInner) fc.Result = res - return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, field.Selections, res) + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, field.Selections, res) } func (ec *executionContext) _PtrToSliceContainer_ptrToSlice(ctx context.Context, field graphql.CollectedField, obj *PtrToSliceContainer) (ret graphql.Marshaler) { @@ -6400,7 +6400,7 @@ func (ec *executionContext) _Query_invalidIdentifier(ctx context.Context, field } res := resTmp.(*invalid_packagename.InvalidIdentifier) fc.Result = res - return ec.marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx, field.Selections, res) + return ec.marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx, field.Selections, res) } func (ec *executionContext) _Query_collision(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6429,7 +6429,7 @@ func (ec *executionContext) _Query_collision(ctx context.Context, field graphql. } res := resTmp.(*introspection1.It) fc.Result = res - return ec.marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋintrospectionᚐIt(ctx, field.Selections, res) + return ec.marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋintrospectionᚐIt(ctx, field.Selections, res) } func (ec *executionContext) _Query_mapInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6566,7 +6566,7 @@ func (ec *executionContext) _Query_nestedOutputs(ctx context.Context, field grap } res := resTmp.([][]*OuterObject) fc.Result = res - return ec.marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx, field.Selections, res) + return ec.marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx, field.Selections, res) } func (ec *executionContext) _Query_modelMethods(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6595,7 +6595,7 @@ func (ec *executionContext) _Query_modelMethods(ctx context.Context, field graph } res := resTmp.(*ModelMethods) fc.Result = res - return ec.marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐModelMethods(ctx, field.Selections, res) + return ec.marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐModelMethods(ctx, field.Selections, res) } func (ec *executionContext) _Query_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6634,7 +6634,7 @@ func (ec *executionContext) _Query_user(ctx context.Context, field graphql.Colle } res := resTmp.(*User) fc.Result = res - return ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUser(ctx, field.Selections, res) + return ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUser(ctx, field.Selections, res) } func (ec *executionContext) _Query_nullableArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6780,7 +6780,7 @@ func (ec *executionContext) _Query_shapeUnion(ctx context.Context, field graphql } res := resTmp.(ShapeUnion) fc.Result = res - return ec.marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShapeUnion(ctx, field.Selections, res) + return ec.marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShapeUnion(ctx, field.Selections, res) } func (ec *executionContext) _Query_autobind(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6809,7 +6809,7 @@ func (ec *executionContext) _Query_autobind(ctx context.Context, field graphql.C } res := resTmp.(*Autobind) fc.Result = res - return ec.marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐAutobind(ctx, field.Selections, res) + return ec.marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐAutobind(ctx, field.Selections, res) } func (ec *executionContext) _Query_deprecatedField(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6870,7 +6870,7 @@ func (ec *executionContext) _Query_overlapping(ctx context.Context, field graphq } res := resTmp.(*OverlappingFields) fc.Result = res - return ec.marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOverlappingFields(ctx, field.Selections, res) + return ec.marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOverlappingFields(ctx, field.Selections, res) } func (ec *executionContext) _Query_defaultParameters(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -6909,7 +6909,7 @@ func (ec *executionContext) _Query_defaultParameters(ctx context.Context, field } res := resTmp.(*DefaultParametersMirror) fc.Result = res - return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx, field.Selections, res) + return ec.marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultParametersMirror(ctx, field.Selections, res) } func (ec *executionContext) _Query_directiveArg(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7164,7 +7164,7 @@ func (ec *executionContext) _Query_directiveObject(ctx context.Context, field gr if data, ok := tmp.(*ObjectDirectives); ok { return data, nil } - return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.ObjectDirectives`, tmp) + return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/singlefile.ObjectDirectives`, tmp) }) if resTmp == nil { @@ -7172,7 +7172,7 @@ func (ec *executionContext) _Query_directiveObject(ctx context.Context, field gr } res := resTmp.(*ObjectDirectives) fc.Result = res - return ec.marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐObjectDirectives(ctx, field.Selections, res) + return ec.marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐObjectDirectives(ctx, field.Selections, res) } func (ec *executionContext) _Query_directiveObjectWithCustomGoModel(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7201,7 +7201,7 @@ func (ec *executionContext) _Query_directiveObjectWithCustomGoModel(ctx context. } res := resTmp.(*ObjectDirectivesWithCustomGoModel) fc.Result = res - return ec.marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐObjectDirectivesWithCustomGoModel(ctx, field.Selections, res) + return ec.marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐObjectDirectivesWithCustomGoModel(ctx, field.Selections, res) } func (ec *executionContext) _Query_directiveFieldDef(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7430,7 +7430,7 @@ func (ec *executionContext) _Query_embeddedCase1(ctx context.Context, field grap } res := resTmp.(*EmbeddedCase1) fc.Result = res - return ec.marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase1(ctx, field.Selections, res) + return ec.marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase1(ctx, field.Selections, res) } func (ec *executionContext) _Query_embeddedCase2(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7459,7 +7459,7 @@ func (ec *executionContext) _Query_embeddedCase2(ctx context.Context, field grap } res := resTmp.(*EmbeddedCase2) fc.Result = res - return ec.marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase2(ctx, field.Selections, res) + return ec.marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase2(ctx, field.Selections, res) } func (ec *executionContext) _Query_embeddedCase3(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7488,7 +7488,7 @@ func (ec *executionContext) _Query_embeddedCase3(ctx context.Context, field grap } res := resTmp.(*EmbeddedCase3) fc.Result = res - return ec.marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase3(ctx, field.Selections, res) + return ec.marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase3(ctx, field.Selections, res) } func (ec *executionContext) _Query_enumInInput(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7527,7 +7527,7 @@ func (ec *executionContext) _Query_enumInInput(ctx context.Context, field graphq } res := resTmp.(EnumTest) fc.Result = res - return ec.marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEnumTest(ctx, field.Selections, res) + return ec.marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEnumTest(ctx, field.Selections, res) } func (ec *executionContext) _Query_shapes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7556,7 +7556,7 @@ func (ec *executionContext) _Query_shapes(ctx context.Context, field graphql.Col } res := resTmp.([]Shape) fc.Result = res - return ec.marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx, field.Selections, res) + return ec.marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx, field.Selections, res) } func (ec *executionContext) _Query_noShape(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7597,7 +7597,7 @@ func (ec *executionContext) _Query_noShape(ctx context.Context, field graphql.Co if data, ok := tmp.(Shape); ok { return data, nil } - return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver.Shape`, tmp) + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/singlefile.Shape`, tmp) }) if resTmp == nil { @@ -7605,7 +7605,7 @@ func (ec *executionContext) _Query_noShape(ctx context.Context, field graphql.Co } res := resTmp.(Shape) fc.Result = res - return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx, field.Selections, res) + return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx, field.Selections, res) } func (ec *executionContext) _Query_node(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7637,7 +7637,7 @@ func (ec *executionContext) _Query_node(ctx context.Context, field graphql.Colle } res := resTmp.(Node) fc.Result = res - return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNode(ctx, field.Selections, res) + return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNode(ctx, field.Selections, res) } func (ec *executionContext) _Query_noShapeTypedNil(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7678,7 +7678,7 @@ func (ec *executionContext) _Query_noShapeTypedNil(ctx context.Context, field gr if data, ok := tmp.(Shape); ok { return data, nil } - return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver.Shape`, tmp) + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/singlefile.Shape`, tmp) }) if resTmp == nil { @@ -7686,7 +7686,7 @@ func (ec *executionContext) _Query_noShapeTypedNil(ctx context.Context, field gr } res := resTmp.(Shape) fc.Result = res - return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx, field.Selections, res) + return ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx, field.Selections, res) } func (ec *executionContext) _Query_animal(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7727,7 +7727,7 @@ func (ec *executionContext) _Query_animal(ctx context.Context, field graphql.Col if data, ok := tmp.(Animal); ok { return data, nil } - return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver.Animal`, tmp) + return nil, fmt.Errorf(`unexpected type %T from directive, should be github.com/99designs/gqlgen/codegen/testserver/singlefile.Animal`, tmp) }) if resTmp == nil { @@ -7735,7 +7735,7 @@ func (ec *executionContext) _Query_animal(ctx context.Context, field graphql.Col } res := resTmp.(Animal) fc.Result = res - return ec.marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐAnimal(ctx, field.Selections, res) + return ec.marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐAnimal(ctx, field.Selections, res) } func (ec *executionContext) _Query_notAnInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7764,7 +7764,7 @@ func (ec *executionContext) _Query_notAnInterface(ctx context.Context, field gra } res := resTmp.(BackedByInterface) fc.Result = res - return ec.marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐBackedByInterface(ctx, field.Selections, res) + return ec.marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐBackedByInterface(ctx, field.Selections, res) } func (ec *executionContext) _Query_issue896a(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7793,7 +7793,7 @@ func (ec *executionContext) _Query_issue896a(ctx context.Context, field graphql. } res := resTmp.([]*CheckIssue896) fc.Result = res - return ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896ᚄ(ctx, field.Selections, res) + return ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896ᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Query_mapStringInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7894,7 +7894,7 @@ func (ec *executionContext) _Query_errorBubble(ctx context.Context, field graphq } res := resTmp.(*Error) fc.Result = res - return ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Query_errorBubbleList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7923,7 +7923,7 @@ func (ec *executionContext) _Query_errorBubbleList(ctx context.Context, field gr } res := resTmp.([]*Error) fc.Result = res - return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx, field.Selections, res) + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐErrorᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Query_errorList(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7952,7 +7952,7 @@ func (ec *executionContext) _Query_errorList(ctx context.Context, field graphql. } res := resTmp.([]*Error) fc.Result = res - return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, field.Selections, res) + return ec.marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, field.Selections, res) } func (ec *executionContext) _Query_errors(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -7981,7 +7981,7 @@ func (ec *executionContext) _Query_errors(ctx context.Context, field graphql.Col } res := resTmp.(*Errors) fc.Result = res - return ec.marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrors(ctx, field.Selections, res) + return ec.marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐErrors(ctx, field.Selections, res) } func (ec *executionContext) _Query_valid(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8042,7 +8042,7 @@ func (ec *executionContext) _Query_panics(ctx context.Context, field graphql.Col } res := resTmp.(*Panics) fc.Result = res - return ec.marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPanics(ctx, field.Selections, res) + return ec.marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPanics(ctx, field.Selections, res) } func (ec *executionContext) _Query_primitiveObject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8074,7 +8074,7 @@ func (ec *executionContext) _Query_primitiveObject(ctx context.Context, field gr } res := resTmp.([]Primitive) fc.Result = res - return ec.marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveᚄ(ctx, field.Selections, res) + return ec.marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Query_primitiveStringObject(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8106,7 +8106,7 @@ func (ec *executionContext) _Query_primitiveStringObject(ctx context.Context, fi } res := resTmp.([]PrimitiveString) fc.Result = res - return ec.marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveStringᚄ(ctx, field.Selections, res) + return ec.marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveStringᚄ(ctx, field.Selections, res) } func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8138,7 +8138,7 @@ func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, fiel } res := resTmp.(*PtrToSliceContainer) fc.Result = res - return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx, field.Selections, res) + return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToSliceContainer(ctx, field.Selections, res) } func (ec *executionContext) _Query_defaultScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8206,7 +8206,7 @@ func (ec *executionContext) _Query_slices(ctx context.Context, field graphql.Col } res := resTmp.(*Slices) fc.Result = res - return ec.marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐSlices(ctx, field.Selections, res) + return ec.marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐSlices(ctx, field.Selections, res) } func (ec *executionContext) _Query_scalarSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8277,7 +8277,7 @@ func (ec *executionContext) _Query_fallback(ctx context.Context, field graphql.C } res := resTmp.(FallbackToStringEncoding) fc.Result = res - return ec.marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐFallbackToStringEncoding(ctx, field.Selections, res) + return ec.marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐFallbackToStringEncoding(ctx, field.Selections, res) } func (ec *executionContext) _Query_optionalUnion(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8306,7 +8306,7 @@ func (ec *executionContext) _Query_optionalUnion(ctx context.Context, field grap } res := resTmp.(TestUnion) fc.Result = res - return ec.marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐTestUnion(ctx, field.Selections, res) + return ec.marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐTestUnion(ctx, field.Selections, res) } func (ec *executionContext) _Query_vOkCaseValue(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8335,7 +8335,7 @@ func (ec *executionContext) _Query_vOkCaseValue(ctx context.Context, field graph } res := resTmp.(*VOkCaseValue) fc.Result = res - return ec.marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseValue(ctx, field.Selections, res) + return ec.marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐVOkCaseValue(ctx, field.Selections, res) } func (ec *executionContext) _Query_vOkCaseNil(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8364,7 +8364,7 @@ func (ec *executionContext) _Query_vOkCaseNil(ctx context.Context, field graphql } res := resTmp.(*VOkCaseNil) fc.Result = res - return ec.marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseNil(ctx, field.Selections, res) + return ec.marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐVOkCaseNil(ctx, field.Selections, res) } func (ec *executionContext) _Query_validType(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8393,7 +8393,7 @@ func (ec *executionContext) _Query_validType(ctx context.Context, field graphql. } res := resTmp.(*ValidType) fc.Result = res - return ec.marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidType(ctx, field.Selections, res) + return ec.marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐValidType(ctx, field.Selections, res) } func (ec *executionContext) _Query_wrappedStruct(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8425,7 +8425,7 @@ func (ec *executionContext) _Query_wrappedStruct(ctx context.Context, field grap } res := resTmp.(*WrappedStruct) fc.Result = res - return ec.marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedStruct(ctx, field.Selections, res) + return ec.marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedStruct(ctx, field.Selections, res) } func (ec *executionContext) _Query_wrappedScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8457,7 +8457,7 @@ func (ec *executionContext) _Query_wrappedScalar(ctx context.Context, field grap } res := resTmp.(otherpkg.Scalar) fc.Result = res - return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx, field.Selections, res) + return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx, field.Selections, res) } func (ec *executionContext) _Query_wrappedMap(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8489,7 +8489,7 @@ func (ec *executionContext) _Query_wrappedMap(ctx context.Context, field graphql } res := resTmp.(WrappedMap) fc.Result = res - return ec.marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedMap(ctx, field.Selections, res) + return ec.marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedMap(ctx, field.Selections, res) } func (ec *executionContext) _Query_wrappedSlice(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -8521,7 +8521,7 @@ func (ec *executionContext) _Query_wrappedSlice(ctx context.Context, field graph } res := resTmp.(WrappedSlice) fc.Result = res - return ec.marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedSlice(ctx, field.Selections, res) + return ec.marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedSlice(ctx, field.Selections, res) } func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { @@ -9131,7 +9131,7 @@ func (ec *executionContext) _Subscription_issue896b(ctx context.Context, field g w.Write([]byte{'{'}) graphql.MarshalString(field.Alias).MarshalGQL(w) w.Write([]byte{':'}) - ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, field.Selections, res).MarshalGQL(w) + ec.marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx, field.Selections, res).MarshalGQL(w) w.Write([]byte{'}'}) }) } @@ -9198,7 +9198,7 @@ func (ec *executionContext) _User_friends(ctx context.Context, field graphql.Col } res := resTmp.([]*User) fc.Result = res - return ec.marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUserᚄ(ctx, field.Selections, res) + return ec.marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUserᚄ(ctx, field.Selections, res) } func (ec *executionContext) _User_created(ctx context.Context, field graphql.CollectedField, obj *User) (ret graphql.Marshaler) { @@ -9577,7 +9577,7 @@ func (ec *executionContext) _WrappedStruct_name(ctx context.Context, field graph } res := resTmp.(otherpkg.Scalar) fc.Result = res - return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx, field.Selections, res) + return ec.marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx, field.Selections, res) } func (ec *executionContext) _WrappedStruct_desc(ctx context.Context, field graphql.CollectedField, obj *WrappedStruct) (ret graphql.Marshaler) { @@ -9606,7 +9606,7 @@ func (ec *executionContext) _WrappedStruct_desc(ctx context.Context, field graph } res := resTmp.(*otherpkg.Scalar) fc.Result = res - return ec.marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx, field.Selections, res) + return ec.marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx, field.Selections, res) } func (ec *executionContext) _XXIt_id(ctx context.Context, field graphql.CollectedField, obj *XXIt) (ret graphql.Marshaler) { @@ -10950,7 +10950,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) directive0 := func(ctx context.Context) (interface{}, error) { - return ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + return ec.unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerDirectives(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { if ec.directives.Directive3 == nil { @@ -10968,7 +10968,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o } else if tmp == nil { it.Inner = nil } else { - err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/singlefile.InnerDirectives`, tmp) return it, graphql.ErrorOnPath(ctx, err) } case "innerNullable": @@ -10976,7 +10976,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("innerNullable")) directive0 := func(ctx context.Context) (interface{}, error) { - return ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx, v) + return ec.unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerDirectives(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { if ec.directives.Directive3 == nil { @@ -10994,7 +10994,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o } else if tmp == nil { it.InnerNullable = nil } else { - err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.InnerDirectives`, tmp) + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/singlefile.InnerDirectives`, tmp) return it, graphql.ErrorOnPath(ctx, err) } case "thirdParty": @@ -11002,7 +11002,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("thirdParty")) directive0 := func(ctx context.Context) (interface{}, error) { - return ec.unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐThirdParty(ctx, v) + return ec.unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐThirdParty(ctx, v) } directive1 := func(ctx context.Context) (interface{}, error) { if ec.directives.Directive3 == nil { @@ -11034,7 +11034,7 @@ func (ec *executionContext) unmarshalInputInputDirectives(ctx context.Context, o } else if tmp == nil { it.ThirdParty = nil } else { - err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver.ThirdParty`, tmp) + err := fmt.Errorf(`unexpected type %T from directive, should be *github.com/99designs/gqlgen/codegen/testserver/singlefile.ThirdParty`, tmp) return it, graphql.ErrorOnPath(ctx, err) } } @@ -11056,7 +11056,7 @@ func (ec *executionContext) unmarshalInputInputWithEnumValue(ctx context.Context var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("enum")) - it.Enum, err = ec.unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEnumTest(ctx, v) + it.Enum, err = ec.unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEnumTest(ctx, v) if err != nil { return it, err } @@ -11079,7 +11079,7 @@ func (ec *executionContext) unmarshalInputNestedInput(ctx context.Context, obj i var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) - it.Field, err = ec.unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmail(ctx, v) + it.Field, err = ec.unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmail(ctx, v) if err != nil { return it, err } @@ -11125,7 +11125,7 @@ func (ec *executionContext) unmarshalInputOuterInput(ctx context.Context, obj in var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) - it.Inner, err = ec.unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx, v) + it.Inner, err = ec.unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerInput(ctx, v) if err != nil { return it, err } @@ -11148,7 +11148,7 @@ func (ec *executionContext) unmarshalInputRecursiveInputSlice(ctx context.Contex var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("self")) - it.Self, err = ec.unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSliceᚄ(ctx, v) + it.Self, err = ec.unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSliceᚄ(ctx, v) if err != nil { return it, err } @@ -11171,7 +11171,7 @@ func (ec *executionContext) unmarshalInputSpecialInput(ctx context.Context, obj var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nesting")) - it.Nesting, err = ec.unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNestedInput(ctx, v) + it.Nesting, err = ec.unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNestedInput(ctx, v) if err != nil { return it, err } @@ -11233,7 +11233,7 @@ func (ec *executionContext) unmarshalInputUpdatePtrToPtrOuter(ctx context.Contex var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("inner")) - it.Inner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + it.Inner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return it, err } @@ -11241,7 +11241,7 @@ func (ec *executionContext) unmarshalInputUpdatePtrToPtrOuter(ctx context.Contex var err error ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("stupidInner")) - it.StupidInner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + it.StupidInner, err = ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return it, err } @@ -15749,7 +15749,7 @@ func (ec *executionContext) marshalNBytes2ᚕbyte(ctx context.Context, sel ast.S return res } -func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { +func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15759,16 +15759,16 @@ func (ec *executionContext) marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋ return ec._CheckIssue896(ctx, sel, v) } -func (ec *executionContext) unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultInput(ctx context.Context, v interface{}) (DefaultInput, error) { +func (ec *executionContext) unmarshalNDefaultInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultInput(ctx context.Context, v interface{}) (DefaultInput, error) { res, err := ec.unmarshalInputDefaultInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNDefaultParametersMirror2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v DefaultParametersMirror) graphql.Marshaler { +func (ec *executionContext) marshalNDefaultParametersMirror2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v DefaultParametersMirror) graphql.Marshaler { return ec._DefaultParametersMirror(ctx, sel, &v) } -func (ec *executionContext) marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v *DefaultParametersMirror) graphql.Marshaler { +func (ec *executionContext) marshalNDefaultParametersMirror2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐDefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, v *DefaultParametersMirror) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15793,31 +15793,31 @@ func (ec *executionContext) marshalNDefaultScalarImplementation2string(ctx conte return res } -func (ec *executionContext) unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmail(ctx context.Context, v interface{}) (Email, error) { +func (ec *executionContext) unmarshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmail(ctx context.Context, v interface{}) (Email, error) { var res Email err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmail(ctx context.Context, sel ast.SelectionSet, v Email) graphql.Marshaler { +func (ec *executionContext) marshalNEmail2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmail(ctx context.Context, sel ast.SelectionSet, v Email) graphql.Marshaler { return v } -func (ec *executionContext) unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEnumTest(ctx context.Context, v interface{}) (EnumTest, error) { +func (ec *executionContext) unmarshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEnumTest(ctx context.Context, v interface{}) (EnumTest, error) { var res EnumTest err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEnumTest(ctx context.Context, sel ast.SelectionSet, v EnumTest) graphql.Marshaler { +func (ec *executionContext) marshalNEnumTest2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEnumTest(ctx context.Context, sel ast.SelectionSet, v EnumTest) graphql.Marshaler { return v } -func (ec *executionContext) marshalNError2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v Error) graphql.Marshaler { +func (ec *executionContext) marshalNError2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx context.Context, sel ast.SelectionSet, v Error) graphql.Marshaler { return ec._Error(ctx, sel, &v) } -func (ec *executionContext) marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { +func (ec *executionContext) marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15827,13 +15827,13 @@ func (ec *executionContext) marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._Error(ctx, sel, v) } -func (ec *executionContext) unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐFallbackToStringEncoding(ctx context.Context, v interface{}) (FallbackToStringEncoding, error) { +func (ec *executionContext) unmarshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐFallbackToStringEncoding(ctx context.Context, v interface{}) (FallbackToStringEncoding, error) { tmp, err := graphql.UnmarshalString(v) res := FallbackToStringEncoding(tmp) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐFallbackToStringEncoding(ctx context.Context, sel ast.SelectionSet, v FallbackToStringEncoding) graphql.Marshaler { +func (ec *executionContext) marshalNFallbackToStringEncoding2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐFallbackToStringEncoding(ctx context.Context, sel ast.SelectionSet, v FallbackToStringEncoding) graphql.Marshaler { res := graphql.MarshalString(string(v)) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -15873,22 +15873,22 @@ func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.Selec return res } -func (ec *executionContext) unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { +func (ec *executionContext) unmarshalNInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { res, err := ec.unmarshalInputInnerDirectives(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx context.Context, v interface{}) (InnerInput, error) { +func (ec *executionContext) unmarshalNInnerInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerInput(ctx context.Context, v interface{}) (InnerInput, error) { res, err := ec.unmarshalInputInnerInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerInput(ctx context.Context, v interface{}) (*InnerInput, error) { +func (ec *executionContext) unmarshalNInnerInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerInput(ctx context.Context, v interface{}) (*InnerInput, error) { res, err := ec.unmarshalInputInnerInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerObject(ctx context.Context, sel ast.SelectionSet, v *InnerObject) graphql.Marshaler { +func (ec *executionContext) marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerObject(ctx context.Context, sel ast.SelectionSet, v *InnerObject) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15898,7 +15898,7 @@ func (ec *executionContext) marshalNInnerObject2ᚖgithubᚗcomᚋ99designsᚋgq return ec._InnerObject(ctx, sel, v) } -func (ec *executionContext) unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputDirectives(ctx context.Context, v interface{}) (InputDirectives, error) { +func (ec *executionContext) unmarshalNInputDirectives2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputDirectives(ctx context.Context, v interface{}) (InputDirectives, error) { res, err := ec.unmarshalInputInputDirectives(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } @@ -15948,7 +15948,7 @@ func (ec *executionContext) marshalNInt2int64(ctx context.Context, sel ast.Selec return res } -func (ec *executionContext) marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐLoopA(ctx context.Context, sel ast.SelectionSet, v *LoopA) graphql.Marshaler { +func (ec *executionContext) marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐLoopA(ctx context.Context, sel ast.SelectionSet, v *LoopA) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15958,7 +15958,7 @@ func (ec *executionContext) marshalNLoopA2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._LoopA(ctx, sel, v) } -func (ec *executionContext) marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐLoopB(ctx context.Context, sel ast.SelectionSet, v *LoopB) graphql.Marshaler { +func (ec *executionContext) marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐLoopB(ctx context.Context, sel ast.SelectionSet, v *LoopB) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -15968,17 +15968,17 @@ func (ec *executionContext) marshalNLoopB2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._LoopB(ctx, sel, v) } -func (ec *executionContext) unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, v interface{}) (MarshalPanic, error) { +func (ec *executionContext) unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanic(ctx context.Context, v interface{}) (MarshalPanic, error) { var res MarshalPanic err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx context.Context, sel ast.SelectionSet, v MarshalPanic) graphql.Marshaler { +func (ec *executionContext) marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanic(ctx context.Context, sel ast.SelectionSet, v MarshalPanic) graphql.Marshaler { return v } -func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx context.Context, v interface{}) ([]MarshalPanic, error) { +func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx context.Context, v interface{}) ([]MarshalPanic, error) { var vSlice []interface{} if v != nil { if tmp1, ok := v.([]interface{}); ok { @@ -15991,7 +15991,7 @@ func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designs res := make([]MarshalPanic, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, vSlice[i]) + res[i], err = ec.unmarshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanic(ctx, vSlice[i]) if err != nil { return nil, err } @@ -15999,10 +15999,10 @@ func (ec *executionContext) unmarshalNMarshalPanic2ᚕgithubᚗcomᚋ99designs return res, nil } -func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanicᚄ(ctx context.Context, sel ast.SelectionSet, v []MarshalPanic) graphql.Marshaler { +func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanicᚄ(ctx context.Context, sel ast.SelectionSet, v []MarshalPanic) graphql.Marshaler { ret := make(graphql.Array, len(v)) for i := range v { - ret[i] = ec.marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐMarshalPanic(ctx, sel, v[i]) + ret[i] = ec.marshalNMarshalPanic2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐMarshalPanic(ctx, sel, v[i]) } for _, e := range ret { @@ -16014,12 +16014,12 @@ func (ec *executionContext) marshalNMarshalPanic2ᚕgithubᚗcomᚋ99designsᚋg return ret } -func (ec *executionContext) unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNestedInput(ctx context.Context, v interface{}) (*NestedInput, error) { +func (ec *executionContext) unmarshalNNestedInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNestedInput(ctx context.Context, v interface{}) (*NestedInput, error) { res, err := ec.unmarshalInputNestedInput(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNode(ctx context.Context, sel ast.SelectionSet, v Node) graphql.Marshaler { +func (ec *executionContext) marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNode(ctx context.Context, sel ast.SelectionSet, v Node) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16029,11 +16029,11 @@ func (ec *executionContext) marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcod return ec._Node(ctx, sel, v) } -func (ec *executionContext) marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitive(ctx context.Context, sel ast.SelectionSet, v Primitive) graphql.Marshaler { +func (ec *executionContext) marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitive(ctx context.Context, sel ast.SelectionSet, v Primitive) graphql.Marshaler { return ec._Primitive(ctx, sel, &v) } -func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveᚄ(ctx context.Context, sel ast.SelectionSet, v []Primitive) graphql.Marshaler { +func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveᚄ(ctx context.Context, sel ast.SelectionSet, v []Primitive) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup isLen1 := len(v) == 1 @@ -16057,7 +16057,7 @@ func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlg if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitive(ctx, sel, v[i]) + ret[i] = ec.marshalNPrimitive2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitive(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16077,11 +16077,11 @@ func (ec *executionContext) marshalNPrimitive2ᚕgithubᚗcomᚋ99designsᚋgqlg return ret } -func (ec *executionContext) marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveString(ctx context.Context, sel ast.SelectionSet, v PrimitiveString) graphql.Marshaler { +func (ec *executionContext) marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveString(ctx context.Context, sel ast.SelectionSet, v PrimitiveString) graphql.Marshaler { return ec._PrimitiveString(ctx, sel, &v) } -func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveStringᚄ(ctx context.Context, sel ast.SelectionSet, v []PrimitiveString) graphql.Marshaler { +func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveStringᚄ(ctx context.Context, sel ast.SelectionSet, v []PrimitiveString) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup isLen1 := len(v) == 1 @@ -16105,7 +16105,7 @@ func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designs if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPrimitiveString(ctx, sel, v[i]) + ret[i] = ec.marshalNPrimitiveString2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPrimitiveString(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16125,11 +16125,11 @@ func (ec *executionContext) marshalNPrimitiveString2ᚕgithubᚗcomᚋ99designs return ret } -func (ec *executionContext) marshalNPtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v PtrToPtrOuter) graphql.Marshaler { +func (ec *executionContext) marshalNPtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v PtrToPtrOuter) graphql.Marshaler { return ec._PtrToPtrOuter(ctx, sel, &v) } -func (ec *executionContext) marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrOuter) graphql.Marshaler { +func (ec *executionContext) marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrOuter(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrOuter) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16139,11 +16139,11 @@ func (ec *executionContext) marshalNPtrToPtrOuter2ᚖgithubᚗcomᚋ99designsᚋ return ec._PtrToPtrOuter(ctx, sel, v) } -func (ec *executionContext) marshalNPtrToSliceContainer2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v PtrToSliceContainer) graphql.Marshaler { +func (ec *executionContext) marshalNPtrToSliceContainer2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v PtrToSliceContainer) graphql.Marshaler { return ec._PtrToSliceContainer(ctx, sel, &v) } -func (ec *executionContext) marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v *PtrToSliceContainer) graphql.Marshaler { +func (ec *executionContext) marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToSliceContainer(ctx context.Context, sel ast.SelectionSet, v *PtrToSliceContainer) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16153,12 +16153,12 @@ func (ec *executionContext) marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99desi return ec._PtrToSliceContainer(ctx, sel, v) } -func (ec *executionContext) unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { +func (ec *executionContext) unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSlice(ctx context.Context, v interface{}) (RecursiveInputSlice, error) { res, err := ec.unmarshalInputRecursiveInputSlice(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShapeUnion(ctx context.Context, sel ast.SelectionSet, v ShapeUnion) graphql.Marshaler { +func (ec *executionContext) marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShapeUnion(ctx context.Context, sel ast.SelectionSet, v ShapeUnion) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16168,7 +16168,7 @@ func (ec *executionContext) marshalNShapeUnion2githubᚗcomᚋ99designsᚋgqlgen return ec._ShapeUnion(ctx, sel, v) } -func (ec *executionContext) unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐSpecialInput(ctx context.Context, v interface{}) (SpecialInput, error) { +func (ec *executionContext) unmarshalNSpecialInput2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐSpecialInput(ctx context.Context, v interface{}) (SpecialInput, error) { res, err := ec.unmarshalInputSpecialInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } @@ -16305,16 +16305,16 @@ func (ec *executionContext) marshalNUUID2string(ctx context.Context, sel ast.Sel return res } -func (ec *executionContext) unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrOuter(ctx context.Context, v interface{}) (UpdatePtrToPtrOuter, error) { +func (ec *executionContext) unmarshalNUpdatePtrToPtrOuter2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrOuter(ctx context.Context, v interface{}) (UpdatePtrToPtrOuter, error) { res, err := ec.unmarshalInputUpdatePtrToPtrOuter(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNUser2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUser(ctx context.Context, sel ast.SelectionSet, v User) graphql.Marshaler { +func (ec *executionContext) marshalNUser2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUser(ctx context.Context, sel ast.SelectionSet, v User) graphql.Marshaler { return ec._User(ctx, sel, &v) } -func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*User) graphql.Marshaler { +func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUserᚄ(ctx context.Context, sel ast.SelectionSet, v []*User) graphql.Marshaler { ret := make(graphql.Array, len(v)) var wg sync.WaitGroup isLen1 := len(v) == 1 @@ -16338,7 +16338,7 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUser(ctx, sel, v[i]) + ret[i] = ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUser(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16358,7 +16358,7 @@ func (ec *executionContext) marshalNUser2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgen return ret } -func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUser(ctx context.Context, sel ast.SelectionSet, v *User) graphql.Marshaler { +func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUser(ctx context.Context, sel ast.SelectionSet, v *User) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16368,7 +16368,7 @@ func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋ return ec._User(ctx, sel, v) } -func (ec *executionContext) marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedMap(ctx context.Context, sel ast.SelectionSet, v WrappedMap) graphql.Marshaler { +func (ec *executionContext) marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedMap(ctx context.Context, sel ast.SelectionSet, v WrappedMap) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16378,13 +16378,13 @@ func (ec *executionContext) marshalNWrappedMap2githubᚗcomᚋ99designsᚋgqlgen return ec._WrappedMap(ctx, sel, v) } -func (ec *executionContext) unmarshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (otherpkg.Scalar, error) { +func (ec *executionContext) unmarshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (otherpkg.Scalar, error) { tmp, err := graphql.UnmarshalString(v) res := otherpkg.Scalar(tmp) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v otherpkg.Scalar) graphql.Marshaler { +func (ec *executionContext) marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v otherpkg.Scalar) graphql.Marshaler { res := graphql.MarshalString(string(v)) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -16394,7 +16394,7 @@ func (ec *executionContext) marshalNWrappedScalar2githubᚗcomᚋ99designsᚋgql return res } -func (ec *executionContext) marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedSlice(ctx context.Context, sel ast.SelectionSet, v WrappedSlice) graphql.Marshaler { +func (ec *executionContext) marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedSlice(ctx context.Context, sel ast.SelectionSet, v WrappedSlice) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16404,11 +16404,11 @@ func (ec *executionContext) marshalNWrappedSlice2githubᚗcomᚋ99designsᚋgqlg return ec._WrappedSlice(ctx, sel, v) } -func (ec *executionContext) marshalNWrappedStruct2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v WrappedStruct) graphql.Marshaler { +func (ec *executionContext) marshalNWrappedStruct2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v WrappedStruct) graphql.Marshaler { return ec._WrappedStruct(ctx, sel, &v) } -func (ec *executionContext) marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v *WrappedStruct) graphql.Marshaler { +func (ec *executionContext) marshalNWrappedStruct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐWrappedStruct(ctx context.Context, sel ast.SelectionSet, v *WrappedStruct) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") @@ -16675,21 +16675,21 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a return res } -func (ec *executionContext) marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐAnimal(ctx context.Context, sel ast.SelectionSet, v Animal) graphql.Marshaler { +func (ec *executionContext) marshalOAnimal2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐAnimal(ctx context.Context, sel ast.SelectionSet, v Animal) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Animal(ctx, sel, v) } -func (ec *executionContext) marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐAutobind(ctx context.Context, sel ast.SelectionSet, v *Autobind) graphql.Marshaler { +func (ec *executionContext) marshalOAutobind2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐAutobind(ctx context.Context, sel ast.SelectionSet, v *Autobind) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Autobind(ctx, sel, v) } -func (ec *executionContext) marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐBackedByInterface(ctx context.Context, sel ast.SelectionSet, v BackedByInterface) graphql.Marshaler { +func (ec *executionContext) marshalOBackedByInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐBackedByInterface(ctx context.Context, sel ast.SelectionSet, v BackedByInterface) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16727,7 +16727,7 @@ func (ec *executionContext) unmarshalOChanges2map(ctx context.Context, v interfa return v.(map[string]interface{}), nil } -func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16754,7 +16754,7 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, sel, v[i]) + ret[i] = ec.marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16768,7 +16768,7 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs return ret } -func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896ᚄ(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { +func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896ᚄ(ctx context.Context, sel ast.SelectionSet, v []*CheckIssue896) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16795,7 +16795,7 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx, sel, v[i]) + ret[i] = ec.marshalNCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16815,14 +16815,14 @@ func (ec *executionContext) marshalOCheckIssue8962ᚕᚖgithubᚗcomᚋ99designs return ret } -func (ec *executionContext) marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { +func (ec *executionContext) marshalOCheckIssue8962ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCheckIssue896(ctx context.Context, sel ast.SelectionSet, v *CheckIssue896) graphql.Marshaler { if v == nil { return graphql.Null } return ec._CheckIssue896(ctx, sel, v) } -func (ec *executionContext) marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐCircle(ctx context.Context, sel ast.SelectionSet, v *Circle) graphql.Marshaler { +func (ec *executionContext) marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCircle(ctx context.Context, sel ast.SelectionSet, v *Circle) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16844,28 +16844,28 @@ func (ec *executionContext) marshalODefaultScalarImplementation2ᚖstring(ctx co return graphql.MarshalString(*v) } -func (ec *executionContext) marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase1(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase1) graphql.Marshaler { +func (ec *executionContext) marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase1(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase1) graphql.Marshaler { if v == nil { return graphql.Null } return ec._EmbeddedCase1(ctx, sel, v) } -func (ec *executionContext) marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase2(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase2) graphql.Marshaler { +func (ec *executionContext) marshalOEmbeddedCase22ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase2(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase2) graphql.Marshaler { if v == nil { return graphql.Null } return ec._EmbeddedCase2(ctx, sel, v) } -func (ec *executionContext) marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐEmbeddedCase3(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase3) graphql.Marshaler { +func (ec *executionContext) marshalOEmbeddedCase32ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase3(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase3) graphql.Marshaler { if v == nil { return graphql.Null } return ec._EmbeddedCase3(ctx, sel, v) } -func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16892,7 +16892,7 @@ func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlge if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, sel, v[i]) + ret[i] = ec.marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16906,7 +16906,7 @@ func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlge return ret } -func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrorᚄ(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { +func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐErrorᚄ(ctx context.Context, sel ast.SelectionSet, v []*Error) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16933,7 +16933,7 @@ func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlge if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx, sel, v[i]) + ret[i] = ec.marshalNError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx, sel, v[i]) } if isLen1 { f(i) @@ -16953,14 +16953,14 @@ func (ec *executionContext) marshalOError2ᚕᚖgithubᚗcomᚋ99designsᚋgqlge return ret } -func (ec *executionContext) marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { +func (ec *executionContext) marshalOError2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐError(ctx context.Context, sel ast.SelectionSet, v *Error) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Error(ctx, sel, v) } -func (ec *executionContext) marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐErrors(ctx context.Context, sel ast.SelectionSet, v *Errors) graphql.Marshaler { +func (ec *executionContext) marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐErrors(ctx context.Context, sel ast.SelectionSet, v *Errors) graphql.Marshaler { if v == nil { return graphql.Null } @@ -16976,7 +16976,7 @@ func (ec *executionContext) marshalOFloat2float64(ctx context.Context, sel ast.S return graphql.MarshalFloat(v) } -func (ec *executionContext) unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { +func (ec *executionContext) unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { if v == nil { return nil, nil } @@ -16984,7 +16984,7 @@ func (ec *executionContext) unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99design return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputDirectives(ctx context.Context, v interface{}) (*InputDirectives, error) { +func (ec *executionContext) unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputDirectives(ctx context.Context, v interface{}) (*InputDirectives, error) { if v == nil { return nil, nil } @@ -16992,7 +16992,7 @@ func (ec *executionContext) unmarshalOInputDirectives2ᚖgithubᚗcomᚋ99design return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐInputWithEnumValue(ctx context.Context, v interface{}) (*InputWithEnumValue, error) { +func (ec *executionContext) unmarshalOInputWithEnumValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInputWithEnumValue(ctx context.Context, v interface{}) (*InputWithEnumValue, error) { if v == nil { return nil, nil } @@ -17015,14 +17015,14 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele return graphql.MarshalInt(*v) } -func (ec *executionContext) marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx context.Context, sel ast.SelectionSet, v *invalid_packagename.InvalidIdentifier) graphql.Marshaler { +func (ec *executionContext) marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx context.Context, sel ast.SelectionSet, v *invalid_packagename.InvalidIdentifier) graphql.Marshaler { if v == nil { return graphql.Null } return ec._InvalidIdentifier(ctx, sel, v) } -func (ec *executionContext) marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋintrospectionᚐIt(ctx context.Context, sel ast.SelectionSet, v *introspection1.It) graphql.Marshaler { +func (ec *executionContext) marshalOIt2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋintrospectionᚐIt(ctx context.Context, sel ast.SelectionSet, v *introspection1.It) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17043,14 +17043,14 @@ func (ec *executionContext) marshalOMapStringInterfaceType2map(ctx context.Conte return ec._MapStringInterfaceType(ctx, sel, v) } -func (ec *executionContext) marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐModelMethods(ctx context.Context, sel ast.SelectionSet, v *ModelMethods) graphql.Marshaler { +func (ec *executionContext) marshalOModelMethods2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐModelMethods(ctx context.Context, sel ast.SelectionSet, v *ModelMethods) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ModelMethods(ctx, sel, v) } -func (ec *executionContext) unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐNestedMapInput(ctx context.Context, v interface{}) (*NestedMapInput, error) { +func (ec *executionContext) unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐNestedMapInput(ctx context.Context, v interface{}) (*NestedMapInput, error) { if v == nil { return nil, nil } @@ -17058,21 +17058,21 @@ func (ec *executionContext) unmarshalONestedMapInput2ᚖgithubᚗcomᚋ99designs return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐObjectDirectives(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectives) graphql.Marshaler { +func (ec *executionContext) marshalOObjectDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐObjectDirectives(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectives) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ObjectDirectives(ctx, sel, v) } -func (ec *executionContext) marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐObjectDirectivesWithCustomGoModel(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectivesWithCustomGoModel) graphql.Marshaler { +func (ec *executionContext) marshalOObjectDirectivesWithCustomGoModel2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐObjectDirectivesWithCustomGoModel(ctx context.Context, sel ast.SelectionSet, v *ObjectDirectivesWithCustomGoModel) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ObjectDirectivesWithCustomGoModel(ctx, sel, v) } -func (ec *executionContext) unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx context.Context, v interface{}) ([][]*OuterInput, error) { +func (ec *executionContext) unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx context.Context, v interface{}) ([][]*OuterInput, error) { if v == nil { return nil, nil } @@ -17088,7 +17088,7 @@ func (ec *executionContext) unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99desig res := make([][]*OuterInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx, vSlice[i]) + res[i], err = ec.unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -17096,7 +17096,7 @@ func (ec *executionContext) unmarshalOOuterInput2ᚕᚕᚖgithubᚗcomᚋ99desig return res, nil } -func (ec *executionContext) unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx context.Context, v interface{}) ([]*OuterInput, error) { +func (ec *executionContext) unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx context.Context, v interface{}) ([]*OuterInput, error) { if v == nil { return nil, nil } @@ -17112,7 +17112,7 @@ func (ec *executionContext) unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designs res := make([]*OuterInput, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx, vSlice[i]) + res[i], err = ec.unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx, vSlice[i]) if err != nil { return nil, err } @@ -17120,7 +17120,7 @@ func (ec *executionContext) unmarshalOOuterInput2ᚕᚖgithubᚗcomᚋ99designs return res, nil } -func (ec *executionContext) unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterInput(ctx context.Context, v interface{}) (*OuterInput, error) { +func (ec *executionContext) unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterInput(ctx context.Context, v interface{}) (*OuterInput, error) { if v == nil { return nil, nil } @@ -17128,7 +17128,7 @@ func (ec *executionContext) unmarshalOOuterInput2ᚖgithubᚗcomᚋ99designsᚋg return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v [][]*OuterObject) graphql.Marshaler { +func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v [][]*OuterObject) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17155,7 +17155,7 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99design if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx, sel, v[i]) + ret[i] = ec.marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx, sel, v[i]) } if isLen1 { f(i) @@ -17169,7 +17169,7 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚕᚖgithubᚗcomᚋ99design return ret } -func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v []*OuterObject) graphql.Marshaler { +func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v []*OuterObject) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17196,7 +17196,7 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designs if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx, sel, v[i]) + ret[i] = ec.marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx, sel, v[i]) } if isLen1 { f(i) @@ -17210,77 +17210,77 @@ func (ec *executionContext) marshalOOuterObject2ᚕᚖgithubᚗcomᚋ99designs return ret } -func (ec *executionContext) marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v *OuterObject) graphql.Marshaler { +func (ec *executionContext) marshalOOuterObject2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOuterObject(ctx context.Context, sel ast.SelectionSet, v *OuterObject) graphql.Marshaler { if v == nil { return graphql.Null } return ec._OuterObject(ctx, sel, v) } -func (ec *executionContext) marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐOverlappingFields(ctx context.Context, sel ast.SelectionSet, v *OverlappingFields) graphql.Marshaler { +func (ec *executionContext) marshalOOverlappingFields2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐOverlappingFields(ctx context.Context, sel ast.SelectionSet, v *OverlappingFields) graphql.Marshaler { if v == nil { return graphql.Null } return ec._OverlappingFields(ctx, sel, v) } -func (ec *executionContext) marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPanics(ctx context.Context, sel ast.SelectionSet, v *Panics) graphql.Marshaler { +func (ec *executionContext) marshalOPanics2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPanics(ctx context.Context, sel ast.SelectionSet, v *Panics) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Panics(ctx, sel, v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } return ec._PtrToPtrInner(ctx, sel, v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v **PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v **PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ***PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ***PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ****PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ****PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *****PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *****PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ******PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v ******PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *******PtrToPtrInner) graphql.Marshaler { +func (ec *executionContext) marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx context.Context, sel ast.SelectionSet, v *******PtrToPtrInner) graphql.Marshaler { if v == nil { return graphql.Null } - return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐPtrToPtrInner(ctx, sel, *v) + return ec.marshalOPtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToPtrInner(ctx, sel, *v) } -func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSliceᚄ(ctx context.Context, v interface{}) ([]RecursiveInputSlice, error) { +func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSliceᚄ(ctx context.Context, v interface{}) ([]RecursiveInputSlice, error) { if v == nil { return nil, nil } @@ -17296,7 +17296,7 @@ func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99de res := make([]RecursiveInputSlice, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx, vSlice[i]) + res[i], err = ec.unmarshalNRecursiveInputSlice2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSlice(ctx, vSlice[i]) if err != nil { return nil, err } @@ -17304,7 +17304,7 @@ func (ec *executionContext) unmarshalORecursiveInputSlice2ᚕgithubᚗcomᚋ99de return res, nil } -func (ec *executionContext) unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐRecursiveInputSlice(ctx context.Context, v interface{}) (*RecursiveInputSlice, error) { +func (ec *executionContext) unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐRecursiveInputSlice(ctx context.Context, v interface{}) (*RecursiveInputSlice, error) { if v == nil { return nil, nil } @@ -17312,14 +17312,14 @@ func (ec *executionContext) unmarshalORecursiveInputSlice2ᚖgithubᚗcomᚋ99de return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx context.Context, sel ast.SelectionSet, v Shape) graphql.Marshaler { +func (ec *executionContext) marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx context.Context, sel ast.SelectionSet, v Shape) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Shape(ctx, sel, v) } -func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx context.Context, sel ast.SelectionSet, v []Shape) graphql.Marshaler { +func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx context.Context, sel ast.SelectionSet, v []Shape) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17346,7 +17346,7 @@ func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgen if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐShape(ctx, sel, v[i]) + ret[i] = ec.marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐShape(ctx, sel, v[i]) } if isLen1 { f(i) @@ -17360,7 +17360,7 @@ func (ec *executionContext) marshalOShape2ᚕgithubᚗcomᚋ99designsᚋgqlgen return ret } -func (ec *executionContext) marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐSlices(ctx context.Context, sel ast.SelectionSet, v *Slices) graphql.Marshaler { +func (ec *executionContext) marshalOSlices2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐSlices(ctx context.Context, sel ast.SelectionSet, v *Slices) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17481,14 +17481,14 @@ func (ec *executionContext) marshalOString2ᚖᚕstringᚄ(ctx context.Context, return ec.marshalOString2ᚕstringᚄ(ctx, sel, *v) } -func (ec *executionContext) marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐTestUnion(ctx context.Context, sel ast.SelectionSet, v TestUnion) graphql.Marshaler { +func (ec *executionContext) marshalOTestUnion2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐTestUnion(ctx context.Context, sel ast.SelectionSet, v TestUnion) graphql.Marshaler { if v == nil { return graphql.Null } return ec._TestUnion(ctx, sel, v) } -func (ec *executionContext) unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐThirdParty(ctx context.Context, v interface{}) (*ThirdParty, error) { +func (ec *executionContext) unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐThirdParty(ctx context.Context, v interface{}) (*ThirdParty, error) { if v == nil { return nil, nil } @@ -17496,7 +17496,7 @@ func (ec *executionContext) unmarshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋg return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐThirdParty(ctx context.Context, sel ast.SelectionSet, v *ThirdParty) graphql.Marshaler { +func (ec *executionContext) marshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐThirdParty(ctx context.Context, sel ast.SelectionSet, v *ThirdParty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -17518,7 +17518,7 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel return graphql.MarshalTime(*v) } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*UpdatePtrToPtrInner, error) { if v == nil { return nil, nil } @@ -17526,10 +17526,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99de return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (**UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (**UpdatePtrToPtrInner, error) { var pres *UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17538,10 +17538,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ9 return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (***UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (***UpdatePtrToPtrInner, error) { var pres **UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17550,10 +17550,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcom return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (****UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (****UpdatePtrToPtrInner, error) { var pres ***UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17562,10 +17562,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗc return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*****UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*****UpdatePtrToPtrInner, error) { var pres ****UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17574,10 +17574,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithub return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (******UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (******UpdatePtrToPtrInner, error) { var pres *****UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17586,10 +17586,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgith return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*******UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*******UpdatePtrToPtrInner, error) { var pres ******UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17598,10 +17598,10 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖg return &pres, nil } -func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (********UpdatePtrToPtrInner, error) { +func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (********UpdatePtrToPtrInner, error) { var pres *******UpdatePtrToPtrInner if v != nil { - res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐUpdatePtrToPtrInner(ctx, v) + res, err := ec.unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx, v) if err != nil { return nil, graphql.ErrorOnPath(ctx, err) } @@ -17610,21 +17610,21 @@ func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖᚖᚖᚖᚖᚖᚖ return &pres, nil } -func (ec *executionContext) marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseNil(ctx context.Context, sel ast.SelectionSet, v *VOkCaseNil) graphql.Marshaler { +func (ec *executionContext) marshalOVOkCaseNil2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐVOkCaseNil(ctx context.Context, sel ast.SelectionSet, v *VOkCaseNil) graphql.Marshaler { if v == nil { return graphql.Null } return ec._VOkCaseNil(ctx, sel, v) } -func (ec *executionContext) marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐVOkCaseValue(ctx context.Context, sel ast.SelectionSet, v *VOkCaseValue) graphql.Marshaler { +func (ec *executionContext) marshalOVOkCaseValue2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐVOkCaseValue(ctx context.Context, sel ast.SelectionSet, v *VOkCaseValue) graphql.Marshaler { if v == nil { return graphql.Null } return ec._VOkCaseValue(ctx, sel, v) } -func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidInput(ctx context.Context, v interface{}) (*ValidInput, error) { +func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐValidInput(ctx context.Context, v interface{}) (*ValidInput, error) { if v == nil { return nil, nil } @@ -17632,14 +17632,14 @@ func (ec *executionContext) unmarshalOValidInput2ᚖgithubᚗcomᚋ99designsᚋg return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚐValidType(ctx context.Context, sel ast.SelectionSet, v *ValidType) graphql.Marshaler { +func (ec *executionContext) marshalOValidType2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐValidType(ctx context.Context, sel ast.SelectionSet, v *ValidType) graphql.Marshaler { if v == nil { return graphql.Null } return ec._ValidType(ctx, sel, v) } -func (ec *executionContext) unmarshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (*otherpkg.Scalar, error) { +func (ec *executionContext) unmarshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx context.Context, v interface{}) (*otherpkg.Scalar, error) { if v == nil { return nil, nil } @@ -17648,7 +17648,7 @@ func (ec *executionContext) unmarshalOWrappedScalar2ᚖgithubᚗcomᚋ99designs return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v *otherpkg.Scalar) graphql.Marshaler { +func (ec *executionContext) marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋotherpkgᚐScalar(ctx context.Context, sel ast.SelectionSet, v *otherpkg.Scalar) graphql.Marshaler { if v == nil { return graphql.Null } diff --git a/codegen/testserver/singlefile/generated_test.go b/codegen/testserver/singlefile/generated_test.go new file mode 100644 index 00000000000..6d1dfa7e3cc --- /dev/null +++ b/codegen/testserver/singlefile/generated_test.go @@ -0,0 +1,80 @@ +//go:generate rm -f resolver.go +//go:generate go run ../../../testdata/gqlgen.go -config gqlgen.yml -stub stub.go + +package singlefile + +import ( + "context" + "reflect" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestForcedResolverFieldIsPointer(t *testing.T) { + field, ok := reflect.TypeOf((*ForcedResolverResolver)(nil)).Elem().MethodByName("Field") + require.True(t, ok) + require.Equal(t, "*singlefile.Circle", field.Type.Out(0).String()) +} + +func TestEnums(t *testing.T) { + t.Run("list of enums", func(t *testing.T) { + require.Equal(t, StatusOk, AllStatus[0]) + require.Equal(t, StatusError, AllStatus[1]) + }) + + t.Run("invalid enum values", func(t *testing.T) { + require.Equal(t, StatusOk, AllStatus[0]) + require.Equal(t, StatusError, AllStatus[1]) + }) +} + +func TestUnionFragments(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.ShapeUnion = func(ctx context.Context) (ShapeUnion, error) { + return &Circle{Radius: 32}, nil + } + + srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})) + c := client.New(srv) + + t.Run("inline fragment on union", func(t *testing.T) { + var resp struct { + ShapeUnion struct { + Radius float64 + } + } + c.MustPost(`query { + shapeUnion { + ... on Circle { + radius + } + } + } + `, &resp) + require.NotEmpty(t, resp.ShapeUnion.Radius) + }) + + t.Run("named fragment", func(t *testing.T) { + var resp struct { + ShapeUnion struct { + Radius float64 + } + } + c.MustPost(`query { + shapeUnion { + ...C + } + } + + fragment C on ShapeUnion { + ... on Circle { + radius + } + } + `, &resp) + require.NotEmpty(t, resp.ShapeUnion.Radius) + }) +} diff --git a/codegen/testserver/singlefile/gqlgen.yml b/codegen/testserver/singlefile/gqlgen.yml new file mode 100644 index 00000000000..868f5799c71 --- /dev/null +++ b/codegen/testserver/singlefile/gqlgen.yml @@ -0,0 +1,23 @@ +schema: + - "*.graphql" +skip_validation: true +exec: + filename: generated.go + package: singlefile +model: + filename: models-gen.go + package: singlefile +resolver: + filename: resolver.go + package: singlefile + type: Resolver + +autobind: + - "github.com/99designs/gqlgen/codegen/testserver" + - "github.com/99designs/gqlgen/codegen/testserver/singlefile" + - "github.com/99designs/gqlgen/codegen/testserver/singlefile/introspection" + - "github.com/99designs/gqlgen/codegen/testserver/singlefile/invalid-packagename" + +models: + Email: + model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.Email" diff --git a/codegen/testserver/input_test.go b/codegen/testserver/singlefile/input_test.go similarity index 99% rename from codegen/testserver/input_test.go rename to codegen/testserver/singlefile/input_test.go index aaba53aa668..454ee615900 100644 --- a/codegen/testserver/input_test.go +++ b/codegen/testserver/singlefile/input_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/interfaces.go b/codegen/testserver/singlefile/interfaces.go similarity index 98% rename from codegen/testserver/interfaces.go rename to codegen/testserver/singlefile/interfaces.go index 87243965a2f..9fd2ae2e2bf 100644 --- a/codegen/testserver/interfaces.go +++ b/codegen/testserver/singlefile/interfaces.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import "math" diff --git a/codegen/testserver/interfaces.graphql b/codegen/testserver/singlefile/interfaces.graphql similarity index 94% rename from codegen/testserver/interfaces.graphql rename to codegen/testserver/singlefile/interfaces.graphql index 8db93578173..1c138f595aa 100644 --- a/codegen/testserver/interfaces.graphql +++ b/codegen/testserver/singlefile/interfaces.graphql @@ -39,7 +39,7 @@ type Rectangle implements Shape { width: Float area: Float } -union ShapeUnion @goModel(model:"testserver.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model:"singlefile.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION diff --git a/codegen/testserver/interfaces_test.go b/codegen/testserver/singlefile/interfaces_test.go similarity index 98% rename from codegen/testserver/interfaces_test.go rename to codegen/testserver/singlefile/interfaces_test.go index b8ae9129b1a..4cdcecbc500 100644 --- a/codegen/testserver/interfaces_test.go +++ b/codegen/testserver/singlefile/interfaces_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" @@ -16,7 +16,7 @@ func TestInterfaces(t *testing.T) { t.Run("slices of interfaces are not pointers", func(t *testing.T) { field, ok := reflect.TypeOf((*QueryResolver)(nil)).Elem().MethodByName("Shapes") require.True(t, ok) - require.Equal(t, "[]testserver.Shape", field.Type.Out(0).String()) + require.Equal(t, "[]singlefile.Shape", field.Type.Out(0).String()) }) t.Run("models returning interfaces", func(t *testing.T) { diff --git a/codegen/testserver/singlefile/introspection/it.go b/codegen/testserver/singlefile/introspection/it.go new file mode 100644 index 00000000000..e1849681a8b --- /dev/null +++ b/codegen/testserver/singlefile/introspection/it.go @@ -0,0 +1,5 @@ +package introspection + +type It struct { + ID string +} diff --git a/codegen/testserver/introspection_test.go b/codegen/testserver/singlefile/introspection_test.go similarity index 99% rename from codegen/testserver/introspection_test.go rename to codegen/testserver/singlefile/introspection_test.go index e98dbe93e2a..f78a8202c10 100644 --- a/codegen/testserver/introspection_test.go +++ b/codegen/testserver/singlefile/introspection_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/invalid-packagename/invalid-identifier.go b/codegen/testserver/singlefile/invalid-packagename/invalid-identifier.go new file mode 100644 index 00000000000..fe0feb7165b --- /dev/null +++ b/codegen/testserver/singlefile/invalid-packagename/invalid-identifier.go @@ -0,0 +1,5 @@ +package invalid_packagename + +type InvalidIdentifier struct { + ID int +} diff --git a/codegen/testserver/singlefile/issue896.graphql b/codegen/testserver/singlefile/issue896.graphql new file mode 100644 index 00000000000..ed324f54ed9 --- /dev/null +++ b/codegen/testserver/singlefile/issue896.graphql @@ -0,0 +1,18 @@ +# This example should build stable output. If the file content starts +# alternating nondeterministically between two outputs, then see +# https://github.com/99designs/gqlgen/issues/896. + +extend schema { + query: Query + subscription: Subscription +} + +type CheckIssue896 {id: Int} + +extend type Query { + issue896a: [CheckIssue896!] # Note the "!" or lack thereof. +} + +extend type Subscription { + issue896b: [CheckIssue896] # Note the "!" or lack thereof. +} diff --git a/codegen/testserver/singlefile/loops.graphql b/codegen/testserver/singlefile/loops.graphql new file mode 100644 index 00000000000..0254ef4a0e6 --- /dev/null +++ b/codegen/testserver/singlefile/loops.graphql @@ -0,0 +1,7 @@ +type LoopA { + b: LoopB! +} + +type LoopB { + a: LoopA! +} diff --git a/codegen/testserver/singlefile/maps.graphql b/codegen/testserver/singlefile/maps.graphql new file mode 100644 index 00000000000..0fd639b0c48 --- /dev/null +++ b/codegen/testserver/singlefile/maps.graphql @@ -0,0 +1,18 @@ +extend type Query { + mapStringInterface(in: MapStringInterfaceInput): MapStringInterfaceType + mapNestedStringInterface(in: NestedMapInput): MapStringInterfaceType +} + +type MapStringInterfaceType @goModel(model: "map[string]interface{}") { + a: String + b: Int +} + +input MapStringInterfaceInput @goModel(model: "map[string]interface{}") { + a: String + b: Int +} + +input NestedMapInput { + map: MapStringInterfaceInput +} diff --git a/codegen/testserver/maps_test.go b/codegen/testserver/singlefile/maps_test.go similarity index 99% rename from codegen/testserver/maps_test.go rename to codegen/testserver/singlefile/maps_test.go index 85b964d9eb8..0c7129ae61f 100644 --- a/codegen/testserver/maps_test.go +++ b/codegen/testserver/singlefile/maps_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/middleware_test.go b/codegen/testserver/singlefile/middleware_test.go similarity index 99% rename from codegen/testserver/middleware_test.go rename to codegen/testserver/singlefile/middleware_test.go index 891280b9e21..4a8babd5ee1 100644 --- a/codegen/testserver/middleware_test.go +++ b/codegen/testserver/singlefile/middleware_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/modelmethod_test.go b/codegen/testserver/singlefile/modelmethod_test.go similarity index 98% rename from codegen/testserver/modelmethod_test.go rename to codegen/testserver/singlefile/modelmethod_test.go index 6455a8cef44..aefb14aa7b7 100644 --- a/codegen/testserver/modelmethod_test.go +++ b/codegen/testserver/singlefile/modelmethod_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/models-gen.go b/codegen/testserver/singlefile/models-gen.go similarity index 99% rename from codegen/testserver/models-gen.go rename to codegen/testserver/singlefile/models-gen.go index 9dc8fd02fb8..0bd3568b5a7 100644 --- a/codegen/testserver/models-gen.go +++ b/codegen/testserver/singlefile/models-gen.go @@ -1,6 +1,6 @@ // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. -package testserver +package singlefile import ( "fmt" diff --git a/codegen/testserver/models.go b/codegen/testserver/singlefile/models.go similarity index 98% rename from codegen/testserver/models.go rename to codegen/testserver/singlefile/models.go index 9bdc3a8d0de..556f80a62a1 100644 --- a/codegen/testserver/models.go +++ b/codegen/testserver/singlefile/models.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/mutation_with_custom_scalar.go b/codegen/testserver/singlefile/mutation_with_custom_scalar.go similarity index 96% rename from codegen/testserver/mutation_with_custom_scalar.go rename to codegen/testserver/singlefile/mutation_with_custom_scalar.go index c2de6a9049e..22c4586f29c 100644 --- a/codegen/testserver/mutation_with_custom_scalar.go +++ b/codegen/testserver/singlefile/mutation_with_custom_scalar.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "encoding/json" diff --git a/codegen/testserver/singlefile/mutation_with_custom_scalar.graphql b/codegen/testserver/singlefile/mutation_with_custom_scalar.graphql new file mode 100644 index 00000000000..e9896ddb537 --- /dev/null +++ b/codegen/testserver/singlefile/mutation_with_custom_scalar.graphql @@ -0,0 +1,13 @@ +extend type Mutation { + updateSomething(input: SpecialInput!): String! +} + +scalar Email + +input SpecialInput { + nesting: NestedInput! +} + +input NestedInput { + field: Email! +} diff --git a/codegen/testserver/mutation_with_custom_scalar_test.go b/codegen/testserver/singlefile/mutation_with_custom_scalar_test.go similarity index 98% rename from codegen/testserver/mutation_with_custom_scalar_test.go rename to codegen/testserver/singlefile/mutation_with_custom_scalar_test.go index 6cc022172c2..3290b373e26 100644 --- a/codegen/testserver/mutation_with_custom_scalar_test.go +++ b/codegen/testserver/singlefile/mutation_with_custom_scalar_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/nulls.graphql b/codegen/testserver/singlefile/nulls.graphql new file mode 100644 index 00000000000..a1fea680ce2 --- /dev/null +++ b/codegen/testserver/singlefile/nulls.graphql @@ -0,0 +1,22 @@ +extend type Query { + errorBubble: Error + errorBubbleList: [Error!] + errorList: [Error] + errors: Errors + valid: String! +} + +type Errors { + a: Error! + b: Error! + c: Error! + d: Error! + e: Error! +} + +type Error { + id: ID! + errorOnNonRequiredField: String + errorOnRequiredField: String! + nilOnRequiredField: String! +} diff --git a/codegen/testserver/nulls_test.go b/codegen/testserver/singlefile/nulls_test.go similarity index 99% rename from codegen/testserver/nulls_test.go rename to codegen/testserver/singlefile/nulls_test.go index 4822829d174..615c89ba968 100644 --- a/codegen/testserver/nulls_test.go +++ b/codegen/testserver/singlefile/nulls_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/otherpkg/model.go b/codegen/testserver/singlefile/otherpkg/model.go new file mode 100644 index 00000000000..f2cc202ede0 --- /dev/null +++ b/codegen/testserver/singlefile/otherpkg/model.go @@ -0,0 +1,12 @@ +package otherpkg + +type ( + Scalar string + Map map[string]string + Slice []string +) + +type Struct struct { + Name Scalar + Desc *Scalar +} diff --git a/codegen/testserver/singlefile/panics.graphql b/codegen/testserver/singlefile/panics.graphql new file mode 100644 index 00000000000..8895fca82c8 --- /dev/null +++ b/codegen/testserver/singlefile/panics.graphql @@ -0,0 +1,12 @@ +extend type Query { + panics: Panics +} + +type Panics { + fieldScalarMarshal: [MarshalPanic!]! + fieldFuncMarshal(u: [MarshalPanic!]!): [MarshalPanic!]! + argUnmarshal(u: [MarshalPanic!]!): Boolean! + +} + +scalar MarshalPanic diff --git a/codegen/testserver/panics_test.go b/codegen/testserver/singlefile/panics_test.go similarity index 99% rename from codegen/testserver/panics_test.go rename to codegen/testserver/singlefile/panics_test.go index 0e1cf838004..209344d79d8 100644 --- a/codegen/testserver/panics_test.go +++ b/codegen/testserver/singlefile/panics_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/primitive_objects.graphql b/codegen/testserver/singlefile/primitive_objects.graphql new file mode 100644 index 00000000000..c53702c2c89 --- /dev/null +++ b/codegen/testserver/singlefile/primitive_objects.graphql @@ -0,0 +1,15 @@ +extend type Query { + primitiveObject: [Primitive!]! + primitiveStringObject: [PrimitiveString!]! +} + +type Primitive { + value: Int! + squared: Int! +} + +type PrimitiveString { + value: String! + doubled: String! + len: Int! +} diff --git a/codegen/testserver/primitive_objects_test.go b/codegen/testserver/singlefile/primitive_objects_test.go similarity index 99% rename from codegen/testserver/primitive_objects_test.go rename to codegen/testserver/singlefile/primitive_objects_test.go index c52a8979d73..80e7a96d7af 100644 --- a/codegen/testserver/primitive_objects_test.go +++ b/codegen/testserver/singlefile/primitive_objects_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/ptr_to_ptr_input.go b/codegen/testserver/singlefile/ptr_to_ptr_input.go similarity index 95% rename from codegen/testserver/ptr_to_ptr_input.go rename to codegen/testserver/singlefile/ptr_to_ptr_input.go index a29ff466299..9fd10328ce8 100644 --- a/codegen/testserver/ptr_to_ptr_input.go +++ b/codegen/testserver/singlefile/ptr_to_ptr_input.go @@ -1,4 +1,4 @@ -package testserver +package singlefile type PtrToPtrOuter struct { Name string diff --git a/codegen/testserver/singlefile/ptr_to_ptr_input.graphql b/codegen/testserver/singlefile/ptr_to_ptr_input.graphql new file mode 100644 index 00000000000..c34b5c56fc5 --- /dev/null +++ b/codegen/testserver/singlefile/ptr_to_ptr_input.graphql @@ -0,0 +1,25 @@ +type PtrToPtrOuter { + name: String! + inner: PtrToPtrInner + stupidInner: PtrToPtrInner +} + +type PtrToPtrInner { + key: String! + value: String! +} + +input UpdatePtrToPtrOuter { + name: String + inner: UpdatePtrToPtrInner + stupidInner: UpdatePtrToPtrInner +} + +input UpdatePtrToPtrInner { + key: String + value: String +} + +extend type Mutation { + updatePtrToPtr(input: UpdatePtrToPtrOuter!): PtrToPtrOuter! +} diff --git a/codegen/testserver/ptr_to_ptr_input_test.go b/codegen/testserver/singlefile/ptr_to_ptr_input_test.go similarity index 99% rename from codegen/testserver/ptr_to_ptr_input_test.go rename to codegen/testserver/singlefile/ptr_to_ptr_input_test.go index 0e0320bbf0d..75bed1266ce 100644 --- a/codegen/testserver/ptr_to_ptr_input_test.go +++ b/codegen/testserver/singlefile/ptr_to_ptr_input_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/ptr_to_slice.go b/codegen/testserver/singlefile/ptr_to_slice.go similarity index 75% rename from codegen/testserver/ptr_to_slice.go rename to codegen/testserver/singlefile/ptr_to_slice.go index b16bf48890f..b4e46d01a19 100644 --- a/codegen/testserver/ptr_to_slice.go +++ b/codegen/testserver/singlefile/ptr_to_slice.go @@ -1,4 +1,4 @@ -package testserver +package singlefile type PtrToSliceContainer struct { PtrToSlice *[]string diff --git a/codegen/testserver/singlefile/ptr_to_slice.graphql b/codegen/testserver/singlefile/ptr_to_slice.graphql new file mode 100644 index 00000000000..b773d83d428 --- /dev/null +++ b/codegen/testserver/singlefile/ptr_to_slice.graphql @@ -0,0 +1,7 @@ +type PtrToSliceContainer { + ptrToSlice: [String!] +} + +extend type Query { + ptrToSliceContainer: PtrToSliceContainer! +} diff --git a/codegen/testserver/ptr_to_slice_test.go b/codegen/testserver/singlefile/ptr_to_slice_test.go similarity index 97% rename from codegen/testserver/ptr_to_slice_test.go rename to codegen/testserver/singlefile/ptr_to_slice_test.go index 2fe498feb8c..86fc004626d 100644 --- a/codegen/testserver/ptr_to_slice_test.go +++ b/codegen/testserver/singlefile/ptr_to_slice_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/recursive.go b/codegen/testserver/singlefile/recursive.go similarity index 77% rename from codegen/testserver/recursive.go rename to codegen/testserver/singlefile/recursive.go index a9d4ac0511e..728fbd911ae 100644 --- a/codegen/testserver/recursive.go +++ b/codegen/testserver/singlefile/recursive.go @@ -1,4 +1,4 @@ -package testserver +package singlefile type RecursiveInputSlice struct { Self []RecursiveInputSlice diff --git a/codegen/testserver/resolver.go b/codegen/testserver/singlefile/resolver.go similarity index 98% rename from codegen/testserver/resolver.go rename to codegen/testserver/singlefile/resolver.go index 6388f83ad3d..972bcd82f82 100644 --- a/codegen/testserver/resolver.go +++ b/codegen/testserver/singlefile/resolver.go @@ -1,13 +1,13 @@ -package testserver +package singlefile // THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES. import ( "context" - introspection1 "github.com/99designs/gqlgen/codegen/testserver/introspection" - invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/invalid-packagename" - "github.com/99designs/gqlgen/codegen/testserver/otherpkg" + introspection1 "github.com/99designs/gqlgen/codegen/testserver/singlefile/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/singlefile/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg" ) type Resolver struct{} diff --git a/codegen/testserver/response_extension_test.go b/codegen/testserver/singlefile/response_extension_test.go similarity index 97% rename from codegen/testserver/response_extension_test.go rename to codegen/testserver/singlefile/response_extension_test.go index 692327d0f2c..9e570dbda06 100644 --- a/codegen/testserver/response_extension_test.go +++ b/codegen/testserver/singlefile/response_extension_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/scalar_default.graphql b/codegen/testserver/singlefile/scalar_default.graphql new file mode 100644 index 00000000000..5e3a9c08fd1 --- /dev/null +++ b/codegen/testserver/singlefile/scalar_default.graphql @@ -0,0 +1,10 @@ +extend type Query { + defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation! +} + +""" This doesnt have an implementation in the typemap, so it should act like a string """ +scalar DefaultScalarImplementation + +type EmbeddedDefaultScalar { + value: DefaultScalarImplementation +} diff --git a/codegen/testserver/scalar_default_test.go b/codegen/testserver/singlefile/scalar_default_test.go similarity index 97% rename from codegen/testserver/scalar_default_test.go rename to codegen/testserver/singlefile/scalar_default_test.go index c510ca46671..556a3eccb4c 100644 --- a/codegen/testserver/scalar_default_test.go +++ b/codegen/testserver/singlefile/scalar_default_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/schema.graphql b/codegen/testserver/singlefile/schema.graphql similarity index 92% rename from codegen/testserver/schema.graphql rename to codegen/testserver/singlefile/schema.graphql index ebc67e129ec..d15b291cda0 100644 --- a/codegen/testserver/schema.graphql +++ b/codegen/testserver/singlefile/schema.graphql @@ -76,7 +76,7 @@ input OuterInput { inner: InnerInput! } -scalar ThirdParty @goModel(model: "testserver.ThirdParty") +scalar ThirdParty @goModel(model:"singlefile.ThirdParty") type OuterObject { inner: InnerObject! @@ -90,7 +90,7 @@ type ForcedResolver { field: Circle @goField(forceResolver: true) } -type EmbeddedPointer @goModel(model: "testserver.EmbeddedPointerModel") { +type EmbeddedPointer @goModel(model:"singlefile.EmbeddedPointerModel") { ID: String Title: String } diff --git a/codegen/testserver/singlefile/slices.graphql b/codegen/testserver/singlefile/slices.graphql new file mode 100644 index 00000000000..b1265c56c0b --- /dev/null +++ b/codegen/testserver/singlefile/slices.graphql @@ -0,0 +1,13 @@ +extend type Query { + slices: Slices + scalarSlice: Bytes! +} + +type Slices { + test1: [String] + test2: [String!] + test3: [String]! + test4: [String!]! +} + +scalar Bytes diff --git a/codegen/testserver/slices_test.go b/codegen/testserver/singlefile/slices_test.go similarity index 98% rename from codegen/testserver/slices_test.go rename to codegen/testserver/singlefile/slices_test.go index 783a4a49b00..b6c3e37b9ae 100644 --- a/codegen/testserver/slices_test.go +++ b/codegen/testserver/singlefile/slices_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/stub.go b/codegen/testserver/singlefile/stub.go similarity index 99% rename from codegen/testserver/stub.go rename to codegen/testserver/singlefile/stub.go index 79fde9c00ad..64145785169 100644 --- a/codegen/testserver/stub.go +++ b/codegen/testserver/singlefile/stub.go @@ -1,13 +1,13 @@ // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. -package testserver +package singlefile import ( "context" - introspection1 "github.com/99designs/gqlgen/codegen/testserver/introspection" - invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/invalid-packagename" - "github.com/99designs/gqlgen/codegen/testserver/otherpkg" + introspection1 "github.com/99designs/gqlgen/codegen/testserver/singlefile/introspection" + invalid_packagename "github.com/99designs/gqlgen/codegen/testserver/singlefile/invalid-packagename" + "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg" ) type Stub struct { diff --git a/codegen/testserver/subscription_test.go b/codegen/testserver/singlefile/subscription_test.go similarity index 99% rename from codegen/testserver/subscription_test.go rename to codegen/testserver/singlefile/subscription_test.go index d855fcc69bf..dd53ba15afa 100644 --- a/codegen/testserver/subscription_test.go +++ b/codegen/testserver/singlefile/subscription_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/thirdparty.go b/codegen/testserver/singlefile/thirdparty.go similarity index 96% rename from codegen/testserver/thirdparty.go rename to codegen/testserver/singlefile/thirdparty.go index aa3424d9060..4b19bb98987 100644 --- a/codegen/testserver/thirdparty.go +++ b/codegen/testserver/singlefile/thirdparty.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "fmt" diff --git a/codegen/testserver/time_test.go b/codegen/testserver/singlefile/time_test.go similarity index 98% rename from codegen/testserver/time_test.go rename to codegen/testserver/singlefile/time_test.go index 012625283db..473d48d95d7 100644 --- a/codegen/testserver/time_test.go +++ b/codegen/testserver/singlefile/time_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/typefallback.graphql b/codegen/testserver/singlefile/typefallback.graphql new file mode 100644 index 00000000000..e1ff1a59d7c --- /dev/null +++ b/codegen/testserver/singlefile/typefallback.graphql @@ -0,0 +1,9 @@ +extend type Query { + fallback(arg: FallbackToStringEncoding!): FallbackToStringEncoding! +} + +enum FallbackToStringEncoding { + A + B + C +} diff --git a/codegen/testserver/typefallback_test.go b/codegen/testserver/singlefile/typefallback_test.go similarity index 97% rename from codegen/testserver/typefallback_test.go rename to codegen/testserver/singlefile/typefallback_test.go index 8ebd091e9ef..13ba74449c9 100644 --- a/codegen/testserver/typefallback_test.go +++ b/codegen/testserver/singlefile/typefallback_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/useptr.graphql b/codegen/testserver/singlefile/useptr.graphql new file mode 100644 index 00000000000..23c1af0b421 --- /dev/null +++ b/codegen/testserver/singlefile/useptr.graphql @@ -0,0 +1,13 @@ +type A { + id: ID! +} + +type B { + id: ID! +} + +union TestUnion = A | B + +extend type Query { + optionalUnion: TestUnion +} diff --git a/codegen/testserver/useptr_test.go b/codegen/testserver/singlefile/useptr_test.go similarity index 92% rename from codegen/testserver/useptr_test.go rename to codegen/testserver/singlefile/useptr_test.go index ba088f49dc0..e4f2039239c 100644 --- a/codegen/testserver/useptr_test.go +++ b/codegen/testserver/singlefile/useptr_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "reflect" diff --git a/codegen/testserver/v-ok.go b/codegen/testserver/singlefile/v-ok.go similarity index 92% rename from codegen/testserver/v-ok.go rename to codegen/testserver/singlefile/v-ok.go index 5ad96bd5b8d..a4de4736d8f 100644 --- a/codegen/testserver/v-ok.go +++ b/codegen/testserver/singlefile/v-ok.go @@ -1,4 +1,4 @@ -package testserver +package singlefile // VOkCaseValue model type VOkCaseValue struct { diff --git a/codegen/testserver/singlefile/v-ok.graphql b/codegen/testserver/singlefile/v-ok.graphql new file mode 100644 index 00000000000..f0c1ae8fb3f --- /dev/null +++ b/codegen/testserver/singlefile/v-ok.graphql @@ -0,0 +1,12 @@ +extend type Query { + vOkCaseValue: VOkCaseValue + vOkCaseNil: VOkCaseNil +} + +type VOkCaseValue @goModel(model:"singlefile.VOkCaseValue") { + value: String +} + +type VOkCaseNil @goModel(model:"singlefile.VOkCaseNil") { + value: String +} diff --git a/codegen/testserver/v-ok_test.go b/codegen/testserver/singlefile/v-ok_test.go similarity index 98% rename from codegen/testserver/v-ok_test.go rename to codegen/testserver/singlefile/v-ok_test.go index fe7037b587d..8e3d10723e4 100644 --- a/codegen/testserver/v-ok_test.go +++ b/codegen/testserver/singlefile/v-ok_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/validtypes.graphql b/codegen/testserver/singlefile/validtypes.graphql new file mode 100644 index 00000000000..9912e9a9515 --- /dev/null +++ b/codegen/testserver/singlefile/validtypes.graphql @@ -0,0 +1,78 @@ +extend type Query { + validType: ValidType +} + +""" These things are all valid, but without care generate invalid go code """ +type ValidType { + differentCase: String! + different_case: String! @goField(name:"DifferentCaseOld") + validInputKeywords(input: ValidInput): Boolean! + validArgs( + break: String!, + default: String!, + func: String!, + interface: String!, + select: String!, + case: String!, + defer: String!, + go: String!, + map: String!, + struct: String!, + chan: String!, + else: String!, + goto: String!, + package: String!, + switch: String!, + const: String!, + fallthrough: String!, + if: String!, + range: String!, + type: String!, + continue: String!, + for: String!, + import: String!, + return: String!, + var: String!, + _: String!, + ): Boolean! +} + +input ValidInput { + break: String! + default: String! + func: String! + interface: String! + select: String! + case: String! + defer: String! + go: String! + map: String! + struct: String! + chan: String! + else: String! + goto: String! + package: String! + switch: String! + const: String! + fallthrough: String! + if: String! + range: String! + type: String! + continue: String! + for: String! + import: String! + return: String! + var: String! + _: String! @goField(name: "Underscore") +} + +# see https://github.com/99designs/gqlgen/issues/694 +type Content_User { + foo: String +} + +type Content_Post { + foo: String +} + +union Content_Child = Content_User | Content_Post diff --git a/codegen/testserver/validtypes_test.go b/codegen/testserver/singlefile/validtypes_test.go similarity index 97% rename from codegen/testserver/validtypes_test.go rename to codegen/testserver/singlefile/validtypes_test.go index 6ae9f1bff1c..28c5f07974c 100644 --- a/codegen/testserver/validtypes_test.go +++ b/codegen/testserver/singlefile/validtypes_test.go @@ -1,4 +1,4 @@ -package testserver +package singlefile import ( "context" diff --git a/codegen/testserver/singlefile/weird_type_cases.graphql b/codegen/testserver/singlefile/weird_type_cases.graphql new file mode 100644 index 00000000000..afd440f1d12 --- /dev/null +++ b/codegen/testserver/singlefile/weird_type_cases.graphql @@ -0,0 +1,8 @@ +# regression test for https://github.com/99designs/gqlgen/issues/583 + +type asdfIt { id: ID! } +type iIt { id: ID! } +type AIt { id: ID! } +type XXIt { id: ID! } +type AbIt { id: ID! } +type XxIt { id: ID! } diff --git a/codegen/testserver/wrapped_type.go b/codegen/testserver/singlefile/wrapped_type.go similarity index 58% rename from codegen/testserver/wrapped_type.go rename to codegen/testserver/singlefile/wrapped_type.go index d17436045b6..54554d2f2f6 100644 --- a/codegen/testserver/wrapped_type.go +++ b/codegen/testserver/singlefile/wrapped_type.go @@ -1,6 +1,6 @@ -package testserver +package singlefile -import "github.com/99designs/gqlgen/codegen/testserver/otherpkg" +import "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg" type WrappedScalar = otherpkg.Scalar type WrappedStruct otherpkg.Struct diff --git a/codegen/testserver/singlefile/wrapped_type.graphql b/codegen/testserver/singlefile/wrapped_type.graphql new file mode 100644 index 00000000000..116147432cb --- /dev/null +++ b/codegen/testserver/singlefile/wrapped_type.graphql @@ -0,0 +1,13 @@ +# regression test for https://github.com/99designs/gqlgen/issues/721 + +extend type Query { + wrappedStruct: WrappedStruct! + wrappedScalar: WrappedScalar! + wrappedMap: WrappedMap! + wrappedSlice: WrappedSlice! +} + +type WrappedStruct { name: WrappedScalar!, desc: WrappedScalar } +scalar WrappedScalar +type WrappedMap { get(key: String!): String! } +type WrappedSlice { get(idx: Int!): String! } diff --git a/codegen/testserver/wrapped_type_test.go b/codegen/testserver/singlefile/wrapped_type_test.go similarity index 96% rename from codegen/testserver/wrapped_type_test.go rename to codegen/testserver/singlefile/wrapped_type_test.go index 0841061a1d4..13a9ccab840 100644 --- a/codegen/testserver/wrapped_type_test.go +++ b/codegen/testserver/singlefile/wrapped_type_test.go @@ -1,11 +1,11 @@ -package testserver +package singlefile import ( "context" "testing" "github.com/99designs/gqlgen/client" - "github.com/99designs/gqlgen/codegen/testserver/otherpkg" + "github.com/99designs/gqlgen/codegen/testserver/singlefile/otherpkg" "github.com/99designs/gqlgen/graphql/handler" "github.com/stretchr/testify/require" ) diff --git a/codegen/testserver/v-ok.graphql b/codegen/testserver/v-ok.graphql deleted file mode 100644 index 0d1530f3636..00000000000 --- a/codegen/testserver/v-ok.graphql +++ /dev/null @@ -1,12 +0,0 @@ -extend type Query { - vOkCaseValue: VOkCaseValue - vOkCaseNil: VOkCaseNil -} - -type VOkCaseValue @goModel(model:"testserver.VOkCaseValue") { - value: String -} - -type VOkCaseNil @goModel(model:"testserver.VOkCaseNil") { - value: String -} diff --git a/docs/content/config.md b/docs/content/config.md index 6ed8c900fba..2c7e415b972 100644 --- a/docs/content/config.md +++ b/docs/content/config.md @@ -17,7 +17,8 @@ schema: # Where should the generated server code go? exec: - filename: graph/generated/generated.go + layout: follow-schema + dir: graph/generated package: generated # Enable Apollo federation support diff --git a/example/go.sum b/example/go.sum index 5ec1311ef26..4e1cadab0ec 100644 --- a/example/go.sum +++ b/example/go.sum @@ -29,6 +29,7 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= diff --git a/go.mod b/go.mod index ffd9f7234dd..76cf01c2a1f 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/gorilla/websocket v1.4.2 github.com/hashicorp/golang-lru v0.5.0 + github.com/kevinmbeaulieu/eq-go v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 github.com/matryer/moq v0.2.3 github.com/mattn/go-colorable v0.1.4 diff --git a/go.sum b/go.sum index e0c714883e9..457b6c1549a 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/kevinmbeaulieu/eq-go v1.0.0 h1:AQgYHURDOmnVJ62jnEk0W/7yFKEn+Lv8RHN6t7mB0Zo= +github.com/kevinmbeaulieu/eq-go v1.0.0/go.mod h1:G3S8ajA56gKBZm4UB9AOyoOS37JO3roToPzKNM8dtdM= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= diff --git a/testdata/gqlgen.go b/testdata/gqlgen.go index e22451c6f98..e52780baf5d 100644 --- a/testdata/gqlgen.go +++ b/testdata/gqlgen.go @@ -8,22 +8,28 @@ import ( "os" "time" - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/api" "github.com/99designs/gqlgen/codegen/config" + "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/plugin/stubgen" ) func main() { stub := flag.String("stub", "", "name of stub file to generate") + cfgPath := flag.String("config", "", "path to config file (use default if omitted)") flag.Parse() log.SetOutput(ioutil.Discard) start := graphql.Now() - cfg, err := config.LoadConfigFromDefaultLocations() + var cfg *config.Config + var err error + if cfgPath != nil && *cfgPath != "" { + cfg, err = config.LoadConfig(*cfgPath) + } else { + cfg, err = config.LoadConfigFromDefaultLocations() + } if err != nil { fmt.Fprintln(os.Stderr, "failed to load config", err.Error()) os.Exit(2) From 8b9737179d3ba08405ab6422fb8c4883dd8e720c Mon Sep 17 00:00:00 2001 From: John Maguire Date: Fri, 15 Oct 2021 07:37:50 -0400 Subject: [PATCH 142/146] Update directives doc page (#1660) * Update directives doc page * Add back one beloved piece of jargon Co-authored-by: Steve Coffman --- docs/content/reference/directives.md | 46 +++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/content/reference/directives.md b/docs/content/reference/directives.md index 44a485f1880..7cee2d1ae0e 100644 --- a/docs/content/reference/directives.md +++ b/docs/content/reference/directives.md @@ -5,13 +5,22 @@ linkTitle: Schema Directives menu: { main: { parent: 'reference', weight: 10 } } --- -Directives are a bit like annotations in any other language. They give you a way to specify some behaviour without directly binding to the implementation. This can be really useful for cross cutting concerns like permission checks. +Directives act a bit like annotations, decorators, or HTTP middleware. They give you a way to specify some behaviour based on a field or argument in a generic and reusable way. This can be really useful for cross-cutting concerns like permission checks which can be applied broadly across your API. **Note**: The current directives implementation is still fairly limited, and is designed to cover the most common "field middleware" case. -## Declare it in the schema +## Restricting access based on user role -Directives are declared in your schema, along with all your other types. Lets define a @hasRole directive: +For example, we might want to restrict which mutations or queries a client can make based on the authenticated user's role: +```graphql +type Mutation { + deleteUser(userID: ID!): Bool @hasRole(role: ADMIN) +} +``` + +### Declare it in the schema + +Before we can use a directive we must declare it in the schema. Here's how we would define the `@hasRole` directive: ```graphql directive @hasRole(role: Role!) on FIELD_DEFINITION @@ -22,7 +31,7 @@ enum Role { } ``` -When we next run go generate, gqlgen will add this directive to the DirectiveRoot +Next, run `go generate` and gqlgen will add the directive to the DirectiveRoot: ```go type DirectiveRoot struct { HasRole func(ctx context.Context, obj interface{}, next graphql.Resolver, role Role) (res interface{}, err error) @@ -31,31 +40,22 @@ type DirectiveRoot struct { The arguments are: - *ctx*: the parent context - - *obj*: the object containing the value this was applied to, eg: - - for field definition directives, the object/input object that contains the field - - for argument directives, a map containing all arguments + - *obj*: the object containing the value this was applied to, e.g.: + - for field definition directives (`FIELD_DEFINITION`), the object/input object that contains the field + - for argument directives (`ARGUMENT_DEFINITION`), a map containing all arguments - *next*: the next directive in the directive chain, or the field resolver. This should be called to get the - value of the field/argument/whatever. You can block access to the field by not calling next for permission - checks etc. - - *...args*: Any args to the directive will be passed in too. - -## Use it in the schema - -We can call this on any field definition now: -```graphql -type Mutation { - deleteUser(userID: ID!): Bool @hasRole(role: ADMIN) -} -``` + value of the field/argument/whatever. You can block access to the field by not calling `next(ctx)` + after checking whether a user has a required permission, for example. + - *...args*: finally, any args defined in the directive schema definition are passed in ## Implement the directive -Finally, we need to implement the directive, and pass it in when starting the server: +Now we must implement the directive. The directive function is assigned to the Config object before registering the GraphQL handler. ```go package main func main() { - c := Config{ Resolvers: &resolvers{} } + c := generated.Config{ Resolvers: &resolvers{} } c.Directives.HasRole = func(ctx context.Context, obj interface{}, next graphql.Resolver, role Role) (interface{}, error) { if !getCurrentUser(ctx).HasRole(role) { // block calling the next resolver @@ -66,7 +66,9 @@ func main() { return next(ctx) } - http.Handle("/query", handler.GraphQL(todo.NewExecutableSchema(c), )) + http.Handle("/query", handler.NewDefaultServer(generated.NewExecutableSchema(c), )) log.Fatal(http.ListenAndServe(":8081", nil)) } ``` + +That's it! You can now apply the `@hasRole` directive to any mutation or query in your schema. From db4b5eb71b4959c3f8b68086b753ec3c01c5b4c9 Mon Sep 17 00:00:00 2001 From: wilhelm Date: Sat, 16 Oct 2021 13:00:42 +1100 Subject: [PATCH 143/146] Merge Inline Fragment Nested Interface Fields (#1663) --- .../followschema/interfaces.generated.go | 181 +++++++++++++ codegen/testserver/followschema/interfaces.go | 3 + .../followschema/interfaces.graphql | 12 +- .../followschema/interfaces_test.go | 56 ++++ codegen/testserver/followschema/models-gen.go | 5 + .../followschema/prelude.generated.go | 15 ++ .../followschema/root!.generated.go | 57 +++- codegen/testserver/singlefile/generated.go | 253 +++++++++++++++++- codegen/testserver/singlefile/interfaces.go | 3 + .../testserver/singlefile/interfaces.graphql | 12 +- .../testserver/singlefile/interfaces_test.go | 56 ++++ codegen/testserver/singlefile/models-gen.go | 5 + graphql/executable_schema.go | 22 +- 13 files changed, 660 insertions(+), 20 deletions(-) diff --git a/codegen/testserver/followschema/interfaces.generated.go b/codegen/testserver/followschema/interfaces.generated.go index 5d139fc5d65..c5e71e7b506 100644 --- a/codegen/testserver/followschema/interfaces.generated.go +++ b/codegen/testserver/followschema/interfaces.generated.go @@ -249,6 +249,35 @@ func (ec *executionContext) _Circle_area(ctx context.Context, field graphql.Coll return ec.marshalOFloat2float64(ctx, field.Selections, res) } +func (ec *executionContext) _Circle_coordinates(ctx context.Context, field graphql.CollectedField, obj *Circle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Circle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Coordinates, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Coordinates) + fc.Result = res + return ec.marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCoordinates(ctx, field.Selections, res) +} + func (ec *executionContext) _ConcreteNodeA_id(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -409,6 +438,70 @@ func (ec *executionContext) _ConcreteNodeInterface_child(ctx context.Context, fi return ec.marshalNNode2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐNode(ctx, field.Selections, res) } +func (ec *executionContext) _Coordinates_x(ctx context.Context, field graphql.CollectedField, obj *Coordinates) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Coordinates", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.X, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Coordinates_y(ctx context.Context, field graphql.CollectedField, obj *Coordinates) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Coordinates", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Y, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + func (ec *executionContext) _Dog_species(ctx context.Context, field graphql.CollectedField, obj *Dog) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -560,6 +653,35 @@ func (ec *executionContext) _Rectangle_area(ctx context.Context, field graphql.C return ec.marshalOFloat2float64(ctx, field.Selections, res) } +func (ec *executionContext) _Rectangle_coordinates(ctx context.Context, field graphql.CollectedField, obj *Rectangle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Rectangle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Coordinates, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Coordinates) + fc.Result = res + return ec.marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCoordinates(ctx, field.Selections, res) +} + // endregion **************************** field.gotpl ***************************** // region **************************** input.gotpl ***************************** @@ -778,6 +900,13 @@ func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, o out.Values[i] = innerFunc(ctx) + case "coordinates": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_coordinates(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -881,6 +1010,47 @@ func (ec *executionContext) _ConcreteNodeInterface(ctx context.Context, sel ast. return out } +var coordinatesImplementors = []string{"Coordinates"} + +func (ec *executionContext) _Coordinates(ctx context.Context, sel ast.SelectionSet, obj *Coordinates) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, coordinatesImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Coordinates") + case "x": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Coordinates_x(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "y": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Coordinates_y(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var dogImplementors = []string{"Dog", "Animal"} func (ec *executionContext) _Dog(ctx context.Context, sel ast.SelectionSet, obj *Dog) graphql.Marshaler { @@ -953,6 +1123,13 @@ func (ec *executionContext) _Rectangle(ctx context.Context, sel ast.SelectionSet out.Values[i] = innerFunc(ctx) + case "coordinates": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_coordinates(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1009,6 +1186,10 @@ func (ec *executionContext) marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._Circle(ctx, sel, v) } +func (ec *executionContext) marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐCoordinates(ctx context.Context, sel ast.SelectionSet, v Coordinates) graphql.Marshaler { + return ec._Coordinates(ctx, sel, &v) +} + func (ec *executionContext) marshalOShape2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐShape(ctx context.Context, sel ast.SelectionSet, v Shape) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/codegen/testserver/followschema/interfaces.go b/codegen/testserver/followschema/interfaces.go index 39d908e4c24..7f06298b714 100644 --- a/codegen/testserver/followschema/interfaces.go +++ b/codegen/testserver/followschema/interfaces.go @@ -14,6 +14,7 @@ type ShapeUnion interface { type Circle struct { Radius float64 + Coordinates } func (c *Circle) Area() float64 { @@ -25,6 +26,7 @@ func (c *Circle) isShape() {} type Rectangle struct { Length, Width float64 + Coordinates } func (r *Rectangle) Area() float64 { @@ -79,6 +81,7 @@ type BackedByInterfaceImpl struct { func (b *BackedByInterfaceImpl) ThisShouldBind() string { return b.Value } + func (b *BackedByInterfaceImpl) ThisShouldBindWithError() (string, error) { return b.Value, b.Error } diff --git a/codegen/testserver/followschema/interfaces.graphql b/codegen/testserver/followschema/interfaces.graphql index 4dc320f9a29..af5c17170c3 100644 --- a/codegen/testserver/followschema/interfaces.graphql +++ b/codegen/testserver/followschema/interfaces.graphql @@ -27,19 +27,27 @@ type Cat implements Animal { catBreed: String! } +type Coordinates { + x: Float! + y: Float! +} interface Shape { area: Float + coordinates: Coordinates } + type Circle implements Shape { radius: Float area: Float + coordinates: Coordinates } type Rectangle implements Shape { length: Float width: Float area: Float + coordinates: Coordinates } -union ShapeUnion @goModel(model:"followschema.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model: "followschema.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION @@ -55,7 +63,7 @@ type ConcreteNodeA implements Node { name: String! } -""" Implements the Node interface with another interface """ +" Implements the Node interface with another interface " type ConcreteNodeInterface implements Node { id: ID! child: Node! diff --git a/codegen/testserver/followschema/interfaces_test.go b/codegen/testserver/followschema/interfaces_test.go index c2fae2ff9ad..d67c7da59f4 100644 --- a/codegen/testserver/followschema/interfaces_test.go +++ b/codegen/testserver/followschema/interfaces_test.go @@ -197,4 +197,60 @@ func TestInterfaces(t *testing.T) { require.Equal(t, "CNII", resp.Node.ID) require.Equal(t, "Child", resp.Node.Child.ID) }) + + t.Run("interface implementors should return merged base fields", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Shapes = func(ctx context.Context) (shapes []Shape, err error) { + return []Shape{ + &Rectangle{ + Coordinates: Coordinates{ + X: -1, + Y: -1, + }, + }, + &Circle{ + Coordinates: Coordinates{ + X: 1, + Y: 1, + }, + }, + }, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + var resp struct { + Shapes []struct { + Coordinates struct { + X float64 + Y float64 + } + } + } + + c.MustPost(` + { + shapes { + coordinates { + x + } + ... on Rectangle { + coordinates { + x + } + } + ... on Circle { + coordinates { + y + } + } + } + } + `, &resp) + + require.Equal(t, 2, len(resp.Shapes)) + require.Equal(t, float64(-1), resp.Shapes[0].Coordinates.X) + require.Equal(t, float64(0), resp.Shapes[0].Coordinates.Y) + require.Equal(t, float64(1), resp.Shapes[1].Coordinates.X) + require.Equal(t, float64(1), resp.Shapes[1].Coordinates.Y) + }) } diff --git a/codegen/testserver/followschema/models-gen.go b/codegen/testserver/followschema/models-gen.go index 7e24f2aa394..6ddd209366c 100644 --- a/codegen/testserver/followschema/models-gen.go +++ b/codegen/testserver/followschema/models-gen.go @@ -64,6 +64,11 @@ type ContentUser struct { func (ContentUser) IsContentChild() {} +type Coordinates struct { + X float64 `json:"x"` + Y float64 `json:"y"` +} + type DefaultInput struct { FalsyBoolean *bool `json:"falsyBoolean"` TruthyBoolean *bool `json:"truthyBoolean"` diff --git a/codegen/testserver/followschema/prelude.generated.go b/codegen/testserver/followschema/prelude.generated.go index 2a306d304e2..0109bde4739 100644 --- a/codegen/testserver/followschema/prelude.generated.go +++ b/codegen/testserver/followschema/prelude.generated.go @@ -1511,6 +1511,21 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { + res, err := graphql.UnmarshalFloat(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + res := graphql.MarshalFloat(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + func (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) { res, err := graphql.UnmarshalIntID(v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/codegen/testserver/followschema/root!.generated.go b/codegen/testserver/followschema/root!.generated.go index c5bd0aeb35e..69079b433cf 100644 --- a/codegen/testserver/followschema/root!.generated.go +++ b/codegen/testserver/followschema/root!.generated.go @@ -102,8 +102,9 @@ type ComplexityRoot struct { } Circle struct { - Area func(childComplexity int) int - Radius func(childComplexity int) int + Area func(childComplexity int) int + Coordinates func(childComplexity int) int + Radius func(childComplexity int) int } ConcreteNodeA struct { @@ -125,6 +126,11 @@ type ComplexityRoot struct { Foo func(childComplexity int) int } + Coordinates struct { + X func(childComplexity int) int + Y func(childComplexity int) int + } + DefaultParametersMirror struct { FalsyBoolean func(childComplexity int) int TruthyBoolean func(childComplexity int) int @@ -333,9 +339,10 @@ type ComplexityRoot struct { } Rectangle struct { - Area func(childComplexity int) int - Length func(childComplexity int) int - Width func(childComplexity int) int + Area func(childComplexity int) int + Coordinates func(childComplexity int) int + Length func(childComplexity int) int + Width func(childComplexity int) int } Slices struct { @@ -534,6 +541,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Circle.Area(childComplexity), true + case "Circle.coordinates": + if e.complexity.Circle.Coordinates == nil { + break + } + + return e.complexity.Circle.Coordinates(childComplexity), true + case "Circle.radius": if e.complexity.Circle.Radius == nil { break @@ -590,6 +604,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Content_User.Foo(childComplexity), true + case "Coordinates.x": + if e.complexity.Coordinates.X == nil { + break + } + + return e.complexity.Coordinates.X(childComplexity), true + + case "Coordinates.y": + if e.complexity.Coordinates.Y == nil { + break + } + + return e.complexity.Coordinates.Y(childComplexity), true + case "DefaultParametersMirror.falsyBoolean": if e.complexity.DefaultParametersMirror.FalsyBoolean == nil { break @@ -1536,6 +1564,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Rectangle.Area(childComplexity), true + case "Rectangle.coordinates": + if e.complexity.Rectangle.Coordinates == nil { + break + } + + return e.complexity.Rectangle.Coordinates(childComplexity), true + case "Rectangle.length": if e.complexity.Rectangle.Length == nil { break @@ -2021,19 +2056,27 @@ type Cat implements Animal { catBreed: String! } +type Coordinates { + x: Float! + y: Float! +} interface Shape { area: Float + coordinates: Coordinates } + type Circle implements Shape { radius: Float area: Float + coordinates: Coordinates } type Rectangle implements Shape { length: Float width: Float area: Float + coordinates: Coordinates } -union ShapeUnion @goModel(model:"followschema.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model: "followschema.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION @@ -2049,7 +2092,7 @@ type ConcreteNodeA implements Node { name: String! } -""" Implements the Node interface with another interface """ +" Implements the Node interface with another interface " type ConcreteNodeInterface implements Node { id: ID! child: Node! diff --git a/codegen/testserver/singlefile/generated.go b/codegen/testserver/singlefile/generated.go index 768095f2535..75724eaecbd 100644 --- a/codegen/testserver/singlefile/generated.go +++ b/codegen/testserver/singlefile/generated.go @@ -113,8 +113,9 @@ type ComplexityRoot struct { } Circle struct { - Area func(childComplexity int) int - Radius func(childComplexity int) int + Area func(childComplexity int) int + Coordinates func(childComplexity int) int + Radius func(childComplexity int) int } ConcreteNodeA struct { @@ -136,6 +137,11 @@ type ComplexityRoot struct { Foo func(childComplexity int) int } + Coordinates struct { + X func(childComplexity int) int + Y func(childComplexity int) int + } + DefaultParametersMirror struct { FalsyBoolean func(childComplexity int) int TruthyBoolean func(childComplexity int) int @@ -344,9 +350,10 @@ type ComplexityRoot struct { } Rectangle struct { - Area func(childComplexity int) int - Length func(childComplexity int) int - Width func(childComplexity int) int + Area func(childComplexity int) int + Coordinates func(childComplexity int) int + Length func(childComplexity int) int + Width func(childComplexity int) int } Slices struct { @@ -664,6 +671,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Circle.Area(childComplexity), true + case "Circle.coordinates": + if e.complexity.Circle.Coordinates == nil { + break + } + + return e.complexity.Circle.Coordinates(childComplexity), true + case "Circle.radius": if e.complexity.Circle.Radius == nil { break @@ -720,6 +734,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Content_User.Foo(childComplexity), true + case "Coordinates.x": + if e.complexity.Coordinates.X == nil { + break + } + + return e.complexity.Coordinates.X(childComplexity), true + + case "Coordinates.y": + if e.complexity.Coordinates.Y == nil { + break + } + + return e.complexity.Coordinates.Y(childComplexity), true + case "DefaultParametersMirror.falsyBoolean": if e.complexity.DefaultParametersMirror.FalsyBoolean == nil { break @@ -1666,6 +1694,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Rectangle.Area(childComplexity), true + case "Rectangle.coordinates": + if e.complexity.Rectangle.Coordinates == nil { + break + } + + return e.complexity.Rectangle.Coordinates(childComplexity), true + case "Rectangle.length": if e.complexity.Rectangle.Length == nil { break @@ -2151,19 +2186,27 @@ type Cat implements Animal { catBreed: String! } +type Coordinates { + x: Float! + y: Float! +} interface Shape { area: Float + coordinates: Coordinates } + type Circle implements Shape { radius: Float area: Float + coordinates: Coordinates } type Rectangle implements Shape { length: Float width: Float area: Float + coordinates: Coordinates } -union ShapeUnion @goModel(model:"singlefile.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model: "singlefile.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION @@ -2179,7 +2222,7 @@ type ConcreteNodeA implements Node { name: String! } -""" Implements the Node interface with another interface """ +" Implements the Node interface with another interface " type ConcreteNodeInterface implements Node { id: ID! child: Node! @@ -4217,6 +4260,35 @@ func (ec *executionContext) _Circle_area(ctx context.Context, field graphql.Coll return ec.marshalOFloat2float64(ctx, field.Selections, res) } +func (ec *executionContext) _Circle_coordinates(ctx context.Context, field graphql.CollectedField, obj *Circle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Circle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Coordinates, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Coordinates) + fc.Result = res + return ec.marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCoordinates(ctx, field.Selections, res) +} + func (ec *executionContext) _ConcreteNodeA_id(ctx context.Context, field graphql.CollectedField, obj *ConcreteNodeA) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -4435,6 +4507,70 @@ func (ec *executionContext) _Content_User_foo(ctx context.Context, field graphql return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } +func (ec *executionContext) _Coordinates_x(ctx context.Context, field graphql.CollectedField, obj *Coordinates) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Coordinates", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.X, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Coordinates_y(ctx context.Context, field graphql.CollectedField, obj *Coordinates) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Coordinates", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Y, nil + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + func (ec *executionContext) _DefaultParametersMirror_falsyBoolean(ctx context.Context, field graphql.CollectedField, obj *DefaultParametersMirror) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -8676,6 +8812,35 @@ func (ec *executionContext) _Rectangle_area(ctx context.Context, field graphql.C return ec.marshalOFloat2float64(ctx, field.Selections, res) } +func (ec *executionContext) _Rectangle_coordinates(ctx context.Context, field graphql.CollectedField, obj *Rectangle) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Rectangle", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, obj, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Coordinates, nil + }) + + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Coordinates) + fc.Result = res + return ec.marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCoordinates(ctx, field.Selections, res) +} + func (ec *executionContext) _Slices_test1(ctx context.Context, field graphql.CollectedField, obj *Slices) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -11957,6 +12122,13 @@ func (ec *executionContext) _Circle(ctx context.Context, sel ast.SelectionSet, o out.Values[i] = innerFunc(ctx) + case "coordinates": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Circle_coordinates(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -12116,6 +12288,47 @@ func (ec *executionContext) _Content_User(ctx context.Context, sel ast.Selection return out } +var coordinatesImplementors = []string{"Coordinates"} + +func (ec *executionContext) _Coordinates(ctx context.Context, sel ast.SelectionSet, obj *Coordinates) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, coordinatesImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Coordinates") + case "x": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Coordinates_x(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "y": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Coordinates_y(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var defaultParametersMirrorImplementors = []string{"DefaultParametersMirror"} func (ec *executionContext) _DefaultParametersMirror(ctx context.Context, sel ast.SelectionSet, obj *DefaultParametersMirror) graphql.Marshaler { @@ -14777,6 +14990,13 @@ func (ec *executionContext) _Rectangle(ctx context.Context, sel ast.SelectionSet out.Values[i] = innerFunc(ctx) + case "coordinates": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Rectangle_coordinates(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -15843,6 +16063,21 @@ func (ec *executionContext) marshalNFallbackToStringEncoding2githubᚗcomᚋ99de return res } +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { + res, err := graphql.UnmarshalFloat(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + res := graphql.MarshalFloat(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return res +} + func (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) { res, err := graphql.UnmarshalIntID(v) return res, graphql.ErrorOnPath(ctx, err) @@ -16829,6 +17064,10 @@ func (ec *executionContext) marshalOCircle2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._Circle(ctx, sel, v) } +func (ec *executionContext) marshalOCoordinates2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐCoordinates(ctx context.Context, sel ast.SelectionSet, v Coordinates) graphql.Marshaler { + return ec._Coordinates(ctx, sel, &v) +} + func (ec *executionContext) unmarshalODefaultScalarImplementation2ᚖstring(ctx context.Context, v interface{}) (*string, error) { if v == nil { return nil, nil diff --git a/codegen/testserver/singlefile/interfaces.go b/codegen/testserver/singlefile/interfaces.go index 9fd2ae2e2bf..1115fabdbac 100644 --- a/codegen/testserver/singlefile/interfaces.go +++ b/codegen/testserver/singlefile/interfaces.go @@ -14,6 +14,7 @@ type ShapeUnion interface { type Circle struct { Radius float64 + Coordinates } func (c *Circle) Area() float64 { @@ -25,6 +26,7 @@ func (c *Circle) isShape() {} type Rectangle struct { Length, Width float64 + Coordinates } func (r *Rectangle) Area() float64 { @@ -79,6 +81,7 @@ type BackedByInterfaceImpl struct { func (b *BackedByInterfaceImpl) ThisShouldBind() string { return b.Value } + func (b *BackedByInterfaceImpl) ThisShouldBindWithError() (string, error) { return b.Value, b.Error } diff --git a/codegen/testserver/singlefile/interfaces.graphql b/codegen/testserver/singlefile/interfaces.graphql index 1c138f595aa..4b6480be83c 100644 --- a/codegen/testserver/singlefile/interfaces.graphql +++ b/codegen/testserver/singlefile/interfaces.graphql @@ -27,19 +27,27 @@ type Cat implements Animal { catBreed: String! } +type Coordinates { + x: Float! + y: Float! +} interface Shape { area: Float + coordinates: Coordinates } + type Circle implements Shape { radius: Float area: Float + coordinates: Coordinates } type Rectangle implements Shape { length: Float width: Float area: Float + coordinates: Coordinates } -union ShapeUnion @goModel(model:"singlefile.ShapeUnion") = Circle | Rectangle +union ShapeUnion @goModel(model: "singlefile.ShapeUnion") = Circle | Rectangle directive @makeNil on FIELD_DEFINITION directive @makeTypedNil on FIELD_DEFINITION @@ -55,7 +63,7 @@ type ConcreteNodeA implements Node { name: String! } -""" Implements the Node interface with another interface """ +" Implements the Node interface with another interface " type ConcreteNodeInterface implements Node { id: ID! child: Node! diff --git a/codegen/testserver/singlefile/interfaces_test.go b/codegen/testserver/singlefile/interfaces_test.go index 4cdcecbc500..6093a8d7024 100644 --- a/codegen/testserver/singlefile/interfaces_test.go +++ b/codegen/testserver/singlefile/interfaces_test.go @@ -197,4 +197,60 @@ func TestInterfaces(t *testing.T) { require.Equal(t, "CNII", resp.Node.ID) require.Equal(t, "Child", resp.Node.Child.ID) }) + + t.Run("interface implementors should return merged base fields", func(t *testing.T) { + resolvers := &Stub{} + resolvers.QueryResolver.Shapes = func(ctx context.Context) (shapes []Shape, err error) { + return []Shape{ + &Rectangle{ + Coordinates: Coordinates{ + X: -1, + Y: -1, + }, + }, + &Circle{ + Coordinates: Coordinates{ + X: 1, + Y: 1, + }, + }, + }, nil + } + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + var resp struct { + Shapes []struct { + Coordinates struct { + X float64 + Y float64 + } + } + } + + c.MustPost(` + { + shapes { + coordinates { + x + } + ... on Rectangle { + coordinates { + x + } + } + ... on Circle { + coordinates { + y + } + } + } + } + `, &resp) + + require.Equal(t, 2, len(resp.Shapes)) + require.Equal(t, float64(-1), resp.Shapes[0].Coordinates.X) + require.Equal(t, float64(0), resp.Shapes[0].Coordinates.Y) + require.Equal(t, float64(1), resp.Shapes[1].Coordinates.X) + require.Equal(t, float64(1), resp.Shapes[1].Coordinates.Y) + }) } diff --git a/codegen/testserver/singlefile/models-gen.go b/codegen/testserver/singlefile/models-gen.go index 0bd3568b5a7..6e59b20b8b8 100644 --- a/codegen/testserver/singlefile/models-gen.go +++ b/codegen/testserver/singlefile/models-gen.go @@ -64,6 +64,11 @@ type ContentUser struct { func (ContentUser) IsContentChild() {} +type Coordinates struct { + X float64 `json:"x"` + Y float64 `json:"y"` +} + type DefaultInput struct { FalsyBoolean *bool `json:"falsyBoolean"` TruthyBoolean *bool `json:"truthyBoolean"` diff --git a/graphql/executable_schema.go b/graphql/executable_schema.go index 012baafff48..541b65fbeea 100644 --- a/graphql/executable_schema.go +++ b/graphql/executable_schema.go @@ -37,6 +37,7 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies }) f.Selections = append(f.Selections, sel.SelectionSet...) + case *ast.InlineFragment: if !shouldIncludeNode(sel.Directives, reqCtx.Variables) { continue @@ -73,6 +74,7 @@ func collectFields(reqCtx *OperationContext, selSet ast.SelectionSet, satisfies f := getOrCreateAndAppendField(&groupedFields, childField.Name, childField.Alias, childField.ObjectDefinition, func() CollectedField { return childField }) f.Selections = append(f.Selections, childField.Selections...) } + default: panic(fmt.Errorf("unsupported %T", sel)) } @@ -98,8 +100,24 @@ func instanceOf(val string, satisfies []string) bool { func getOrCreateAndAppendField(c *[]CollectedField, name string, alias string, objectDefinition *ast.Definition, creator func() CollectedField) *CollectedField { for i, cf := range *c { - if cf.Name == name && cf.Alias == alias && (cf.ObjectDefinition == objectDefinition || (cf.ObjectDefinition != nil && objectDefinition != nil && cf.ObjectDefinition.Name == objectDefinition.Name)) { - return &(*c)[i] + if cf.Name == name && cf.Alias == alias { + if cf.ObjectDefinition == objectDefinition { + return &(*c)[i] + } + + if cf.ObjectDefinition == nil || objectDefinition == nil { + continue + } + + if cf.ObjectDefinition.Name == objectDefinition.Name { + return &(*c)[i] + } + + for _, ifc := range objectDefinition.Interfaces { + if ifc == cf.ObjectDefinition.Name { + return &(*c)[i] + } + } } } From a626d9b47e54e4439976d3ad333dfefe4c2710d6 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Tue, 19 Oct 2021 01:45:14 -0400 Subject: [PATCH 144/146] Add ICMP to common initialisms (#1666) --- codegen/templates/templates.go | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen/templates/templates.go b/codegen/templates/templates.go index ca8f923c1f3..2358452af27 100644 --- a/codegen/templates/templates.go +++ b/codegen/templates/templates.go @@ -459,6 +459,7 @@ var commonInitialisms = map[string]bool{ "HTML": true, "HTTP": true, "HTTPS": true, + "ICMP": true, "ID": true, "IP": true, "JSON": true, From 488a31fc12979b825b166cf6f317f4b27ee456a0 Mon Sep 17 00:00:00 2001 From: Jonathan Duck Date: Tue, 19 Oct 2021 04:23:27 -0700 Subject: [PATCH 145/146] ContextMarshaler (#1652) * Add interface and detection for ContextMarshaler * Test error on float marshalling * Revert prettier changes * Rename context test * Only use the erroring float printer * Test that context is passed to marshal functions * Update scalar docs to include the context * Generate the examples * Move ContextMarshaller test code to new followschema * Resolve conflict a little more Signed-off-by: Steve Coffman * Replicate sclar test for singlefile Co-authored-by: Steve Coffman --- .gitignore | 1 + codegen/config/binder.go | 49 ++- codegen/config/config.go | 2 +- codegen/testserver/followschema/gqlgen.yml | 2 + .../followschema/prelude.generated.go | 26 +- codegen/testserver/followschema/resolver.go | 12 + .../followschema/root!.generated.go | 33 +++ .../followschema/scalar_context.generated.go | 83 ++++++ .../testserver/followschema/scalar_context.go | 36 +++ .../followschema/scalar_context.graphql | 8 + .../followschema/scalar_context_test.go | 52 ++++ .../followschema/scalar_default.generated.go | 3 +- .../followschema/schema.generated.go | 174 ++++++++++- codegen/testserver/followschema/stub.go | 12 + .../followschema/wrapped_type.generated.go | 3 +- codegen/testserver/gqlgen.yml | 19 -- codegen/testserver/singlefile/generated.go | 280 +++++++++++++++++- codegen/testserver/singlefile/gqlgen.yml | 2 + codegen/testserver/singlefile/resolver.go | 12 + .../testserver/singlefile/scalar_context.go | 36 +++ .../singlefile/scalar_context.graphql | 8 + .../singlefile/scalar_context_test.go | 52 ++++ codegen/testserver/singlefile/stub.go | 12 + codegen/type.gotpl | 40 ++- docs/content/reference/scalars.md | 53 +++- example/chat/generated.go | 12 +- example/config/generated.go | 12 +- example/dataloader/generated.go | 18 +- .../accounts/graph/generated/generated.go | 12 +- .../products/graph/generated/generated.go | 15 +- .../reviews/graph/generated/generated.go | 12 +- example/fileupload/generated.go | 12 +- example/scalars/generated.go | 24 +- example/selection/generated.go | 12 +- example/starwars/generated/exec.go | 35 ++- example/todo/generated.go | 12 +- example/type-system-extension/generated.go | 12 +- graphql/float.go | 16 + graphql/jsonw.go | 37 +++ integration/generated.go | 15 +- 40 files changed, 1101 insertions(+), 165 deletions(-) create mode 100644 codegen/testserver/followschema/scalar_context.generated.go create mode 100644 codegen/testserver/followschema/scalar_context.go create mode 100644 codegen/testserver/followschema/scalar_context.graphql create mode 100644 codegen/testserver/followschema/scalar_context_test.go delete mode 100644 codegen/testserver/gqlgen.yml create mode 100644 codegen/testserver/singlefile/scalar_context.go create mode 100644 codegen/testserver/singlefile/scalar_context.graphql create mode 100644 codegen/testserver/singlefile/scalar_context_test.go diff --git a/.gitignore b/.gitignore index b918d6a6f20..a2017efe91e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /codegen/gen /gen +/.vscode .idea/ *.test *.out diff --git a/codegen/config/binder.go b/codegen/config/binder.go index 459114d6fce..0974e44cf91 100644 --- a/codegen/config/binder.go +++ b/codegen/config/binder.go @@ -152,18 +152,10 @@ func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, erro } func (b *Binder) PointerTo(ref *TypeReference) *TypeReference { - newRef := &TypeReference{ - GO: types.NewPointer(ref.GO), - GQL: ref.GQL, - CastType: ref.CastType, - Definition: ref.Definition, - Unmarshaler: ref.Unmarshaler, - Marshaler: ref.Marshaler, - IsMarshaler: ref.IsMarshaler, - } - - b.References = append(b.References, newRef) - return newRef + newRef := *ref + newRef.GO = types.NewPointer(ref.GO) + b.References = append(b.References, &newRef) + return &newRef } // TypeReference is used by args and field types. The Definition can refer to both input and output types. @@ -176,33 +168,21 @@ type TypeReference struct { Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler + IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety. } func (ref *TypeReference) Elem() *TypeReference { if p, isPtr := ref.GO.(*types.Pointer); isPtr { - return &TypeReference{ - GO: p.Elem(), - Target: ref.Target, - GQL: ref.GQL, - CastType: ref.CastType, - Definition: ref.Definition, - Unmarshaler: ref.Unmarshaler, - Marshaler: ref.Marshaler, - IsMarshaler: ref.IsMarshaler, - } + newRef := *ref + newRef.GO = p.Elem() + return &newRef } if ref.IsSlice() { - return &TypeReference{ - GO: ref.GO.(*types.Slice).Elem(), - Target: ref.Target, - GQL: ref.GQL.Elem, - CastType: ref.CastType, - Definition: ref.Definition, - Unmarshaler: ref.Unmarshaler, - Marshaler: ref.Marshaler, - IsMarshaler: ref.IsMarshaler, - } + newRef := *ref + newRef.GO = ref.GO.(*types.Slice).Elem() + newRef.GQL = ref.GQL.Elem + return &newRef } return nil } @@ -373,8 +353,13 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret if fun, isFunc := obj.(*types.Func); isFunc { ref.GO = fun.Type().(*types.Signature).Params().At(0).Type() + ref.IsContext = fun.Type().(*types.Signature).Results().At(0).Type().String() == "github.com/99designs/gqlgen/graphql.ContextMarshaler" ref.Marshaler = fun ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil) + } else if hasMethod(obj.Type(), "MarshalGQLContext") && hasMethod(obj.Type(), "UnmarshalGQLContext") { + ref.GO = obj.Type() + ref.IsContext = true + ref.IsMarshaler = true } else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") { ref.GO = obj.Type() ref.IsMarshaler = true diff --git a/codegen/config/config.go b/codegen/config/config.go index d2016f4bd09..b030ab6cbc5 100644 --- a/codegen/config/config.go +++ b/codegen/config/config.go @@ -593,7 +593,7 @@ func (c *Config) injectBuiltins() { "__EnumValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.EnumValue"}}, "__InputValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.InputValue"}}, "__Schema": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Schema"}}, - "Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.Float"}}, + "Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.FloatContext"}}, "String": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}}, "Boolean": {Model: StringList{"github.com/99designs/gqlgen/graphql.Boolean"}}, "Int": {Model: StringList{ diff --git a/codegen/testserver/followschema/gqlgen.yml b/codegen/testserver/followschema/gqlgen.yml index 02f25a0d120..5119a2f5038 100644 --- a/codegen/testserver/followschema/gqlgen.yml +++ b/codegen/testserver/followschema/gqlgen.yml @@ -22,3 +22,5 @@ autobind: models: Email: model: "github.com/99designs/gqlgen/codegen/testserver/followschema.Email" + StringFromContextFunction: + model: "github.com/99designs/gqlgen/codegen/testserver/followschema.StringFromContextFunction" diff --git a/codegen/testserver/followschema/prelude.generated.go b/codegen/testserver/followschema/prelude.generated.go index 0109bde4739..39c1364a7c4 100644 --- a/codegen/testserver/followschema/prelude.generated.go +++ b/codegen/testserver/followschema/prelude.generated.go @@ -1512,18 +1512,18 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se } func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") } } - return res + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) { @@ -1966,7 +1966,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -1981,16 +1982,18 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalOFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - return graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v interface{}) (*int, error) { @@ -2005,7 +2008,8 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele if v == nil { return graphql.Null } - return graphql.MarshalInt(*v) + res := graphql.MarshalInt(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -2014,7 +2018,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { @@ -2107,7 +2112,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) unmarshalOString2ᚖᚕstringᚄ(ctx context.Context, v interface{}) (*[]string, error) { diff --git a/codegen/testserver/followschema/resolver.go b/codegen/testserver/followschema/resolver.go index 7cf60b2455e..5e46f854016 100644 --- a/codegen/testserver/followschema/resolver.go +++ b/codegen/testserver/followschema/resolver.go @@ -276,6 +276,18 @@ func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceCon panic("not implemented") } +func (r *queryResolver) Infinity(ctx context.Context) (float64, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextFunction(ctx context.Context) (string, error) { + panic("not implemented") +} + func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { panic("not implemented") } diff --git a/codegen/testserver/followschema/root!.generated.go b/codegen/testserver/followschema/root!.generated.go index 69079b433cf..a79ff80a1b0 100644 --- a/codegen/testserver/followschema/root!.generated.go +++ b/codegen/testserver/followschema/root!.generated.go @@ -301,6 +301,7 @@ type ComplexityRoot struct { ErrorList func(childComplexity int) int Errors func(childComplexity int) int Fallback func(childComplexity int, arg FallbackToStringEncoding) int + Infinity func(childComplexity int) int InputNullableSlice func(childComplexity int, arg []string) int InputSlice func(childComplexity int, arg []string) int InvalidIdentifier func(childComplexity int) int @@ -327,6 +328,8 @@ type ComplexityRoot struct { ShapeUnion func(childComplexity int) int Shapes func(childComplexity int) int Slices func(childComplexity int) int + StringFromContextFunction func(childComplexity int) int + StringFromContextInterface func(childComplexity int) int User func(childComplexity int, id int) int VOkCaseNil func(childComplexity int) int VOkCaseValue func(childComplexity int) int @@ -1267,6 +1270,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Fallback(childComplexity, args["arg"].(FallbackToStringEncoding)), true + case "Query.infinity": + if e.complexity.Query.Infinity == nil { + break + } + + return e.complexity.Query.Infinity(childComplexity), true + case "Query.inputNullableSlice": if e.complexity.Query.InputNullableSlice == nil { break @@ -1489,6 +1499,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Slices(childComplexity), true + case "Query.stringFromContextFunction": + if e.complexity.Query.StringFromContextFunction == nil { + break + } + + return e.complexity.Query.StringFromContextFunction(childComplexity), true + + case "Query.stringFromContextInterface": + if e.complexity.Query.StringFromContextInterface == nil { + break + } + + return e.complexity.Query.StringFromContextInterface(childComplexity), true + case "Query.user": if e.complexity.Query.User == nil { break @@ -2243,6 +2267,15 @@ extend type Mutation { extend type Query { ptrToSliceContainer: PtrToSliceContainer! } +`, BuiltIn: false}, + {Name: "scalar_context.graphql", Input: `extend type Query { + infinity: Float! + stringFromContextInterface: StringFromContextInterface! + stringFromContextFunction: StringFromContextFunction! +} + +scalar StringFromContextInterface +scalar StringFromContextFunction `, BuiltIn: false}, {Name: "scalar_default.graphql", Input: `extend type Query { defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation! diff --git a/codegen/testserver/followschema/scalar_context.generated.go b/codegen/testserver/followschema/scalar_context.generated.go new file mode 100644 index 00000000000..c1607f021e6 --- /dev/null +++ b/codegen/testserver/followschema/scalar_context.generated.go @@ -0,0 +1,83 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package followschema + +import ( + "context" + + "github.com/99designs/gqlgen/graphql" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNStringFromContextFunction2string(ctx context.Context, v interface{}) (string, error) { + res, err := UnmarshalStringFromContextFunction(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextFunction2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := MarshalStringFromContextFunction(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNStringFromContextInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐStringFromContextInterface(ctx context.Context, v interface{}) (StringFromContextInterface, error) { + var res StringFromContextInterface + err := res.UnmarshalGQLContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐStringFromContextInterface(ctx context.Context, sel ast.SelectionSet, v StringFromContextInterface) graphql.Marshaler { + return graphql.WrapContextMarshaler(ctx, v) +} + +func (ec *executionContext) unmarshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐStringFromContextInterface(ctx context.Context, v interface{}) (*StringFromContextInterface, error) { + var res = new(StringFromContextInterface) + err := res.UnmarshalGQLContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐStringFromContextInterface(ctx context.Context, sel ast.SelectionSet, v *StringFromContextInterface) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return graphql.WrapContextMarshaler(ctx, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/scalar_context.go b/codegen/testserver/followschema/scalar_context.go new file mode 100644 index 00000000000..7b8e7cca865 --- /dev/null +++ b/codegen/testserver/followschema/scalar_context.go @@ -0,0 +1,36 @@ +package followschema + +import ( + "context" + "io" + "strconv" + + "github.com/99designs/gqlgen/graphql" +) + +type StringFromContextInterface struct { + OperationName string +} + +var _ graphql.ContextMarshaler = StringFromContextInterface{} +var _ graphql.ContextUnmarshaler = (*StringFromContextInterface)(nil) + +func (StringFromContextInterface) MarshalGQLContext(ctx context.Context, w io.Writer) error { + io.WriteString(w, strconv.Quote(graphql.GetFieldContext(ctx).Field.Name)) + return nil +} +func (i *StringFromContextInterface) UnmarshalGQLContext(ctx context.Context, v interface{}) error { + i.OperationName = graphql.GetFieldContext(ctx).Field.Name + return nil +} + +func MarshalStringFromContextFunction(v string) graphql.ContextMarshaler { + return graphql.ContextWriterFunc(func(ctx context.Context, w io.Writer) error { + io.WriteString(w, strconv.Quote(graphql.GetFieldContext(ctx).Field.Name)) + return nil + }) +} + +func UnmarshalStringFromContextFunction(ctx context.Context, v interface{}) (string, error) { + return graphql.GetFieldContext(ctx).Field.Name, nil +} diff --git a/codegen/testserver/followschema/scalar_context.graphql b/codegen/testserver/followschema/scalar_context.graphql new file mode 100644 index 00000000000..f49fa553139 --- /dev/null +++ b/codegen/testserver/followschema/scalar_context.graphql @@ -0,0 +1,8 @@ +extend type Query { + infinity: Float! + stringFromContextInterface: StringFromContextInterface! + stringFromContextFunction: StringFromContextFunction! +} + +scalar StringFromContextInterface +scalar StringFromContextFunction diff --git a/codegen/testserver/followschema/scalar_context_test.go b/codegen/testserver/followschema/scalar_context_test.go new file mode 100644 index 00000000000..b8427065c54 --- /dev/null +++ b/codegen/testserver/followschema/scalar_context_test.go @@ -0,0 +1,52 @@ +package followschema + +import ( + "context" + "math" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestFloatInfAndNaN(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.Infinity = func(ctx context.Context) (float64, error) { + return math.Inf(-1), nil + } + + t.Run("errors on marshaller with context", func(t *testing.T) { + err := c.Post(`query { infinity }`, nil) + require.Error(t, err) + }) + +} + +func TestContextPassedToMarshal(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.StringFromContextInterface = func(ctx context.Context) (*StringFromContextInterface, error) { + return &StringFromContextInterface{}, nil + } + resolvers.QueryResolver.StringFromContextFunction = func(ctx context.Context) (string, error) { + return "", nil + } + + var res struct { + StringFromContextInterface string + StringFromContextFunction string + } + err := c.Post(`query my_name { + stringFromContextInterface + stringFromContextFunction + }`, &res) + require.NoError(t, err) + require.Equal(t, "stringFromContextInterface", res.StringFromContextInterface) + require.Equal(t, "stringFromContextFunction", res.StringFromContextFunction) +} diff --git a/codegen/testserver/followschema/scalar_default.generated.go b/codegen/testserver/followschema/scalar_default.generated.go index dcbd4dc63cf..5ac087b7d54 100644 --- a/codegen/testserver/followschema/scalar_default.generated.go +++ b/codegen/testserver/followschema/scalar_default.generated.go @@ -124,7 +124,8 @@ func (ec *executionContext) marshalODefaultScalarImplementation2ᚖstring(ctx co if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } // endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/schema.generated.go b/codegen/testserver/followschema/schema.generated.go index 3d27d92643d..5d8d9b6ce02 100644 --- a/codegen/testserver/followschema/schema.generated.go +++ b/codegen/testserver/followschema/schema.generated.go @@ -78,6 +78,9 @@ type QueryResolver interface { PrimitiveObject(ctx context.Context) ([]Primitive, error) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) + Infinity(ctx context.Context) (float64, error) + StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) + StringFromContextFunction(ctx context.Context) (string, error) DefaultScalar(ctx context.Context, arg string) (string, error) Slices(ctx context.Context) (*Slices, error) ScalarSlice(ctx context.Context) ([]byte, error) @@ -2900,6 +2903,102 @@ func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, fiel return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐPtrToSliceContainer(ctx, field.Selections, res) } +func (ec *executionContext) _Query_infinity(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Infinity(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_stringFromContextInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().StringFromContextInterface(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*StringFromContextInterface) + fc.Result = res + return ec.marshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋfollowschemaᚐStringFromContextInterface(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_stringFromContextFunction(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().StringFromContextFunction(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNStringFromContextFunction2string(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_defaultScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -5267,6 +5366,75 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) } + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "infinity": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_infinity(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "stringFromContextInterface": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_stringFromContextInterface(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "stringFromContextFunction": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_stringFromContextFunction(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) @@ -5997,7 +6165,8 @@ func (ec *executionContext) marshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgql if v == nil { return graphql.Null } - return MarshalThirdParty(*v) + res := MarshalThirdParty(*v) + return res } func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { @@ -6012,7 +6181,8 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel if v == nil { return graphql.Null } - return graphql.MarshalTime(*v) + res := graphql.MarshalTime(*v) + return res } // endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/followschema/stub.go b/codegen/testserver/followschema/stub.go index 20491526095..41d639d0e2d 100644 --- a/codegen/testserver/followschema/stub.go +++ b/codegen/testserver/followschema/stub.go @@ -96,6 +96,9 @@ type Stub struct { PrimitiveObject func(ctx context.Context) ([]Primitive, error) PrimitiveStringObject func(ctx context.Context) ([]PrimitiveString, error) PtrToSliceContainer func(ctx context.Context) (*PtrToSliceContainer, error) + Infinity func(ctx context.Context) (float64, error) + StringFromContextInterface func(ctx context.Context) (*StringFromContextInterface, error) + StringFromContextFunction func(ctx context.Context) (string, error) DefaultScalar func(ctx context.Context, arg string) (string, error) Slices func(ctx context.Context) (*Slices, error) ScalarSlice func(ctx context.Context) ([]byte, error) @@ -399,6 +402,15 @@ func (r *stubQuery) PrimitiveStringObject(ctx context.Context) ([]PrimitiveStrin func (r *stubQuery) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { return r.QueryResolver.PtrToSliceContainer(ctx) } +func (r *stubQuery) Infinity(ctx context.Context) (float64, error) { + return r.QueryResolver.Infinity(ctx) +} +func (r *stubQuery) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { + return r.QueryResolver.StringFromContextInterface(ctx) +} +func (r *stubQuery) StringFromContextFunction(ctx context.Context) (string, error) { + return r.QueryResolver.StringFromContextFunction(ctx) +} func (r *stubQuery) DefaultScalar(ctx context.Context, arg string) (string, error) { return r.QueryResolver.DefaultScalar(ctx, arg) } diff --git a/codegen/testserver/followschema/wrapped_type.generated.go b/codegen/testserver/followschema/wrapped_type.generated.go index c3a4c80ecf3..529421ee708 100644 --- a/codegen/testserver/followschema/wrapped_type.generated.go +++ b/codegen/testserver/followschema/wrapped_type.generated.go @@ -401,7 +401,8 @@ func (ec *executionContext) marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋ if v == nil { return graphql.Null } - return graphql.MarshalString(string(*v)) + res := graphql.MarshalString(string(*v)) + return res } // endregion ***************************** type.gotpl ***************************** diff --git a/codegen/testserver/gqlgen.yml b/codegen/testserver/gqlgen.yml deleted file mode 100644 index d9d4f0c5b17..00000000000 --- a/codegen/testserver/gqlgen.yml +++ /dev/null @@ -1,19 +0,0 @@ -schema: - - "*.graphql" -skip_validation: true -exec: - filename: generated.go -model: - filename: models-gen.go -resolver: - filename: resolver.go - type: Resolver - -autobind: - - "github.com/99designs/gqlgen/codegen/testserver" - - "github.com/99designs/gqlgen/codegen/testserver/introspection" - - "github.com/99designs/gqlgen/codegen/testserver/invalid-packagename" - -models: - Email: - model: "github.com/99designs/gqlgen/codegen/testserver.Email" diff --git a/codegen/testserver/singlefile/generated.go b/codegen/testserver/singlefile/generated.go index 75724eaecbd..6452652234e 100644 --- a/codegen/testserver/singlefile/generated.go +++ b/codegen/testserver/singlefile/generated.go @@ -312,6 +312,7 @@ type ComplexityRoot struct { ErrorList func(childComplexity int) int Errors func(childComplexity int) int Fallback func(childComplexity int, arg FallbackToStringEncoding) int + Infinity func(childComplexity int) int InputNullableSlice func(childComplexity int, arg []string) int InputSlice func(childComplexity int, arg []string) int InvalidIdentifier func(childComplexity int) int @@ -338,6 +339,8 @@ type ComplexityRoot struct { ShapeUnion func(childComplexity int) int Shapes func(childComplexity int) int Slices func(childComplexity int) int + StringFromContextFunction func(childComplexity int) int + StringFromContextInterface func(childComplexity int) int User func(childComplexity int, id int) int VOkCaseNil func(childComplexity int) int VOkCaseValue func(childComplexity int) int @@ -512,6 +515,9 @@ type QueryResolver interface { PrimitiveObject(ctx context.Context) ([]Primitive, error) PrimitiveStringObject(ctx context.Context) ([]PrimitiveString, error) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) + Infinity(ctx context.Context) (float64, error) + StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) + StringFromContextFunction(ctx context.Context) (string, error) DefaultScalar(ctx context.Context, arg string) (string, error) Slices(ctx context.Context) (*Slices, error) ScalarSlice(ctx context.Context) ([]byte, error) @@ -1397,6 +1403,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Fallback(childComplexity, args["arg"].(FallbackToStringEncoding)), true + case "Query.infinity": + if e.complexity.Query.Infinity == nil { + break + } + + return e.complexity.Query.Infinity(childComplexity), true + case "Query.inputNullableSlice": if e.complexity.Query.InputNullableSlice == nil { break @@ -1619,6 +1632,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Slices(childComplexity), true + case "Query.stringFromContextFunction": + if e.complexity.Query.StringFromContextFunction == nil { + break + } + + return e.complexity.Query.StringFromContextFunction(childComplexity), true + + case "Query.stringFromContextInterface": + if e.complexity.Query.StringFromContextInterface == nil { + break + } + + return e.complexity.Query.StringFromContextInterface(childComplexity), true + case "Query.user": if e.complexity.Query.User == nil { break @@ -2373,6 +2400,15 @@ extend type Mutation { extend type Query { ptrToSliceContainer: PtrToSliceContainer! } +`, BuiltIn: false}, + {Name: "scalar_context.graphql", Input: `extend type Query { + infinity: Float! + stringFromContextInterface: StringFromContextInterface! + stringFromContextFunction: StringFromContextFunction! +} + +scalar StringFromContextInterface +scalar StringFromContextFunction `, BuiltIn: false}, {Name: "scalar_default.graphql", Input: `extend type Query { defaultScalar(arg: DefaultScalarImplementation! = "default"): DefaultScalarImplementation! @@ -8277,6 +8313,102 @@ func (ec *executionContext) _Query_ptrToSliceContainer(ctx context.Context, fiel return ec.marshalNPtrToSliceContainer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐPtrToSliceContainer(ctx, field.Selections, res) } +func (ec *executionContext) _Query_infinity(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Infinity(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_stringFromContextInterface(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().StringFromContextInterface(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*StringFromContextInterface) + fc.Result = res + return ec.marshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐStringFromContextInterface(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_stringFromContextFunction(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp := ec._fieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().StringFromContextFunction(rctx) + }) + + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNStringFromContextFunction2string(ctx, field.Selections, res) +} + func (ec *executionContext) _Query_defaultScalar(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -14670,6 +14802,75 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) } + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "infinity": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_infinity(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "stringFromContextInterface": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_stringFromContextInterface(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "stringFromContextFunction": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_stringFromContextFunction(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) @@ -16064,18 +16265,18 @@ func (ec *executionContext) marshalNFallbackToStringEncoding2githubᚗcomᚋ99de } func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") } } - return res + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) unmarshalNID2int(ctx context.Context, v interface{}) (int, error) { @@ -16510,6 +16711,47 @@ func (ec *executionContext) marshalNString2ᚖstring(ctx context.Context, sel as return res } +func (ec *executionContext) unmarshalNStringFromContextFunction2string(ctx context.Context, v interface{}) (string, error) { + res, err := UnmarshalStringFromContextFunction(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextFunction2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := MarshalStringFromContextFunction(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNStringFromContextInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐStringFromContextInterface(ctx context.Context, v interface{}) (StringFromContextInterface, error) { + var res StringFromContextInterface + err := res.UnmarshalGQLContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextInterface2githubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐStringFromContextInterface(ctx context.Context, sel ast.SelectionSet, v StringFromContextInterface) graphql.Marshaler { + return graphql.WrapContextMarshaler(ctx, v) +} + +func (ec *executionContext) unmarshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐStringFromContextInterface(ctx context.Context, v interface{}) (*StringFromContextInterface, error) { + var res = new(StringFromContextInterface) + err := res.UnmarshalGQLContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNStringFromContextInterface2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐStringFromContextInterface(ctx context.Context, sel ast.SelectionSet, v *StringFromContextInterface) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return graphql.WrapContextMarshaler(ctx, v) +} + func (ec *executionContext) unmarshalNTime2timeᚐTime(ctx context.Context, v interface{}) (time.Time, error) { res, err := graphql.UnmarshalTime(v) return res, graphql.ErrorOnPath(ctx, err) @@ -16937,7 +17179,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -16952,7 +17195,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOChanges2map(ctx context.Context, v interface{}) (map[string]interface{}, error) { @@ -17080,7 +17324,8 @@ func (ec *executionContext) marshalODefaultScalarImplementation2ᚖstring(ctx co if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalOEmbeddedCase12ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐEmbeddedCase1(ctx context.Context, sel ast.SelectionSet, v *EmbeddedCase1) graphql.Marshaler { @@ -17207,12 +17452,13 @@ func (ec *executionContext) marshalOErrors2ᚖgithubᚗcomᚋ99designsᚋgqlgen } func (ec *executionContext) unmarshalOFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalOFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - return graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) unmarshalOInnerDirectives2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐInnerDirectives(ctx context.Context, v interface{}) (*InnerDirectives, error) { @@ -17251,7 +17497,8 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele if v == nil { return graphql.Null } - return graphql.MarshalInt(*v) + res := graphql.MarshalInt(*v) + return res } func (ec *executionContext) marshalOInvalidIdentifier2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚋinvalidᚑpackagenameᚐInvalidIdentifier(ctx context.Context, sel ast.SelectionSet, v *invalid_packagename.InvalidIdentifier) graphql.Marshaler { @@ -17612,7 +17859,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { @@ -17705,7 +17953,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) unmarshalOString2ᚖᚕstringᚄ(ctx context.Context, v interface{}) (*[]string, error) { @@ -17739,7 +17988,8 @@ func (ec *executionContext) marshalOThirdParty2ᚖgithubᚗcomᚋ99designsᚋgql if v == nil { return graphql.Null } - return MarshalThirdParty(*v) + res := MarshalThirdParty(*v) + return res } func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { @@ -17754,7 +18004,8 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel if v == nil { return graphql.Null } - return graphql.MarshalTime(*v) + res := graphql.MarshalTime(*v) + return res } func (ec *executionContext) unmarshalOUpdatePtrToPtrInner2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋcodegenᚋtestserverᚋsinglefileᚐUpdatePtrToPtrInner(ctx context.Context, v interface{}) (*UpdatePtrToPtrInner, error) { @@ -17891,7 +18142,8 @@ func (ec *executionContext) marshalOWrappedScalar2ᚖgithubᚗcomᚋ99designsᚋ if v == nil { return graphql.Null } - return graphql.MarshalString(string(*v)) + res := graphql.MarshalString(string(*v)) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/codegen/testserver/singlefile/gqlgen.yml b/codegen/testserver/singlefile/gqlgen.yml index 868f5799c71..afd3fb90dd8 100644 --- a/codegen/testserver/singlefile/gqlgen.yml +++ b/codegen/testserver/singlefile/gqlgen.yml @@ -21,3 +21,5 @@ autobind: models: Email: model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.Email" + StringFromContextFunction: + model: "github.com/99designs/gqlgen/codegen/testserver/singlefile.StringFromContextFunction" diff --git a/codegen/testserver/singlefile/resolver.go b/codegen/testserver/singlefile/resolver.go index 972bcd82f82..90d5c07a226 100644 --- a/codegen/testserver/singlefile/resolver.go +++ b/codegen/testserver/singlefile/resolver.go @@ -276,6 +276,18 @@ func (r *queryResolver) PtrToSliceContainer(ctx context.Context) (*PtrToSliceCon panic("not implemented") } +func (r *queryResolver) Infinity(ctx context.Context) (float64, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { + panic("not implemented") +} + +func (r *queryResolver) StringFromContextFunction(ctx context.Context) (string, error) { + panic("not implemented") +} + func (r *queryResolver) DefaultScalar(ctx context.Context, arg string) (string, error) { panic("not implemented") } diff --git a/codegen/testserver/singlefile/scalar_context.go b/codegen/testserver/singlefile/scalar_context.go new file mode 100644 index 00000000000..fc002caf5e3 --- /dev/null +++ b/codegen/testserver/singlefile/scalar_context.go @@ -0,0 +1,36 @@ +package singlefile + +import ( + "context" + "io" + "strconv" + + "github.com/99designs/gqlgen/graphql" +) + +type StringFromContextInterface struct { + OperationName string +} + +var _ graphql.ContextMarshaler = StringFromContextInterface{} +var _ graphql.ContextUnmarshaler = (*StringFromContextInterface)(nil) + +func (StringFromContextInterface) MarshalGQLContext(ctx context.Context, w io.Writer) error { + io.WriteString(w, strconv.Quote(graphql.GetFieldContext(ctx).Field.Name)) + return nil +} +func (i *StringFromContextInterface) UnmarshalGQLContext(ctx context.Context, v interface{}) error { + i.OperationName = graphql.GetFieldContext(ctx).Field.Name + return nil +} + +func MarshalStringFromContextFunction(v string) graphql.ContextMarshaler { + return graphql.ContextWriterFunc(func(ctx context.Context, w io.Writer) error { + io.WriteString(w, strconv.Quote(graphql.GetFieldContext(ctx).Field.Name)) + return nil + }) +} + +func UnmarshalStringFromContextFunction(ctx context.Context, v interface{}) (string, error) { + return graphql.GetFieldContext(ctx).Field.Name, nil +} diff --git a/codegen/testserver/singlefile/scalar_context.graphql b/codegen/testserver/singlefile/scalar_context.graphql new file mode 100644 index 00000000000..f49fa553139 --- /dev/null +++ b/codegen/testserver/singlefile/scalar_context.graphql @@ -0,0 +1,8 @@ +extend type Query { + infinity: Float! + stringFromContextInterface: StringFromContextInterface! + stringFromContextFunction: StringFromContextFunction! +} + +scalar StringFromContextInterface +scalar StringFromContextFunction diff --git a/codegen/testserver/singlefile/scalar_context_test.go b/codegen/testserver/singlefile/scalar_context_test.go new file mode 100644 index 00000000000..8a235b1d439 --- /dev/null +++ b/codegen/testserver/singlefile/scalar_context_test.go @@ -0,0 +1,52 @@ +package singlefile + +import ( + "context" + "math" + "testing" + + "github.com/99designs/gqlgen/client" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/stretchr/testify/require" +) + +func TestFloatInfAndNaN(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.Infinity = func(ctx context.Context) (float64, error) { + return math.Inf(-1), nil + } + + t.Run("errors on marshaller with context", func(t *testing.T) { + err := c.Post(`query { infinity }`, nil) + require.Error(t, err) + }) + +} + +func TestContextPassedToMarshal(t *testing.T) { + resolvers := &Stub{} + + c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))) + + resolvers.QueryResolver.StringFromContextInterface = func(ctx context.Context) (*StringFromContextInterface, error) { + return &StringFromContextInterface{}, nil + } + resolvers.QueryResolver.StringFromContextFunction = func(ctx context.Context) (string, error) { + return "", nil + } + + var res struct { + StringFromContextInterface string + StringFromContextFunction string + } + err := c.Post(`query my_name { + stringFromContextInterface + stringFromContextFunction + }`, &res) + require.NoError(t, err) + require.Equal(t, "stringFromContextInterface", res.StringFromContextInterface) + require.Equal(t, "stringFromContextFunction", res.StringFromContextFunction) +} diff --git a/codegen/testserver/singlefile/stub.go b/codegen/testserver/singlefile/stub.go index 64145785169..fc5e2325b4b 100644 --- a/codegen/testserver/singlefile/stub.go +++ b/codegen/testserver/singlefile/stub.go @@ -96,6 +96,9 @@ type Stub struct { PrimitiveObject func(ctx context.Context) ([]Primitive, error) PrimitiveStringObject func(ctx context.Context) ([]PrimitiveString, error) PtrToSliceContainer func(ctx context.Context) (*PtrToSliceContainer, error) + Infinity func(ctx context.Context) (float64, error) + StringFromContextInterface func(ctx context.Context) (*StringFromContextInterface, error) + StringFromContextFunction func(ctx context.Context) (string, error) DefaultScalar func(ctx context.Context, arg string) (string, error) Slices func(ctx context.Context) (*Slices, error) ScalarSlice func(ctx context.Context) ([]byte, error) @@ -399,6 +402,15 @@ func (r *stubQuery) PrimitiveStringObject(ctx context.Context) ([]PrimitiveStrin func (r *stubQuery) PtrToSliceContainer(ctx context.Context) (*PtrToSliceContainer, error) { return r.QueryResolver.PtrToSliceContainer(ctx) } +func (r *stubQuery) Infinity(ctx context.Context) (float64, error) { + return r.QueryResolver.Infinity(ctx) +} +func (r *stubQuery) StringFromContextInterface(ctx context.Context) (*StringFromContextInterface, error) { + return r.QueryResolver.StringFromContextInterface(ctx) +} +func (r *stubQuery) StringFromContextFunction(ctx context.Context) (string, error) { + return r.QueryResolver.StringFromContextFunction(ctx) +} func (r *stubQuery) DefaultScalar(ctx context.Context, arg string) (string, error) { return r.QueryResolver.DefaultScalar(ctx, arg) } diff --git a/codegen/type.gotpl b/codegen/type.gotpl index e9468ae3a23..b82eef3cf1c 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -39,14 +39,22 @@ {{- else }} {{- if $type.Unmarshaler }} {{- if $type.CastType }} - tmp, err := {{ $type.Unmarshaler | call }}(v) + {{- if $type.IsContext }} + tmp, err := {{ $type.Unmarshaler | call }}(ctx, v) + {{- else }} + tmp, err := {{ $type.Unmarshaler | call }}(v) + {{- end }} {{- if and $type.IsNilable $type.Elem }} res := {{ $type.Elem.GO | ref }}(tmp) {{- else}} res := {{ $type.GO | ref }}(tmp) {{- end }} {{- else}} - res, err := {{ $type.Unmarshaler | call }}(v) + {{- if $type.IsContext }} + res, err := {{ $type.Unmarshaler | call }}(ctx, v) + {{- else }} + res, err := {{ $type.Unmarshaler | call }}(v) + {{- end }} {{- end }} {{- if and $type.IsTargetNilable (not $type.IsNilable) }} return *res, graphql.ErrorOnPath(ctx, err) @@ -63,7 +71,11 @@ {{- else}} var res {{ $type.GO | ref }} {{- end }} - err := res.UnmarshalGQL(v) + {{- if $type.IsContext }} + err := res.UnmarshalGQLContext(ctx, v) + {{- else }} + err := res.UnmarshalGQL(v) + {{- end }} return res, graphql.ErrorOnPath(ctx, err) {{- else }} res, err := ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v) @@ -150,7 +162,11 @@ } {{- end }} {{- if $type.IsMarshaler }} - return v + {{- if $type.IsContext }} + return graphql.WrapContextMarshaler(ctx, v) + {{- else }} + return v + {{- end }} {{- else if $type.Marshaler }} {{- $v := "v" }} {{- if and $type.IsTargetNilable (not $type.IsNilable) }} @@ -158,16 +174,18 @@ {{- else if and (not $type.IsTargetNilable) $type.IsNilable }} {{- $v = "*v" }} {{- end }} + res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }}) {{- if $type.GQL.NonNull }} - res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }}) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "must not be null") - } + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") } - return res + } + {{- end }} + {{- if $type.IsContext }} + return graphql.WrapContextMarshaler(ctx, res) {{- else }} - return {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }}) + return res {{- end }} {{- else }} return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v) diff --git a/docs/content/reference/scalars.md b/docs/content/reference/scalars.md index 10e835d42cb..21ffe180838 100644 --- a/docs/content/reference/scalars.md +++ b/docs/content/reference/scalars.md @@ -52,16 +52,22 @@ Maps an arbitrary GraphQL value to a `interface{}` Go type. ## Custom scalars with user defined types -For user defined types you can implement the graphql.Marshaler and graphql.Unmarshaler interfaces and they will be called. +For user defined types you can implement the [graphql.Marshaler](https://pkg.go.dev/github.com/99designs/gqlgen/graphql#Marshaler) and [graphql.Unmarshaler](https://pkg.go.dev/github.com/99designs/gqlgen/graphql#Unmarshaler) or implement the [graphql.ContextMarshaler](https://pkg.go.dev/github.com/99designs/gqlgen/graphql#ContextMarshaler) and [graphql.ContextUnmarshaler](https://pkg.go.dev/github.com/99designs/gqlgen/graphql#ContextUnmarshaler) interfaces and they will be called. ```go package mypkg import ( + "context" "fmt" "io" + "strconv" ) +// +// Most common scalars +// + type YesNo bool // UnmarshalGQL implements the graphql.Unmarshaler interface @@ -87,6 +93,42 @@ func (y YesNo) MarshalGQL(w io.Writer) { w.Write([]byte(`"no"`)) } } + +// +// Scalars that need access to the request context +// + +type Length float64 + +// UnmarshalGQLContext implements the graphql.ContextUnmarshaler interface +func (l *Length) UnmarshalGQLContext(ctx context.Context, v interface{}) error { + s, ok := v.(string) + if !ok { + return fmt.Errorf("Length must be a string") + } + length, err := ParseLength(s) + if err != nil { + return err + } + *l = length + return nil +} + +// MarshalGQLContext implements the graphql.ContextMarshaler interface +func (l Length) MarshalGQLContext(ctx context.Context, w io.Writer) error { + s, err := l.FormatContext(ctx) + if err != nil { + return err + } + w.Write([]byte(strconv.Quote(s))) + return nil +} + +// ParseLength parses a length measurement string with unit on the end (eg: "12.45in") +func ParseLength(string) (Length, error) + +// ParseLength formats the string using a value in the context to specify format +func (l Length) FormatContext(ctx context.Context) (string, error) ``` and then wire up the type in .gqlgen.yml or via directives like normal: @@ -149,11 +191,14 @@ models: **Note:** you also can un/marshal to pointer types via this approach, simply accept a pointer in your `Marshal...` func and return one in your `Unmarshal...` func. +**Note:** you can also un/marshal with a context by having your custom marshal function return a +`graphql.ContextMarshaler` _and_ your unmarshal function take a `context.Context` as the first argument. + See the [example/scalars](https://github.com/99designs/gqlgen/tree/master/example/scalars) package for more examples. -## Unmarshaling Errors +## Marshaling/Unmarshaling Errors -The errors that occur as part of custom scalar unmarshaling will return a full path to the field. +The errors that occur as part of custom scalar marshaling/unmarshaling will return a full path to the field. For example, given the following schema ... ```graphql @@ -203,4 +248,4 @@ input ContactDetailsInput { } ``` - +**Note:** Marshaling errors can only be returned when using the `graphql.ContextMarshaler` style interface. diff --git a/example/chat/generated.go b/example/chat/generated.go index 70d41c98b3c..067b1d01bf9 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -3019,7 +3019,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3034,7 +3035,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOChatroom2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋchatᚐChatroom(ctx context.Context, sel ast.SelectionSet, v *Chatroom) graphql.Marshaler { @@ -3050,7 +3052,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3065,7 +3068,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/config/generated.go b/example/config/generated.go index 86bfb26a2b4..c85a2564fc9 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -3069,7 +3069,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3084,7 +3085,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -3093,7 +3095,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { @@ -3150,7 +3153,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 82cd522228a..45bcce22bb2 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -2877,18 +2877,18 @@ func (ec *executionContext) marshalNCustomer2ᚖgithubᚗcomᚋ99designsᚋgqlge } func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") } } - return res + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { @@ -3226,7 +3226,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3241,7 +3242,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOCustomer2ᚕᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋdataloaderᚐCustomer(ctx context.Context, sel ast.SelectionSet, v [][]*Customer) graphql.Marshaler { @@ -3510,7 +3512,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3525,7 +3528,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index 388055bf2e7..fb31df149cf 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -2871,7 +2871,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -2886,7 +2887,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -2895,7 +2897,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -2910,7 +2913,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋaccountsᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler { diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 8134be72e0a..8d568c1ce03 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -2952,7 +2952,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -2967,7 +2968,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v interface{}) (*int, error) { @@ -2982,7 +2984,8 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele if v == nil { return graphql.Null } - return graphql.MarshalInt(*v) + res := graphql.MarshalInt(*v) + return res } func (ec *executionContext) marshalOProduct2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v []*model.Product) graphql.Marshaler { @@ -3039,7 +3042,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3054,7 +3058,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 6fc2cf679fc..2ba1cd32126 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -3259,7 +3259,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3274,7 +3275,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOReview2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐReview(ctx context.Context, sel ast.SelectionSet, v []*model.Review) graphql.Marshaler { @@ -3331,7 +3333,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3346,7 +3349,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO_Entity2githubᚗcomᚋ99designsᚋgqlgenᚋpluginᚋfederationᚋfedruntimeᚐEntity(ctx context.Context, sel ast.SelectionSet, v fedruntime.Entity) graphql.Marshaler { diff --git a/example/fileupload/generated.go b/example/fileupload/generated.go index 32717ad1843..bc8426e5994 100644 --- a/example/fileupload/generated.go +++ b/example/fileupload/generated.go @@ -3036,7 +3036,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3051,7 +3052,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -3060,7 +3062,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3075,7 +3078,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/scalars/generated.go b/example/scalars/generated.go index cd067e341cc..9dfce956a15 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -3359,7 +3359,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -3374,7 +3375,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalODarkMode2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐPrefs(ctx context.Context, v interface{}) (model.Prefs, error) { @@ -3383,7 +3385,8 @@ func (ec *executionContext) unmarshalODarkMode2githubᚗcomᚋ99designsᚋgqlgen } func (ec *executionContext) marshalODarkMode2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐPrefs(ctx context.Context, sel ast.SelectionSet, v model.Prefs) graphql.Marshaler { - return model.MarshalPreferences(&v) + res := model.MarshalPreferences(&v) + return res } func (ec *executionContext) unmarshalODarkMode2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐPrefs(ctx context.Context, v interface{}) (*model.Prefs, error) { @@ -3398,7 +3401,8 @@ func (ec *executionContext) marshalODarkMode2ᚖgithubᚗcomᚋ99designsᚋgqlge if v == nil { return graphql.Null } - return model.MarshalPreferences(v) + res := model.MarshalPreferences(v) + return res } func (ec *executionContext) unmarshalOPoint2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐPoint(ctx context.Context, v interface{}) (*model.Point, error) { @@ -3431,7 +3435,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3446,7 +3451,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) unmarshalOTier2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐTier(ctx context.Context, v interface{}) (model.Tier, error) { @@ -3465,7 +3471,8 @@ func (ec *executionContext) unmarshalOTimestamp2timeᚐTime(ctx context.Context, } func (ec *executionContext) marshalOTimestamp2timeᚐTime(ctx context.Context, sel ast.SelectionSet, v time.Time) graphql.Marshaler { - return model.MarshalTimestamp(v) + res := model.MarshalTimestamp(v) + return res } func (ec *executionContext) unmarshalOTimestamp2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { @@ -3480,7 +3487,8 @@ func (ec *executionContext) marshalOTimestamp2ᚖtimeᚐTime(ctx context.Context if v == nil { return graphql.Null } - return model.MarshalTimestamp(*v) + res := model.MarshalTimestamp(*v) + return res } func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋscalarsᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler { diff --git a/example/selection/generated.go b/example/selection/generated.go index 39bbdb271e1..37047440082 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -2703,7 +2703,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -2718,7 +2719,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOEvent2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋselectionᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []Event) graphql.Marshaler { @@ -2774,7 +2776,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { @@ -2831,7 +2834,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index 6052f45ceef..2d958a72106 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -4851,18 +4851,18 @@ func (ec *executionContext) marshalNEpisode2ᚕgithubᚗcomᚋ99designsᚋgqlgen } func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) if res == graphql.Null { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "must not be null") } } - return res + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) marshalNFriendsConnection2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋstarwarsᚋmodelsᚐFriendsConnection(ctx context.Context, sel ast.SelectionSet, v models.FriendsConnection) graphql.Marshaler { @@ -5396,7 +5396,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -5411,7 +5412,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) marshalOCharacter2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋstarwarsᚋmodelsᚐCharacter(ctx context.Context, sel ast.SelectionSet, v models.Character) graphql.Marshaler { @@ -5492,12 +5494,13 @@ func (ec *executionContext) marshalOEpisode2ᚖgithubᚗcomᚋ99designsᚋgqlgen } func (ec *executionContext) unmarshalOFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloat(v) + res, err := graphql.UnmarshalFloatContext(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalOFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - return graphql.MarshalFloat(v) + res := graphql.MarshalFloatContext(v) + return graphql.WrapContextMarshaler(ctx, res) } func (ec *executionContext) marshalOFriendsEdge2ᚕᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋstarwarsᚋmodelsᚐFriendsEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []*models.FriendsEdge) graphql.Marshaler { @@ -5566,7 +5569,8 @@ func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.Se if v == nil { return graphql.Null } - return graphql.MarshalID(*v) + res := graphql.MarshalID(*v) + return res } func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v interface{}) (*int, error) { @@ -5581,7 +5585,8 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele if v == nil { return graphql.Null } - return graphql.MarshalInt(*v) + res := graphql.MarshalInt(*v) + return res } func (ec *executionContext) unmarshalOLengthUnit2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋstarwarsᚋmodelsᚐLengthUnit(ctx context.Context, v interface{}) (models.LengthUnit, error) { @@ -5677,7 +5682,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -5692,7 +5698,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) unmarshalOTime2timeᚐTime(ctx context.Context, v interface{}) (time.Time, error) { @@ -5701,7 +5708,8 @@ func (ec *executionContext) unmarshalOTime2timeᚐTime(ctx context.Context, v in } func (ec *executionContext) marshalOTime2timeᚐTime(ctx context.Context, sel ast.SelectionSet, v time.Time) graphql.Marshaler { - return graphql.MarshalTime(v) + res := graphql.MarshalTime(v) + return res } func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { @@ -5716,7 +5724,8 @@ func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel if v == nil { return graphql.Null } - return graphql.MarshalTime(*v) + res := graphql.MarshalTime(*v) + return res } func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { diff --git a/example/todo/generated.go b/example/todo/generated.go index bdf847f6fc0..101f2288ecf 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -2941,7 +2941,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -2956,7 +2957,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -2965,7 +2967,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -2980,7 +2983,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalOTodo2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋtodoᚐTodo(ctx context.Context, sel ast.SelectionSet, v *Todo) graphql.Marshaler { diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index 1411a10eebd..62b405602bd 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -2962,7 +2962,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { @@ -2977,7 +2978,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -2986,7 +2988,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3001,7 +3004,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalOTodo2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋtypeᚑsystemᚑextensionᚐTodo(ctx context.Context, sel ast.SelectionSet, v *Todo) graphql.Marshaler { diff --git a/graphql/float.go b/graphql/float.go index fabbad04687..ccb825ddb8b 100644 --- a/graphql/float.go +++ b/graphql/float.go @@ -1,9 +1,11 @@ package graphql import ( + "context" "encoding/json" "fmt" "io" + "math" "strconv" ) @@ -29,3 +31,17 @@ func UnmarshalFloat(v interface{}) (float64, error) { return 0, fmt.Errorf("%T is not an float", v) } } + +func MarshalFloatContext(f float64) ContextMarshaler { + return ContextWriterFunc(func(ctx context.Context, w io.Writer) error { + if math.IsInf(f, 0) || math.IsNaN(f) { + return fmt.Errorf("cannot marshal infinite no NaN float values") + } + io.WriteString(w, fmt.Sprintf("%g", f)) + return nil + }) +} + +func UnmarshalFloatContext(ctx context.Context, v interface{}) (float64, error) { + return UnmarshalFloat(v) +} diff --git a/graphql/jsonw.go b/graphql/jsonw.go index db95d8e4419..19b1529b749 100644 --- a/graphql/jsonw.go +++ b/graphql/jsonw.go @@ -1,6 +1,7 @@ package graphql import ( + "context" "io" ) @@ -26,12 +27,43 @@ type Unmarshaler interface { UnmarshalGQL(v interface{}) error } +type ContextMarshaler interface { + MarshalGQLContext(ctx context.Context, w io.Writer) error +} + +type ContextUnmarshaler interface { + UnmarshalGQLContext(ctx context.Context, v interface{}) error +} + +type contextMarshalerAdapter struct { + Context context.Context + ContextMarshaler +} + +func WrapContextMarshaler(ctx context.Context, m ContextMarshaler) Marshaler { + return contextMarshalerAdapter{Context: ctx, ContextMarshaler: m} +} + +func (a contextMarshalerAdapter) MarshalGQL(w io.Writer) { + err := a.MarshalGQLContext(a.Context, w) + if err != nil { + AddError(a.Context, err) + Null.MarshalGQL(w) + } +} + type WriterFunc func(writer io.Writer) func (f WriterFunc) MarshalGQL(w io.Writer) { f(w) } +type ContextWriterFunc func(ctx context.Context, writer io.Writer) error + +func (f ContextWriterFunc) MarshalGQLContext(ctx context.Context, w io.Writer) error { + return f(ctx, w) +} + type Array []Marshaler func (a Array) MarshalGQL(writer io.Writer) { @@ -50,3 +82,8 @@ type lit struct{ b []byte } func (l lit) MarshalGQL(w io.Writer) { w.Write(l.b) } + +func (l lit) MarshalGQLContext(ctx context.Context, w io.Writer) error { + w.Write(l.b) + return nil +} diff --git a/integration/generated.go b/integration/generated.go index dca5b6006ee..90af66550d1 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -3205,7 +3205,8 @@ func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interf } func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - return graphql.MarshalBoolean(v) + res := graphql.MarshalBoolean(v) + return res } func (ec *executionContext) unmarshalOBoolean2ᚕboolᚄ(ctx context.Context, v interface{}) ([]bool, error) { @@ -3262,7 +3263,8 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast if v == nil { return graphql.Null } - return graphql.MarshalBoolean(*v) + res := graphql.MarshalBoolean(*v) + return res } func (ec *executionContext) unmarshalODATE_FILTER_OP2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋintegrationᚋmodelsᚑgoᚐDateFilterOp(ctx context.Context, v interface{}) (*models.DateFilterOp, error) { @@ -3357,7 +3359,8 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele if v == nil { return graphql.Null } - return graphql.MarshalInt(*v) + res := graphql.MarshalInt(*v) + return res } func (ec *executionContext) unmarshalOString2string(ctx context.Context, v interface{}) (string, error) { @@ -3366,7 +3369,8 @@ func (ec *executionContext) unmarshalOString2string(ctx context.Context, v inter } func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - return graphql.MarshalString(v) + res := graphql.MarshalString(v) + return res } func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { @@ -3381,7 +3385,8 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as if v == nil { return graphql.Null } - return graphql.MarshalString(*v) + res := graphql.MarshalString(*v) + return res } func (ec *executionContext) marshalOUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋintegrationᚋremote_apiᚐUser(ctx context.Context, sel ast.SelectionSet, v *remote_api.User) graphql.Marshaler { From 7db941a56e742dca10cbba1e32d4d09458cdc8ef Mon Sep 17 00:00:00 2001 From: Carl Dunham Date: Wed, 20 Oct 2021 06:06:56 -0700 Subject: [PATCH 146/146] Fix 1138: nested fieldset support (#1669) * formatting * update federation schema to latest Apollo spec * add nested FieldSet support to @key and @requires directives also: handle extra spaces in FieldSet upgrade deps in federation integration tests --- .../accounts/graph/entity.resolvers.go | 7 + .../accounts/graph/generated/federation.go | 15 + .../accounts/graph/generated/generated.go | 369 +++++++++++++- .../accounts/graph/model/models_gen.go | 13 +- .../federation/accounts/graph/schema.graphqls | 7 + .../accounts/graph/schema.resolvers.go | 7 +- example/federation/integration-test.js | 4 +- example/federation/package.json | 6 +- .../products/graph/entity.resolvers.go | 15 +- .../products/graph/generated/federation.go | 27 +- .../products/graph/generated/generated.go | 414 +++++++++++++++- .../products/graph/model/models_gen.go | 15 +- example/federation/products/graph/products.go | 15 + .../federation/products/graph/schema.graphqls | 9 +- .../reviews/graph/entity.resolvers.go | 18 +- .../reviews/graph/generated/federation.go | 22 +- .../reviews/graph/generated/generated.go | 463 +++++++++++++++--- .../federation/reviews/graph/model/models.go | 9 +- .../reviews/graph/model/models_gen.go | 12 + example/federation/reviews/graph/reviews.go | 6 +- .../federation/reviews/graph/schema.graphqls | 17 +- .../reviews/graph/schema.resolvers.go | 24 +- plugin/federation/federation.go | 137 +++--- plugin/federation/federation.gotpl | 18 +- plugin/federation/federation_test.go | 54 +- plugin/federation/fieldset/fieldset.go | 189 +++++++ plugin/federation/fieldset/fieldset_test.go | 77 +++ plugin/federation/test_data/schema.graphql | 36 +- 28 files changed, 1777 insertions(+), 228 deletions(-) create mode 100644 plugin/federation/fieldset/fieldset.go create mode 100644 plugin/federation/fieldset/fieldset_test.go diff --git a/example/federation/accounts/graph/entity.resolvers.go b/example/federation/accounts/graph/entity.resolvers.go index 79f530cc046..aa6cfb3a9da 100644 --- a/example/federation/accounts/graph/entity.resolvers.go +++ b/example/federation/accounts/graph/entity.resolvers.go @@ -10,6 +10,13 @@ import ( "github.com/99designs/gqlgen/example/federation/accounts/graph/model" ) +func (r *entityResolver) FindEmailHostByID(ctx context.Context, id string) (*model.EmailHost, error) { + return &model.EmailHost{ + ID: id, + Name: "Email Host " + id, + }, nil +} + func (r *entityResolver) FindUserByID(ctx context.Context, id string) (*model.User, error) { name := "User " + id if id == "1234" { diff --git a/example/federation/accounts/graph/generated/federation.go b/example/federation/accounts/graph/generated/federation.go index 095c6ab8eb9..1d7ee7ca52a 100644 --- a/example/federation/accounts/graph/generated/federation.go +++ b/example/federation/accounts/graph/generated/federation.go @@ -48,6 +48,21 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati } switch typeName { + case "EmailHost": + id0, err := ec.unmarshalNString2string(ctx, rep["id"]) + if err != nil { + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) + } + + entity, err := ec.resolvers.Entity().FindEmailHostByID(ctx, + id0) + if err != nil { + return err + } + + list[i] = entity + return nil + case "User": id0, err := ec.unmarshalNID2string(ctx, rep["id"]) if err != nil { diff --git a/example/federation/accounts/graph/generated/generated.go b/example/federation/accounts/graph/generated/generated.go index fb31df149cf..d1598942b42 100644 --- a/example/federation/accounts/graph/generated/generated.go +++ b/example/federation/accounts/graph/generated/generated.go @@ -45,8 +45,14 @@ type DirectiveRoot struct { } type ComplexityRoot struct { + EmailHost struct { + ID func(childComplexity int) int + Name func(childComplexity int) int + } + Entity struct { - FindUserByID func(childComplexity int, id string) int + FindEmailHostByID func(childComplexity int, id string) int + FindUserByID func(childComplexity int, id string) int } Query struct { @@ -56,6 +62,8 @@ type ComplexityRoot struct { } User struct { + Email func(childComplexity int) int + Host func(childComplexity int) int ID func(childComplexity int) int Username func(childComplexity int) int } @@ -66,6 +74,7 @@ type ComplexityRoot struct { } type EntityResolver interface { + FindEmailHostByID(ctx context.Context, id string) (*model.EmailHost, error) FindUserByID(ctx context.Context, id string) (*model.User, error) } type QueryResolver interface { @@ -87,6 +96,32 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { + case "EmailHost.id": + if e.complexity.EmailHost.ID == nil { + break + } + + return e.complexity.EmailHost.ID(childComplexity), true + + case "EmailHost.name": + if e.complexity.EmailHost.Name == nil { + break + } + + return e.complexity.EmailHost.Name(childComplexity), true + + case "Entity.findEmailHostByID": + if e.complexity.Entity.FindEmailHostByID == nil { + break + } + + args, err := ec.field_Entity_findEmailHostByID_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindEmailHostByID(childComplexity, args["id"].(string)), true + case "Entity.findUserByID": if e.complexity.Entity.FindUserByID == nil { break @@ -125,6 +160,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.__resolve_entities(childComplexity, args["representations"].([]map[string]interface{})), true + case "User.email": + if e.complexity.User.Email == nil { + break + } + + return e.complexity.User.Email(childComplexity), true + + case "User.host": + if e.complexity.User.Host == nil { + break + } + + return e.complexity.User.Host(childComplexity), true + case "User.id": if e.complexity.User.ID == nil { break @@ -200,8 +249,15 @@ var sources = []*ast.Source{ me: User } +type EmailHost @key(fields: "id") { + id: String! + name: String! +} + type User @key(fields: "id") { id: ID! + host: EmailHost! + email: String! username: String! } `, BuiltIn: false}, @@ -212,16 +268,17 @@ scalar _FieldSet directive @external on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) on OBJECT | INTERFACE -directive @extends on OBJECT +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive -union _Entity = User +union _Entity = EmailHost | User # fake type to build resolver interfaces for users to implement type Entity { - findUserByID(id: ID!,): User! + findEmailHostByID(id: String!,): EmailHost! + findUserByID(id: ID!,): User! } @@ -241,6 +298,21 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** +func (ec *executionContext) field_Entity_findEmailHostByID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + func (ec *executionContext) field_Entity_findUserByID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -324,6 +396,118 @@ func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArg // region **************************** field.gotpl ***************************** +func (ec *executionContext) _EmailHost_id(ctx context.Context, field graphql.CollectedField, obj *model.EmailHost) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmailHost", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _EmailHost_name(ctx context.Context, field graphql.CollectedField, obj *model.EmailHost) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmailHost", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Entity_findEmailHostByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Entity", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Entity_findEmailHostByID_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindEmailHostByID(rctx, args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.EmailHost) + fc.Result = res + return ec.marshalNEmailHost2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋaccountsᚋgraphᚋmodelᚐEmailHost(ctx, field.Selections, res) +} + func (ec *executionContext) _Entity_findUserByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -581,6 +765,76 @@ func (ec *executionContext) _User_id(ctx context.Context, field graphql.Collecte return ec.marshalNID2string(ctx, field.Selections, res) } +func (ec *executionContext) _User_host(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Host, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.EmailHost) + fc.Result = res + return ec.marshalNEmailHost2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋaccountsᚋgraphᚋmodelᚐEmailHost(ctx, field.Selections, res) +} + +func (ec *executionContext) _User_email(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _User_username(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1778,6 +2032,13 @@ func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, switch obj := (obj).(type) { case nil: return graphql.Null + case model.EmailHost: + return ec._EmailHost(ctx, sel, &obj) + case *model.EmailHost: + if obj == nil { + return graphql.Null + } + return ec._EmailHost(ctx, sel, obj) case model.User: return ec._User(ctx, sel, &obj) case *model.User: @@ -1794,6 +2055,47 @@ func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, // region **************************** object.gotpl **************************** +var emailHostImplementors = []string{"EmailHost", "_Entity"} + +func (ec *executionContext) _EmailHost(ctx context.Context, sel ast.SelectionSet, obj *model.EmailHost) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, emailHostImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmailHost") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmailHost_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmailHost_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var entityImplementors = []string{"Entity"} func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { @@ -1813,6 +2115,29 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") + case "findEmailHostByID": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findEmailHostByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) case "findUserByID": field := field @@ -1974,6 +2299,26 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { + invalids++ + } + case "host": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_host(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "email": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_email(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { invalids++ } @@ -2450,6 +2795,20 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) marshalNEmailHost2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋaccountsᚋgraphᚋmodelᚐEmailHost(ctx context.Context, sel ast.SelectionSet, v model.EmailHost) graphql.Marshaler { + return ec._EmailHost(ctx, sel, &v) +} + +func (ec *executionContext) marshalNEmailHost2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋaccountsᚋgraphᚋmodelᚐEmailHost(ctx context.Context, sel ast.SelectionSet, v *model.EmailHost) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._EmailHost(ctx, sel, v) +} + func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalID(v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/example/federation/accounts/graph/model/models_gen.go b/example/federation/accounts/graph/model/models_gen.go index 67853e2ba3d..8ccceef61fd 100644 --- a/example/federation/accounts/graph/model/models_gen.go +++ b/example/federation/accounts/graph/model/models_gen.go @@ -2,9 +2,18 @@ package model +type EmailHost struct { + ID string `json:"id"` + Name string `json:"name"` +} + +func (EmailHost) IsEntity() {} + type User struct { - ID string `json:"id"` - Username string `json:"username"` + ID string `json:"id"` + Host *EmailHost `json:"host"` + Email string `json:"email"` + Username string `json:"username"` } func (User) IsEntity() {} diff --git a/example/federation/accounts/graph/schema.graphqls b/example/federation/accounts/graph/schema.graphqls index 29581a5d29a..01c7c2e11b7 100644 --- a/example/federation/accounts/graph/schema.graphqls +++ b/example/federation/accounts/graph/schema.graphqls @@ -2,7 +2,14 @@ extend type Query { me: User } +type EmailHost @key(fields: "id") { + id: String! + name: String! +} + type User @key(fields: "id") { id: ID! + host: EmailHost! + email: String! username: String! } diff --git a/example/federation/accounts/graph/schema.resolvers.go b/example/federation/accounts/graph/schema.resolvers.go index 52184482275..266cc3b3b01 100644 --- a/example/federation/accounts/graph/schema.resolvers.go +++ b/example/federation/accounts/graph/schema.resolvers.go @@ -12,7 +12,12 @@ import ( func (r *queryResolver) Me(ctx context.Context) (*model.User, error) { return &model.User{ - ID: "1234", + ID: "1234", + Host: &model.EmailHost{ + ID: "4567", + Name: "Email Host 4567", + }, + Email: "me@example.com", Username: "Me", }, nil } diff --git a/example/federation/integration-test.js b/example/federation/integration-test.js index 17b8b5bd9bc..399177b919f 100644 --- a/example/federation/integration-test.js +++ b/example/federation/integration-test.js @@ -47,8 +47,8 @@ describe('Json', () => { "body": "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.", "product": { "__typename": "Product", - "name": "Trilby", - "upc": "top-1" + "name": "Fedora", + "upc": "top-2" } } ] diff --git a/example/federation/package.json b/example/federation/package.json index bc79f98efcc..aa2093e8c62 100644 --- a/example/federation/package.json +++ b/example/federation/package.json @@ -9,9 +9,9 @@ "author": "", "license": "ISC", "dependencies": { - "@apollo/gateway": "^0.11.7", - "apollo-server": "^2.9.16", - "graphql": "^14.6.0" + "@apollo/gateway": "^0.42.0", + "apollo-server": "^3.3.0", + "graphql": "^15.6.1" }, "devDependencies": { "apollo-cache-inmemory": "^1.6.5", diff --git a/example/federation/products/graph/entity.resolvers.go b/example/federation/products/graph/entity.resolvers.go index 54c94a7c002..1af00473615 100644 --- a/example/federation/products/graph/entity.resolvers.go +++ b/example/federation/products/graph/entity.resolvers.go @@ -10,10 +10,17 @@ import ( "github.com/99designs/gqlgen/example/federation/products/graph/model" ) -func (r *entityResolver) FindProductByUpc(ctx context.Context, upc string) (*model.Product, error) { - for _, h := range hats { - if h.Upc == upc { - return h, nil +func (r *entityResolver) FindManufacturerByID(ctx context.Context, id string) (*model.Manufacturer, error) { + return &model.Manufacturer{ + ID: id, + Name: "Millinery " + id, + }, nil +} + +func (r *entityResolver) FindProductByManufacturerIDAndID(ctx context.Context, manufacturerID string, id string) (*model.Product, error) { + for _, hat := range hats { + if hat.ID == id && hat.Manufacturer.ID == manufacturerID { + return hat, nil } } return nil, nil diff --git a/example/federation/products/graph/generated/federation.go b/example/federation/products/graph/generated/federation.go index b92e6c227ca..410d467a82d 100644 --- a/example/federation/products/graph/generated/federation.go +++ b/example/federation/products/graph/generated/federation.go @@ -48,13 +48,13 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati } switch typeName { - case "Product": - id0, err := ec.unmarshalNString2string(ctx, rep["upc"]) + case "Manufacturer": + id0, err := ec.unmarshalNString2string(ctx, rep["id"]) if err != nil { - return errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) } - entity, err := ec.resolvers.Entity().FindProductByUpc(ctx, + entity, err := ec.resolvers.Entity().FindManufacturerByID(ctx, id0) if err != nil { return err @@ -63,6 +63,25 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati list[i] = entity return nil + case "Product": + id0, err := ec.unmarshalNString2string(ctx, rep["manufacturer"].(map[string]interface{})["id"]) + if err != nil { + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "manufacturerID")) + } + id1, err := ec.unmarshalNString2string(ctx, rep["id"]) + if err != nil { + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) + } + + entity, err := ec.resolvers.Entity().FindProductByManufacturerIDAndID(ctx, + id0, id1) + if err != nil { + return err + } + + list[i] = entity + return nil + default: return errors.New("unknown type: " + typeName) } diff --git a/example/federation/products/graph/generated/generated.go b/example/federation/products/graph/generated/generated.go index 8d568c1ce03..db9b6e3a572 100644 --- a/example/federation/products/graph/generated/generated.go +++ b/example/federation/products/graph/generated/generated.go @@ -46,13 +46,21 @@ type DirectiveRoot struct { type ComplexityRoot struct { Entity struct { - FindProductByUpc func(childComplexity int, upc string) int + FindManufacturerByID func(childComplexity int, id string) int + FindProductByManufacturerIDAndID func(childComplexity int, manufacturerID string, id string) int + } + + Manufacturer struct { + ID func(childComplexity int) int + Name func(childComplexity int) int } Product struct { - Name func(childComplexity int) int - Price func(childComplexity int) int - Upc func(childComplexity int) int + ID func(childComplexity int) int + Manufacturer func(childComplexity int) int + Name func(childComplexity int) int + Price func(childComplexity int) int + Upc func(childComplexity int) int } Query struct { @@ -67,7 +75,8 @@ type ComplexityRoot struct { } type EntityResolver interface { - FindProductByUpc(ctx context.Context, upc string) (*model.Product, error) + FindManufacturerByID(ctx context.Context, id string) (*model.Manufacturer, error) + FindProductByManufacturerIDAndID(ctx context.Context, manufacturerID string, id string) (*model.Product, error) } type QueryResolver interface { TopProducts(ctx context.Context, first *int) ([]*model.Product, error) @@ -88,17 +97,57 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Entity.findProductByUpc": - if e.complexity.Entity.FindProductByUpc == nil { + case "Entity.findManufacturerByID": + if e.complexity.Entity.FindManufacturerByID == nil { + break + } + + args, err := ec.field_Entity_findManufacturerByID_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Entity.FindManufacturerByID(childComplexity, args["id"].(string)), true + + case "Entity.findProductByManufacturerIDAndID": + if e.complexity.Entity.FindProductByManufacturerIDAndID == nil { break } - args, err := ec.field_Entity_findProductByUpc_args(context.TODO(), rawArgs) + args, err := ec.field_Entity_findProductByManufacturerIDAndID_args(context.TODO(), rawArgs) if err != nil { return 0, false } - return e.complexity.Entity.FindProductByUpc(childComplexity, args["upc"].(string)), true + return e.complexity.Entity.FindProductByManufacturerIDAndID(childComplexity, args["manufacturerID"].(string), args["id"].(string)), true + + case "Manufacturer.id": + if e.complexity.Manufacturer.ID == nil { + break + } + + return e.complexity.Manufacturer.ID(childComplexity), true + + case "Manufacturer.name": + if e.complexity.Manufacturer.Name == nil { + break + } + + return e.complexity.Manufacturer.Name(childComplexity), true + + case "Product.id": + if e.complexity.Product.ID == nil { + break + } + + return e.complexity.Product.ID(childComplexity), true + + case "Product.manufacturer": + if e.complexity.Product.Manufacturer == nil { + break + } + + return e.complexity.Product.Manufacturer(childComplexity), true case "Product.name": if e.complexity.Product.Name == nil { @@ -213,7 +262,14 @@ var sources = []*ast.Source{ topProducts(first: Int = 5): [Product] } -type Product @key(fields: "upc") { +type Manufacturer @key(fields: "id") { + id: String! + name: String! +} + +type Product @key(fields: "manufacturer { id } id") { + id: String! + manufacturer: Manufacturer! upc: String! name: String! price: Int! @@ -226,16 +282,17 @@ scalar _FieldSet directive @external on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) on OBJECT | INTERFACE -directive @extends on OBJECT +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive -union _Entity = Product +union _Entity = Manufacturer | Product # fake type to build resolver interfaces for users to implement type Entity { - findProductByUpc(upc: String!,): Product! + findManufacturerByID(id: String!,): Manufacturer! + findProductByManufacturerIDAndID(manufacturerID: String!,id: String!,): Product! } @@ -255,18 +312,42 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** -func (ec *executionContext) field_Entity_findProductByUpc_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { +func (ec *executionContext) field_Entity_findManufacturerByID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Entity_findProductByManufacturerIDAndID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} var arg0 string - if tmp, ok := rawArgs["upc"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("upc")) + if tmp, ok := rawArgs["manufacturerID"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("manufacturerID")) arg0, err = ec.unmarshalNString2string(ctx, tmp) if err != nil { return nil, err } } - args["upc"] = arg0 + args["manufacturerID"] = arg0 + var arg1 string + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg1, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg1 return args, nil } @@ -353,7 +434,7 @@ func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArg // region **************************** field.gotpl ***************************** -func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { +func (ec *executionContext) _Entity_findManufacturerByID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -370,7 +451,7 @@ func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) rawArgs := field.ArgumentMap(ec.Variables) - args, err := ec.field_Entity_findProductByUpc_args(ctx, rawArgs) + args, err := ec.field_Entity_findManufacturerByID_args(ctx, rawArgs) if err != nil { ec.Error(ctx, err) return graphql.Null @@ -378,7 +459,49 @@ func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Entity().FindProductByUpc(rctx, args["upc"].(string)) + return ec.resolvers.Entity().FindManufacturerByID(rctx, args["id"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Manufacturer) + fc.Result = res + return ec.marshalNManufacturer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐManufacturer(ctx, field.Selections, res) +} + +func (ec *executionContext) _Entity_findProductByManufacturerIDAndID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Entity", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Entity_findProductByManufacturerIDAndID_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Entity().FindProductByManufacturerIDAndID(rctx, args["manufacturerID"].(string), args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -395,6 +518,146 @@ func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field return ec.marshalNProduct2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐProduct(ctx, field.Selections, res) } +func (ec *executionContext) _Manufacturer_id(ctx context.Context, field graphql.CollectedField, obj *model.Manufacturer) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Manufacturer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Manufacturer_name(ctx context.Context, field graphql.CollectedField, obj *model.Manufacturer) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Manufacturer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Product", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Product_manufacturer(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Product", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Manufacturer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Manufacturer) + fc.Result = res + return ec.marshalNManufacturer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐManufacturer(ctx, field.Selections, res) +} + func (ec *executionContext) _Product_upc(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1849,6 +2112,13 @@ func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, switch obj := (obj).(type) { case nil: return graphql.Null + case model.Manufacturer: + return ec._Manufacturer(ctx, sel, &obj) + case *model.Manufacturer: + if obj == nil { + return graphql.Null + } + return ec._Manufacturer(ctx, sel, obj) case model.Product: return ec._Product(ctx, sel, &obj) case *model.Product: @@ -1884,7 +2154,7 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") - case "findProductByUpc": + case "findManufacturerByID": field := field innerFunc := func(ctx context.Context) (res graphql.Marshaler) { @@ -1893,7 +2163,30 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Entity_findProductByUpc(ctx, field) + res = ec._Entity_findManufacturerByID(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "findProductByManufacturerIDAndID": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Entity_findProductByManufacturerIDAndID(ctx, field) if res == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -1918,6 +2211,47 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g return out } +var manufacturerImplementors = []string{"Manufacturer", "_Entity"} + +func (ec *executionContext) _Manufacturer(ctx context.Context, sel ast.SelectionSet, obj *model.Manufacturer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, manufacturerImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Manufacturer") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Manufacturer_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "name": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Manufacturer_name(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var productImplementors = []string{"Product", "_Entity"} func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { @@ -1928,6 +2262,26 @@ func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Product") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "manufacturer": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_manufacturer(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } case "upc": innerFunc := func(ctx context.Context) (res graphql.Marshaler) { return ec._Product_upc(ctx, field, obj) @@ -2546,6 +2900,20 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } +func (ec *executionContext) marshalNManufacturer2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐManufacturer(ctx context.Context, sel ast.SelectionSet, v model.Manufacturer) graphql.Marshaler { + return ec._Manufacturer(ctx, sel, &v) +} + +func (ec *executionContext) marshalNManufacturer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐManufacturer(ctx context.Context, sel ast.SelectionSet, v *model.Manufacturer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._Manufacturer(ctx, sel, v) +} + func (ec *executionContext) marshalNProduct2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋproductsᚋgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v model.Product) graphql.Marshaler { return ec._Product(ctx, sel, &v) } diff --git a/example/federation/products/graph/model/models_gen.go b/example/federation/products/graph/model/models_gen.go index c18b34dc211..3e86a4cc86e 100644 --- a/example/federation/products/graph/model/models_gen.go +++ b/example/federation/products/graph/model/models_gen.go @@ -2,10 +2,19 @@ package model +type Manufacturer struct { + ID string `json:"id"` + Name string `json:"name"` +} + +func (Manufacturer) IsEntity() {} + type Product struct { - Upc string `json:"upc"` - Name string `json:"name"` - Price int `json:"price"` + ID string `json:"id"` + Manufacturer *Manufacturer `json:"manufacturer"` + Upc string `json:"upc"` + Name string `json:"name"` + Price int `json:"price"` } func (Product) IsEntity() {} diff --git a/example/federation/products/graph/products.go b/example/federation/products/graph/products.go index 7c23ba7fc03..ebfdf00a612 100644 --- a/example/federation/products/graph/products.go +++ b/example/federation/products/graph/products.go @@ -4,16 +4,31 @@ import "github.com/99designs/gqlgen/example/federation/products/graph/model" var hats = []*model.Product{ { + ID: "111", + Manufacturer: &model.Manufacturer{ + ID: "1234", + Name: "Millinery 1234", + }, Upc: "top-1", Name: "Trilby", Price: 11, }, { + ID: "222", + Manufacturer: &model.Manufacturer{ + ID: "2345", + Name: "Millinery 2345", + }, Upc: "top-2", Name: "Fedora", Price: 22, }, { + ID: "333", + Manufacturer: &model.Manufacturer{ + ID: "2345", + Name: "Millinery 2345", + }, Upc: "top-3", Name: "Boater", Price: 33, diff --git a/example/federation/products/graph/schema.graphqls b/example/federation/products/graph/schema.graphqls index 02ea017a700..7e55ac996eb 100644 --- a/example/federation/products/graph/schema.graphqls +++ b/example/federation/products/graph/schema.graphqls @@ -2,7 +2,14 @@ extend type Query { topProducts(first: Int = 5): [Product] } -type Product @key(fields: "upc") { +type Manufacturer @key(fields: "id") { + id: String! + name: String! +} + +type Product @key(fields: "manufacturer { id } id") { + id: String! + manufacturer: Manufacturer! upc: String! name: String! price: Int! diff --git a/example/federation/reviews/graph/entity.resolvers.go b/example/federation/reviews/graph/entity.resolvers.go index 37c280df920..5f447f2bea0 100644 --- a/example/federation/reviews/graph/entity.resolvers.go +++ b/example/federation/reviews/graph/entity.resolvers.go @@ -10,15 +10,27 @@ import ( "github.com/99designs/gqlgen/example/federation/reviews/graph/model" ) -func (r *entityResolver) FindProductByUpc(ctx context.Context, upc string) (*model.Product, error) { +func (r *entityResolver) FindProductByManufacturerIDAndID(ctx context.Context, manufacturerID string, id string) (*model.Product, error) { + var productReviews []*model.Review + + for _, review := range reviews { + if review.Product.ID == id && review.Product.Manufacturer.ID == manufacturerID { + productReviews = append(productReviews, review) + } + } return &model.Product{ - Upc: upc, + ID: id, + Manufacturer: &model.Manufacturer{ + ID: manufacturerID, + }, + Reviews: productReviews, }, nil } func (r *entityResolver) FindUserByID(ctx context.Context, id string) (*model.User, error) { return &model.User{ - ID: id, + ID: id, + Host: &model.EmailHost{}, }, nil } diff --git a/example/federation/reviews/graph/generated/federation.go b/example/federation/reviews/graph/generated/federation.go index 3dff729b252..55391a46eae 100644 --- a/example/federation/reviews/graph/generated/federation.go +++ b/example/federation/reviews/graph/generated/federation.go @@ -49,13 +49,17 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati switch typeName { case "Product": - id0, err := ec.unmarshalNString2string(ctx, rep["upc"]) + id0, err := ec.unmarshalNString2string(ctx, rep["manufacturer"].(map[string]interface{})["id"]) if err != nil { - return errors.New(fmt.Sprintf("Field %s undefined in schema.", "upc")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "manufacturerID")) + } + id1, err := ec.unmarshalNString2string(ctx, rep["id"]) + if err != nil { + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "id")) } - entity, err := ec.resolvers.Entity().FindProductByUpc(ctx, - id0) + entity, err := ec.resolvers.Entity().FindProductByManufacturerIDAndID(ctx, + id0, id1) if err != nil { return err } @@ -75,6 +79,16 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati return err } + entity.Host.ID, err = ec.unmarshalNString2string(ctx, rep["hostID"]) + if err != nil { + return err + } + + entity.Email, err = ec.unmarshalNString2string(ctx, rep["email"]) + if err != nil { + return err + } + list[i] = entity return nil diff --git a/example/federation/reviews/graph/generated/generated.go b/example/federation/reviews/graph/generated/generated.go index 2ba1cd32126..ee3d560a206 100644 --- a/example/federation/reviews/graph/generated/generated.go +++ b/example/federation/reviews/graph/generated/generated.go @@ -38,7 +38,6 @@ type Config struct { type ResolverRoot interface { Entity() EntityResolver - Product() ProductResolver User() UserResolver } @@ -46,14 +45,23 @@ type DirectiveRoot struct { } type ComplexityRoot struct { + EmailHost struct { + ID func(childComplexity int) int + } + Entity struct { - FindProductByUpc func(childComplexity int, upc string) int - FindUserByID func(childComplexity int, id string) int + FindProductByManufacturerIDAndID func(childComplexity int, manufacturerID string, id string) int + FindUserByID func(childComplexity int, id string) int + } + + Manufacturer struct { + ID func(childComplexity int) int } Product struct { - Reviews func(childComplexity int) int - Upc func(childComplexity int) int + ID func(childComplexity int) int + Manufacturer func(childComplexity int) int + Reviews func(childComplexity int) int } Query struct { @@ -68,6 +76,8 @@ type ComplexityRoot struct { } User struct { + Email func(childComplexity int) int + Host func(childComplexity int) int ID func(childComplexity int) int Reviews func(childComplexity int) int } @@ -78,12 +88,9 @@ type ComplexityRoot struct { } type EntityResolver interface { - FindProductByUpc(ctx context.Context, upc string) (*model.Product, error) + FindProductByManufacturerIDAndID(ctx context.Context, manufacturerID string, id string) (*model.Product, error) FindUserByID(ctx context.Context, id string) (*model.User, error) } -type ProductResolver interface { - Reviews(ctx context.Context, obj *model.Product) ([]*model.Review, error) -} type UserResolver interface { Reviews(ctx context.Context, obj *model.User) ([]*model.Review, error) } @@ -103,17 +110,24 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Entity.findProductByUpc": - if e.complexity.Entity.FindProductByUpc == nil { + case "EmailHost.id": + if e.complexity.EmailHost.ID == nil { break } - args, err := ec.field_Entity_findProductByUpc_args(context.TODO(), rawArgs) + return e.complexity.EmailHost.ID(childComplexity), true + + case "Entity.findProductByManufacturerIDAndID": + if e.complexity.Entity.FindProductByManufacturerIDAndID == nil { + break + } + + args, err := ec.field_Entity_findProductByManufacturerIDAndID_args(context.TODO(), rawArgs) if err != nil { return 0, false } - return e.complexity.Entity.FindProductByUpc(childComplexity, args["upc"].(string)), true + return e.complexity.Entity.FindProductByManufacturerIDAndID(childComplexity, args["manufacturerID"].(string), args["id"].(string)), true case "Entity.findUserByID": if e.complexity.Entity.FindUserByID == nil { @@ -127,19 +141,33 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Entity.FindUserByID(childComplexity, args["id"].(string)), true - case "Product.reviews": - if e.complexity.Product.Reviews == nil { + case "Manufacturer.id": + if e.complexity.Manufacturer.ID == nil { break } - return e.complexity.Product.Reviews(childComplexity), true + return e.complexity.Manufacturer.ID(childComplexity), true + + case "Product.id": + if e.complexity.Product.ID == nil { + break + } - case "Product.upc": - if e.complexity.Product.Upc == nil { + return e.complexity.Product.ID(childComplexity), true + + case "Product.manufacturer": + if e.complexity.Product.Manufacturer == nil { break } - return e.complexity.Product.Upc(childComplexity), true + return e.complexity.Product.Manufacturer(childComplexity), true + + case "Product.reviews": + if e.complexity.Product.Reviews == nil { + break + } + + return e.complexity.Product.Reviews(childComplexity), true case "Query._service": if e.complexity.Query.__resolve__service == nil { @@ -181,6 +209,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Review.Product(childComplexity), true + case "User.email": + if e.complexity.User.Email == nil { + break + } + + return e.complexity.User.Email(childComplexity), true + + case "User.host": + if e.complexity.User.Host == nil { + break + } + + return e.complexity.User.Host(childComplexity), true + case "User.id": if e.complexity.User.ID == nil { break @@ -258,13 +300,24 @@ var sources = []*ast.Source{ product: Product! } +extend type EmailHost @key(fields: "id") { + id: String! @external +} + extend type User @key(fields: "id") { id: ID! @external - reviews: [Review] + host: EmailHost! @external + email: String! @external + reviews: [Review] @requires(fields: "host {id} email") +} + +extend type Manufacturer @key(fields: "id") { + id: String! @external } -extend type Product @key(fields: "upc") { - upc: String! @external +extend type Product @key(fields: " manufacturer{ id} id") { + id: String! @external + manufacturer: Manufacturer! @external reviews: [Review] } `, BuiltIn: false}, @@ -275,16 +328,16 @@ scalar _FieldSet directive @external on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) on OBJECT | INTERFACE -directive @extends on OBJECT +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE `, BuiltIn: true}, {Name: "federation/entity.graphql", Input: ` # a union of all types that use the @key directive -union _Entity = Product | User +union _Entity = EmailHost | Manufacturer | Product | User # fake type to build resolver interfaces for users to implement type Entity { - findProductByUpc(upc: String!,): Product! + findProductByManufacturerIDAndID(manufacturerID: String!,id: String!,): Product! findUserByID(id: ID!,): User! } @@ -305,18 +358,27 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** -func (ec *executionContext) field_Entity_findProductByUpc_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { +func (ec *executionContext) field_Entity_findProductByManufacturerIDAndID_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} var arg0 string - if tmp, ok := rawArgs["upc"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("upc")) + if tmp, ok := rawArgs["manufacturerID"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("manufacturerID")) arg0, err = ec.unmarshalNString2string(ctx, tmp) if err != nil { return nil, err } } - args["upc"] = arg0 + args["manufacturerID"] = arg0 + var arg1 string + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg1, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg1 return args, nil } @@ -403,7 +465,42 @@ func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArg // region **************************** field.gotpl ***************************** -func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { +func (ec *executionContext) _EmailHost_id(ctx context.Context, field graphql.CollectedField, obj *model.EmailHost) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "EmailHost", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Entity_findProductByManufacturerIDAndID(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -420,7 +517,7 @@ func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field ctx = graphql.WithFieldContext(ctx, fc) rawArgs := field.ArgumentMap(ec.Variables) - args, err := ec.field_Entity_findProductByUpc_args(ctx, rawArgs) + args, err := ec.field_Entity_findProductByManufacturerIDAndID_args(ctx, rawArgs) if err != nil { ec.Error(ctx, err) return graphql.Null @@ -428,7 +525,7 @@ func (ec *executionContext) _Entity_findProductByUpc(ctx context.Context, field fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Entity().FindProductByUpc(rctx, args["upc"].(string)) + return ec.resolvers.Entity().FindProductByManufacturerIDAndID(rctx, args["manufacturerID"].(string), args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -487,7 +584,42 @@ func (ec *executionContext) _Entity_findUserByID(ctx context.Context, field grap return ec.marshalNUser2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐUser(ctx, field.Selections, res) } -func (ec *executionContext) _Product_upc(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { +func (ec *executionContext) _Manufacturer_id(ctx context.Context, field graphql.CollectedField, obj *model.Manufacturer) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Manufacturer", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Product_id(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) @@ -505,7 +637,7 @@ func (ec *executionContext) _Product_upc(ctx context.Context, field graphql.Coll ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Upc, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) @@ -522,6 +654,41 @@ func (ec *executionContext) _Product_upc(ctx context.Context, field graphql.Coll return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Product_manufacturer(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Product", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Manufacturer, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Manufacturer) + fc.Result = res + return ec.marshalNManufacturer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐManufacturer(ctx, field.Selections, res) +} + func (ec *executionContext) _Product_reviews(ctx context.Context, field graphql.CollectedField, obj *model.Product) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -533,14 +700,14 @@ func (ec *executionContext) _Product_reviews(ctx context.Context, field graphql. Object: "Product", Field: field, Args: nil, - IsMethod: true, - IsResolver: true, + IsMethod: false, + IsResolver: false, } ctx = graphql.WithFieldContext(ctx, fc) resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Product().Reviews(rctx, obj) + return obj.Reviews, nil }) if err != nil { ec.Error(ctx, err) @@ -842,6 +1009,76 @@ func (ec *executionContext) _User_id(ctx context.Context, field graphql.Collecte return ec.marshalNID2string(ctx, field.Selections, res) } +func (ec *executionContext) _User_host(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Host, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.EmailHost) + fc.Result = res + return ec.marshalNEmailHost2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐEmailHost(ctx, field.Selections, res) +} + +func (ec *executionContext) _User_email(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "User", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Email, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + func (ec *executionContext) _User_reviews(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2036,6 +2273,20 @@ func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, switch obj := (obj).(type) { case nil: return graphql.Null + case model.EmailHost: + return ec._EmailHost(ctx, sel, &obj) + case *model.EmailHost: + if obj == nil { + return graphql.Null + } + return ec._EmailHost(ctx, sel, obj) + case model.Manufacturer: + return ec._Manufacturer(ctx, sel, &obj) + case *model.Manufacturer: + if obj == nil { + return graphql.Null + } + return ec._Manufacturer(ctx, sel, obj) case model.Product: return ec._Product(ctx, sel, &obj) case *model.Product: @@ -2059,6 +2310,37 @@ func (ec *executionContext) __Entity(ctx context.Context, sel ast.SelectionSet, // region **************************** object.gotpl **************************** +var emailHostImplementors = []string{"EmailHost", "_Entity"} + +func (ec *executionContext) _EmailHost(ctx context.Context, sel ast.SelectionSet, obj *model.EmailHost) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, emailHostImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EmailHost") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._EmailHost_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var entityImplementors = []string{"Entity"} func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { @@ -2078,7 +2360,7 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Entity") - case "findProductByUpc": + case "findProductByManufacturerIDAndID": field := field innerFunc := func(ctx context.Context) (res graphql.Marshaler) { @@ -2087,7 +2369,7 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Entity_findProductByUpc(ctx, field) + res = ec._Entity_findProductByManufacturerIDAndID(ctx, field) if res == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -2135,6 +2417,37 @@ func (ec *executionContext) _Entity(ctx context.Context, sel ast.SelectionSet) g return out } +var manufacturerImplementors = []string{"Manufacturer", "_Entity"} + +func (ec *executionContext) _Manufacturer(ctx context.Context, sel ast.SelectionSet, obj *model.Manufacturer) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, manufacturerImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Manufacturer") + case "id": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Manufacturer_id(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var productImplementors = []string{"Product", "_Entity"} func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, obj *model.Product) graphql.Marshaler { @@ -2145,33 +2458,33 @@ func (ec *executionContext) _Product(ctx context.Context, sel ast.SelectionSet, switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Product") - case "upc": + case "id": innerFunc := func(ctx context.Context) (res graphql.Marshaler) { - return ec._Product_upc(ctx, field, obj) + return ec._Product_id(ctx, field, obj) } out.Values[i] = innerFunc(ctx) if out.Values[i] == graphql.Null { - atomic.AddUint32(&invalids, 1) + invalids++ + } + case "manufacturer": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._Product_manufacturer(ctx, field, obj) } - case "reviews": - field := field + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "reviews": innerFunc := func(ctx context.Context) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Product_reviews(ctx, field, obj) - return res + return ec._Product_reviews(ctx, field, obj) } - out.Concurrently(i, func() graphql.Marshaler { - return innerFunc(ctx) + out.Values[i] = innerFunc(ctx) - }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2341,6 +2654,26 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "host": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_host(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + + if out.Values[i] == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + case "email": + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + return ec._User_email(ctx, field, obj) + } + + out.Values[i] = innerFunc(ctx) + if out.Values[i] == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -2824,6 +3157,16 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) marshalNEmailHost2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐEmailHost(ctx context.Context, sel ast.SelectionSet, v *model.EmailHost) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._EmailHost(ctx, sel, v) +} + func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalID(v) return res, graphql.ErrorOnPath(ctx, err) @@ -2839,6 +3182,16 @@ func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.Selec return res } +func (ec *executionContext) marshalNManufacturer2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐManufacturer(ctx context.Context, sel ast.SelectionSet, v *model.Manufacturer) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._Manufacturer(ctx, sel, v) +} + func (ec *executionContext) marshalNProduct2githubᚗcomᚋ99designsᚋgqlgenᚋexampleᚋfederationᚋreviewsᚋgraphᚋmodelᚐProduct(ctx context.Context, sel ast.SelectionSet, v model.Product) graphql.Marshaler { return ec._Product(ctx, sel, &v) } diff --git a/example/federation/reviews/graph/model/models.go b/example/federation/reviews/graph/model/models.go index 51394035234..af4eb24755a 100644 --- a/example/federation/reviews/graph/model/models.go +++ b/example/federation/reviews/graph/model/models.go @@ -1,7 +1,9 @@ package model type Product struct { - Upc string `json:"upc"` + ID string `json:"id"` + Manufacturer *Manufacturer `json:"manufacturer"` + Reviews []*Review `json:"reviews"` } func (Product) IsEntity() {} @@ -13,7 +15,10 @@ type Review struct { } type User struct { - ID string `json:"id"` + ID string `json:"id"` + Host *EmailHost `json:"host"` + Email string `json:"email"` + // Reviews []*Review `json:"reviews"` } func (User) IsEntity() {} diff --git a/example/federation/reviews/graph/model/models_gen.go b/example/federation/reviews/graph/model/models_gen.go index 8e0d251dce1..5cd133b3330 100644 --- a/example/federation/reviews/graph/model/models_gen.go +++ b/example/federation/reviews/graph/model/models_gen.go @@ -1,3 +1,15 @@ // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. package model + +type EmailHost struct { + ID string `json:"id"` +} + +func (EmailHost) IsEntity() {} + +type Manufacturer struct { + ID string `json:"id"` +} + +func (Manufacturer) IsEntity() {} diff --git a/example/federation/reviews/graph/reviews.go b/example/federation/reviews/graph/reviews.go index c30a84fe319..922ed1446f2 100644 --- a/example/federation/reviews/graph/reviews.go +++ b/example/federation/reviews/graph/reviews.go @@ -5,17 +5,17 @@ import "github.com/99designs/gqlgen/example/federation/reviews/graph/model" var reviews = []*model.Review{ { Body: "A highly effective form of birth control.", - Product: &model.Product{Upc: "top-1"}, + Product: &model.Product{ID: "111", Manufacturer: &model.Manufacturer{ID: "1234"}}, Author: &model.User{ID: "1234"}, }, { Body: "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.", - Product: &model.Product{Upc: "top-1"}, + Product: &model.Product{ID: "222", Manufacturer: &model.Manufacturer{ID: "2345"}}, Author: &model.User{ID: "1234"}, }, { Body: "This is the last straw. Hat you will wear. 11/10", - Product: &model.Product{Upc: "top-1"}, + Product: &model.Product{ID: "333", Manufacturer: &model.Manufacturer{ID: "2345"}}, Author: &model.User{ID: "7777"}, }, } diff --git a/example/federation/reviews/graph/schema.graphqls b/example/federation/reviews/graph/schema.graphqls index 72cfcf3a3c8..fde407128ed 100644 --- a/example/federation/reviews/graph/schema.graphqls +++ b/example/federation/reviews/graph/schema.graphqls @@ -4,12 +4,23 @@ type Review { product: Product! } +extend type EmailHost @key(fields: "id") { + id: String! @external +} + extend type User @key(fields: "id") { id: ID! @external - reviews: [Review] + host: EmailHost! @external + email: String! @external + reviews: [Review] @requires(fields: "host {id} email") +} + +extend type Manufacturer @key(fields: "id") { + id: String! @external } -extend type Product @key(fields: "upc") { - upc: String! @external +extend type Product @key(fields: " manufacturer{ id} id") { + id: String! @external + manufacturer: Manufacturer! @external reviews: [Review] } diff --git a/example/federation/reviews/graph/schema.resolvers.go b/example/federation/reviews/graph/schema.resolvers.go index 572a6be6e8d..5876306ecb5 100644 --- a/example/federation/reviews/graph/schema.resolvers.go +++ b/example/federation/reviews/graph/schema.resolvers.go @@ -10,35 +10,17 @@ import ( "github.com/99designs/gqlgen/example/federation/reviews/graph/model" ) -func (r *productResolver) Reviews(ctx context.Context, obj *model.Product) ([]*model.Review, error) { - var res []*model.Review - - for _, review := range reviews { - if review.Product.Upc == obj.Upc { - res = append(res, review) - } - } - - return res, nil -} - func (r *userResolver) Reviews(ctx context.Context, obj *model.User) ([]*model.Review, error) { - var res []*model.Review - + var productReviews []*model.Review for _, review := range reviews { if review.Author.ID == obj.ID { - res = append(res, review) + productReviews = append(productReviews, review) } } - - return res, nil + return productReviews, nil } -// Product returns generated.ProductResolver implementation. -func (r *Resolver) Product() generated.ProductResolver { return &productResolver{r} } - // User returns generated.UserResolver implementation. func (r *Resolver) User() generated.UserResolver { return &userResolver{r} } -type productResolver struct{ *Resolver } type userResolver struct{ *Resolver } diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go index cdcea8c4f0c..dd1b8ca38ed 100644 --- a/plugin/federation/federation.go +++ b/plugin/federation/federation.go @@ -3,7 +3,6 @@ package federation import ( "fmt" "sort" - "strings" "github.com/vektah/gqlparser/v2/ast" @@ -11,6 +10,7 @@ import ( "github.com/99designs/gqlgen/codegen/config" "github.com/99designs/gqlgen/codegen/templates" "github.com/99designs/gqlgen/plugin" + "github.com/99designs/gqlgen/plugin/federation/fieldset" ) type federation struct { @@ -75,8 +75,8 @@ scalar _FieldSet directive @external on FIELD_DEFINITION directive @requires(fields: _FieldSet!) on FIELD_DEFINITION directive @provides(fields: _FieldSet!) on FIELD_DEFINITION -directive @key(fields: _FieldSet!) on OBJECT | INTERFACE -directive @extends on OBJECT +directive @key(fields: _FieldSet!) repeatable on OBJECT | INTERFACE +directive @extends on OBJECT | INTERFACE `, BuiltIn: true, } @@ -97,12 +97,11 @@ func (f *federation) InjectSourceLate(schema *ast.Schema) *ast.Source { if e.ResolverName != "" { resolverArgs := "" - for _, field := range e.KeyFields { - resolverArgs += fmt.Sprintf("%s: %s,", field.Field.Name, field.Field.Type.String()) + for _, keyField := range e.KeyFields { + resolverArgs += fmt.Sprintf("%s: %s,", keyField.Field.ToGoPrivate(), keyField.Definition.Type.String()) } resolvers += fmt.Sprintf("\t%s(%s): %s!\n", e.ResolverName, resolverArgs, e.Def.Name) } - } if len(f.Entities) == 0 { @@ -152,22 +151,16 @@ type Entity struct { } type KeyField struct { - Field *ast.FieldDefinition - TypeReference *config.TypeReference // The Go representation of that field type + Definition *ast.FieldDefinition + Field fieldset.Field // len > 1 for nested fields + Type *config.TypeReference // The Go representation of that field type } // Requires represents an @requires clause type Requires struct { - Name string // the name of the field - Fields []*RequireField // the name of the sibling fields -} - -// RequireField is similar to an entity but it is a field not -// an object -type RequireField struct { - Name string // The same name as the type declaration - NameGo string // The Go struct field name - TypeReference *config.TypeReference // The Go representation of that field type + Name string // the name of the field + Field fieldset.Field // source Field, len > 1 for nested fields + Type *config.TypeReference // The Go representation of that field type } func (e *Entity) allFieldsAreExternal() bool { @@ -186,22 +179,27 @@ func (f *federation) GenerateCode(data *codegen.Data) error { } for _, e := range f.Entities { obj := data.Objects.ByName(e.Def.Name) - for _, field := range obj.Fields { - // Storing key fields in a slice rather than a map - // to preserve insertion order at the tradeoff of higher - // lookup complexity. - keyField := f.getKeyField(e.KeyFields, field.Name) - if keyField != nil { - keyField.TypeReference = field.TypeReference + + // fill in types for key fields + // + for _, keyField := range e.KeyFields { + if len(keyField.Field) == 0 { + fmt.Println("skipping key field " + keyField.Definition.Name + " in " + e.Def.Name) + continue } - for _, r := range e.Requires { - for _, rf := range r.Fields { - if rf.Name == field.Name { - rf.TypeReference = field.TypeReference - rf.NameGo = field.GoFieldName - } - } + cgField := keyField.Field.TypeReference(obj, data.Objects) + keyField.Type = cgField.TypeReference + } + + // fill in types for requires fields + // + for _, reqField := range e.Requires { + if len(reqField.Field) == 0 { + fmt.Println("skipping requires field " + reqField.Name + " in " + e.Def.Name) + continue } + cgField := reqField.Field.TypeReference(obj, data.Objects) + reqField.Type = cgField.TypeReference } } } @@ -215,64 +213,63 @@ func (f *federation) GenerateCode(data *codegen.Data) error { }) } -func (f *federation) getKeyField(keyFields []*KeyField, fieldName string) *KeyField { - for _, field := range keyFields { - if field.Field.Name == fieldName { - return field - } - } - return nil -} - func (f *federation) setEntities(schema *ast.Schema) { for _, schemaType := range schema.Types { + if schemaType.Kind == ast.Interface { + // TODO: support @key and @extends for interfaces + if dir := schemaType.Directives.ForName("key"); dir != nil { + panic("@key directive is not currently supported for interfaces.") + } + if dir := schemaType.Directives.ForName("extends"); dir != nil { + panic("@extends directive is not currently supported for interfaces.") + } + continue + } if schemaType.Kind == ast.Object { - dir := schemaType.Directives.ForName("key") // TODO: interfaces - if dir != nil { - if len(dir.Arguments) > 1 { - panic("Multiple arguments are not currently supported in @key declaration.") - } - fieldName := dir.Arguments[0].Value.Raw // TODO: multiple arguments - if strings.Contains(fieldName, "{") { - panic("Nested fields are not currently supported in @key declaration.") + keys := schemaType.Directives.ForNames("key") + if len(keys) > 1 { + // TODO: support multiple keys -- multiple resolvers per Entity + panic("only one @key directive currently supported") + } + + if len(keys) > 0 { + dir := keys[0] + if len(dir.Arguments) != 1 || dir.Arguments[0].Name != "fields" { + panic("Exactly one `fields` argument needed for @key declaration.") } + arg := dir.Arguments[0] + keyFieldSet := fieldset.New(arg.Value.Raw, nil) + // TODO: why is this nested inside the @key handling? -- because it's per-Entity, and we make one per @key requires := []*Requires{} for _, f := range schemaType.Fields { dir := f.Directives.ForName("requires") if dir == nil { continue } - args := dir.Arguments[0].Value.Raw - if strings.Contains(args, "{") { - // TODO: see. https://github.com/99designs/gqlgen/issues/1138 - panic("Nested fields are not currently supported in @requires declaration.") - } - fields := strings.Split(args, " ") - requireFields := []*RequireField{} - for _, f := range fields { - requireFields = append(requireFields, &RequireField{ - Name: f, + requiresFieldSet := fieldset.New(dir.Arguments[0].Value.Raw, nil) + for _, field := range requiresFieldSet { + requires = append(requires, &Requires{ + Name: field.ToGoPrivate(), + Field: field, }) } - requires = append(requires, &Requires{ - Name: f.Name, - Fields: requireFields, - }) } - fieldNames := strings.Split(fieldName, " ") - keyFields := make([]*KeyField, len(fieldNames)) + keyFields := make([]*KeyField, len(keyFieldSet)) resolverName := fmt.Sprintf("find%sBy", schemaType.Name) - for i, f := range fieldNames { - field := schemaType.Fields.ForName(f) + for i, field := range keyFieldSet { + def := field.FieldDefinition(schemaType, schema) - keyFields[i] = &KeyField{Field: field} + if def == nil { + panic(fmt.Sprintf("no field for %v", field)) + } + + keyFields[i] = &KeyField{Definition: def, Field: field} if i > 0 { resolverName += "And" } - resolverName += templates.ToGo(f) - + resolverName += field.ToGo() } e := &Entity{ diff --git a/plugin/federation/federation.gotpl b/plugin/federation/federation.gotpl index 33427987f01..7dbb00535d7 100644 --- a/plugin/federation/federation.gotpl +++ b/plugin/federation/federation.gotpl @@ -46,25 +46,23 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati {{ if .ResolverName }} case "{{.Def.Name}}": {{ range $i, $keyField := .KeyFields -}} - id{{$i}}, err := ec.{{.TypeReference.UnmarshalFunc}}(ctx, rep["{{$keyField.Field.Name}}"]) + id{{$i}}, err := ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Field.Join `"].(map[string]interface{})["`}}"]) if err != nil { - return errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{$keyField.Field.Name}}")) + return errors.New(fmt.Sprintf("Field %s undefined in schema.", "{{.Definition.Name}}")) } {{end}} - + entity, err := ec.resolvers.Entity().{{.ResolverName | go}}(ctx, {{ range $i, $_ := .KeyFields -}} id{{$i}}, {{end}}) if err != nil { return err } - + {{ range .Requires }} - {{ range .Fields}} - entity.{{.NameGo}}, err = ec.{{.TypeReference.UnmarshalFunc}}(ctx, rep["{{.Name}}"]) - if err != nil { - return err - } - {{ end }} + entity.{{.Field.JoinGo `.`}}, err = ec.{{.Type.UnmarshalFunc}}(ctx, rep["{{.Name}}"]) + if err != nil { + return err + } {{ end }} list[i] = entity return nil diff --git a/plugin/federation/federation_test.go b/plugin/federation/federation_test.go index f6a164e89ed..20578cf7a7a 100644 --- a/plugin/federation/federation_test.go +++ b/plugin/federation/federation_test.go @@ -10,13 +10,63 @@ import ( func TestWithEntities(t *testing.T) { f, cfg := load(t, "test_data/gqlgen.yml") - require.Equal(t, []string{"ExternalExtension", "Hello", "World"}, cfg.Schema.Types["_Entity"].Types) + require.Equal(t, []string{"ExternalExtension", "Hello", "MoreNesting", "NestedKey", "VeryNestedKey", "World"}, cfg.Schema.Types["_Entity"].Types) + + require.Len(t, cfg.Schema.Types["Entity"].Fields, 5) require.Equal(t, "findExternalExtensionByUpc", cfg.Schema.Types["Entity"].Fields[0].Name) require.Equal(t, "findHelloByName", cfg.Schema.Types["Entity"].Fields[1].Name) - require.Equal(t, "findWorldByFooAndBar", cfg.Schema.Types["Entity"].Fields[2].Name) + require.Equal(t, "findNestedKeyByIDAndHelloName", cfg.Schema.Types["Entity"].Fields[2].Name) + require.Equal(t, "findVeryNestedKeyByIDAndHelloNameAndWorldFooAndWorldBarAndMoreWorldFoo", cfg.Schema.Types["Entity"].Fields[3].Name) + require.Equal(t, "findWorldByFooAndBar", cfg.Schema.Types["Entity"].Fields[4].Name) require.NoError(t, f.MutateConfig(cfg)) + + require.Equal(t, "ExternalExtension", f.Entities[0].Name) + require.Len(t, f.Entities[0].KeyFields, 1) + require.Equal(t, "upc", f.Entities[0].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[0].KeyFields[0].Definition.Type.Name()) + + require.Equal(t, "Hello", f.Entities[1].Name) + require.Len(t, f.Entities[1].KeyFields, 1) + require.Equal(t, "name", f.Entities[1].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[1].KeyFields[0].Definition.Type.Name()) + + require.Equal(t, "MoreNesting", f.Entities[2].Name) + require.Len(t, f.Entities[2].KeyFields, 1) + require.Equal(t, "id", f.Entities[2].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[2].KeyFields[0].Definition.Type.Name()) + + require.Equal(t, "NestedKey", f.Entities[3].Name) + require.Len(t, f.Entities[3].KeyFields, 2) + require.Equal(t, "id", f.Entities[3].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[3].KeyFields[0].Definition.Type.Name()) + require.Equal(t, "helloName", f.Entities[3].KeyFields[1].Definition.Name) + require.Equal(t, "String", f.Entities[3].KeyFields[1].Definition.Type.Name()) + + require.Equal(t, "VeryNestedKey", f.Entities[4].Name) + require.Len(t, f.Entities[4].KeyFields, 5) + require.Equal(t, "id", f.Entities[4].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[4].KeyFields[0].Definition.Type.Name()) + require.Equal(t, "helloName", f.Entities[4].KeyFields[1].Definition.Name) + require.Equal(t, "String", f.Entities[4].KeyFields[1].Definition.Type.Name()) + require.Equal(t, "worldFoo", f.Entities[4].KeyFields[2].Definition.Name) + require.Equal(t, "String", f.Entities[4].KeyFields[2].Definition.Type.Name()) + require.Equal(t, "worldBar", f.Entities[4].KeyFields[3].Definition.Name) + require.Equal(t, "Int", f.Entities[4].KeyFields[3].Definition.Type.Name()) + require.Equal(t, "moreWorldFoo", f.Entities[4].KeyFields[4].Definition.Name) + require.Equal(t, "String", f.Entities[4].KeyFields[4].Definition.Type.Name()) + + require.Len(t, f.Entities[4].Requires, 2) + require.Equal(t, f.Entities[4].Requires[0].Name, "id") + require.Equal(t, f.Entities[4].Requires[1].Name, "helloSecondary") + + require.Equal(t, "World", f.Entities[5].Name) + require.Len(t, f.Entities[5].KeyFields, 2) + require.Equal(t, "foo", f.Entities[5].KeyFields[0].Definition.Name) + require.Equal(t, "String", f.Entities[5].KeyFields[0].Definition.Type.Name()) + require.Equal(t, "bar", f.Entities[5].KeyFields[1].Definition.Name) + require.Equal(t, "Int", f.Entities[5].KeyFields[1].Definition.Type.Name()) } func TestNoEntities(t *testing.T) { diff --git a/plugin/federation/fieldset/fieldset.go b/plugin/federation/fieldset/fieldset.go new file mode 100644 index 00000000000..a7157ed673e --- /dev/null +++ b/plugin/federation/fieldset/fieldset.go @@ -0,0 +1,189 @@ +package fieldset + +import ( + "fmt" + "strings" + + "github.com/99designs/gqlgen/codegen" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/v2/ast" +) + +// Set represents a FieldSet that is used in federation directives @key and @requires. +// Would be happier to reuse FieldSet parsing from gqlparser, but this suits for now. +// +type Set []Field + +// Field represents a single field in a FieldSet +// +type Field []string + +// New parses a FieldSet string into a TinyFieldSet. +// +func New(raw string, prefix []string) Set { + if !strings.Contains(raw, "{") { + return parseUnnestedKeyFieldSet(raw, prefix) + } + + var ( + ret = Set{} + subPrefix = prefix + ) + before, during, after := extractSubs(raw) + + if before != "" { + befores := New(before, prefix) + if len(befores) > 0 { + subPrefix = befores[len(befores)-1] + ret = append(ret, befores[:len(befores)-1]...) + } + } + if during != "" { + ret = append(ret, New(during, subPrefix)...) + } + if after != "" { + ret = append(ret, New(after, prefix)...) + } + return ret +} + +// FieldDefinition looks up a field in the type. +// +func (f Field) FieldDefinition(schemaType *ast.Definition, schema *ast.Schema) *ast.FieldDefinition { + objType := schemaType + def := objType.Fields.ForName(f[0]) + + for _, part := range f[1:] { + if objType.Kind != ast.Object { + panic(fmt.Sprintf(`invalid sub-field reference "%s" in %v: `, objType.Name, f)) + } + x := def.Type.Name() + objType = schema.Types[x] + if objType == nil { + panic("invalid schema type: " + x) + } + def = objType.Fields.ForName(part) + } + if def == nil { + return nil + } + ret := *def // shallow copy + ret.Name = f.ToGoPrivate() + + return &ret +} + +// TypeReference looks up the type of a field. +// +func (f Field) TypeReference(obj *codegen.Object, objects codegen.Objects) *codegen.Field { + var def *codegen.Field + + for _, part := range f { + def = fieldByName(obj, part) + if def == nil { + panic("unable to find field " + f[0]) + } + obj = objects.ByName(def.TypeReference.Definition.Name) + } + return def +} + +// ToGo converts a (possibly nested) field into a proper public Go name. +// +func (f Field) ToGo() string { + var ret string + + for _, field := range f { + ret += templates.ToGo(field) + } + return ret +} + +// ToGoPrivate converts a (possibly nested) field into a proper private Go name. +// +func (f Field) ToGoPrivate() string { + var ret string + + for i, field := range f { + if i == 0 { + ret += templates.ToGoPrivate(field) + continue + } + ret += templates.ToGo(field) + } + return ret +} + +// Join concatenates the field parts with a string separator between. Useful in templates. +// +func (f Field) Join(str string) string { + return strings.Join(f, str) +} + +// JoinGo concatenates the Go name of field parts with a string separator between. Useful in templates. +// +func (f Field) JoinGo(str string) string { + strs := []string{} + + for _, s := range f { + strs = append(strs, templates.ToGo(s)) + } + return strings.Join(strs, str) +} + +// local functions + +// parseUnnestedKeyFieldSet // handles simple case where none of the fields are nested. +// +func parseUnnestedKeyFieldSet(raw string, prefix []string) Set { + ret := Set{} + + for _, s := range strings.Fields(raw) { + next := append(prefix[:], s) //nolint:gocritic // slicing out on purpose + ret = append(ret, next) + } + return ret +} + +// extractSubs splits out and trims sub-expressions from before, inside, and after "{}". +// +func extractSubs(str string) (string, string, string) { + start := strings.Index(str, "{") + end := matchingBracketIndex(str, start) + + if start < 0 || end < 0 { + panic("invalid key fieldSet: " + str) + } + return strings.TrimSpace(str[:start]), strings.TrimSpace(str[start+1 : end]), strings.TrimSpace(str[end+1:]) +} + +// matchingBracketIndex returns the index of the closing bracket, assuming an open bracket at start. +// +func matchingBracketIndex(str string, start int) int { + if start < 0 || len(str) <= start+1 { + return -1 + } + var depth int + + for i, c := range str[start+1:] { + switch c { + case '{': + depth++ + case '}': + if depth == 0 { + return start + 1 + i + } + depth-- + } + } + return -1 +} + +func fieldByName(obj *codegen.Object, name string) *codegen.Field { + for _, field := range obj.Fields { + if field.Name == name { + return field + } + } + return nil +} diff --git a/plugin/federation/fieldset/fieldset_test.go b/plugin/federation/fieldset/fieldset_test.go new file mode 100644 index 00000000000..dd4b9046e62 --- /dev/null +++ b/plugin/federation/fieldset/fieldset_test.go @@ -0,0 +1,77 @@ +package fieldset + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestUnnestedWithoutPrefix(t *testing.T) { + fieldSet := New("foo bar", nil) + + require.Len(t, fieldSet, 2) + + require.Len(t, fieldSet[0], 1) + require.Equal(t, "foo", fieldSet[0][0]) + + require.Len(t, fieldSet[1], 1) + require.Equal(t, "bar", fieldSet[1][0]) +} + +func TestNestedWithoutPrefix(t *testing.T) { + fieldSet := New("foo bar { baz} a b {c{d}}e", nil) + + require.Len(t, fieldSet, 5) + + require.Len(t, fieldSet[0], 1) + require.Equal(t, "foo", fieldSet[0][0]) + + require.Len(t, fieldSet[1], 2) + require.Equal(t, "bar", fieldSet[1][0]) + require.Equal(t, "baz", fieldSet[1][1]) + + require.Len(t, fieldSet[2], 1) + require.Equal(t, "a", fieldSet[2][0]) + + require.Len(t, fieldSet[3], 3) + require.Equal(t, "b", fieldSet[3][0]) + require.Equal(t, "c", fieldSet[3][1]) + require.Equal(t, "d", fieldSet[3][2]) + + require.Len(t, fieldSet[4], 1) + require.Equal(t, "e", fieldSet[4][0]) +} + +func TestWithPrefix(t *testing.T) { + fieldSet := New("foo bar{id}", []string{"prefix"}) + + require.Len(t, fieldSet, 2) + + require.Len(t, fieldSet[0], 2) + require.Equal(t, "prefix", fieldSet[0][0]) + require.Equal(t, "foo", fieldSet[0][1]) + + require.Len(t, fieldSet[1], 3) + require.Equal(t, "prefix", fieldSet[1][0]) + require.Equal(t, "bar", fieldSet[1][1]) + require.Equal(t, "id", fieldSet[1][2]) +} + +func TestInvalid(t *testing.T) { + + require.Panics(t, func() { + New("foo bar{baz", nil) + }) +} + +func TestToGo(t *testing.T) { + require.Equal(t, Field{"foo"}.ToGo(), "Foo") + require.Equal(t, Field{"foo", "bar"}.ToGo(), "FooBar") + require.Equal(t, Field{"bar", "id"}.ToGo(), "BarID") +} + +func TestToGoPrivate(t *testing.T) { + require.Equal(t, Field{"foo"}.ToGoPrivate(), "foo") + require.Equal(t, Field{"foo", "bar"}.ToGoPrivate(), "fooBar") + require.Equal(t, Field{"bar", "id"}.ToGoPrivate(), "barID") +} diff --git a/plugin/federation/test_data/schema.graphql b/plugin/federation/test_data/schema.graphql index a47f8b224aa..cf5a72004e5 100644 --- a/plugin/federation/test_data/schema.graphql +++ b/plugin/federation/test_data/schema.graphql @@ -1,18 +1,40 @@ type Hello @key(fields: "name") { - name: String! + name: String! + secondary: String! } -type World @key(fields: "foo bar") { - foo: String! - bar: Int! +type World @key(fields: " foo bar ") { + foo: String! + bar: Int! } -extend type ExternalExtension @key(fields: "upc") { +extend type ExternalExtension @key(fields: " upc ") { upc: String! @external reviews: [World] } +extend type NestedKey @key(fields: "id hello { name}") { + id: String! @external + hello: Hello +} + +extend type MoreNesting @key(fields: "id") { + id: String! @external + world: World! @external +} + +extend type VeryNestedKey + @key( + fields: "id hello { name} world {foo } world{bar} more { world { foo }}" + ) { + id: String! @external + hello: Hello + world: World + nested: NestedKey @requires(fields: "id hello {secondary }") + more: MoreNesting +} + type Query { - hello: Hello! - world: World! + hello: Hello! + world: World! }