aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs')
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/gen.go60
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/init.go162
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/root.go53
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/version.go16
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/ambient.go10
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/build.go78
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/codegen.go7
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/config.go98
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/directive_build.go1
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/import.go29
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/import_build.go120
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/input_build.go4
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/interface_build.go19
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/model.go1
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/models_build.go9
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/object.go33
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/object_build.go18
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/data.go10
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl10
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl52
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/import.go135
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl27
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl21
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl12
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/templates.go48
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/type.go16
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/type_build.go3
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/util.go68
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/context.go45
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/float.go2
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go52
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/type.go18
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/response.go8
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/tracer.go58
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/version.go2
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/context.go57
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/graphql.go386
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/playground.go2
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/websocket.go16
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/imports/prune.go119
40 files changed, 1402 insertions, 483 deletions
diff --git a/vendor/github.com/99designs/gqlgen/cmd/gen.go b/vendor/github.com/99designs/gqlgen/cmd/gen.go
new file mode 100644
index 00000000..3842f02b
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/cmd/gen.go
@@ -0,0 +1,60 @@
+package cmd
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/pkg/errors"
+ "github.com/urfave/cli"
+)
+
+var genCmd = cli.Command{
+ Name: "generate",
+ Usage: "generate a graphql server based on schema",
+ Flags: []cli.Flag{
+ cli.BoolFlag{Name: "verbose, v", Usage: "show logs"},
+ cli.StringFlag{Name: "config, c", Usage: "the config filename"},
+ },
+ Action: func(ctx *cli.Context) {
+ var config *codegen.Config
+ var err error
+ if configFilename := ctx.String("config"); configFilename != "" {
+ config, err = codegen.LoadConfig(configFilename)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+ } else {
+ config, err = codegen.LoadConfigFromDefaultLocations()
+ if os.IsNotExist(errors.Cause(err)) {
+ config = codegen.DefaultConfig()
+ } else if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+ }
+
+ for _, filename := range config.SchemaFilename {
+ var schemaRaw []byte
+ schemaRaw, err = ioutil.ReadFile(filename)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to open schema: "+err.Error())
+ os.Exit(1)
+ }
+ config.SchemaStr[filename] = string(schemaRaw)
+ }
+
+ if err = config.Check(); err != nil {
+ fmt.Fprintln(os.Stderr, "invalid config format: "+err.Error())
+ os.Exit(1)
+ }
+
+ err = codegen.Generate(*config)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(2)
+ }
+ },
+}
diff --git a/vendor/github.com/99designs/gqlgen/cmd/init.go b/vendor/github.com/99designs/gqlgen/cmd/init.go
new file mode 100644
index 00000000..1e7c18b9
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/cmd/init.go
@@ -0,0 +1,162 @@
+package cmd
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/pkg/errors"
+ "github.com/urfave/cli"
+ "gopkg.in/yaml.v2"
+)
+
+var configComment = `
+# .gqlgen.yml example
+#
+# Refer to https://gqlgen.com/config/
+# for detailed .gqlgen.yml documentation.
+`
+
+var schemaDefault = `
+# GraphQL schema example
+#
+# https://gqlgen.com/getting-started/
+
+type Todo {
+ id: ID!
+ text: String!
+ done: Boolean!
+ user: User!
+}
+
+type User {
+ id: ID!
+ name: String!
+}
+
+type Query {
+ todos: [Todo!]!
+}
+
+input NewTodo {
+ text: String!
+ userId: String!
+}
+
+type Mutation {
+ createTodo(input: NewTodo!): Todo!
+}
+`
+
+var initCmd = cli.Command{
+ Name: "init",
+ 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: "server", Usage: "where to write the server stub to", Value: "server/server.go"},
+ cli.StringFlag{Name: "schema", Usage: "where to write the schema stub to", Value: "schema.graphql"},
+ },
+ Action: func(ctx *cli.Context) {
+ initSchema(ctx.String("schema"))
+ config := initConfig(ctx)
+
+ GenerateGraphServer(config, ctx.String("server"))
+ },
+}
+
+func GenerateGraphServer(config *codegen.Config, serverFilename string) {
+ for _, filename := range config.SchemaFilename {
+ schemaRaw, err := ioutil.ReadFile(filename)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to open schema: "+err.Error())
+ os.Exit(1)
+ }
+ config.SchemaStr[filename] = string(schemaRaw)
+ }
+
+ if err := config.Check(); err != nil {
+ fmt.Fprintln(os.Stderr, "invalid config format: "+err.Error())
+ os.Exit(1)
+ }
+
+ if err := codegen.Generate(*config); err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+
+ if err := codegen.GenerateServer(*config, serverFilename); err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+
+ fmt.Fprintf(os.Stdout, "Exec \"go run ./%s\" to start GraphQL server\n", serverFilename)
+}
+
+func initConfig(ctx *cli.Context) *codegen.Config {
+ var config *codegen.Config
+ var err error
+ configFilename := ctx.String("config")
+ if configFilename != "" {
+ config, err = codegen.LoadConfig(configFilename)
+ } else {
+ config, err = codegen.LoadConfigFromDefaultLocations()
+ }
+
+ if config != nil {
+ fmt.Fprintf(os.Stderr, "init failed: a configuration file already exists at %s\n", config.FilePath)
+ os.Exit(1)
+ }
+
+ if !os.IsNotExist(errors.Cause(err)) {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+
+ if configFilename == "" {
+ configFilename = "gqlgen.yml"
+ }
+ config = codegen.DefaultConfig()
+
+ config.Resolver = codegen.PackageConfig{
+ Filename: "resolver.go",
+ Type: "Resolver",
+ }
+
+ var buf bytes.Buffer
+ buf.WriteString(strings.TrimSpace(configComment))
+ buf.WriteString("\n\n")
+ {
+ var b []byte
+ b, err = yaml.Marshal(config)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to marshal yaml: "+err.Error())
+ os.Exit(1)
+ }
+ buf.Write(b)
+ }
+
+ err = ioutil.WriteFile(configFilename, buf.Bytes(), 0644)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to write config file: "+err.Error())
+ os.Exit(1)
+ }
+
+ return config
+}
+
+func initSchema(schemaFilename string) {
+ _, err := os.Stat(schemaFilename)
+ if !os.IsNotExist(err) {
+ return
+ }
+
+ err = ioutil.WriteFile(schemaFilename, []byte(strings.TrimSpace(schemaDefault)), 0644)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to write schema file: "+err.Error())
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/cmd/root.go b/vendor/github.com/99designs/gqlgen/cmd/root.go
new file mode 100644
index 00000000..519c2e1a
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/cmd/root.go
@@ -0,0 +1,53 @@
+package cmd
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+
+ "github.com/99designs/gqlgen/graphql"
+ "github.com/99designs/gqlgen/internal/gopath"
+ "github.com/urfave/cli"
+
+ // Required since otherwise dep will prune away these unused packages before codegen has a chance to run
+ _ "github.com/99designs/gqlgen/handler"
+)
+
+func Execute() {
+ app := cli.NewApp()
+ app.Name = "gqlgen"
+ app.Usage = genCmd.Usage
+ app.Description = "This is a library for quickly creating strictly typed graphql servers in golang. See https://gqlgen.com/ for a getting started guide."
+ app.HideVersion = true
+ app.Flags = genCmd.Flags
+ app.Version = graphql.Version
+ app.Before = func(context *cli.Context) error {
+ pwd, err := os.Getwd()
+ if err != nil {
+ return fmt.Errorf("unable to determine current workding dir: %s\n", err.Error())
+ }
+
+ if !gopath.Contains(pwd) {
+ return fmt.Errorf("gqlgen must be run from inside your $GOPATH\n")
+ }
+ if context.Bool("verbose") {
+ log.SetFlags(0)
+ } else {
+ log.SetOutput(ioutil.Discard)
+ }
+ return nil
+ }
+
+ app.Action = genCmd.Action
+ app.Commands = []cli.Command{
+ genCmd,
+ initCmd,
+ versionCmd,
+ }
+
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintf(os.Stderr, err.Error())
+ os.Exit(1)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/cmd/version.go b/vendor/github.com/99designs/gqlgen/cmd/version.go
new file mode 100644
index 00000000..8b7442d4
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/cmd/version.go
@@ -0,0 +1,16 @@
+package cmd
+
+import (
+ "fmt"
+
+ "github.com/99designs/gqlgen/graphql"
+ "github.com/urfave/cli"
+)
+
+var versionCmd = cli.Command{
+ Name: "version",
+ Usage: "print the version string",
+ Action: func(ctx *cli.Context) {
+ fmt.Println(graphql.Version)
+ },
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/ambient.go b/vendor/github.com/99designs/gqlgen/codegen/ambient.go
new file mode 100644
index 00000000..c9909fcc
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/ambient.go
@@ -0,0 +1,10 @@
+package codegen
+
+import (
+ // Import and ignore the ambient imports listed below so dependency managers
+ // don't prune unused code for us. Both lists should be kept in sync.
+ _ "github.com/99designs/gqlgen/graphql"
+ _ "github.com/99designs/gqlgen/graphql/introspection"
+ _ "github.com/vektah/gqlparser"
+ _ "github.com/vektah/gqlparser/ast"
+)
diff --git a/vendor/github.com/99designs/gqlgen/codegen/build.go b/vendor/github.com/99designs/gqlgen/codegen/build.go
index 42dedbf8..582689a7 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/build.go
@@ -15,25 +15,22 @@ type Build struct {
Objects Objects
Inputs Objects
Interfaces []*Interface
- Imports []*Import
QueryRoot *Object
MutationRoot *Object
SubscriptionRoot *Object
- SchemaRaw string
- SchemaFilename string
+ SchemaRaw map[string]string
+ SchemaFilename SchemaFilenames
Directives []*Directive
}
type ModelBuild struct {
PackageName string
- Imports []*Import
Models []Model
Enums []Enum
}
type ResolverBuild struct {
PackageName string
- Imports []*Import
ResolverType string
Objects Objects
ResolverFound bool
@@ -41,7 +38,6 @@ type ResolverBuild struct {
type ServerBuild struct {
PackageName string
- Imports []*Import
ExecPackageName string
ResolverPackageName string
}
@@ -50,16 +46,16 @@ type ServerBuild struct {
func (cfg *Config) models() (*ModelBuild, error) {
namedTypes := cfg.buildNamedTypes()
- progLoader := newLoader(namedTypes, true)
+ progLoader := cfg.newLoaderWithoutErrors()
+
prog, err := progLoader.Load()
if err != nil {
return nil, errors.Wrap(err, "loading failed")
}
- imports := buildImports(namedTypes, cfg.Model.Dir())
- cfg.bindTypes(imports, namedTypes, cfg.Model.Dir(), prog)
+ cfg.bindTypes(namedTypes, cfg.Model.Dir(), prog)
- models, err := cfg.buildModels(namedTypes, prog, imports)
+ models, err := cfg.buildModels(namedTypes, prog)
if err != nil {
return nil, err
}
@@ -67,13 +63,12 @@ func (cfg *Config) models() (*ModelBuild, error) {
PackageName: cfg.Model.Package,
Models: models,
Enums: cfg.buildEnums(namedTypes),
- Imports: imports.finalize(),
}, nil
}
// bind a schema together with some code to generate a Build
func (cfg *Config) resolver() (*ResolverBuild, error) {
- progLoader := newLoader(cfg.buildNamedTypes(), true)
+ progLoader := cfg.newLoaderWithoutErrors()
progLoader.Import(cfg.Resolver.ImportPath())
prog, err := progLoader.Load()
@@ -84,13 +79,10 @@ func (cfg *Config) resolver() (*ResolverBuild, error) {
destDir := cfg.Resolver.Dir()
namedTypes := cfg.buildNamedTypes()
- imports := buildImports(namedTypes, destDir)
- imports.add(cfg.Exec.ImportPath())
- imports.add("github.com/99designs/gqlgen/handler") // avoid import github.com/vektah/gqlgen/handler
- cfg.bindTypes(imports, namedTypes, destDir, prog)
+ cfg.bindTypes(namedTypes, destDir, prog)
- objects, err := cfg.buildObjects(namedTypes, prog, imports)
+ objects, err := cfg.buildObjects(namedTypes, prog)
if err != nil {
return nil, err
}
@@ -100,7 +92,6 @@ func (cfg *Config) resolver() (*ResolverBuild, error) {
return &ResolverBuild{
PackageName: cfg.Resolver.Package,
- Imports: imports.finalize(),
Objects: objects,
ResolverType: cfg.Resolver.Type,
ResolverFound: resolverFound,
@@ -108,15 +99,10 @@ func (cfg *Config) resolver() (*ResolverBuild, error) {
}
func (cfg *Config) server(destDir string) *ServerBuild {
- imports := buildImports(NamedTypes{}, destDir)
- imports.add(cfg.Exec.ImportPath())
- imports.add(cfg.Resolver.ImportPath())
-
return &ServerBuild{
PackageName: cfg.Resolver.Package,
- Imports: imports.finalize(),
- ExecPackageName: cfg.Exec.Package,
- ResolverPackageName: cfg.Resolver.Package,
+ ExecPackageName: cfg.Exec.ImportPath(),
+ ResolverPackageName: cfg.Resolver.ImportPath(),
}
}
@@ -124,21 +110,20 @@ func (cfg *Config) server(destDir string) *ServerBuild {
func (cfg *Config) bind() (*Build, error) {
namedTypes := cfg.buildNamedTypes()
- progLoader := newLoader(namedTypes, true)
+ progLoader := cfg.newLoaderWithoutErrors()
prog, err := progLoader.Load()
if err != nil {
return nil, errors.Wrap(err, "loading failed")
}
- imports := buildImports(namedTypes, cfg.Exec.Dir())
- cfg.bindTypes(imports, namedTypes, cfg.Exec.Dir(), prog)
+ cfg.bindTypes(namedTypes, cfg.Exec.Dir(), prog)
- objects, err := cfg.buildObjects(namedTypes, prog, imports)
+ objects, err := cfg.buildObjects(namedTypes, prog)
if err != nil {
return nil, err
}
- inputs, err := cfg.buildInputs(namedTypes, prog, imports)
+ inputs, err := cfg.buildInputs(namedTypes, prog)
if err != nil {
return nil, err
}
@@ -152,7 +137,6 @@ func (cfg *Config) bind() (*Build, error) {
Objects: objects,
Interfaces: cfg.buildInterfaces(namedTypes, prog),
Inputs: inputs,
- Imports: imports.finalize(),
SchemaRaw: cfg.SchemaStr,
SchemaFilename: cfg.SchemaFilename,
Directives: directives,
@@ -175,29 +159,25 @@ func (cfg *Config) bind() (*Build, error) {
}
func (cfg *Config) validate() error {
- progLoader := newLoader(cfg.buildNamedTypes(), false)
+ progLoader := cfg.newLoaderWithErrors()
_, err := progLoader.Load()
return err
}
-func newLoader(namedTypes NamedTypes, allowErrors bool) loader.Config {
+func (cfg *Config) newLoaderWithErrors() loader.Config {
conf := loader.Config{}
- if allowErrors {
- conf = loader.Config{
- AllowErrors: true,
- TypeChecker: types.Config{
- Error: func(e error) {},
- },
- }
- }
- for _, imp := range ambientImports {
- conf.Import(imp)
- }
-
- for _, imp := range namedTypes {
- if imp.Package != "" {
- conf.Import(imp.Package)
- }
+
+ for _, pkg := range cfg.Models.referencedPackages() {
+ conf.Import(pkg)
+ }
+ return conf
+}
+
+func (cfg *Config) newLoaderWithoutErrors() loader.Config {
+ conf := cfg.newLoaderWithErrors()
+ conf.AllowErrors = true
+ conf.TypeChecker = types.Config{
+ Error: func(e error) {},
}
return conf
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/codegen.go b/vendor/github.com/99designs/gqlgen/codegen/codegen.go
index 27873400..773e3db7 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/codegen.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/codegen.go
@@ -151,8 +151,13 @@ func (cfg *Config) normalize() error {
}
}
+ var sources []*ast.Source
+ for _, filename := range cfg.SchemaFilename {
+ sources = append(sources, &ast.Source{Name: filename, Input: cfg.SchemaStr[filename]})
+ }
+
var err *gqlerror.Error
- cfg.schema, err = gqlparser.LoadSchema(&ast.Source{Name: cfg.SchemaFilename, Input: cfg.SchemaStr})
+ cfg.schema, err = gqlparser.LoadSchema(sources...)
if err != nil {
return err
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config.go b/vendor/github.com/99designs/gqlgen/codegen/config.go
index db0e467b..f9df24fb 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/config.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/config.go
@@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"strings"
"github.com/99designs/gqlgen/internal/gopath"
@@ -19,7 +20,8 @@ var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"}
// DefaultConfig creates a copy of the default config
func DefaultConfig() *Config {
return &Config{
- SchemaFilename: "schema.graphql",
+ SchemaFilename: SchemaFilenames{"schema.graphql"},
+ SchemaStr: map[string]string{},
Model: PackageConfig{Filename: "models_gen.go"},
Exec: PackageConfig{Filename: "generated.go"},
}
@@ -53,19 +55,36 @@ func LoadConfig(filename string) (*Config, error) {
return nil, errors.Wrap(err, "unable to parse config")
}
+ preGlobbing := config.SchemaFilename
+ config.SchemaFilename = SchemaFilenames{}
+ for _, f := range preGlobbing {
+ matches, err := filepath.Glob(f)
+ if err != nil {
+ return nil, errors.Wrapf(err, "failed to glob schema filename %s", f)
+ }
+
+ for _, m := range matches {
+ if config.SchemaFilename.Has(m) {
+ continue
+ }
+ config.SchemaFilename = append(config.SchemaFilename, m)
+ }
+ }
+
config.FilePath = filename
+ config.SchemaStr = map[string]string{}
return config, nil
}
type Config struct {
- SchemaFilename string `yaml:"schema,omitempty"`
- SchemaStr string `yaml:"-"`
- Exec PackageConfig `yaml:"exec"`
- Model PackageConfig `yaml:"model"`
- Resolver PackageConfig `yaml:"resolver,omitempty"`
- Models TypeMap `yaml:"models,omitempty"`
- StructTag string `yaml:"struct_tag,omitempty"`
+ SchemaFilename SchemaFilenames `yaml:"schema,omitempty"`
+ SchemaStr map[string]string `yaml:"-"`
+ Exec PackageConfig `yaml:"exec"`
+ Model PackageConfig `yaml:"model"`
+ Resolver PackageConfig `yaml:"resolver,omitempty"`
+ Models TypeMap `yaml:"models,omitempty"`
+ StructTag string `yaml:"struct_tag,omitempty"`
FilePath string `yaml:"-"`
@@ -84,8 +103,37 @@ type TypeMapEntry struct {
}
type TypeMapField struct {
- Resolver bool `yaml:"resolver"`
- FieldName string `yaml:"fieldName"`
+ Resolver bool `yaml:"resolver"`
+ FieldName string `yaml:"fieldName"`
+}
+
+type SchemaFilenames []string
+
+func (a *SchemaFilenames) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ var single string
+ err := unmarshal(&single)
+ if err == nil {
+ *a = []string{single}
+ return nil
+ }
+
+ var multi []string
+ err = unmarshal(&multi)
+ if err != nil {
+ return err
+ }
+
+ *a = multi
+ return nil
+}
+
+func (a SchemaFilenames) Has(file string) bool {
+ for _, existing := range a {
+ if existing == file {
+ return true
+ }
+ }
+ return false
}
func (c *PackageConfig) normalize() error {
@@ -162,6 +210,36 @@ func (tm TypeMap) Check() error {
return nil
}
+func (tm TypeMap) referencedPackages() []string {
+ var pkgs []string
+
+ for _, typ := range tm {
+ if typ.Model == "map[string]interface{}" {
+ continue
+ }
+ pkg, _ := pkgAndType(typ.Model)
+ if pkg == "" || inStrSlice(pkgs, pkg) {
+ continue
+ }
+ pkgs = append(pkgs, pkg)
+ }
+
+ sort.Slice(pkgs, func(i, j int) bool {
+ return pkgs[i] > pkgs[j]
+ })
+ return pkgs
+}
+
+func inStrSlice(haystack []string, needle string) bool {
+ for _, v := range haystack {
+ if needle == v {
+ return true
+ }
+ }
+
+ return false
+}
+
// findCfg searches for the config file in this directory and all parents up the tree
// looking for the closest match
func findCfg() (string, error) {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go b/vendor/github.com/99designs/gqlgen/codegen/directive_build.go
index 32828841..af77dc44 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/directive_build.go
@@ -32,7 +32,6 @@ func (cfg *Config) buildDirectives(types NamedTypes) ([]*Directive, error) {
if err != nil {
return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error())
}
- newArg.StripPtr()
}
args = append(args, newArg)
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/import.go b/vendor/github.com/99designs/gqlgen/codegen/import.go
deleted file mode 100644
index b511e8f6..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/import.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package codegen
-
-import (
- "strconv"
-)
-
-type Import struct {
- Name string
- Path string
-
- alias string
-}
-
-type Imports struct {
- imports []*Import
- destDir string
-}
-
-func (i *Import) Write() string {
- return i.Alias() + " " + strconv.Quote(i.Path)
-}
-
-func (i *Import) Alias() string {
- if i.alias == "" {
- panic("alias called before imports are finalized")
- }
-
- return i.alias
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/import_build.go b/vendor/github.com/99designs/gqlgen/codegen/import_build.go
deleted file mode 100644
index d634834e..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/import_build.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package codegen
-
-import (
- "fmt"
- "go/build"
- "sort"
- "strconv"
-
- // Import and ignore the ambient imports listed below so dependency managers
- // don't prune unused code for us. Both lists should be kept in sync.
- _ "github.com/99designs/gqlgen/graphql"
- _ "github.com/99designs/gqlgen/graphql/introspection"
- "github.com/99designs/gqlgen/internal/gopath"
- _ "github.com/vektah/gqlparser"
- _ "github.com/vektah/gqlparser/ast"
-)
-
-// These imports are referenced by the generated code, and are assumed to have the
-// default alias. So lets make sure they get added first, and any later collisions get
-// renamed.
-var ambientImports = []string{
- "context",
- "fmt",
- "io",
- "strconv",
- "time",
- "sync",
- "errors",
-
- "github.com/vektah/gqlparser",
- "github.com/vektah/gqlparser/ast",
- "github.com/99designs/gqlgen/graphql",
- "github.com/99designs/gqlgen/graphql/introspection",
-}
-
-func buildImports(types NamedTypes, destDir string) *Imports {
- imports := Imports{
- destDir: destDir,
- }
-
- for _, ambient := range ambientImports {
- imports.add(ambient)
- }
-
- // Imports from top level user types
- for _, t := range types {
- t.Import = imports.add(t.Package)
- }
-
- return &imports
-}
-
-func (s *Imports) add(path string) *Import {
- if path == "" {
- return nil
- }
-
- // if we are referencing our own package we dont need an import
- if gopath.MustDir2Import(s.destDir) == path {
- return nil
- }
-
- if existing := s.findByPath(path); existing != nil {
- return existing
- }
-
- pkg, err := build.Default.Import(path, s.destDir, 0)
- if err != nil {
- panic(err)
- }
-
- imp := &Import{
- Name: pkg.Name,
- Path: path,
- }
- s.imports = append(s.imports, imp)
-
- return imp
-}
-
-func (s Imports) finalize() []*Import {
- // ensure stable ordering by sorting
- sort.Slice(s.imports, func(i, j int) bool {
- return s.imports[i].Path > s.imports[j].Path
- })
-
- for _, imp := range s.imports {
- alias := imp.Name
-
- i := 1
- for s.findByAlias(alias) != nil {
- alias = imp.Name + strconv.Itoa(i)
- i++
- if i > 10 {
- panic(fmt.Errorf("too many collisions, last attempt was %s", alias))
- }
- }
- imp.alias = alias
- }
-
- return s.imports
-}
-
-func (s Imports) findByPath(importPath string) *Import {
- for _, imp := range s.imports {
- if imp.Path == importPath {
- return imp
- }
- }
- return nil
-}
-
-func (s Imports) findByAlias(alias string) *Import {
- for _, imp := range s.imports {
- if imp.alias == alias {
- return imp
- }
- }
- return nil
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/input_build.go b/vendor/github.com/99designs/gqlgen/codegen/input_build.go
index 06ff37a0..70fa564d 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/input_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/input_build.go
@@ -9,7 +9,7 @@ import (
"golang.org/x/tools/go/loader"
)
-func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, imports *Imports) (Objects, error) {
+func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program) (Objects, error) {
var inputs Objects
for _, typ := range cfg.schema.Types {
@@ -26,7 +26,7 @@ func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, impo
}
if def != nil {
input.Marshaler = buildInputMarshaler(typ, def)
- bindErrs := bindObject(def.Type(), input, imports, cfg.StructTag)
+ bindErrs := bindObject(def.Type(), input, cfg.StructTag)
if len(bindErrs) > 0 {
return nil, bindErrs
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go
index 9f4a4ff4..92052ba6 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go
@@ -1,9 +1,7 @@
package codegen
import (
- "fmt"
"go/types"
- "os"
"sort"
"github.com/vektah/gqlparser/ast"
@@ -51,20 +49,5 @@ func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog
return true
}
- for i := 0; i < interfaceType.NumMethods(); i++ {
- intfMethod := interfaceType.Method(i)
-
- implMethod := findMethod(implementorType, intfMethod.Name())
- if implMethod == nil {
- fmt.Fprintf(os.Stderr, "missing method %s on %s\n", intfMethod.Name(), implementor.GoType)
- return false
- }
-
- sig := implMethod.Type().(*types.Signature)
- if _, isPtr := sig.Recv().Type().(*types.Pointer); isPtr {
- return false
- }
- }
-
- return true
+ return types.Implements(implementorType, interfaceType)
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/model.go b/vendor/github.com/99designs/gqlgen/codegen/model.go
index 5ba50337..bcdc8703 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/model.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/model.go
@@ -4,6 +4,7 @@ type Model struct {
*NamedType
Description string
Fields []ModelField
+ Implements []*NamedType
}
type ModelField struct {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/models_build.go b/vendor/github.com/99designs/gqlgen/codegen/models_build.go
index 9f98a07d..56d2ff1f 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/models_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/models_build.go
@@ -7,14 +7,14 @@ import (
"golang.org/x/tools/go/loader"
)
-func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports *Imports) ([]Model, error) {
+func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program) ([]Model, error) {
var models []Model
for _, typ := range cfg.schema.Types {
var model Model
switch typ.Kind {
case ast.Object:
- obj, err := cfg.buildObject(types, typ, imports)
+ obj, err := cfg.buildObject(types, typ)
if err != nil {
return nil, err
}
@@ -54,8 +54,9 @@ func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports *
func (cfg *Config) obj2Model(obj *Object) Model {
model := Model{
- NamedType: obj.NamedType,
- Fields: []ModelField{},
+ NamedType: obj.NamedType,
+ Implements: obj.Implements,
+ Fields: []ModelField{},
}
model.GoType = ucFirst(obj.GQLType)
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.go b/vendor/github.com/99designs/gqlgen/codegen/object.go
index d9f610f4..656af297 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/object.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/object.go
@@ -24,6 +24,7 @@ type Object struct {
Fields []Field
Satisfies []string
+ Implements []*NamedType
ResolverInterface *Ref
Root bool
DisableConcurrency bool
@@ -32,16 +33,17 @@ type Object struct {
type Field struct {
*Type
- Description string // Description of a field
- GQLName string // The name of the field in graphql
- GoFieldType GoFieldType // The field type in go, if any
- GoReceiverName string // The name of method & var receiver in go, if any
- GoFieldName string // The name of the method or var in go, if any
- Args []FieldArgument // A list of arguments to be passed to this field
- ForceResolver bool // Should be emit Resolver method
- NoErr bool // If this is bound to a go method, does that method have an error as the second argument
- Object *Object // A link back to the parent object
- Default interface{} // The default value
+ Description string // Description of a field
+ GQLName string // The name of the field in graphql
+ GoFieldType GoFieldType // The field type in go, if any
+ GoReceiverName string // The name of method & var receiver in go, if any
+ GoFieldName string // The name of the method or var in go, if any
+ Args []FieldArgument // A list of arguments to be passed to this field
+ ForceResolver bool // Should be emit Resolver method
+ 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
+ Object *Object // A link back to the parent object
+ Default interface{} // The default value
}
type FieldArgument struct {
@@ -102,7 +104,10 @@ func (f *Field) IsVariable() bool {
}
func (f *Field) IsConcurrent() bool {
- return f.IsResolver() && !f.Object.DisableConcurrency
+ if f.Object.DisableConcurrency {
+ return false
+ }
+ return f.MethodHasContext || f.IsResolver()
}
func (f *Field) GoNameExported() string {
@@ -203,11 +208,15 @@ func (f *Field) CallArgs() string {
var args []string
if f.IsResolver() {
- args = append(args, "ctx")
+ args = append(args, "rctx")
if !f.Object.Root {
args = append(args, "obj")
}
+ } else {
+ if f.MethodHasContext {
+ args = append(args, "ctx")
+ }
}
for _, arg := range f.Args {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object_build.go b/vendor/github.com/99designs/gqlgen/codegen/object_build.go
index ee2b2f1c..279d1eb6 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/object_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/object_build.go
@@ -9,7 +9,7 @@ import (
"golang.org/x/tools/go/loader"
)
-func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports *Imports) (Objects, error) {
+func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program) (Objects, error) {
var objects Objects
for _, typ := range cfg.schema.Types {
@@ -17,7 +17,7 @@ func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports
continue
}
- obj, err := cfg.buildObject(types, typ, imports)
+ obj, err := cfg.buildObject(types, typ)
if err != nil {
return nil, err
}
@@ -27,7 +27,7 @@ func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports
return nil, err
}
if def != nil {
- for _, bindErr := range bindObject(def.Type(), obj, imports, cfg.StructTag) {
+ for _, bindErr := range bindObject(def.Type(), obj, cfg.StructTag) {
log.Println(bindErr.Error())
log.Println(" Adding resolver method")
}
@@ -81,12 +81,11 @@ func sanitizeArgName(name string) string {
return name
}
-func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *Imports) (*Object, error) {
+func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition) (*Object, error) {
obj := &Object{NamedType: types[typ.Name]}
typeEntry, entryExists := cfg.Models[typ.Name]
- imp := imports.findByPath(cfg.Exec.ImportPath())
- obj.ResolverInterface = &Ref{GoType: obj.GQLType + "Resolver", Import: imp}
+ obj.ResolverInterface = &Ref{GoType: obj.GQLType + "Resolver"}
if typ == cfg.schema.Query {
obj.Root = true
@@ -104,12 +103,15 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I
obj.Satisfies = append(obj.Satisfies, typ.Interfaces...)
+ for _, intf := range cfg.schema.GetImplements(typ) {
+ obj.Implements = append(obj.Implements, types[intf.Name])
+ }
+
for _, field := range typ.Fields {
if typ == cfg.schema.Query && field.Name == "__type" {
obj.Fields = append(obj.Fields, Field{
Type: &Type{types["__Schema"], []string{modPtr}, ast.NamedType("__Schema", nil), nil},
GQLName: "__schema",
- NoErr: true,
GoFieldType: GoFieldMethod,
GoReceiverName: "ec",
GoFieldName: "introspectSchema",
@@ -122,7 +124,6 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I
obj.Fields = append(obj.Fields, Field{
Type: &Type{types["__Type"], []string{modPtr}, ast.NamedType("__Schema", nil), nil},
GQLName: "__type",
- NoErr: true,
GoFieldType: GoFieldMethod,
GoReceiverName: "ec",
GoFieldName: "introspectType",
@@ -162,7 +163,6 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I
if err != nil {
return nil, errors.Errorf("default value for %s.%s is not valid: %s", typ.Name, field.Name, err.Error())
}
- newArg.StripPtr()
}
args = append(args, newArg)
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go b/vendor/github.com/99designs/gqlgen/codegen/templates/data.go
index d168fa31..d3098aaa 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/data.go
@@ -2,12 +2,12 @@ package templates
var data = map[string]string{
"args.gotpl": "\targs := map[string]interface{}{}\n\t{{- range $i, $arg := . }}\n\t\tvar arg{{$i}} {{$arg.Signature }}\n\t\tif tmp, ok := rawArgs[{{$arg.GQLName|quote}}]; ok {\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\targs[{{$arg.GQLName|quote}}] = arg{{$i}}\n\t{{- end }}\n\treturn args, nil\n",
- "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t{{- end }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tField: field,\n\t\t})\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\t// nolint: vetshadow\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t{{- end }}\n\t\trctx := &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\tField: field,\n\t\t}\n\t\tctx = graphql.WithResolverContext(ctx, rctx)\n\t\tresTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(ctx context.Context) (interface{}, error) {\n\t\t\t{{- if $field.IsResolver }}\n\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t{{- else if $field.IsMethod }}\n\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }})\n\t\t\t\t{{- end }}\n\t\t\t{{- else if $field.IsVariable }}\n\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil\n\t\t\t{{- end }}\n\t\t})\n\t\tif resTmp == nil {\n\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\tif !ec.HasError(rctx) {\n\t\t\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\treturn graphql.Null\n\t\t}\n\t\tres := resTmp.({{$field.Signature}})\n\t\trctx.Result = res\n\t\t{{ $field.WriteJson }}\n\t}\n{{ end }}\n",
- "generated.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers: cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t\tcomplexity: cfg.Complexity,\n\t}\n}\n\ntype Config struct {\n\tResolvers ResolverRoot\n\tDirectives DirectiveRoot\n\tComplexity ComplexityRoot\n}\n\ntype ResolverRoot interface {\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers -}}\n\t\t{{$object.GQLType}}() {{$object.GQLType}}Resolver\n\t{{ end }}\n{{- end }}\n}\n\ntype DirectiveRoot struct {\n{{ range $directive := .Directives }}\n\t{{ $directive.Declaration }}\n{{ end }}\n}\n\ntype ComplexityRoot struct {\n{{ range $object := .Objects }}\n\t{{ if not $object.IsReserved -}}\n\t\t{{ $object.GQLType|toCamel }} struct {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ if not $field.IsReserved -}}\n\t\t\t\t{{ $field.GQLName|toCamel }} {{ $field.ComplexitySignature }}\n\t\t\t{{ end }}\n\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{ end }}\n}\n\n{{ range $object := .Objects -}}\n\t{{ if $object.HasResolvers }}\n\t\ttype {{$object.GQLType}}Resolver interface {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ $field.ShortResolverDeclaration }}\n\t\t{{ end }}\n\t\t}\n\t{{- end }}\n{{- end }}\n\n{{ range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ if $field.Args }}\n\t\t\tfunc {{ $field.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t\t{{ template \"args.gotpl\" $field.Args }}\n\t\t\t}\n\t\t{{ end }}\n\t{{ end }}\n{{- end }}\n\n{{ range $directive := .Directives }}\n\t{{ if $directive.Args }}\n\t\tfunc {{ $directive.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t{{ template \"args.gotpl\" $directive.Args }}\n\t\t}\n\t{{ end }}\n{{ end }}\n\ntype executableSchema struct {\n\tresolvers ResolverRoot\n\tdirectives DirectiveRoot\n\tcomplexity ComplexityRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {\n\tswitch typeName + \".\" + field {\n\t{{ range $object := .Objects }}\n\t\t{{ if not $object.IsReserved }}\n\t\t\t{{ range $field := $object.Fields }}\n\t\t\t\t{{ if not $field.IsReserved }}\n\t\t\t\t\tcase \"{{$object.GQLType}}.{{$field.GQLName}}\":\n\t\t\t\t\t\tif e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}} == nil {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ if $field.Args }}\n\t\t\t\t\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn 0, false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ end }}\n\t\t\t\t\t\treturn e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true\n\t\t\t\t{{ end }}\n\t\t\t{{ end }}\n\t\t{{ end }}\n\t{{ end }}\n\t}\n\treturn 0, false\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"queries are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"mutations are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\t\tbuf.Reset()\n\t\t\t\tdata := next()\n\n\t\t\t\tif data == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tdata.MarshalGQL(&buf)\n\t\t\t\treturn buf.Bytes()\n\t\t\t})\n\n\t\t\tif buf == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf,\n\t\t\t\tErrors: ec.Errors,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"subscriptions are not supported\"))\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\t*executableSchema\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = nil\n\t\t}\n\t}()\n\t{{- if .Directives }}\n\trctx := graphql.GetResolverContext(ctx)\n\tfor _, d := range rctx.Field.Definition.Directives {\n\t\tswitch d.Name {\n\t\t{{- range $directive := .Directives }}\n\t\tcase \"{{$directive.Name}}\":\n\t\t\tif ec.directives.{{$directive.Name|ucFirst}} != nil {\n\t\t\t\t{{- if $directive.Args }}\n\t\t\t\t\trawArgs := d.ArgumentMap(ec.Variables)\n\t\t\t\t\targs, err := {{ $directive.ArgsFunc }}(rawArgs)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tec.Error(ctx, err)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t\tn := next\n\t\t\t\tnext = func(ctx context.Context) (interface{}, error) {\n\t\t\t\t\treturn ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})\n\t\t\t\t}\n\t\t\t}\n\t\t{{- end }}\n\t\t}\n\t}\n\t{{- end }}\n\tres, err := ec.ResolverMiddleware(ctx, next)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn nil\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) introspectSchema() *introspection.Schema {\n\treturn introspection.WrapSchema(parsedSchema)\n}\n\nfunc (ec *executionContext) introspectType(name string) *introspection.Type {\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name])\n}\n\nvar parsedSchema = gqlparser.MustLoadSchema(\n\t&ast.Source{Name: {{.SchemaFilename|quote}}, Input: {{.SchemaRaw|rawQuote}}},\n)\n",
+ "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t{{- end }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tField: field,\n\t\t})\n\t\t// FIXME: subscriptions are missing request middleware stack https://github.com/99designs/gqlgen/issues/259\n\t\t// and Tracer stack\n\t\trctx := ctx\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\t// nolint: vetshadow\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\tctx = ec.Tracer.StartFieldExecution(ctx, field)\n\t\tdefer func () { ec.Tracer.EndFieldExecution(ctx) }()\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t{{- end }}\n\t\trctx := &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\tField: field,\n\t\t}\n\t\tctx = graphql.WithResolverContext(ctx, rctx)\n\t\tctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)\n\t\tresTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {\n\t\t\tctx = rctx // use context from middleware stack in children\n\t\t\t{{- if $field.IsResolver }}\n\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t{{- else if $field.IsMethod }}\n\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }})\n\t\t\t\t{{- end }}\n\t\t\t{{- else if $field.IsVariable }}\n\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil\n\t\t\t{{- end }}\n\t\t})\n\t\tif resTmp == nil {\n\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\tif !ec.HasError(rctx) {\n\t\t\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\treturn graphql.Null\n\t\t}\n\t\tres := resTmp.({{$field.Signature}})\n\t\trctx.Result = res\n\t\tctx = ec.Tracer.StartFieldChildExecution(ctx)\n\t\t{{ $field.WriteJson }}\n\t}\n{{ end }}\n",
+ "generated.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers: cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t\tcomplexity: cfg.Complexity,\n\t}\n}\n\ntype Config struct {\n\tResolvers ResolverRoot\n\tDirectives DirectiveRoot\n\tComplexity ComplexityRoot\n}\n\ntype ResolverRoot interface {\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers -}}\n\t\t{{$object.GQLType}}() {{$object.GQLType}}Resolver\n\t{{ end }}\n{{- end }}\n}\n\ntype DirectiveRoot struct {\n{{ range $directive := .Directives }}\n\t{{ $directive.Declaration }}\n{{ end }}\n}\n\ntype ComplexityRoot struct {\n{{ range $object := .Objects }}\n\t{{ if not $object.IsReserved -}}\n\t\t{{ $object.GQLType|toCamel }} struct {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ if not $field.IsReserved -}}\n\t\t\t\t{{ $field.GQLName|toCamel }} {{ $field.ComplexitySignature }}\n\t\t\t{{ end }}\n\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{ end }}\n}\n\n{{ range $object := .Objects -}}\n\t{{ if $object.HasResolvers }}\n\t\ttype {{$object.GQLType}}Resolver interface {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ $field.ShortResolverDeclaration }}\n\t\t{{ end }}\n\t\t}\n\t{{- end }}\n{{- end }}\n\n{{ range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ if $field.Args }}\n\t\t\tfunc {{ $field.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t\t{{ template \"args.gotpl\" $field.Args }}\n\t\t\t}\n\t\t{{ end }}\n\t{{ end }}\n{{- end }}\n\n{{ range $directive := .Directives }}\n\t{{ if $directive.Args }}\n\t\tfunc {{ $directive.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t{{ template \"args.gotpl\" $directive.Args }}\n\t\t}\n\t{{ end }}\n{{ end }}\n\ntype executableSchema struct {\n\tresolvers ResolverRoot\n\tdirectives DirectiveRoot\n\tcomplexity ComplexityRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {\n\tswitch typeName + \".\" + field {\n\t{{ range $object := .Objects }}\n\t\t{{ if not $object.IsReserved }}\n\t\t\t{{ range $field := $object.Fields }}\n\t\t\t\t{{ if not $field.IsReserved }}\n\t\t\t\t\tcase \"{{$object.GQLType}}.{{$field.GQLName}}\":\n\t\t\t\t\t\tif e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}} == nil {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ if $field.Args }}\n\t\t\t\t\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn 0, false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ end }}\n\t\t\t\t\t\treturn e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true\n\t\t\t\t{{ end }}\n\t\t\t{{ end }}\n\t\t{{ end }}\n\t{{ end }}\n\t}\n\treturn 0, false\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t\tExtensions: ec.Extensions,\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"queries are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t\tExtensions: ec.Extensions,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"mutations are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\t\tbuf.Reset()\n\t\t\t\tdata := next()\n\n\t\t\t\tif data == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tdata.MarshalGQL(&buf)\n\t\t\t\treturn buf.Bytes()\n\t\t\t})\n\n\t\t\tif buf == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf,\n\t\t\t\tErrors: ec.Errors,\n\t\t\t\tExtensions: ec.Extensions,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"subscriptions are not supported\"))\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\t*executableSchema\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = nil\n\t\t}\n\t}()\n\t{{- if .Directives }}\n\trctx := graphql.GetResolverContext(ctx)\n\tfor _, d := range rctx.Field.Definition.Directives {\n\t\tswitch d.Name {\n\t\t{{- range $directive := .Directives }}\n\t\tcase \"{{$directive.Name}}\":\n\t\t\tif ec.directives.{{$directive.Name|ucFirst}} != nil {\n\t\t\t\t{{- if $directive.Args }}\n\t\t\t\t\trawArgs := d.ArgumentMap(ec.Variables)\n\t\t\t\t\targs, err := {{ $directive.ArgsFunc }}(rawArgs)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tec.Error(ctx, err)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t\tn := next\n\t\t\t\tnext = func(ctx context.Context) (interface{}, error) {\n\t\t\t\t\treturn ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})\n\t\t\t\t}\n\t\t\t}\n\t\t{{- end }}\n\t\t}\n\t}\n\t{{- end }}\n\tres, err := ec.ResolverMiddleware(ctx, next)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn nil\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) introspectSchema() (*introspection.Schema, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapSchema(parsedSchema), nil\n}\n\nfunc (ec *executionContext) introspectType(name string) (*introspection.Type, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil\n}\n\nvar parsedSchema = gqlparser.MustLoadSchema(\n\t{{- range $filename, $schema := .SchemaRaw }}\n\t\t&ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},\n\t{{- end }}\n)\n",
"input.gotpl": "\t{{- if .IsMarshaled }}\n\tfunc Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {\n\t\tvar it {{.FullName}}\n\t\tvar asMap = v.(map[string]interface{})\n\t\t{{ range $field := .Fields}}\n\t\t\t{{- if $field.Default}}\n\t\t\t\tif _, present := asMap[{{$field.GQLName|quote}}] ; !present {\n\t\t\t\t\tasMap[{{$field.GQLName|quote}}] = {{ $field.Default | dump }}\n\t\t\t\t}\n\t\t\t{{- end}}\n\t\t{{- end }}\n\n\t\tfor k, v := range asMap {\n\t\t\tswitch k {\n\t\t\t{{- range $field := .Fields }}\n\t\t\tcase {{$field.GQLName|quote}}:\n\t\t\t\tvar err error\n\t\t\t\t{{ $field.Unmarshal (print \"it.\" $field.GoFieldName) \"v\" }}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn it, err\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\n\t\treturn it, nil\n\t}\n\t{{- end }}\n",
"interface.gotpl": "{{- $interface := . }}\n\nfunc (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.FullName}}) graphql.Marshaler {\n\tswitch obj := (*obj).(type) {\n\tcase nil:\n\t\treturn graphql.Null\n\t{{- range $implementor := $interface.Implementors }}\n\t\t{{- if $implementor.ValueReceiver }}\n\t\t\tcase {{$implementor.FullName}}:\n\t\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, &obj)\n\t\t{{- end}}\n\t\tcase *{{$implementor.FullName}}:\n\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, obj)\n\t{{- end }}\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type %T\", obj))\n\t}\n}\n",
- "models.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n{{ range $model := .Models }}\n\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- with .Description}}\n\t\t\t\t\t{{.|prefixLines \"// \"}}\n\t\t\t\t{{- end}}\n\t\t\t\t{{- if $field.GoFieldName }}\n\t\t\t\t\t{{ $field.GoFieldName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\t{{with .Description}}{{.|prefixLines \"// \"}} {{end}}\n\ttype {{.GoType}} string\n\tconst (\n\t{{- range $value := .Values}}\n\t\t{{- with .Description}}\n\t\t\t{{.|prefixLines \"// \"}}\n\t\t{{- end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n",
+ "models.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\n{{ range $model := .Models }}\n\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {\n\t\t\tIs{{.GoType}}()\n\t\t}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- with .Description}}\n\t\t\t\t\t{{.|prefixLines \"// \"}}\n\t\t\t\t{{- end}}\n\t\t\t\t{{- if $field.GoFieldName }}\n\t\t\t\t\t{{ $field.GoFieldName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\n\t\t{{- range $iface := .Implements }}\n\t\t\tfunc ({{$model.GoType}}) Is{{$iface.GoType}}() {}\n\t\t{{- end }}\n\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\t{{with .Description}}{{.|prefixLines \"// \"}} {{end}}\n\ttype {{.GoType}} string\n\tconst (\n\t{{- range $value := .Values}}\n\t\t{{- with .Description}}\n\t\t\t{{.|prefixLines \"// \"}}\n\t\t{{- end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n",
"object.gotpl": "{{ $object := . }}\n\nvar {{ $object.GQLType|lcFirst}}Implementors = {{$object.Implementors}}\n\n// nolint: gocyclo, errcheck, gas, goconst\n{{- if .Stream }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\tObject: {{$object.GQLType|quote}},\n\t})\n\tif len(fields) != 1 {\n\t\tec.Errorf(ctx, \"must subscribe to exactly one stream\")\n\t\treturn nil\n\t}\n\n\tswitch fields[0].Name {\n\t{{- range $field := $object.Fields }}\n\tcase \"{{$field.GQLName}}\":\n\t\treturn ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, fields[0])\n\t{{- end }}\n\tdefault:\n\t\tpanic(\"unknown field \" + strconv.Quote(fields[0].Name))\n\t}\n}\n{{- else }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\t{{if $object.Root}}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t})\n\t{{end}}\n\n\t{{if $object.IsConcurrent}} var wg sync.WaitGroup {{end}}\n\tout := graphql.NewOrderedMap(len(fields))\n\tinvalid := false\n\tfor i, field := range fields {\n\t\tout.Keys[i] = field.Alias\n\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString({{$object.GQLType|quote}})\n\t\t{{- range $field := $object.Fields }}\n\t\tcase \"{{$field.GQLName}}\":\n\t\t\t{{- if $field.IsConcurrent }}\n\t\t\t\twg.Add(1)\n\t\t\t\tgo func(i int, field graphql.CollectedField) {\n\t\t\t{{- end }}\n\t\t\t\tout.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, field{{if not $object.Root}}, obj{{end}})\n\t\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\t\t\tinvalid = true\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t{{- if $field.IsConcurrent }}\n\t\t\t\t\twg.Done()\n\t\t\t\t}(i, field)\n\t\t\t{{- end }}\n\t\t{{- end }}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\t{{if $object.IsConcurrent}} wg.Wait() {{end}}\n\tif invalid { return graphql.Null }\n\treturn out\n}\n{{- end }}\n",
- "resolver.gotpl": "//go:generate gorunpkg github.com/99designs/gqlgen\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\ntype {{.ResolverType}} struct {}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\tfunc (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {\n\t\t\treturn &{{lcFirst $object.GQLType}}Resolver{r}\n\t\t}\n\t{{ end -}}\n{{ end }}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\ttype {{lcFirst $object.GQLType}}Resolver struct { *Resolver }\n\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{- if $field.IsResolver -}}\n\t\t\tfunc (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {\n\t\t\t\tpanic(\"not implemented\")\n\t\t\t}\n\t\t\t{{ end -}}\n\t\t{{ end -}}\n\t{{ end -}}\n{{ end }}\n",
- "server.gotpl": "package main\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\nconst defaultPort = \"8080\"\n\nfunc main() {\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = defaultPort\n\t}\n\n\thttp.Handle(\"/\", handler.Playground(\"GraphQL playground\", \"/query\"))\n\thttp.Handle(\"/query\", handler.GraphQL({{.ExecPackageName}}.NewExecutableSchema({{.ExecPackageName}}.Config{Resolvers: &{{.ResolverPackageName}}.Resolver{}})))\n\n\tlog.Printf(\"connect to http://localhost:%s/ for GraphQL playground\", port)\n\tlog.Fatal(http.ListenAndServe(\":\" + port, nil))\n}\n",
+ "resolver.gotpl": "package {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/99designs/gqlgen/handler\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\ntype {{.ResolverType}} struct {}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\tfunc (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {\n\t\t\treturn &{{lcFirst $object.GQLType}}Resolver{r}\n\t\t}\n\t{{ end -}}\n{{ end }}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\ttype {{lcFirst $object.GQLType}}Resolver struct { *Resolver }\n\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{- if $field.IsResolver -}}\n\t\t\tfunc (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {\n\t\t\t\tpanic(\"not implemented\")\n\t\t\t}\n\t\t\t{{ end -}}\n\t\t{{ end -}}\n\t{{ end -}}\n{{ end }}\n",
+ "server.gotpl": "package main\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"log\" }}\n\t{{ reserveImport \"net/http\" }}\n\t{{ reserveImport \"os\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/handler\" }}\n)\n\nconst defaultPort = \"8080\"\n\nfunc main() {\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = defaultPort\n\t}\n\n\thttp.Handle(\"/\", handler.Playground(\"GraphQL playground\", \"/query\"))\n\thttp.Handle(\"/query\", handler.GraphQL({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}})))\n\n\tlog.Printf(\"connect to http://localhost:%s/ for GraphQL playground\", port)\n\tlog.Fatal(http.ListenAndServe(\":\" + port, nil))\n}\n",
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl
index b33f2123..3df847fa 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl
@@ -14,6 +14,9 @@
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
Field: field,
})
+ // FIXME: subscriptions are missing request middleware stack https://github.com/99designs/gqlgen/issues/259
+ // and Tracer stack
+ rctx := ctx
results, err := ec.resolvers.{{ $field.ShortInvocation }}
if err != nil {
ec.Error(ctx, err)
@@ -32,6 +35,8 @@
{{ else }}
// nolint: vetshadow
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {
+ ctx = ec.Tracer.StartFieldExecution(ctx, field)
+ defer func () { ec.Tracer.EndFieldExecution(ctx) }()
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
args, err := {{ $field.ArgsFunc }}(rawArgs)
@@ -46,7 +51,9 @@
Field: field,
}
ctx = graphql.WithResolverContext(ctx, rctx)
- resTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(ctx context.Context) (interface{}, error) {
+ ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
+ resTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {
+ ctx = rctx // use context from middleware stack in children
{{- if $field.IsResolver }}
return ec.resolvers.{{ $field.ShortInvocation }}
{{- else if $field.IsMethod }}
@@ -69,6 +76,7 @@
}
res := resTmp.({{$field.Signature}})
rctx.Result = res
+ ctx = ec.Tracer.StartFieldChildExecution(ctx)
{{ $field.WriteJson }}
}
{{ end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl
index 8250bc7a..a37a1613 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl
@@ -3,9 +3,21 @@
package {{ .PackageName }}
import (
-{{- range $import := .Imports }}
- {{- $import.Write }}
-{{ end }}
+ %%%IMPORTS%%%
+
+ {{ reserveImport "context" }}
+ {{ reserveImport "fmt" }}
+ {{ reserveImport "io" }}
+ {{ reserveImport "strconv" }}
+ {{ reserveImport "time" }}
+ {{ reserveImport "sync" }}
+ {{ reserveImport "errors" }}
+ {{ reserveImport "bytes" }}
+
+ {{ reserveImport "github.com/vektah/gqlparser" }}
+ {{ reserveImport "github.com/vektah/gqlparser/ast" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
)
// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
@@ -126,9 +138,9 @@ func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinitio
})
return &graphql.Response{
- Data: buf,
- Errors: ec.Errors,
- }
+ Data: buf,
+ Errors: ec.Errors,
+ Extensions: ec.Extensions, }
{{- else }}
return graphql.ErrorResponse(ctx, "queries are not supported")
{{- end }}
@@ -146,8 +158,9 @@ func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefini
})
return &graphql.Response{
- Data: buf,
- Errors: ec.Errors,
+ Data: buf,
+ Errors: ec.Errors,
+ Extensions: ec.Extensions,
}
{{- else }}
return graphql.ErrorResponse(ctx, "mutations are not supported")
@@ -181,8 +194,9 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe
}
return &graphql.Response{
- Data: buf,
- Errors: ec.Errors,
+ Data: buf,
+ Errors: ec.Errors,
+ Extensions: ec.Extensions,
}
}
{{- else }}
@@ -250,14 +264,22 @@ func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}
return res
}
-func (ec *executionContext) introspectSchema() *introspection.Schema {
- return introspection.WrapSchema(parsedSchema)
+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 {
- return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name])
+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 parsedSchema = gqlparser.MustLoadSchema(
- &ast.Source{Name: {{.SchemaFilename|quote}}, Input: {{.SchemaRaw|rawQuote}}},
+ {{- range $filename, $schema := .SchemaRaw }}
+ &ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},
+ {{- end }}
)
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go
new file mode 100644
index 00000000..c9db2d96
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go
@@ -0,0 +1,135 @@
+package templates
+
+import (
+ "fmt"
+ "go/build"
+ "strconv"
+
+ "github.com/99designs/gqlgen/internal/gopath"
+)
+
+type Import struct {
+ Name string
+ Path string
+ Alias string
+}
+
+type Imports struct {
+ imports []*Import
+ destDir string
+}
+
+func (i *Import) String() string {
+ if i.Alias == i.Name {
+ return strconv.Quote(i.Path)
+ }
+
+ return i.Alias + " " + strconv.Quote(i.Path)
+}
+
+func (s *Imports) String() string {
+ res := ""
+ for i, imp := range s.imports {
+ if i != 0 {
+ res += "\n"
+ }
+ res += imp.String()
+ }
+ return res
+}
+
+func (s *Imports) Reserve(path string, aliases ...string) string {
+ if path == "" {
+ panic("empty ambient import")
+ }
+
+ // if we are referencing our own package we dont need an import
+ if gopath.MustDir2Import(s.destDir) == path {
+ return ""
+ }
+
+ pkg, err := build.Default.Import(path, s.destDir, 0)
+ if err != nil {
+ panic(err)
+ }
+
+ var alias string
+ if len(aliases) != 1 {
+ alias = pkg.Name
+ } else {
+ alias = aliases[0]
+ }
+
+ if existing := s.findByPath(path); existing != nil {
+ panic("ambient import already exists")
+ }
+
+ if alias := s.findByAlias(alias); alias != nil {
+ panic("ambient import collides on an alias")
+ }
+
+ s.imports = append(s.imports, &Import{
+ Name: pkg.Name,
+ Path: path,
+ Alias: alias,
+ })
+
+ return ""
+}
+
+func (s *Imports) Lookup(path string) string {
+ if path == "" {
+ return ""
+ }
+
+ // if we are referencing our own package we dont need an import
+ if gopath.MustDir2Import(s.destDir) == path {
+ return ""
+ }
+
+ if existing := s.findByPath(path); existing != nil {
+ return existing.Alias
+ }
+
+ pkg, err := build.Default.Import(path, s.destDir, 0)
+ if err != nil {
+ panic(err)
+ }
+
+ imp := &Import{
+ Name: pkg.Name,
+ Path: path,
+ }
+ s.imports = append(s.imports, imp)
+
+ alias := imp.Name
+ i := 1
+ for s.findByAlias(alias) != nil {
+ alias = imp.Name + strconv.Itoa(i)
+ i++
+ if i > 10 {
+ panic(fmt.Errorf("too many collisions, last attempt was %s", alias))
+ }
+ }
+ imp.Alias = alias
+
+ return imp.Alias
+}
+
+func (s Imports) findByPath(importPath string) *Import {
+ for _, imp := range s.imports {
+ if imp.Path == importPath {
+ return imp
+ }
+ }
+ return nil
+}
+
+func (s Imports) findByAlias(alias string) *Import {
+ for _, imp := range s.imports {
+ if imp.Alias == alias {
+ return imp
+ }
+ }
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl
index 7427d71d..db63a996 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl
@@ -3,15 +3,29 @@
package {{ .PackageName }}
import (
-{{- range $import := .Imports }}
- {{- $import.Write }}
-{{ end }}
+ %%%IMPORTS%%%
+
+ {{ reserveImport "context" }}
+ {{ reserveImport "fmt" }}
+ {{ reserveImport "io" }}
+ {{ reserveImport "strconv" }}
+ {{ reserveImport "time" }}
+ {{ reserveImport "sync" }}
+ {{ reserveImport "errors" }}
+ {{ reserveImport "bytes" }}
+
+ {{ reserveImport "github.com/vektah/gqlparser" }}
+ {{ reserveImport "github.com/vektah/gqlparser/ast" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
)
{{ range $model := .Models }}
{{with .Description}} {{.|prefixLines "// "}} {{end}}
{{- if .IsInterface }}
- type {{.GoType}} interface {}
+ type {{.GoType}} interface {
+ Is{{.GoType}}()
+ }
{{- else }}
type {{.GoType}} struct {
{{- range $field := .Fields }}
@@ -25,6 +39,11 @@ import (
{{- end }}
{{- end }}
}
+
+ {{- range $iface := .Implements }}
+ func ({{$model.GoType}}) Is{{$iface.GoType}}() {}
+ {{- end }}
+
{{- end }}
{{- end}}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl
index dd8acf24..53ba8c43 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl
@@ -1,11 +1,22 @@
-//go:generate gorunpkg github.com/99designs/gqlgen
-
package {{ .PackageName }}
import (
-{{- range $import := .Imports }}
- {{- $import.Write }}
-{{ end }}
+ %%%IMPORTS%%%
+
+ {{ reserveImport "context" }}
+ {{ reserveImport "fmt" }}
+ {{ reserveImport "io" }}
+ {{ reserveImport "strconv" }}
+ {{ reserveImport "time" }}
+ {{ reserveImport "sync" }}
+ {{ reserveImport "errors" }}
+ {{ reserveImport "bytes" }}
+
+ {{ reserveImport "github.com/99designs/gqlgen/handler" }}
+ {{ reserveImport "github.com/vektah/gqlparser" }}
+ {{ reserveImport "github.com/vektah/gqlparser/ast" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql" }}
+ {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
)
type {{.ResolverType}} struct {}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl
index f23b30e1..38dc0d18 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl
@@ -1,9 +1,13 @@
package main
import (
-{{- range $import := .Imports }}
- {{- $import.Write }}
-{{ end }}
+ %%%IMPORTS%%%
+
+ {{ reserveImport "context" }}
+ {{ reserveImport "log" }}
+ {{ reserveImport "net/http" }}
+ {{ reserveImport "os" }}
+ {{ reserveImport "github.com/99designs/gqlgen/handler" }}
)
const defaultPort = "8080"
@@ -15,7 +19,7 @@ func main() {
}
http.Handle("/", handler.Playground("GraphQL playground", "/query"))
- http.Handle("/query", handler.GraphQL({{.ExecPackageName}}.NewExecutableSchema({{.ExecPackageName}}.Config{Resolvers: &{{.ResolverPackageName}}.Resolver{}})))
+ http.Handle("/query", handler.GraphQL({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}})))
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":" + port, nil))
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
index df909cb5..22e5d739 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
@@ -14,21 +14,25 @@ import (
"text/template"
"unicode"
- "log"
+ "github.com/99designs/gqlgen/internal/imports"
"github.com/pkg/errors"
- "golang.org/x/tools/imports"
)
+// this is done with a global because subtemplates currently get called in functions. Lets aim to remove this eventually.
+var CurrentImports *Imports
+
func Run(name string, tpldata interface{}) (*bytes.Buffer, error) {
t := template.New("").Funcs(template.FuncMap{
- "ucFirst": ucFirst,
- "lcFirst": lcFirst,
- "quote": strconv.Quote,
- "rawQuote": rawQuote,
- "toCamel": ToCamel,
- "dump": dump,
- "prefixLines": prefixLines,
+ "ucFirst": ucFirst,
+ "lcFirst": lcFirst,
+ "quote": strconv.Quote,
+ "rawQuote": rawQuote,
+ "toCamel": ToCamel,
+ "dump": dump,
+ "prefixLines": prefixLines,
+ "reserveImport": CurrentImports.Reserve,
+ "lookupImport": CurrentImports.Lookup,
})
for filename, data := range data {
@@ -149,27 +153,21 @@ func prefixLines(prefix, s string) string {
}
func RenderToFile(tpl string, filename string, data interface{}) error {
+ if CurrentImports != nil {
+ panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected"))
+ }
+ CurrentImports = &Imports{destDir: filepath.Dir(filename)}
+
var buf *bytes.Buffer
buf, err := Run(tpl, data)
if err != nil {
return errors.Wrap(err, filename+" generation failed")
}
- if err := write(filename, buf.Bytes()); err != nil {
- return err
- }
-
- log.Println(filename)
+ b := bytes.Replace(buf.Bytes(), []byte("%%%IMPORTS%%%"), []byte(CurrentImports.String()), -1)
+ CurrentImports = nil
- return nil
-}
-
-func gofmt(filename string, b []byte) ([]byte, error) {
- out, err := imports.Process(filename, b, nil)
- if err != nil {
- return b, errors.Wrap(err, "unable to gofmt")
- }
- return out, nil
+ return write(filename, b)
}
func write(filename string, b []byte) error {
@@ -178,9 +176,9 @@ func write(filename string, b []byte) error {
return errors.Wrap(err, "failed to create directory")
}
- formatted, err := gofmt(filename, b)
+ formatted, err := imports.Prune(filename, b)
if err != nil {
- fmt.Fprintf(os.Stderr, "gofmt failed: %s\n", err.Error())
+ fmt.Fprintf(os.Stderr, "gofmt failed on %s: %s\n", filepath.Base(filename), err.Error())
formatted = b
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.go b/vendor/github.com/99designs/gqlgen/codegen/type.go
index 8c53fe55..04d9bb2f 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/type.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/type.go
@@ -4,6 +4,8 @@ import (
"strconv"
"strings"
+ "github.com/99designs/gqlgen/codegen/templates"
+
"github.com/vektah/gqlparser/ast"
)
@@ -19,10 +21,9 @@ type NamedType struct {
}
type Ref struct {
- GoType string // Name of the go type
- Package string // the package the go type lives in
- Import *Import // the resolved import with alias
- IsUserDefined bool // does the type exist in the typemap
+ GoType string // Name of the go type
+ Package string // the package the go type lives in
+ IsUserDefined bool // does the type exist in the typemap
}
type Type struct {
@@ -43,10 +44,13 @@ func (t Ref) FullName() string {
}
func (t Ref) PkgDot() string {
- if t.Import == nil || t.Import.Alias() == "" {
+ name := templates.CurrentImports.Lookup(t.Package)
+ if name == "" {
return ""
+
}
- return t.Import.Alias() + "."
+
+ return name + "."
}
func (t Type) Signature() string {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type_build.go b/vendor/github.com/99designs/gqlgen/codegen/type_build.go
index f0ec6785..586b0db2 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/type_build.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/type_build.go
@@ -27,7 +27,7 @@ func (cfg *Config) buildNamedTypes() NamedTypes {
return types
}
-func (cfg *Config) bindTypes(imports *Imports, namedTypes NamedTypes, destDir string, prog *loader.Program) {
+func (cfg *Config) bindTypes(namedTypes NamedTypes, destDir string, prog *loader.Program) {
for _, t := range namedTypes {
if t.Package == "" {
continue
@@ -41,7 +41,6 @@ func (cfg *Config) bindTypes(imports *Imports, namedTypes NamedTypes, destDir st
t.Marshaler = &cpy
t.Package, t.GoType = pkgAndType(sig.Params().At(0).Type().String())
- t.Import = imports.add(t.Package)
}
}
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/util.go b/vendor/github.com/99designs/gqlgen/codegen/util.go
index 1849f100..cc6246fd 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/util.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/util.go
@@ -105,6 +105,12 @@ func findMethod(typ *types.Named, name string) *types.Func {
return nil
}
+func equalFieldName(source, target string) bool {
+ source = strings.Replace(source, "_", "", -1)
+ target = strings.Replace(target, "_", "", -1)
+ return strings.EqualFold(source, target)
+}
+
// findField attempts to match the name to a struct field with the following
// priorites:
// 1. If struct tag is passed then struct tag has highest priority
@@ -120,7 +126,7 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) {
if structTag != "" {
tags := reflect.StructTag(typ.Tag(i))
if val, ok := tags.Lookup(structTag); ok {
- if strings.EqualFold(val, name) {
+ if equalFieldName(val, name) {
if foundField != nil && foundFieldWasTag {
return nil, errors.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", structTag, val)
}
@@ -132,17 +138,16 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) {
}
if field.Anonymous() {
- if named, ok := field.Type().(*types.Struct); ok {
- f, err := findField(named, name, structTag)
- if err != nil && !strings.HasPrefix(err.Error(), "no field named") {
- return nil, err
- }
- if f != nil && foundField == nil {
- foundField = f
- }
+
+ fieldType := field.Type()
+
+ if ptr, ok := fieldType.(*types.Pointer); ok {
+ fieldType = ptr.Elem()
}
- if named, ok := field.Type().Underlying().(*types.Struct); ok {
+ // Type.Underlying() returns itself for all types except types.Named, where it returns a struct type.
+ // It should be safe to always call.
+ if named, ok := fieldType.Underlying().(*types.Struct); ok {
f, err := findField(named, name, structTag)
if err != nil && !strings.HasPrefix(err.Error(), "no field named") {
return nil, err
@@ -157,7 +162,7 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) {
continue
}
- if strings.EqualFold(field.Name(), name) && foundField == nil {
+ if equalFieldName(field.Name(), name) && foundField == nil { // aqui!
foundField = field
}
}
@@ -198,7 +203,7 @@ func (b BindErrors) Error() string {
return strings.Join(errs, "\n\n")
}
-func bindObject(t types.Type, object *Object, imports *Imports, structTag string) BindErrors {
+func bindObject(t types.Type, object *Object, structTag string) BindErrors {
var errs BindErrors
for i := range object.Fields {
field := &object.Fields[i]
@@ -208,13 +213,13 @@ func bindObject(t types.Type, object *Object, imports *Imports, structTag string
}
// first try binding to a method
- methodErr := bindMethod(imports, t, field)
+ methodErr := bindMethod(t, field)
if methodErr == nil {
continue
}
// otherwise try binding to a var
- varErr := bindVar(imports, t, field, structTag)
+ varErr := bindVar(t, field, structTag)
if varErr != nil {
errs = append(errs, BindError{
@@ -229,7 +234,7 @@ func bindObject(t types.Type, object *Object, imports *Imports, structTag string
return errs
}
-func bindMethod(imports *Imports, t types.Type, field *Field) error {
+func bindMethod(t types.Type, field *Field) error {
namedType, ok := t.(*types.Named)
if !ok {
return fmt.Errorf("not a named type")
@@ -250,13 +255,25 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error {
} else if sig.Results().Len() != 2 {
return fmt.Errorf("method has wrong number of args")
}
- newArgs, err := matchArgs(field, sig.Params())
+ params := sig.Params()
+ // If the first argument is the context, remove it from the comparison and set
+ // the MethodHasContext flag so that the context will be passed to this model's method
+ if params.Len() > 0 && params.At(0).Type().String() == "context.Context" {
+ field.MethodHasContext = true
+ vars := make([]*types.Var, params.Len()-1)
+ for i := 1; i < params.Len(); i++ {
+ vars[i-1] = params.At(i)
+ }
+ params = types.NewTuple(vars...)
+ }
+
+ newArgs, err := matchArgs(field, params)
if err != nil {
return err
}
result := sig.Results().At(0)
- if err := validateTypeBinding(imports, field, result.Type()); err != nil {
+ if err := validateTypeBinding(field, result.Type()); err != nil {
return errors.Wrap(err, "method has wrong return type")
}
@@ -268,7 +285,7 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error {
return nil
}
-func bindVar(imports *Imports, t types.Type, field *Field, structTag string) error {
+func bindVar(t types.Type, field *Field, structTag string) error {
underlying, ok := t.Underlying().(*types.Struct)
if !ok {
return fmt.Errorf("not a struct")
@@ -283,7 +300,7 @@ func bindVar(imports *Imports, t types.Type, field *Field, structTag string) err
return err
}
- if err := validateTypeBinding(imports, field, structField.Type()); err != nil {
+ if err := validateTypeBinding(field, structField.Type()); err != nil {
return errors.Wrap(err, "field has wrong type")
}
@@ -316,22 +333,21 @@ nextArg:
return newArgs, nil
}
-func validateTypeBinding(imports *Imports, field *Field, goType types.Type) error {
+func validateTypeBinding(field *Field, goType types.Type) error {
gqlType := normalizeVendor(field.Type.FullSignature())
goTypeStr := normalizeVendor(goType.String())
- if goTypeStr == gqlType || "*"+goTypeStr == gqlType || goTypeStr == "*"+gqlType {
+ if equalTypes(goTypeStr, gqlType) {
field.Type.Modifiers = modifiersFromGoType(goType)
return nil
}
// deal with type aliases
underlyingStr := normalizeVendor(goType.Underlying().String())
- if underlyingStr == gqlType || "*"+underlyingStr == gqlType || underlyingStr == "*"+gqlType {
+ if equalTypes(underlyingStr, gqlType) {
field.Type.Modifiers = modifiersFromGoType(goType)
pkg, typ := pkgAndType(goType.String())
- imp := imports.findByPath(pkg)
- field.AliasedType = &Ref{GoType: typ, Import: imp}
+ field.AliasedType = &Ref{GoType: typ, Package: pkg}
return nil
}
@@ -365,3 +381,7 @@ func normalizeVendor(pkg string) string {
parts := strings.Split(pkg, "/vendor/")
return modifiers + parts[len(parts)-1]
}
+
+func equalTypes(goType string, gqlType string) bool {
+ return goType == gqlType || "*"+goType == gqlType || goType == "*"+gqlType || strings.Replace(goType, "[]*", "[]", -1) == gqlType
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/context.go b/vendor/github.com/99designs/gqlgen/graphql/context.go
index 6baee83c..f83fa36f 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/context.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/context.go
@@ -17,6 +17,11 @@ type RequestContext struct {
RawQuery string
Variables map[string]interface{}
Doc *ast.QueryDocument
+
+ ComplexityLimit int
+ OperationComplexity int
+ DisableIntrospection bool
+
// ErrorPresenter will be used to generate the error
// message from errors given to Error().
ErrorPresenter ErrorPresenterFunc
@@ -24,9 +29,12 @@ type RequestContext struct {
ResolverMiddleware FieldMiddleware
DirectiveMiddleware FieldMiddleware
RequestMiddleware RequestMiddleware
+ Tracer Tracer
- errorsMu sync.Mutex
- Errors gqlerror.List
+ errorsMu sync.Mutex
+ Errors gqlerror.List
+ extensionsMu sync.Mutex
+ Extensions map[string]interface{}
}
func DefaultResolverMiddleware(ctx context.Context, next Resolver) (res interface{}, err error) {
@@ -51,6 +59,7 @@ func NewRequestContext(doc *ast.QueryDocument, query string, variables map[strin
RequestMiddleware: DefaultRequestMiddleware,
Recover: DefaultRecover,
ErrorPresenter: DefaultErrorPresenter,
+ Tracer: &NopTracer{},
}
}
@@ -153,6 +162,21 @@ func (c *RequestContext) HasError(rctx *ResolverContext) bool {
return false
}
+// GetErrors returns a list of errors that occurred in the current field
+func (c *RequestContext) GetErrors(rctx *ResolverContext) gqlerror.List {
+ c.errorsMu.Lock()
+ defer c.errorsMu.Unlock()
+ path := rctx.Path()
+
+ var errs gqlerror.List
+ for _, err := range c.Errors {
+ if equalPath(err.Path, path) {
+ errs = append(errs, err)
+ }
+ }
+ return errs
+}
+
func equalPath(a []interface{}, b []interface{}) bool {
if len(a) != len(b) {
return false
@@ -176,3 +200,20 @@ func AddError(ctx context.Context, err error) {
func AddErrorf(ctx context.Context, format string, args ...interface{}) {
GetRequestContext(ctx).Errorf(ctx, format, args...)
}
+
+// RegisterExtension registers an extension, returns error if extension has already been registered
+func (c *RequestContext) RegisterExtension(key string, value interface{}) error {
+ c.extensionsMu.Lock()
+ defer c.extensionsMu.Unlock()
+
+ if c.Extensions == nil {
+ c.Extensions = make(map[string]interface{})
+ }
+
+ if _, ok := c.Extensions[key]; ok {
+ return fmt.Errorf("extension already registered for key %s", key)
+ }
+
+ c.Extensions[key] = value
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/float.go b/vendor/github.com/99designs/gqlgen/graphql/float.go
index d204335c..fabbad04 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/float.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/float.go
@@ -9,7 +9,7 @@ import (
func MarshalFloat(f float64) Marshaler {
return WriterFunc(func(w io.Writer) {
- io.WriteString(w, fmt.Sprintf("%f", f))
+ io.WriteString(w, fmt.Sprintf("%g", f))
})
}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
index baff882e..ca0b065f 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/introspection.go
@@ -12,19 +12,17 @@ type (
}
EnumValue struct {
- Name string
- Description string
- IsDeprecated bool
- DeprecationReason string
+ Name string
+ Description string
+ deprecation *ast.Directive
}
Field struct {
- Name string
- Description string
- Type *Type
- Args []InputValue
- IsDeprecated bool
- DeprecationReason string
+ Name string
+ Description string
+ Type *Type
+ Args []InputValue
+ deprecation *ast.Directive
}
InputValue struct {
@@ -39,20 +37,36 @@ func WrapSchema(schema *ast.Schema) *Schema {
return &Schema{schema: schema}
}
-func isDeprecated(directives ast.DirectiveList) bool {
- return directives.ForName("deprecated") != nil
+func (f *EnumValue) IsDeprecated() bool {
+ return f.deprecation != nil
+}
+
+func (f *EnumValue) DeprecationReason() *string {
+ if f.deprecation == nil {
+ return nil
+ }
+
+ reason := f.deprecation.Arguments.ForName("reason")
+ if reason == nil {
+ return nil
+ }
+
+ return &reason.Value.Raw
+}
+
+func (f *Field) IsDeprecated() bool {
+ return f.deprecation != nil
}
-func deprecationReason(directives ast.DirectiveList) string {
- deprecation := directives.ForName("deprecated")
- if deprecation == nil {
- return ""
+func (f *Field) DeprecationReason() *string {
+ if f.deprecation == nil {
+ return nil
}
- reason := deprecation.Arguments.ForName("reason")
+ reason := f.deprecation.Arguments.ForName("reason")
if reason == nil {
- return ""
+ return nil
}
- return reason.Value.Raw
+ return &reason.Value.Raw
}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
index dce144e0..b963aa0e 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
@@ -81,12 +81,11 @@ func (t *Type) Fields(includeDeprecated bool) []Field {
}
fields = append(fields, Field{
- Name: f.Name,
- Description: f.Description,
- Args: args,
- Type: WrapTypeFromType(t.schema, f.Type),
- IsDeprecated: isDeprecated(f.Directives),
- DeprecationReason: deprecationReason(f.Directives),
+ Name: f.Name,
+ Description: f.Description,
+ Args: args,
+ Type: WrapTypeFromType(t.schema, f.Type),
+ deprecation: f.Directives.ForName("deprecated"),
})
}
return fields
@@ -150,10 +149,9 @@ func (t *Type) EnumValues(includeDeprecated bool) []EnumValue {
var res []EnumValue
for _, val := range t.def.EnumValues {
res = append(res, EnumValue{
- Name: val.Name,
- Description: val.Description,
- IsDeprecated: isDeprecated(val.Directives),
- DeprecationReason: deprecationReason(val.Directives),
+ Name: val.Name,
+ Description: val.Description,
+ deprecation: val.Directives.ForName("deprecated"),
})
}
return res
diff --git a/vendor/github.com/99designs/gqlgen/graphql/response.go b/vendor/github.com/99designs/gqlgen/graphql/response.go
index 18664dca..6fe55d56 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/response.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/response.go
@@ -8,9 +8,13 @@ import (
"github.com/vektah/gqlparser/gqlerror"
)
+// Errors are intentionally serialized first based on the advice in
+// https://github.com/facebook/graphql/commit/7b40390d48680b15cb93e02d46ac5eb249689876#diff-757cea6edf0288677a9eea4cfc801d87R107
+// and https://github.com/facebook/graphql/pull/384
type Response struct {
- Data json.RawMessage `json:"data"`
- Errors gqlerror.List `json:"errors,omitempty"`
+ Errors gqlerror.List `json:"errors,omitempty"`
+ Data json.RawMessage `json:"data"`
+ Extensions map[string]interface{} `json:"extensions,omitempty"`
}
func ErrorResponse(ctx context.Context, messagef string, args ...interface{}) *Response {
diff --git a/vendor/github.com/99designs/gqlgen/graphql/tracer.go b/vendor/github.com/99designs/gqlgen/graphql/tracer.go
new file mode 100644
index 00000000..0597ce8c
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/tracer.go
@@ -0,0 +1,58 @@
+package graphql
+
+import (
+ "context"
+)
+
+var _ Tracer = (*NopTracer)(nil)
+
+type Tracer interface {
+ StartOperationParsing(ctx context.Context) context.Context
+ EndOperationParsing(ctx context.Context)
+ StartOperationValidation(ctx context.Context) context.Context
+ EndOperationValidation(ctx context.Context)
+ StartOperationExecution(ctx context.Context) context.Context
+ StartFieldExecution(ctx context.Context, field CollectedField) context.Context
+ StartFieldResolverExecution(ctx context.Context, rc *ResolverContext) context.Context
+ StartFieldChildExecution(ctx context.Context) context.Context
+ EndFieldExecution(ctx context.Context)
+ EndOperationExecution(ctx context.Context)
+}
+
+type NopTracer struct{}
+
+func (NopTracer) StartOperationParsing(ctx context.Context) context.Context {
+ return ctx
+}
+
+func (NopTracer) EndOperationParsing(ctx context.Context) {
+}
+
+func (NopTracer) StartOperationValidation(ctx context.Context) context.Context {
+ return ctx
+}
+
+func (NopTracer) EndOperationValidation(ctx context.Context) {
+}
+
+func (NopTracer) StartOperationExecution(ctx context.Context) context.Context {
+ return ctx
+}
+
+func (NopTracer) StartFieldExecution(ctx context.Context, field CollectedField) context.Context {
+ return ctx
+}
+
+func (NopTracer) StartFieldResolverExecution(ctx context.Context, rc *ResolverContext) context.Context {
+ return ctx
+}
+
+func (NopTracer) StartFieldChildExecution(ctx context.Context) context.Context {
+ return ctx
+}
+
+func (NopTracer) EndFieldExecution(ctx context.Context) {
+}
+
+func (NopTracer) EndOperationExecution(ctx context.Context) {
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go
index 38d3720b..8cf3c9ba 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/version.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/version.go
@@ -1,3 +1,3 @@
package graphql
-const Version = "v0.5.1"
+const Version = "dev"
diff --git a/vendor/github.com/99designs/gqlgen/handler/context.go b/vendor/github.com/99designs/gqlgen/handler/context.go
new file mode 100644
index 00000000..2992aa3d
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/handler/context.go
@@ -0,0 +1,57 @@
+package handler
+
+import "context"
+
+type key string
+
+const (
+ initpayload key = "ws_initpayload_context"
+)
+
+// InitPayload is a structure that is parsed from the websocket init message payload. TO use
+// request headers for non-websocket, instead wrap the graphql handler in a middleware.
+type InitPayload map[string]interface{}
+
+// GetString safely gets a string value from the payload. It returns an empty string if the
+// payload is nil or the value isn't set.
+func (payload InitPayload) GetString(key string) string {
+ if payload == nil {
+ return ""
+ }
+
+ if value, ok := payload[key]; ok {
+ res, _ := value.(string)
+ return res
+ }
+
+ return ""
+}
+
+// Authorization is a short hand for getting the Authorization header from the
+// payload.
+func (payload InitPayload) Authorization() string {
+ if value := payload.GetString("Authorization"); value != "" {
+ return value
+ }
+
+ if value := payload.GetString("authorization"); value != "" {
+ return value
+ }
+
+ return ""
+}
+
+func withInitPayload(ctx context.Context, payload InitPayload) context.Context {
+ return context.WithValue(ctx, initpayload, payload)
+}
+
+// GetInitPayload gets a map of the data sent with the connection_init message, which is used by
+// graphql clients as a stand-in for HTTP headers.
+func GetInitPayload(ctx context.Context) InitPayload {
+ payload, ok := ctx.Value(initpayload).(InitPayload)
+ if !ok {
+ return nil
+ }
+
+ return payload
+}
diff --git a/vendor/github.com/99designs/gqlgen/handler/graphql.go b/vendor/github.com/99designs/gqlgen/handler/graphql.go
index 9d222826..eb8880de 100644
--- a/vendor/github.com/99designs/gqlgen/handler/graphql.go
+++ b/vendor/github.com/99designs/gqlgen/handler/graphql.go
@@ -12,9 +12,9 @@ import (
"github.com/99designs/gqlgen/graphql"
"github.com/gorilla/websocket"
"github.com/hashicorp/golang-lru"
- "github.com/vektah/gqlparser"
"github.com/vektah/gqlparser/ast"
"github.com/vektah/gqlparser/gqlerror"
+ "github.com/vektah/gqlparser/parser"
"github.com/vektah/gqlparser/validator"
)
@@ -25,17 +25,21 @@ type params struct {
}
type Config struct {
- cacheSize int
- upgrader websocket.Upgrader
- recover graphql.RecoverFunc
- errorPresenter graphql.ErrorPresenterFunc
- resolverHook graphql.FieldMiddleware
- requestHook graphql.RequestMiddleware
- complexityLimit int
+ cacheSize int
+ upgrader websocket.Upgrader
+ recover graphql.RecoverFunc
+ errorPresenter graphql.ErrorPresenterFunc
+ resolverHook graphql.FieldMiddleware
+ requestHook graphql.RequestMiddleware
+ tracer graphql.Tracer
+ complexityLimit int
+ disableIntrospection bool
}
-func (c *Config) newRequestContext(doc *ast.QueryDocument, query string, variables map[string]interface{}) *graphql.RequestContext {
+func (c *Config) newRequestContext(es graphql.ExecutableSchema, doc *ast.QueryDocument, op *ast.OperationDefinition, query string, variables map[string]interface{}) *graphql.RequestContext {
reqCtx := graphql.NewRequestContext(doc, query, variables)
+ reqCtx.DisableIntrospection = c.disableIntrospection
+
if hook := c.recover; hook != nil {
reqCtx.Recover = hook
}
@@ -52,6 +56,18 @@ func (c *Config) newRequestContext(doc *ast.QueryDocument, query string, variabl
reqCtx.RequestMiddleware = hook
}
+ if hook := c.tracer; hook != nil {
+ reqCtx.Tracer = hook
+ } else {
+ reqCtx.Tracer = &graphql.NopTracer{}
+ }
+
+ if c.complexityLimit > 0 {
+ reqCtx.ComplexityLimit = c.complexityLimit
+ operationComplexity := complexity.Calculate(es, op, variables)
+ reqCtx.OperationComplexity = operationComplexity
+ }
+
return reqCtx
}
@@ -78,6 +94,14 @@ func ErrorPresenter(f graphql.ErrorPresenterFunc) Option {
}
}
+// IntrospectionEnabled = false will forbid clients from calling introspection endpoints. Can be useful in prod when you dont
+// want clients introspecting the full schema.
+func IntrospectionEnabled(enabled bool) Option {
+ return func(cfg *Config) {
+ cfg.disableIntrospection = !enabled
+ }
+}
+
// ComplexityLimit sets a maximum query complexity that is allowed to be executed.
// If a query is submitted that exceeds the limit, a 422 status code will be returned.
func ComplexityLimit(limit int) Option {
@@ -87,7 +111,7 @@ func ComplexityLimit(limit int) Option {
}
// ResolverMiddleware allows you to define a function that will be called around every resolver,
-// useful for tracing and logging.
+// useful for logging.
func ResolverMiddleware(middleware graphql.FieldMiddleware) Option {
return func(cfg *Config) {
if cfg.resolverHook == nil {
@@ -105,7 +129,7 @@ func ResolverMiddleware(middleware graphql.FieldMiddleware) Option {
}
// RequestMiddleware allows you to define a function that will be called around the root request,
-// after the query has been parsed. This is useful for logging and tracing
+// after the query has been parsed. This is useful for logging
func RequestMiddleware(middleware graphql.RequestMiddleware) Option {
return func(cfg *Config) {
if cfg.requestHook == nil {
@@ -122,6 +146,93 @@ func RequestMiddleware(middleware graphql.RequestMiddleware) Option {
}
}
+// Tracer allows you to add a request/resolver tracer that will be called around the root request,
+// calling resolver. This is useful for tracing
+func Tracer(tracer graphql.Tracer) Option {
+ return func(cfg *Config) {
+ if cfg.tracer == nil {
+ cfg.tracer = tracer
+
+ } else {
+ lastResolve := cfg.tracer
+ cfg.tracer = &tracerWrapper{
+ tracer1: lastResolve,
+ tracer2: tracer,
+ }
+ }
+
+ opt := RequestMiddleware(func(ctx context.Context, next func(ctx context.Context) []byte) []byte {
+ ctx = tracer.StartOperationExecution(ctx)
+ resp := next(ctx)
+ tracer.EndOperationExecution(ctx)
+
+ return resp
+ })
+ opt(cfg)
+ }
+}
+
+type tracerWrapper struct {
+ tracer1 graphql.Tracer
+ tracer2 graphql.Tracer
+}
+
+func (tw *tracerWrapper) StartOperationParsing(ctx context.Context) context.Context {
+ ctx = tw.tracer1.StartOperationParsing(ctx)
+ ctx = tw.tracer2.StartOperationParsing(ctx)
+ return ctx
+}
+
+func (tw *tracerWrapper) EndOperationParsing(ctx context.Context) {
+ tw.tracer2.EndOperationParsing(ctx)
+ tw.tracer1.EndOperationParsing(ctx)
+}
+
+func (tw *tracerWrapper) StartOperationValidation(ctx context.Context) context.Context {
+ ctx = tw.tracer1.StartOperationValidation(ctx)
+ ctx = tw.tracer2.StartOperationValidation(ctx)
+ return ctx
+}
+
+func (tw *tracerWrapper) EndOperationValidation(ctx context.Context) {
+ tw.tracer2.EndOperationValidation(ctx)
+ tw.tracer1.EndOperationValidation(ctx)
+}
+
+func (tw *tracerWrapper) StartOperationExecution(ctx context.Context) context.Context {
+ ctx = tw.tracer1.StartOperationExecution(ctx)
+ ctx = tw.tracer2.StartOperationExecution(ctx)
+ return ctx
+}
+
+func (tw *tracerWrapper) StartFieldExecution(ctx context.Context, field graphql.CollectedField) context.Context {
+ ctx = tw.tracer1.StartFieldExecution(ctx, field)
+ ctx = tw.tracer2.StartFieldExecution(ctx, field)
+ return ctx
+}
+
+func (tw *tracerWrapper) StartFieldResolverExecution(ctx context.Context, rc *graphql.ResolverContext) context.Context {
+ ctx = tw.tracer1.StartFieldResolverExecution(ctx, rc)
+ ctx = tw.tracer2.StartFieldResolverExecution(ctx, rc)
+ return ctx
+}
+
+func (tw *tracerWrapper) StartFieldChildExecution(ctx context.Context) context.Context {
+ ctx = tw.tracer1.StartFieldChildExecution(ctx)
+ ctx = tw.tracer2.StartFieldChildExecution(ctx)
+ return ctx
+}
+
+func (tw *tracerWrapper) EndFieldExecution(ctx context.Context) {
+ tw.tracer2.EndFieldExecution(ctx)
+ tw.tracer1.EndFieldExecution(ctx)
+}
+
+func (tw *tracerWrapper) EndOperationExecution(ctx context.Context) {
+ tw.tracer2.EndOperationExecution(ctx)
+ tw.tracer1.EndOperationExecution(ctx)
+}
+
// CacheSize sets the maximum size of the query cache.
// If size is less than or equal to 0, the cache is disabled.
func CacheSize(size int) Option {
@@ -133,7 +244,7 @@ func CacheSize(size int) Option {
const DefaultCacheSize = 1000
func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc {
- cfg := Config{
+ cfg := &Config{
cacheSize: DefaultCacheSize,
upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
@@ -142,7 +253,7 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc
}
for _, option := range options {
- option(&cfg)
+ option(cfg)
}
var cache *lru.Cache
@@ -155,112 +266,187 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc
panic("unexpected error creating cache: " + err.Error())
}
}
+ if cfg.tracer == nil {
+ cfg.tracer = &graphql.NopTracer{}
+ }
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if r.Method == http.MethodOptions {
- w.Header().Set("Allow", "OPTIONS, GET, POST")
- w.WriteHeader(http.StatusOK)
- return
- }
+ handler := &graphqlHandler{
+ cfg: cfg,
+ cache: cache,
+ exec: exec,
+ }
- if strings.Contains(r.Header.Get("Upgrade"), "websocket") {
- connectWs(exec, w, r, &cfg)
- return
- }
+ return handler.ServeHTTP
+}
- var reqParams params
- switch r.Method {
- case http.MethodGet:
- reqParams.Query = r.URL.Query().Get("query")
- reqParams.OperationName = r.URL.Query().Get("operationName")
-
- if variables := r.URL.Query().Get("variables"); variables != "" {
- if err := jsonDecode(strings.NewReader(variables), &reqParams.Variables); err != nil {
- sendErrorf(w, http.StatusBadRequest, "variables could not be decoded")
- return
- }
- }
- case http.MethodPost:
- if err := jsonDecode(r.Body, &reqParams); err != nil {
- sendErrorf(w, http.StatusBadRequest, "json body could not be decoded: "+err.Error())
+var _ http.Handler = (*graphqlHandler)(nil)
+
+type graphqlHandler struct {
+ cfg *Config
+ cache *lru.Cache
+ exec graphql.ExecutableSchema
+}
+
+func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if r.Method == http.MethodOptions {
+ w.Header().Set("Allow", "OPTIONS, GET, POST")
+ w.WriteHeader(http.StatusOK)
+ return
+ }
+
+ if strings.Contains(r.Header.Get("Upgrade"), "websocket") {
+ connectWs(gh.exec, w, r, gh.cfg)
+ return
+ }
+
+ var reqParams params
+ switch r.Method {
+ case http.MethodGet:
+ reqParams.Query = r.URL.Query().Get("query")
+ reqParams.OperationName = r.URL.Query().Get("operationName")
+
+ if variables := r.URL.Query().Get("variables"); variables != "" {
+ if err := jsonDecode(strings.NewReader(variables), &reqParams.Variables); err != nil {
+ sendErrorf(w, http.StatusBadRequest, "variables could not be decoded")
return
}
- default:
- w.WriteHeader(http.StatusMethodNotAllowed)
+ }
+ case http.MethodPost:
+ if err := jsonDecode(r.Body, &reqParams); err != nil {
+ sendErrorf(w, http.StatusBadRequest, "json body could not be decoded: "+err.Error())
return
}
- w.Header().Set("Content-Type", "application/json")
+ default:
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return
+ }
+ w.Header().Set("Content-Type", "application/json")
- var doc *ast.QueryDocument
- if cache != nil {
- val, ok := cache.Get(reqParams.Query)
- if ok {
- doc = val.(*ast.QueryDocument)
- }
- }
- if doc == nil {
- var qErr gqlerror.List
- doc, qErr = gqlparser.LoadQuery(exec.Schema(), reqParams.Query)
- if len(qErr) > 0 {
- sendError(w, http.StatusUnprocessableEntity, qErr...)
- return
- }
- if cache != nil {
- cache.Add(reqParams.Query, doc)
- }
- }
+ ctx := r.Context()
- op := doc.Operations.ForName(reqParams.OperationName)
- if op == nil {
- sendErrorf(w, http.StatusUnprocessableEntity, "operation %s not found", reqParams.OperationName)
- return
+ var doc *ast.QueryDocument
+ var cacheHit bool
+ if gh.cache != nil {
+ val, ok := gh.cache.Get(reqParams.Query)
+ if ok {
+ doc = val.(*ast.QueryDocument)
+ cacheHit = true
}
+ }
- if op.Operation != ast.Query && r.Method == http.MethodGet {
- sendErrorf(w, http.StatusUnprocessableEntity, "GET requests only allow query operations")
- return
+ ctx, doc, gqlErr := gh.parseOperation(ctx, &parseOperationArgs{
+ Query: reqParams.Query,
+ CachedDoc: doc,
+ })
+ if gqlErr != nil {
+ sendError(w, http.StatusUnprocessableEntity, gqlErr)
+ return
+ }
+
+ ctx, op, vars, listErr := gh.validateOperation(ctx, &validateOperationArgs{
+ Doc: doc,
+ OperationName: reqParams.OperationName,
+ CacheHit: cacheHit,
+ R: r,
+ Variables: reqParams.Variables,
+ })
+ if len(listErr) != 0 {
+ sendError(w, http.StatusUnprocessableEntity, listErr...)
+ return
+ }
+
+ if gh.cache != nil && !cacheHit {
+ gh.cache.Add(reqParams.Query, doc)
+ }
+
+ reqCtx := gh.cfg.newRequestContext(gh.exec, doc, op, reqParams.Query, vars)
+ ctx = graphql.WithRequestContext(ctx, reqCtx)
+
+ defer func() {
+ if err := recover(); err != nil {
+ userErr := reqCtx.Recover(ctx, err)
+ sendErrorf(w, http.StatusUnprocessableEntity, userErr.Error())
}
+ }()
- vars, err := validator.VariableValues(exec.Schema(), op, reqParams.Variables)
+ if reqCtx.ComplexityLimit > 0 && reqCtx.OperationComplexity > reqCtx.ComplexityLimit {
+ sendErrorf(w, http.StatusUnprocessableEntity, "operation has complexity %d, which exceeds the limit of %d", reqCtx.OperationComplexity, reqCtx.ComplexityLimit)
+ return
+ }
+
+ switch op.Operation {
+ case ast.Query:
+ b, err := json.Marshal(gh.exec.Query(ctx, op))
if err != nil {
- sendError(w, http.StatusUnprocessableEntity, err)
- return
+ panic(err)
}
- reqCtx := cfg.newRequestContext(doc, reqParams.Query, vars)
- ctx := graphql.WithRequestContext(r.Context(), reqCtx)
+ w.Write(b)
+ case ast.Mutation:
+ b, err := json.Marshal(gh.exec.Mutation(ctx, op))
+ if err != nil {
+ panic(err)
+ }
+ w.Write(b)
+ default:
+ sendErrorf(w, http.StatusBadRequest, "unsupported operation type")
+ }
+}
- defer func() {
- if err := recover(); err != nil {
- userErr := reqCtx.Recover(ctx, err)
- sendErrorf(w, http.StatusUnprocessableEntity, userErr.Error())
- }
- }()
+type parseOperationArgs struct {
+ Query string
+ CachedDoc *ast.QueryDocument
+}
- if cfg.complexityLimit > 0 {
- queryComplexity := complexity.Calculate(exec, op, vars)
- if queryComplexity > cfg.complexityLimit {
- sendErrorf(w, http.StatusUnprocessableEntity, "query has complexity %d, which exceeds the limit of %d", queryComplexity, cfg.complexityLimit)
- return
- }
- }
+func (gh *graphqlHandler) parseOperation(ctx context.Context, args *parseOperationArgs) (context.Context, *ast.QueryDocument, *gqlerror.Error) {
+ ctx = gh.cfg.tracer.StartOperationParsing(ctx)
+ defer func() { gh.cfg.tracer.EndOperationParsing(ctx) }()
- switch op.Operation {
- case ast.Query:
- b, err := json.Marshal(exec.Query(ctx, op))
- if err != nil {
- panic(err)
- }
- w.Write(b)
- case ast.Mutation:
- b, err := json.Marshal(exec.Mutation(ctx, op))
- if err != nil {
- panic(err)
- }
- w.Write(b)
- default:
- sendErrorf(w, http.StatusBadRequest, "unsupported operation type")
+ if args.CachedDoc != nil {
+ return ctx, args.CachedDoc, nil
+ }
+
+ doc, gqlErr := parser.ParseQuery(&ast.Source{Input: args.Query})
+ if gqlErr != nil {
+ return ctx, nil, gqlErr
+ }
+
+ return ctx, doc, nil
+}
+
+type validateOperationArgs struct {
+ Doc *ast.QueryDocument
+ OperationName string
+ CacheHit bool
+ R *http.Request
+ Variables map[string]interface{}
+}
+
+func (gh *graphqlHandler) validateOperation(ctx context.Context, args *validateOperationArgs) (context.Context, *ast.OperationDefinition, map[string]interface{}, gqlerror.List) {
+ ctx = gh.cfg.tracer.StartOperationValidation(ctx)
+ defer func() { gh.cfg.tracer.EndOperationValidation(ctx) }()
+
+ if !args.CacheHit {
+ listErr := validator.Validate(gh.exec.Schema(), args.Doc)
+ if len(listErr) != 0 {
+ return ctx, nil, nil, listErr
}
- })
+ }
+
+ op := args.Doc.Operations.ForName(args.OperationName)
+ if op == nil {
+ return ctx, nil, nil, gqlerror.List{gqlerror.Errorf("operation %s not found", args.OperationName)}
+ }
+
+ if op.Operation != ast.Query && args.R.Method == http.MethodGet {
+ return ctx, nil, nil, gqlerror.List{gqlerror.Errorf("GET requests only allow query operations")}
+ }
+
+ vars, err := validator.VariableValues(gh.exec.Schema(), op, args.Variables)
+ if err != nil {
+ return ctx, nil, nil, gqlerror.List{err}
+ }
+
+ return ctx, op, vars, nil
}
func jsonDecode(r io.Reader, val interface{}) error {
diff --git a/vendor/github.com/99designs/gqlgen/handler/playground.go b/vendor/github.com/99designs/gqlgen/handler/playground.go
index d0ada8ca..f1687def 100644
--- a/vendor/github.com/99designs/gqlgen/handler/playground.go
+++ b/vendor/github.com/99designs/gqlgen/handler/playground.go
@@ -45,7 +45,7 @@ func Playground(title string, endpoint string) http.HandlerFunc {
err := page.Execute(w, map[string]string{
"title": title,
"endpoint": endpoint,
- "version": "1.6.2",
+ "version": "1.7.8",
})
if err != nil {
panic(err)
diff --git a/vendor/github.com/99designs/gqlgen/handler/websocket.go b/vendor/github.com/99designs/gqlgen/handler/websocket.go
index 2be1e87f..dae262bd 100644
--- a/vendor/github.com/99designs/gqlgen/handler/websocket.go
+++ b/vendor/github.com/99designs/gqlgen/handler/websocket.go
@@ -43,6 +43,8 @@ type wsConnection struct {
active map[string]context.CancelFunc
mu sync.Mutex
cfg *Config
+
+ initPayload InitPayload
}
func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Request, cfg *Config) {
@@ -79,6 +81,14 @@ func (c *wsConnection) init() bool {
switch message.Type {
case connectionInitMsg:
+ if len(message.Payload) > 0 {
+ c.initPayload = make(InitPayload)
+ err := json.Unmarshal(message.Payload, &c.initPayload)
+ if err != nil {
+ return false
+ }
+ }
+
c.write(&operationMessage{Type: connectionAckMsg})
case connectionTerminateMsg:
c.close(websocket.CloseNormalClosure, "terminated")
@@ -155,9 +165,13 @@ func (c *wsConnection) subscribe(message *operationMessage) bool {
c.sendError(message.ID, err)
return true
}
- reqCtx := c.cfg.newRequestContext(doc, reqParams.Query, vars)
+ reqCtx := c.cfg.newRequestContext(c.exec, doc, op, reqParams.Query, vars)
ctx := graphql.WithRequestContext(c.ctx, reqCtx)
+ if c.initPayload != nil {
+ ctx = withInitPayload(ctx, c.initPayload)
+ }
+
if op.Operation != ast.Subscription {
var result *graphql.Response
if op.Operation == ast.Query {
diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
new file mode 100644
index 00000000..d2469e83
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
@@ -0,0 +1,119 @@
+// Wrapper around x/tools/imports that only removes imports, never adds new ones.
+
+package imports
+
+import (
+ "bytes"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "path/filepath"
+ "strings"
+
+ "golang.org/x/tools/imports"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+type visitFn func(node ast.Node)
+
+func (fn visitFn) Visit(node ast.Node) ast.Visitor {
+ fn(node)
+ return fn
+}
+
+// Prune removes any unused imports
+func Prune(filename string, src []byte) ([]byte, error) {
+ fset := token.NewFileSet()
+
+ file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors)
+ if err != nil {
+ return nil, err
+ }
+
+ unused, err := getUnusedImports(file, filename)
+ if err != nil {
+ return nil, err
+ }
+ for ipath, name := range unused {
+ astutil.DeleteNamedImport(fset, file, name, ipath)
+ }
+ printConfig := &printer.Config{Mode: printer.TabIndent, Tabwidth: 8}
+
+ var buf bytes.Buffer
+ if err := printConfig.Fprint(&buf, fset, file); err != nil {
+ return nil, err
+ }
+
+ return imports.Process(filename, buf.Bytes(), &imports.Options{FormatOnly: true, Comments: true, TabIndent: true, TabWidth: 8})
+}
+
+func getUnusedImports(file ast.Node, filename string) (map[string]string, error) {
+ imported := map[string]*ast.ImportSpec{}
+ used := map[string]bool{}
+
+ abs, err := filepath.Abs(filename)
+ if err != nil {
+ return nil, err
+ }
+ srcDir := filepath.Dir(abs)
+
+ ast.Walk(visitFn(func(node ast.Node) {
+ if node == nil {
+ return
+ }
+ switch v := node.(type) {
+ case *ast.ImportSpec:
+ if v.Name != nil {
+ imported[v.Name.Name] = v
+ break
+ }
+ ipath := strings.Trim(v.Path.Value, `"`)
+ if ipath == "C" {
+ break
+ }
+
+ local := importPathToName(ipath, srcDir)
+
+ imported[local] = v
+ case *ast.SelectorExpr:
+ xident, ok := v.X.(*ast.Ident)
+ if !ok {
+ break
+ }
+ if xident.Obj != nil {
+ // if the parser can resolve it, it's not a package ref
+ break
+ }
+ used[xident.Name] = true
+ }
+ }), file)
+
+ for pkg := range used {
+ delete(imported, pkg)
+ }
+
+ unusedImport := map[string]string{}
+ for pkg, is := range imported {
+ if !used[pkg] && pkg != "_" && pkg != "." {
+ name := ""
+ if is.Name != nil {
+ name = is.Name.Name
+ }
+ unusedImport[strings.Trim(is.Path.Value, `"`)] = name
+ }
+ }
+
+ return unusedImport, nil
+}
+
+func importPathToName(importPath, srcDir string) (packageName string) {
+ pkg, err := build.Default.Import(importPath, srcDir, 0)
+ if err != nil {
+ return ""
+ }
+
+ return pkg.Name
+}