aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs/gqlgen
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs/gqlgen')
-rw-r--r--vendor/github.com/99designs/gqlgen/api/generate.go76
-rw-r--r--vendor/github.com/99designs/gqlgen/api/option.go20
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/ambient.go (renamed from vendor/github.com/99designs/gqlgen/codegen/ambient.go)2
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/gen.go34
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/init.go66
-rw-r--r--vendor/github.com/99designs/gqlgen/cmd/root.go11
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/args.go104
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/args.gotpl43
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/build.go194
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/codegen.go179
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/complexity.go11
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/config.go273
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/config/binder.go451
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/config/config.go408
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/data.go168
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/directive.go119
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/directive_build.go48
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/enum.go12
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/enum_build.go39
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/field.go394
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/field.gotpl (renamed from vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl)62
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/generate.go15
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl (renamed from vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl)104
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/input.gotpl56
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/input_build.go96
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/interface.go58
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/interface.gotpl20
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/interface_build.go53
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/model.go17
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/models_build.go91
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/object.go483
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/object.gotpl77
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/object_build.go181
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/args.gotpl13
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/data.go13
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/import.go46
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/input.gotpl28
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/interface.gotpl18
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl91
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/object.gotpl69
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl44
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/templates/templates.go452
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/type.go174
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/type.gotpl131
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/type_build.go100
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/util.go358
l---------vendor/github.com/99designs/gqlgen/docs/content/_introduction.md1
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/bool.go2
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/context.go69
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/error.go4
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/exec.go10
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/fieldset.go63
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/id.go21
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/int.go50
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/introspection/type.go20
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/jsonw.go31
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/root.go7
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/string.go59
-rw-r--r--vendor/github.com/99designs/gqlgen/graphql/version.go2
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/graphql.go38
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/playground.go19
-rw-r--r--vendor/github.com/99designs/gqlgen/handler/websocket.go30
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/compare.go163
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/imports.go60
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/code/util.go56
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go37
-rw-r--r--vendor/github.com/99designs/gqlgen/internal/imports/prune.go22
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go207
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl85
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/plugin.go20
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go53
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl40
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/servergen/server.go49
-rw-r--r--vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl (renamed from vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl)16
74 files changed, 3852 insertions, 2884 deletions
diff --git a/vendor/github.com/99designs/gqlgen/api/generate.go b/vendor/github.com/99designs/gqlgen/api/generate.go
new file mode 100644
index 00000000..3dd083f5
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/api/generate.go
@@ -0,0 +1,76 @@
+package api
+
+import (
+ "syscall"
+
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/99designs/gqlgen/plugin"
+ "github.com/99designs/gqlgen/plugin/modelgen"
+ "github.com/99designs/gqlgen/plugin/resolvergen"
+ "github.com/pkg/errors"
+ "golang.org/x/tools/go/packages"
+)
+
+func Generate(cfg *config.Config, option ...Option) error {
+ _ = syscall.Unlink(cfg.Exec.Filename)
+ _ = syscall.Unlink(cfg.Model.Filename)
+
+ plugins := []plugin.Plugin{
+ modelgen.New(),
+ resolvergen.New(),
+ }
+
+ for _, o := range option {
+ o(cfg, &plugins)
+ }
+
+ for _, p := range plugins {
+ if mut, ok := p.(plugin.ConfigMutator); ok {
+ err := mut.MutateConfig(cfg)
+ if err != nil {
+ return errors.Wrap(err, p.Name())
+ }
+ }
+ }
+ // Merge again now that the generated models have been injected into the typemap
+ data, err := codegen.BuildData(cfg)
+ if err != nil {
+ return errors.Wrap(err, "merging failed")
+ }
+
+ if err = codegen.GenerateCode(data); err != nil {
+ return errors.Wrap(err, "generating core failed")
+ }
+
+ for _, p := range plugins {
+ if mut, ok := p.(plugin.CodeGenerator); ok {
+ err := mut.GenerateCode(data)
+ if err != nil {
+ return errors.Wrap(err, p.Name())
+ }
+ }
+ }
+
+ if err := validate(cfg); err != nil {
+ return errors.Wrap(err, "validation failed")
+ }
+
+ return nil
+}
+
+func validate(cfg *config.Config) error {
+ roots := []string{cfg.Exec.ImportPath()}
+ if cfg.Model.IsDefined() {
+ roots = append(roots, cfg.Model.ImportPath())
+ }
+
+ if cfg.Resolver.IsDefined() {
+ roots = append(roots, cfg.Resolver.ImportPath())
+ }
+ _, err := packages.Load(&packages.Config{Mode: packages.LoadTypes | packages.LoadSyntax}, roots...)
+ if err != nil {
+ return errors.Wrap(err, "validation failed")
+ }
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/api/option.go b/vendor/github.com/99designs/gqlgen/api/option.go
new file mode 100644
index 00000000..f7ba6774
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/api/option.go
@@ -0,0 +1,20 @@
+package api
+
+import (
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/99designs/gqlgen/plugin"
+)
+
+type Option func(cfg *config.Config, plugins *[]plugin.Plugin)
+
+func NoPlugins() Option {
+ return func(cfg *config.Config, plugins *[]plugin.Plugin) {
+ *plugins = nil
+ }
+}
+
+func AddPlugin(p plugin.Plugin) Option {
+ return func(cfg *config.Config, plugins *[]plugin.Plugin) {
+ *plugins = append(*plugins, p)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/ambient.go b/vendor/github.com/99designs/gqlgen/cmd/ambient.go
index c9909fcc..7838fdf1 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/ambient.go
+++ b/vendor/github.com/99designs/gqlgen/cmd/ambient.go
@@ -1,4 +1,4 @@
-package codegen
+package cmd
import (
// Import and ignore the ambient imports listed below so dependency managers
diff --git a/vendor/github.com/99designs/gqlgen/cmd/gen.go b/vendor/github.com/99designs/gqlgen/cmd/gen.go
index 3842f02b..c69858b4 100644
--- a/vendor/github.com/99designs/gqlgen/cmd/gen.go
+++ b/vendor/github.com/99designs/gqlgen/cmd/gen.go
@@ -2,10 +2,10 @@ package cmd
import (
"fmt"
- "io/ioutil"
"os"
- "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/api"
+ "github.com/99designs/gqlgen/codegen/config"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
@@ -18,43 +18,27 @@ var genCmd = cli.Command{
cli.StringFlag{Name: "config, c", Usage: "the config filename"},
},
Action: func(ctx *cli.Context) {
- var config *codegen.Config
+ var cfg *config.Config
var err error
if configFilename := ctx.String("config"); configFilename != "" {
- config, err = codegen.LoadConfig(configFilename)
+ cfg, err = config.LoadConfig(configFilename)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
} else {
- config, err = codegen.LoadConfigFromDefaultLocations()
+ cfg, err = config.LoadConfigFromDefaultLocations()
if os.IsNotExist(errors.Cause(err)) {
- config = codegen.DefaultConfig()
+ cfg = config.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)
+ os.Exit(2)
}
- 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 {
+ if err = api.Generate(cfg); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(2)
+ os.Exit(3)
}
},
}
diff --git a/vendor/github.com/99designs/gqlgen/cmd/init.go b/vendor/github.com/99designs/gqlgen/cmd/init.go
index 1e7c18b9..e07bed97 100644
--- a/vendor/github.com/99designs/gqlgen/cmd/init.go
+++ b/vendor/github.com/99designs/gqlgen/cmd/init.go
@@ -7,10 +7,13 @@ import (
"os"
"strings"
- "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/api"
+ "github.com/99designs/gqlgen/plugin/servergen"
+
+ "github.com/99designs/gqlgen/codegen/config"
"github.com/pkg/errors"
"github.com/urfave/cli"
- "gopkg.in/yaml.v2"
+ yaml "gopkg.in/yaml.v2"
)
var configComment = `
@@ -68,46 +71,27 @@ var initCmd = cli.Command{
},
}
-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 {
+func GenerateGraphServer(cfg *config.Config, serverFilename string) {
+ err := api.Generate(cfg, api.AddPlugin(servergen.New(serverFilename)))
+ if 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
+func initConfig(ctx *cli.Context) *config.Config {
+ var cfg *config.Config
var err error
configFilename := ctx.String("config")
if configFilename != "" {
- config, err = codegen.LoadConfig(configFilename)
+ cfg, err = config.LoadConfig(configFilename)
} else {
- config, err = codegen.LoadConfigFromDefaultLocations()
+ cfg, err = config.LoadConfigFromDefaultLocations()
}
- if config != nil {
- fmt.Fprintf(os.Stderr, "init failed: a configuration file already exists at %s\n", config.FilePath)
+ if cfg != nil {
+ fmt.Fprintf(os.Stderr, "init failed: a configuration file already exists\n")
os.Exit(1)
}
@@ -119,9 +103,9 @@ func initConfig(ctx *cli.Context) *codegen.Config {
if configFilename == "" {
configFilename = "gqlgen.yml"
}
- config = codegen.DefaultConfig()
+ cfg = config.DefaultConfig()
- config.Resolver = codegen.PackageConfig{
+ cfg.Resolver = config.PackageConfig{
Filename: "resolver.go",
Type: "Resolver",
}
@@ -129,23 +113,21 @@ func initConfig(ctx *cli.Context) *codegen.Config {
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)
+ var b []byte
+ b, err = yaml.Marshal(cfg)
+ 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())
+ fmt.Fprintln(os.Stderr, "unable to write cfg file: "+err.Error())
os.Exit(1)
}
- return config
+ return cfg
}
func initSchema(schemaFilename string) {
diff --git a/vendor/github.com/99designs/gqlgen/cmd/root.go b/vendor/github.com/99designs/gqlgen/cmd/root.go
index 519c2e1a..dc2970ac 100644
--- a/vendor/github.com/99designs/gqlgen/cmd/root.go
+++ b/vendor/github.com/99designs/gqlgen/cmd/root.go
@@ -7,7 +7,6 @@ import (
"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
@@ -23,14 +22,6 @@ func Execute() {
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 {
@@ -47,7 +38,7 @@ func Execute() {
}
if err := app.Run(os.Args); err != nil {
- fmt.Fprintf(os.Stderr, err.Error())
+ fmt.Fprint(os.Stderr, err.Error())
os.Exit(1)
}
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.go b/vendor/github.com/99designs/gqlgen/codegen/args.go
new file mode 100644
index 00000000..d1498bdd
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/args.go
@@ -0,0 +1,104 @@
+package codegen
+
+import (
+ "fmt"
+ "go/types"
+ "strings"
+
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
+)
+
+type ArgSet struct {
+ Args []*FieldArgument
+ FuncDecl string
+}
+
+type FieldArgument struct {
+ *ast.ArgumentDefinition
+ TypeReference *config.TypeReference
+ VarName string // The name of the var in go
+ Object *Object // A link back to the parent object
+ Default interface{} // The default value
+ Directives []*Directive
+ Value interface{} // value set in Data
+}
+
+func (f *FieldArgument) Stream() bool {
+ return f.Object != nil && f.Object.Stream
+}
+
+func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) {
+ tr, err := b.Binder.TypeReference(arg.Type, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ argDirs, err := b.getDirectives(arg.Directives)
+ if err != nil {
+ return nil, err
+ }
+ newArg := FieldArgument{
+ ArgumentDefinition: arg,
+ TypeReference: tr,
+ Object: obj,
+ VarName: templates.ToGoPrivate(arg.Name),
+ Directives: argDirs,
+ }
+
+ if arg.DefaultValue != nil {
+ newArg.Default, err = arg.DefaultValue.Value(nil)
+ if err != nil {
+ return nil, errors.Errorf("default value is not valid: %s", err.Error())
+ }
+ }
+
+ return &newArg, nil
+}
+
+func (b *builder) bindArgs(field *Field, params *types.Tuple) error {
+ var newArgs []*FieldArgument
+
+nextArg:
+ for j := 0; j < params.Len(); j++ {
+ param := params.At(j)
+ for _, oldArg := range field.Args {
+ if strings.EqualFold(oldArg.Name, param.Name()) {
+ tr, err := b.Binder.TypeReference(oldArg.Type, param.Type())
+ if err != nil {
+ return err
+ }
+ oldArg.TypeReference = tr
+
+ newArgs = append(newArgs, oldArg)
+ continue nextArg
+ }
+ }
+
+ // no matching arg found, abort
+ return fmt.Errorf("arg %s not in schema", param.Name())
+ }
+
+ field.Args = newArgs
+ return nil
+}
+
+func (a *Data) Args() map[string][]*FieldArgument {
+ ret := map[string][]*FieldArgument{}
+ for _, o := range a.Objects {
+ for _, f := range o.Fields {
+ if len(f.Args) > 0 {
+ ret[f.ArgsFunc()] = f.Args
+ }
+ }
+ }
+
+ for _, d := range a.Directives {
+ if len(d.Args) > 0 {
+ ret[d.ArgsFunc()] = d.Args
+ }
+ }
+ return ret
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/args.gotpl b/vendor/github.com/99designs/gqlgen/codegen/args.gotpl
new file mode 100644
index 00000000..4c721218
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/args.gotpl
@@ -0,0 +1,43 @@
+{{ range $name, $args := .Args }}
+func (ec *executionContext) {{ $name }}(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
+ var err error
+ args := map[string]interface{}{}
+ {{- range $i, $arg := . }}
+ var arg{{$i}} {{ $arg.TypeReference.GO | ref}}
+ if tmp, ok := rawArgs[{{$arg.Name|quote}}]; ok {
+ {{- if $arg.Directives }}
+ getArg0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp) }
+
+ {{- range $i, $directive := $arg.Directives }}
+ getArg{{add $i 1}} := func(ctx context.Context) (res interface{}, err error) {
+ {{- range $dArg := $directive.Args }}
+ {{- if and $dArg.TypeReference.IsPtr ( notNil "Value" $dArg ) }}
+ {{ $dArg.VarName }} := {{ $dArg.Value | dump }}
+ {{- end }}
+ {{- end }}
+ n := getArg{{$i}}
+ return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs "tmp" "n" }})
+ }
+ {{- end }}
+
+ tmp, err = getArg{{$arg.Directives|len}}(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if data, ok := tmp.({{ $arg.TypeReference.GO | ref }}) ; ok {
+ arg{{$i}} = data
+ } else {
+ return nil, fmt.Errorf(`unexpected type %T from directive, should be {{ $arg.TypeReference.GO }}`, tmp)
+ }
+ {{- else }}
+ arg{{$i}}, err = ec.{{ $arg.TypeReference.UnmarshalFunc }}(ctx, tmp)
+ if err != nil {
+ return nil, err
+ }
+ {{- end }}
+ }
+ args[{{$arg.Name|quote}}] = arg{{$i}}
+ {{- end }}
+ return args, nil
+}
+{{ end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/build.go b/vendor/github.com/99designs/gqlgen/codegen/build.go
deleted file mode 100644
index 582689a7..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/build.go
+++ /dev/null
@@ -1,194 +0,0 @@
-package codegen
-
-import (
- "fmt"
- "go/build"
- "go/types"
- "os"
-
- "github.com/pkg/errors"
- "golang.org/x/tools/go/loader"
-)
-
-type Build struct {
- PackageName string
- Objects Objects
- Inputs Objects
- Interfaces []*Interface
- QueryRoot *Object
- MutationRoot *Object
- SubscriptionRoot *Object
- SchemaRaw map[string]string
- SchemaFilename SchemaFilenames
- Directives []*Directive
-}
-
-type ModelBuild struct {
- PackageName string
- Models []Model
- Enums []Enum
-}
-
-type ResolverBuild struct {
- PackageName string
- ResolverType string
- Objects Objects
- ResolverFound bool
-}
-
-type ServerBuild struct {
- PackageName string
- ExecPackageName string
- ResolverPackageName string
-}
-
-// Create a list of models that need to be generated
-func (cfg *Config) models() (*ModelBuild, error) {
- namedTypes := cfg.buildNamedTypes()
-
- progLoader := cfg.newLoaderWithoutErrors()
-
- prog, err := progLoader.Load()
- if err != nil {
- return nil, errors.Wrap(err, "loading failed")
- }
-
- cfg.bindTypes(namedTypes, cfg.Model.Dir(), prog)
-
- models, err := cfg.buildModels(namedTypes, prog)
- if err != nil {
- return nil, err
- }
- return &ModelBuild{
- PackageName: cfg.Model.Package,
- Models: models,
- Enums: cfg.buildEnums(namedTypes),
- }, nil
-}
-
-// bind a schema together with some code to generate a Build
-func (cfg *Config) resolver() (*ResolverBuild, error) {
- progLoader := cfg.newLoaderWithoutErrors()
- progLoader.Import(cfg.Resolver.ImportPath())
-
- prog, err := progLoader.Load()
- if err != nil {
- return nil, err
- }
-
- destDir := cfg.Resolver.Dir()
-
- namedTypes := cfg.buildNamedTypes()
-
- cfg.bindTypes(namedTypes, destDir, prog)
-
- objects, err := cfg.buildObjects(namedTypes, prog)
- if err != nil {
- return nil, err
- }
-
- def, _ := findGoType(prog, cfg.Resolver.ImportPath(), cfg.Resolver.Type)
- resolverFound := def != nil
-
- return &ResolverBuild{
- PackageName: cfg.Resolver.Package,
- Objects: objects,
- ResolverType: cfg.Resolver.Type,
- ResolverFound: resolverFound,
- }, nil
-}
-
-func (cfg *Config) server(destDir string) *ServerBuild {
- return &ServerBuild{
- PackageName: cfg.Resolver.Package,
- ExecPackageName: cfg.Exec.ImportPath(),
- ResolverPackageName: cfg.Resolver.ImportPath(),
- }
-}
-
-// bind a schema together with some code to generate a Build
-func (cfg *Config) bind() (*Build, error) {
- namedTypes := cfg.buildNamedTypes()
-
- progLoader := cfg.newLoaderWithoutErrors()
- prog, err := progLoader.Load()
- if err != nil {
- return nil, errors.Wrap(err, "loading failed")
- }
-
- cfg.bindTypes(namedTypes, cfg.Exec.Dir(), prog)
-
- objects, err := cfg.buildObjects(namedTypes, prog)
- if err != nil {
- return nil, err
- }
-
- inputs, err := cfg.buildInputs(namedTypes, prog)
- if err != nil {
- return nil, err
- }
- directives, err := cfg.buildDirectives(namedTypes)
- if err != nil {
- return nil, err
- }
-
- b := &Build{
- PackageName: cfg.Exec.Package,
- Objects: objects,
- Interfaces: cfg.buildInterfaces(namedTypes, prog),
- Inputs: inputs,
- SchemaRaw: cfg.SchemaStr,
- SchemaFilename: cfg.SchemaFilename,
- Directives: directives,
- }
-
- if cfg.schema.Query != nil {
- b.QueryRoot = b.Objects.ByName(cfg.schema.Query.Name)
- } else {
- return b, fmt.Errorf("query entry point missing")
- }
-
- if cfg.schema.Mutation != nil {
- b.MutationRoot = b.Objects.ByName(cfg.schema.Mutation.Name)
- }
-
- if cfg.schema.Subscription != nil {
- b.SubscriptionRoot = b.Objects.ByName(cfg.schema.Subscription.Name)
- }
- return b, nil
-}
-
-func (cfg *Config) validate() error {
- progLoader := cfg.newLoaderWithErrors()
- _, err := progLoader.Load()
- return err
-}
-
-func (cfg *Config) newLoaderWithErrors() loader.Config {
- conf := loader.Config{}
-
- 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
-}
-
-func resolvePkg(pkgName string) (string, error) {
- cwd, _ := os.Getwd()
-
- pkg, err := build.Default.Import(pkgName, cwd, build.FindOnly)
- if err != nil {
- return "", err
- }
-
- return pkg.ImportPath, nil
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/codegen.go b/vendor/github.com/99designs/gqlgen/codegen/codegen.go
deleted file mode 100644
index 773e3db7..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/codegen.go
+++ /dev/null
@@ -1,179 +0,0 @@
-package codegen
-
-import (
- "log"
- "os"
- "path/filepath"
- "regexp"
- "syscall"
-
- "github.com/99designs/gqlgen/codegen/templates"
- "github.com/pkg/errors"
- "github.com/vektah/gqlparser"
- "github.com/vektah/gqlparser/ast"
- "github.com/vektah/gqlparser/gqlerror"
-)
-
-func Generate(cfg Config) error {
- if err := cfg.normalize(); err != nil {
- return err
- }
-
- _ = syscall.Unlink(cfg.Exec.Filename)
- _ = syscall.Unlink(cfg.Model.Filename)
-
- modelsBuild, err := cfg.models()
- if err != nil {
- return errors.Wrap(err, "model plan failed")
- }
- if len(modelsBuild.Models) > 0 || len(modelsBuild.Enums) > 0 {
- if err = templates.RenderToFile("models.gotpl", cfg.Model.Filename, modelsBuild); err != nil {
- return err
- }
-
- for _, model := range modelsBuild.Models {
- modelCfg := cfg.Models[model.GQLType]
- modelCfg.Model = cfg.Model.ImportPath() + "." + model.GoType
- cfg.Models[model.GQLType] = modelCfg
- }
-
- for _, enum := range modelsBuild.Enums {
- modelCfg := cfg.Models[enum.GQLType]
- modelCfg.Model = cfg.Model.ImportPath() + "." + enum.GoType
- cfg.Models[enum.GQLType] = modelCfg
- }
- }
-
- build, err := cfg.bind()
- if err != nil {
- return errors.Wrap(err, "exec plan failed")
- }
-
- if err := templates.RenderToFile("generated.gotpl", cfg.Exec.Filename, build); err != nil {
- return err
- }
-
- if cfg.Resolver.IsDefined() {
- if err := generateResolver(cfg); err != nil {
- return errors.Wrap(err, "generating resolver failed")
- }
- }
-
- if err := cfg.validate(); err != nil {
- return errors.Wrap(err, "validation failed")
- }
-
- return nil
-}
-
-func GenerateServer(cfg Config, filename string) error {
- if err := cfg.Exec.normalize(); err != nil {
- return errors.Wrap(err, "exec")
- }
- if err := cfg.Resolver.normalize(); err != nil {
- return errors.Wrap(err, "resolver")
- }
-
- serverFilename := abs(filename)
- serverBuild := cfg.server(filepath.Dir(serverFilename))
-
- if _, err := os.Stat(serverFilename); os.IsNotExist(errors.Cause(err)) {
- err = templates.RenderToFile("server.gotpl", serverFilename, serverBuild)
- if err != nil {
- return errors.Wrap(err, "generate server failed")
- }
- } else {
- log.Printf("Skipped server: %s already exists\n", serverFilename)
- }
- return nil
-}
-
-func generateResolver(cfg Config) error {
- resolverBuild, err := cfg.resolver()
- if err != nil {
- return errors.Wrap(err, "resolver build failed")
- }
- filename := cfg.Resolver.Filename
-
- if resolverBuild.ResolverFound {
- log.Printf("Skipped resolver: %s.%s already exists\n", cfg.Resolver.ImportPath(), cfg.Resolver.Type)
- return nil
- }
-
- if _, err := os.Stat(filename); os.IsNotExist(errors.Cause(err)) {
- if err := templates.RenderToFile("resolver.gotpl", filename, resolverBuild); err != nil {
- return err
- }
- } else {
- log.Printf("Skipped resolver: %s already exists\n", filename)
- }
-
- return nil
-}
-
-func (cfg *Config) normalize() error {
- if err := cfg.Model.normalize(); err != nil {
- return errors.Wrap(err, "model")
- }
-
- if err := cfg.Exec.normalize(); err != nil {
- return errors.Wrap(err, "exec")
- }
-
- if cfg.Resolver.IsDefined() {
- if err := cfg.Resolver.normalize(); err != nil {
- return errors.Wrap(err, "resolver")
- }
- }
-
- builtins := TypeMap{
- "__Directive": {Model: "github.com/99designs/gqlgen/graphql/introspection.Directive"},
- "__Type": {Model: "github.com/99designs/gqlgen/graphql/introspection.Type"},
- "__Field": {Model: "github.com/99designs/gqlgen/graphql/introspection.Field"},
- "__EnumValue": {Model: "github.com/99designs/gqlgen/graphql/introspection.EnumValue"},
- "__InputValue": {Model: "github.com/99designs/gqlgen/graphql/introspection.InputValue"},
- "__Schema": {Model: "github.com/99designs/gqlgen/graphql/introspection.Schema"},
- "Int": {Model: "github.com/99designs/gqlgen/graphql.Int"},
- "Float": {Model: "github.com/99designs/gqlgen/graphql.Float"},
- "String": {Model: "github.com/99designs/gqlgen/graphql.String"},
- "Boolean": {Model: "github.com/99designs/gqlgen/graphql.Boolean"},
- "ID": {Model: "github.com/99designs/gqlgen/graphql.ID"},
- "Time": {Model: "github.com/99designs/gqlgen/graphql.Time"},
- "Map": {Model: "github.com/99designs/gqlgen/graphql.Map"},
- }
-
- if cfg.Models == nil {
- cfg.Models = TypeMap{}
- }
- for typeName, entry := range builtins {
- if !cfg.Models.Exists(typeName) {
- cfg.Models[typeName] = entry
- }
- }
-
- 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(sources...)
- if err != nil {
- return err
- }
- return nil
-}
-
-var invalidPackageNameChar = regexp.MustCompile(`[^\w]`)
-
-func sanitizePackageName(pkg string) string {
- return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_")
-}
-
-func abs(path string) string {
- absPath, err := filepath.Abs(path)
- if err != nil {
- panic(err)
- }
- return filepath.ToSlash(absPath)
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/complexity.go b/vendor/github.com/99designs/gqlgen/codegen/complexity.go
new file mode 100644
index 00000000..66d21a84
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/complexity.go
@@ -0,0 +1,11 @@
+package codegen
+
+func (o *Object) UniqueFields() map[string]*Field {
+ m := map[string]*Field{}
+
+ for _, f := range o.Fields {
+ m[f.GoFieldName] = f
+ }
+
+ return m
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config.go b/vendor/github.com/99designs/gqlgen/codegen/config.go
deleted file mode 100644
index f9df24fb..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/config.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package codegen
-
-import (
- "fmt"
- "go/build"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
- "strings"
-
- "github.com/99designs/gqlgen/internal/gopath"
- "github.com/pkg/errors"
- "github.com/vektah/gqlparser/ast"
- "gopkg.in/yaml.v2"
-)
-
-var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"}
-
-// DefaultConfig creates a copy of the default config
-func DefaultConfig() *Config {
- return &Config{
- SchemaFilename: SchemaFilenames{"schema.graphql"},
- SchemaStr: map[string]string{},
- Model: PackageConfig{Filename: "models_gen.go"},
- Exec: PackageConfig{Filename: "generated.go"},
- }
-}
-
-// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories
-// walking up the tree. The closest config file will be returned.
-func LoadConfigFromDefaultLocations() (*Config, error) {
- cfgFile, err := findCfg()
- if err != nil {
- return nil, err
- }
-
- err = os.Chdir(filepath.Dir(cfgFile))
- if err != nil {
- return nil, errors.Wrap(err, "unable to enter config dir")
- }
- return LoadConfig(cfgFile)
-}
-
-// LoadConfig reads the gqlgen.yml config file
-func LoadConfig(filename string) (*Config, error) {
- config := DefaultConfig()
-
- b, err := ioutil.ReadFile(filename)
- if err != nil {
- return nil, errors.Wrap(err, "unable to read config")
- }
-
- if err := yaml.UnmarshalStrict(b, config); err != nil {
- 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 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:"-"`
-
- schema *ast.Schema `yaml:"-"`
-}
-
-type PackageConfig struct {
- Filename string `yaml:"filename,omitempty"`
- Package string `yaml:"package,omitempty"`
- Type string `yaml:"type,omitempty"`
-}
-
-type TypeMapEntry struct {
- Model string `yaml:"model"`
- Fields map[string]TypeMapField `yaml:"fields,omitempty"`
-}
-
-type TypeMapField struct {
- 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 {
- if c.Filename == "" {
- return errors.New("Filename is required")
- }
- c.Filename = abs(c.Filename)
- // If Package is not set, first attempt to load the package at the output dir. If that fails
- // fallback to just the base dir name of the output filename.
- if c.Package == "" {
- cwd, _ := os.Getwd()
- pkg, _ := build.Default.Import(c.ImportPath(), cwd, 0)
- if pkg.Name != "" {
- c.Package = pkg.Name
- } else {
- c.Package = filepath.Base(c.Dir())
- }
- }
- c.Package = sanitizePackageName(c.Package)
- return nil
-}
-
-func (c *PackageConfig) ImportPath() string {
- return gopath.MustDir2Import(c.Dir())
-}
-
-func (c *PackageConfig) Dir() string {
- return filepath.Dir(c.Filename)
-}
-
-func (c *PackageConfig) Check() error {
- if strings.ContainsAny(c.Package, "./\\") {
- return fmt.Errorf("package should be the output package name only, do not include the output filename")
- }
- if c.Filename != "" && !strings.HasSuffix(c.Filename, ".go") {
- return fmt.Errorf("filename should be path to a go source file")
- }
- return nil
-}
-
-func (c *PackageConfig) IsDefined() bool {
- return c.Filename != ""
-}
-
-func (cfg *Config) Check() error {
- if err := cfg.Models.Check(); err != nil {
- return errors.Wrap(err, "config.models")
- }
- if err := cfg.Exec.Check(); err != nil {
- return errors.Wrap(err, "config.exec")
- }
- if err := cfg.Model.Check(); err != nil {
- return errors.Wrap(err, "config.model")
- }
- if err := cfg.Resolver.Check(); err != nil {
- return errors.Wrap(err, "config.resolver")
- }
- return nil
-}
-
-type TypeMap map[string]TypeMapEntry
-
-func (tm TypeMap) Exists(typeName string) bool {
- _, ok := tm[typeName]
- return ok
-}
-
-func (tm TypeMap) Check() error {
- for typeName, entry := range tm {
- if strings.LastIndex(entry.Model, ".") < strings.LastIndex(entry.Model, "/") {
- return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model)
- }
- }
- 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) {
- dir, err := os.Getwd()
- if err != nil {
- return "", errors.Wrap(err, "unable to get working dir to findCfg")
- }
-
- cfg := findCfgInDir(dir)
-
- for cfg == "" && dir != filepath.Dir(dir) {
- dir = filepath.Dir(dir)
- cfg = findCfgInDir(dir)
- }
-
- if cfg == "" {
- return "", os.ErrNotExist
- }
-
- return cfg, nil
-}
-
-func findCfgInDir(dir string) string {
- for _, cfgName := range cfgFilenames {
- path := filepath.Join(dir, cfgName)
- if _, err := os.Stat(path); err == nil {
- return path
- }
- }
- return ""
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go
new file mode 100644
index 00000000..f3956387
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go
@@ -0,0 +1,451 @@
+package config
+
+import (
+ "fmt"
+ "go/token"
+ "go/types"
+
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/99designs/gqlgen/internal/code"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
+ "golang.org/x/tools/go/packages"
+)
+
+// Binder connects graphql types to golang types using static analysis
+type Binder struct {
+ pkgs []*packages.Package
+ schema *ast.Schema
+ cfg *Config
+ References []*TypeReference
+}
+
+func (c *Config) NewBinder(s *ast.Schema) (*Binder, error) {
+ pkgs, err := packages.Load(&packages.Config{Mode: packages.LoadTypes | packages.LoadSyntax}, c.Models.ReferencedPackages()...)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, p := range pkgs {
+ for _, e := range p.Errors {
+ if e.Kind == packages.ListError {
+ return nil, p.Errors[0]
+ }
+ }
+ }
+
+ return &Binder{
+ pkgs: pkgs,
+ schema: s,
+ cfg: c,
+ }, nil
+}
+
+func (b *Binder) TypePosition(typ types.Type) token.Position {
+ named, isNamed := typ.(*types.Named)
+ if !isNamed {
+ return token.Position{
+ Filename: "unknown",
+ }
+ }
+
+ return b.ObjectPosition(named.Obj())
+}
+
+func (b *Binder) ObjectPosition(typ types.Object) token.Position {
+ if typ == nil {
+ return token.Position{
+ Filename: "unknown",
+ }
+ }
+ pkg := b.getPkg(typ.Pkg().Path())
+ return pkg.Fset.Position(typ.Pos())
+}
+
+func (b *Binder) FindType(pkgName string, typeName string) (types.Type, error) {
+ obj, err := b.FindObject(pkgName, typeName)
+ if err != nil {
+ return nil, err
+ }
+
+ if fun, isFunc := obj.(*types.Func); isFunc {
+ return fun.Type().(*types.Signature).Params().At(0).Type(), nil
+ }
+ return obj.Type(), nil
+}
+
+func (b *Binder) getPkg(find string) *packages.Package {
+ for _, p := range b.pkgs {
+ if code.NormalizeVendor(find) == code.NormalizeVendor(p.PkgPath) {
+ return p
+ }
+ }
+ return nil
+}
+
+var MapType = types.NewMap(types.Typ[types.String], types.NewInterfaceType(nil, nil).Complete())
+var InterfaceType = types.NewInterfaceType(nil, nil)
+
+func (b *Binder) DefaultUserObject(name string) (types.Type, error) {
+ models := b.cfg.Models[name].Model
+ if len(models) == 0 {
+ return nil, fmt.Errorf(name + " not found in typemap")
+ }
+
+ if models[0] == "map[string]interface{}" {
+ return MapType, nil
+ }
+
+ if models[0] == "interface{}" {
+ return InterfaceType, nil
+ }
+
+ pkgName, typeName := code.PkgAndType(models[0])
+ if pkgName == "" {
+ return nil, fmt.Errorf("missing package name for %s", name)
+ }
+
+ obj, err := b.FindObject(pkgName, typeName)
+ if err != nil {
+ return nil, err
+ }
+
+ return obj.Type(), nil
+}
+
+func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, error) {
+ if pkgName == "" {
+ return nil, fmt.Errorf("package cannot be nil")
+ }
+ fullName := typeName
+ if pkgName != "" {
+ fullName = pkgName + "." + typeName
+ }
+
+ pkg := b.getPkg(pkgName)
+ if pkg == nil {
+ return nil, errors.Errorf("required package was not loaded: %s", fullName)
+ }
+
+ // function based marshalers take precedence
+ for astNode, def := range pkg.TypesInfo.Defs {
+ // only look at defs in the top scope
+ if def == nil || def.Parent() == nil || def.Parent() != pkg.Types.Scope() {
+ continue
+ }
+
+ if astNode.Name == "Marshal"+typeName {
+ return def, nil
+ }
+ }
+
+ // then look for types directly
+ for astNode, def := range pkg.TypesInfo.Defs {
+ // only look at defs in the top scope
+ if def == nil || def.Parent() == nil || def.Parent() != pkg.Types.Scope() {
+ continue
+ }
+
+ if astNode.Name == typeName {
+ return def, nil
+ }
+ }
+
+ return nil, errors.Errorf("unable to find type %s\n", fullName)
+}
+
+func (b *Binder) PointerTo(ref *TypeReference) *TypeReference {
+ newRef := &TypeReference{
+ GO: types.NewPointer(ref.GO),
+ GQL: ref.GQL,
+ CastType: ref.CastType,
+ Definition: ref.Definition,
+ Unmarshaler: ref.Unmarshaler,
+ Marshaler: ref.Marshaler,
+ IsMarshaler: ref.IsMarshaler,
+ }
+
+ b.References = append(b.References, newRef)
+ return newRef
+}
+
+// TypeReference is used by args and field types. The Definition can refer to both input and output types.
+type TypeReference struct {
+ Definition *ast.Definition
+ GQL *ast.Type
+ GO types.Type
+ CastType types.Type // Before calling marshalling functions cast from/to this base type
+ Marshaler *types.Func // When using external marshalling functions this will point to the Marshal function
+ Unmarshaler *types.Func // When using external marshalling functions this will point to the Unmarshal function
+ IsMarshaler bool // Does the type implement graphql.Marshaler and graphql.Unmarshaler
+}
+
+func (ref *TypeReference) Elem() *TypeReference {
+ if p, isPtr := ref.GO.(*types.Pointer); isPtr {
+ return &TypeReference{
+ GO: p.Elem(),
+ GQL: ref.GQL,
+ CastType: ref.CastType,
+ Definition: ref.Definition,
+ Unmarshaler: ref.Unmarshaler,
+ Marshaler: ref.Marshaler,
+ IsMarshaler: ref.IsMarshaler,
+ }
+ }
+
+ if ref.IsSlice() {
+ return &TypeReference{
+ GO: ref.GO.(*types.Slice).Elem(),
+ GQL: ref.GQL.Elem,
+ CastType: ref.CastType,
+ Definition: ref.Definition,
+ Unmarshaler: ref.Unmarshaler,
+ Marshaler: ref.Marshaler,
+ IsMarshaler: ref.IsMarshaler,
+ }
+ }
+ return nil
+}
+
+func (t *TypeReference) IsPtr() bool {
+ _, isPtr := t.GO.(*types.Pointer)
+ return isPtr
+}
+
+func (t *TypeReference) IsNilable() bool {
+ _, isPtr := t.GO.(*types.Pointer)
+ _, isMap := t.GO.(*types.Map)
+ _, isInterface := t.GO.(*types.Interface)
+ return isPtr || isMap || isInterface
+}
+
+func (t *TypeReference) IsSlice() bool {
+ _, isSlice := t.GO.(*types.Slice)
+ return t.GQL.Elem != nil && isSlice
+}
+
+func (t *TypeReference) IsNamed() bool {
+ _, isSlice := t.GO.(*types.Named)
+ return isSlice
+}
+
+func (t *TypeReference) IsStruct() bool {
+ _, isStruct := t.GO.Underlying().(*types.Struct)
+ return isStruct
+}
+
+func (t *TypeReference) IsScalar() bool {
+ return t.Definition.Kind == ast.Scalar
+}
+
+func (t *TypeReference) HasIsZero() bool {
+ it := t.GO
+ if ptr, isPtr := it.(*types.Pointer); isPtr {
+ it = ptr.Elem()
+ }
+ namedType, ok := it.(*types.Named)
+ if !ok {
+ return false
+ }
+
+ for i := 0; i < namedType.NumMethods(); i++ {
+ switch namedType.Method(i).Name() {
+ case "IsZero":
+ return true
+ }
+ }
+ return false
+}
+
+func (t *TypeReference) UniquenessKey() string {
+ var nullability = "O"
+ if t.GQL.NonNull {
+ nullability = "N"
+ }
+
+ return nullability + t.Definition.Name + "2" + templates.TypeIdentifier(t.GO)
+}
+
+func (t *TypeReference) MarshalFunc() string {
+ if t.Definition == nil {
+ panic(errors.New("Definition missing for " + t.GQL.Name()))
+ }
+
+ if t.Definition.Kind == ast.InputObject {
+ return ""
+ }
+
+ return "marshal" + t.UniquenessKey()
+}
+
+func (t *TypeReference) UnmarshalFunc() string {
+ if t.Definition == nil {
+ panic(errors.New("Definition missing for " + t.GQL.Name()))
+ }
+
+ if !t.Definition.IsInputType() {
+ return ""
+ }
+
+ return "unmarshal" + t.UniquenessKey()
+}
+
+func (b *Binder) PushRef(ret *TypeReference) {
+ b.References = append(b.References, ret)
+}
+
+func isMap(t types.Type) bool {
+ if t == nil {
+ return true
+ }
+ _, ok := t.(*types.Map)
+ return ok
+}
+
+func isIntf(t types.Type) bool {
+ if t == nil {
+ return true
+ }
+ _, ok := t.(*types.Interface)
+ return ok
+}
+
+func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret *TypeReference, err error) {
+ var pkgName, typeName string
+ def := b.schema.Types[schemaType.Name()]
+ defer func() {
+ if err == nil && ret != nil {
+ b.PushRef(ret)
+ }
+ }()
+
+ if len(b.cfg.Models[schemaType.Name()].Model) == 0 {
+ return nil, fmt.Errorf("%s was not found", schemaType.Name())
+ }
+
+ for _, model := range b.cfg.Models[schemaType.Name()].Model {
+ if model == "map[string]interface{}" {
+ if !isMap(bindTarget) {
+ continue
+ }
+ return &TypeReference{
+ Definition: def,
+ GQL: schemaType,
+ GO: MapType,
+ }, nil
+ }
+
+ if model == "interface{}" {
+ if !isIntf(bindTarget) {
+ continue
+ }
+ return &TypeReference{
+ Definition: def,
+ GQL: schemaType,
+ GO: InterfaceType,
+ }, nil
+ }
+
+ pkgName, typeName = code.PkgAndType(model)
+ if pkgName == "" {
+ return nil, fmt.Errorf("missing package name for %s", schemaType.Name())
+ }
+
+ ref := &TypeReference{
+ Definition: def,
+ GQL: schemaType,
+ }
+
+ obj, err := b.FindObject(pkgName, typeName)
+ if err != nil {
+ return nil, err
+ }
+
+ if fun, isFunc := obj.(*types.Func); isFunc {
+ ref.GO = fun.Type().(*types.Signature).Params().At(0).Type()
+ ref.Marshaler = fun
+ ref.Unmarshaler = types.NewFunc(0, fun.Pkg(), "Unmarshal"+typeName, nil)
+ } else if hasMethod(obj.Type(), "MarshalGQL") && hasMethod(obj.Type(), "UnmarshalGQL") {
+ ref.GO = obj.Type()
+ ref.IsMarshaler = true
+ } else if underlying := basicUnderlying(obj.Type()); underlying != nil && underlying.Kind() == types.String {
+ // Special case for named types wrapping strings. Used by default enum implementations.
+
+ ref.GO = obj.Type()
+ ref.CastType = underlying
+
+ underlyingRef, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ ref.Marshaler = underlyingRef.Marshaler
+ ref.Unmarshaler = underlyingRef.Unmarshaler
+ } else {
+ ref.GO = obj.Type()
+ }
+
+ ref.GO = b.CopyModifiersFromAst(schemaType, ref.GO)
+
+ if bindTarget != nil {
+ if err = code.CompatibleTypes(ref.GO, bindTarget); err != nil {
+ continue
+ }
+ ref.GO = bindTarget
+ }
+
+ return ref, nil
+ }
+
+ return nil, fmt.Errorf("%s has type compatible with %s", schemaType.Name(), bindTarget.String())
+}
+
+func (b *Binder) CopyModifiersFromAst(t *ast.Type, base types.Type) types.Type {
+ if t.Elem != nil {
+ return types.NewSlice(b.CopyModifiersFromAst(t.Elem, base))
+ }
+
+ var isInterface bool
+ if named, ok := base.(*types.Named); ok {
+ _, isInterface = named.Underlying().(*types.Interface)
+ }
+
+ if !isInterface && !t.NonNull {
+ return types.NewPointer(base)
+ }
+
+ return base
+}
+
+func hasMethod(it types.Type, name string) bool {
+ if ptr, isPtr := it.(*types.Pointer); isPtr {
+ it = ptr.Elem()
+ }
+ namedType, ok := it.(*types.Named)
+ if !ok {
+ return false
+ }
+
+ for i := 0; i < namedType.NumMethods(); i++ {
+ if namedType.Method(i).Name() == name {
+ return true
+ }
+ }
+ return false
+}
+
+func basicUnderlying(it types.Type) *types.Basic {
+ if ptr, isPtr := it.(*types.Pointer); isPtr {
+ it = ptr.Elem()
+ }
+ namedType, ok := it.(*types.Named)
+ if !ok {
+ return nil
+ }
+
+ if basic, ok := namedType.Underlying().(*types.Basic); ok {
+ return basic
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/config.go b/vendor/github.com/99designs/gqlgen/codegen/config/config.go
new file mode 100644
index 00000000..0c72420e
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/config/config.go
@@ -0,0 +1,408 @@
+package config
+
+import (
+ "fmt"
+ "go/types"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "github.com/99designs/gqlgen/internal/code"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser"
+ "github.com/vektah/gqlparser/ast"
+ yaml "gopkg.in/yaml.v2"
+)
+
+type Config struct {
+ SchemaFilename StringList `yaml:"schema,omitempty"`
+ Exec PackageConfig `yaml:"exec"`
+ Model PackageConfig `yaml:"model"`
+ Resolver PackageConfig `yaml:"resolver,omitempty"`
+ Models TypeMap `yaml:"models,omitempty"`
+ StructTag string `yaml:"struct_tag,omitempty"`
+}
+
+var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"}
+
+// DefaultConfig creates a copy of the default config
+func DefaultConfig() *Config {
+ return &Config{
+ SchemaFilename: StringList{"schema.graphql"},
+ Model: PackageConfig{Filename: "models_gen.go"},
+ Exec: PackageConfig{Filename: "generated.go"},
+ }
+}
+
+// LoadConfigFromDefaultLocations looks for a config file in the current directory, and all parent directories
+// walking up the tree. The closest config file will be returned.
+func LoadConfigFromDefaultLocations() (*Config, error) {
+ cfgFile, err := findCfg()
+ if err != nil {
+ return nil, err
+ }
+
+ err = os.Chdir(filepath.Dir(cfgFile))
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to enter config dir")
+ }
+ return LoadConfig(cfgFile)
+}
+
+// LoadConfig reads the gqlgen.yml config file
+func LoadConfig(filename string) (*Config, error) {
+ config := DefaultConfig()
+
+ b, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to read config")
+ }
+
+ if err := yaml.UnmarshalStrict(b, config); err != nil {
+ return nil, errors.Wrap(err, "unable to parse config")
+ }
+
+ preGlobbing := config.SchemaFilename
+ config.SchemaFilename = StringList{}
+ 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)
+ }
+ }
+
+ return config, nil
+}
+
+type PackageConfig struct {
+ Filename string `yaml:"filename,omitempty"`
+ Package string `yaml:"package,omitempty"`
+ Type string `yaml:"type,omitempty"`
+}
+
+type TypeMapEntry struct {
+ Model StringList `yaml:"model"`
+ Fields map[string]TypeMapField `yaml:"fields,omitempty"`
+}
+
+type TypeMapField struct {
+ Resolver bool `yaml:"resolver"`
+ FieldName string `yaml:"fieldName"`
+}
+
+type StringList []string
+
+func (a *StringList) 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 StringList) Has(file string) bool {
+ for _, existing := range a {
+ if existing == file {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *PackageConfig) normalize() error {
+ if c.Filename == "" {
+ return errors.New("Filename is required")
+ }
+ c.Filename = abs(c.Filename)
+ // If Package is not set, first attempt to load the package at the output dir. If that fails
+ // fallback to just the base dir name of the output filename.
+ if c.Package == "" {
+ c.Package = code.NameForPackage(c.ImportPath())
+ }
+
+ return nil
+}
+
+func (c *PackageConfig) ImportPath() string {
+ return code.ImportPathForDir(c.Dir())
+}
+
+func (c *PackageConfig) Dir() string {
+ return filepath.Dir(c.Filename)
+}
+
+func (c *PackageConfig) Check() error {
+ if strings.ContainsAny(c.Package, "./\\") {
+ return fmt.Errorf("package should be the output package name only, do not include the output filename")
+ }
+ if c.Filename != "" && !strings.HasSuffix(c.Filename, ".go") {
+ return fmt.Errorf("filename should be path to a go source file")
+ }
+
+ return c.normalize()
+}
+
+func (c *PackageConfig) Pkg() *types.Package {
+ return types.NewPackage(c.ImportPath(), c.Dir())
+}
+
+func (c *PackageConfig) IsDefined() bool {
+ return c.Filename != ""
+}
+
+func (c *Config) Check() error {
+ if err := c.Models.Check(); err != nil {
+ return errors.Wrap(err, "config.models")
+ }
+ if err := c.Exec.Check(); err != nil {
+ return errors.Wrap(err, "config.exec")
+ }
+ if err := c.Model.Check(); err != nil {
+ return errors.Wrap(err, "config.model")
+ }
+ if c.Resolver.IsDefined() {
+ if err := c.Resolver.Check(); err != nil {
+ return errors.Wrap(err, "config.resolver")
+ }
+ }
+
+ // check packages names against conflict, if present in the same dir
+ // and check filenames for uniqueness
+ packageConfigList := []PackageConfig{
+ c.Model,
+ c.Exec,
+ c.Resolver,
+ }
+ filesMap := make(map[string]bool)
+ pkgConfigsByDir := make(map[string]PackageConfig)
+ for _, current := range packageConfigList {
+ _, fileFound := filesMap[current.Filename]
+ if fileFound {
+ return fmt.Errorf("filename %s defined more than once", current.Filename)
+ }
+ filesMap[current.Filename] = true
+ previous, inSameDir := pkgConfigsByDir[current.Dir()]
+ if inSameDir && current.Package != previous.Package {
+ return fmt.Errorf("filenames %s and %s are in the same directory but have different package definitions", stripPath(current.Filename), stripPath(previous.Filename))
+ }
+ pkgConfigsByDir[current.Dir()] = current
+ }
+
+ return c.normalize()
+}
+
+func stripPath(path string) string {
+ return filepath.Base(path)
+}
+
+type TypeMap map[string]TypeMapEntry
+
+func (tm TypeMap) Exists(typeName string) bool {
+ _, ok := tm[typeName]
+ return ok
+}
+
+func (tm TypeMap) UserDefined(typeName string) bool {
+ m, ok := tm[typeName]
+ return ok && len(m.Model) > 0
+}
+
+func (tm TypeMap) Check() error {
+ for typeName, entry := range tm {
+ for _, model := range entry.Model {
+ if strings.LastIndex(model, ".") < strings.LastIndex(model, "/") {
+ return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model)
+ }
+ }
+ }
+ return nil
+}
+
+func (tm TypeMap) ReferencedPackages() []string {
+ var pkgs []string
+
+ for _, typ := range tm {
+ for _, model := range typ.Model {
+ if model == "map[string]interface{}" || model == "interface{}" {
+ continue
+ }
+ pkg, _ := code.PkgAndType(model)
+ if pkg == "" || inStrSlice(pkgs, pkg) {
+ continue
+ }
+ pkgs = append(pkgs, code.QualifyPackagePath(pkg))
+ }
+ }
+
+ sort.Slice(pkgs, func(i, j int) bool {
+ return pkgs[i] > pkgs[j]
+ })
+ return pkgs
+}
+
+func (tm TypeMap) Add(Name string, goType string) {
+ modelCfg := tm[Name]
+ modelCfg.Model = append(modelCfg.Model, goType)
+ tm[Name] = modelCfg
+}
+
+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) {
+ dir, err := os.Getwd()
+ if err != nil {
+ return "", errors.Wrap(err, "unable to get working dir to findCfg")
+ }
+
+ cfg := findCfgInDir(dir)
+
+ for cfg == "" && dir != filepath.Dir(dir) {
+ dir = filepath.Dir(dir)
+ cfg = findCfgInDir(dir)
+ }
+
+ if cfg == "" {
+ return "", os.ErrNotExist
+ }
+
+ return cfg, nil
+}
+
+func findCfgInDir(dir string) string {
+ for _, cfgName := range cfgFilenames {
+ path := filepath.Join(dir, cfgName)
+ if _, err := os.Stat(path); err == nil {
+ return path
+ }
+ }
+ return ""
+}
+
+func (c *Config) normalize() error {
+ if err := c.Model.normalize(); err != nil {
+ return errors.Wrap(err, "model")
+ }
+
+ if err := c.Exec.normalize(); err != nil {
+ return errors.Wrap(err, "exec")
+ }
+
+ if c.Resolver.IsDefined() {
+ if err := c.Resolver.normalize(); err != nil {
+ return errors.Wrap(err, "resolver")
+ }
+ }
+
+ if c.Models == nil {
+ c.Models = TypeMap{}
+ }
+
+ return nil
+}
+
+func (c *Config) InjectBuiltins(s *ast.Schema) {
+ builtins := TypeMap{
+ "__Directive": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Directive"}},
+ "__DirectiveLocation": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
+ "__Type": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Type"}},
+ "__TypeKind": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
+ "__Field": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Field"}},
+ "__EnumValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.EnumValue"}},
+ "__InputValue": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.InputValue"}},
+ "__Schema": {Model: StringList{"github.com/99designs/gqlgen/graphql/introspection.Schema"}},
+ "Float": {Model: StringList{"github.com/99designs/gqlgen/graphql.Float"}},
+ "String": {Model: StringList{"github.com/99designs/gqlgen/graphql.String"}},
+ "Boolean": {Model: StringList{"github.com/99designs/gqlgen/graphql.Boolean"}},
+ "Int": {Model: StringList{
+ "github.com/99designs/gqlgen/graphql.Int",
+ "github.com/99designs/gqlgen/graphql.Int32",
+ "github.com/99designs/gqlgen/graphql.Int64",
+ }},
+ "ID": {
+ Model: StringList{
+ "github.com/99designs/gqlgen/graphql.ID",
+ "github.com/99designs/gqlgen/graphql.IntID",
+ },
+ },
+ }
+
+ for typeName, entry := range builtins {
+ if !c.Models.Exists(typeName) {
+ c.Models[typeName] = entry
+ }
+ }
+
+ // These are additional types that are injected if defined in the schema as scalars.
+ extraBuiltins := TypeMap{
+ "Time": {Model: StringList{"github.com/99designs/gqlgen/graphql.Time"}},
+ "Map": {Model: StringList{"github.com/99designs/gqlgen/graphql.Map"}},
+ }
+
+ for typeName, entry := range extraBuiltins {
+ if t, ok := s.Types[typeName]; !c.Models.Exists(typeName) && ok && t.Kind == ast.Scalar {
+ c.Models[typeName] = entry
+ }
+ }
+}
+
+func (c *Config) LoadSchema() (*ast.Schema, map[string]string, error) {
+ schemaStrings := map[string]string{}
+
+ var sources []*ast.Source
+
+ for _, filename := range c.SchemaFilename {
+ filename = filepath.ToSlash(filename)
+ var err error
+ var schemaRaw []byte
+ schemaRaw, err = ioutil.ReadFile(filename)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "unable to open schema: "+err.Error())
+ os.Exit(1)
+ }
+ schemaStrings[filename] = string(schemaRaw)
+ sources = append(sources, &ast.Source{Name: filename, Input: schemaStrings[filename]})
+ }
+
+ schema, err := gqlparser.LoadSchema(sources...)
+ if err != nil {
+ return nil, nil, err
+ }
+ return schema, schemaStrings, nil
+}
+
+func abs(path string) string {
+ absPath, err := filepath.Abs(path)
+ if err != nil {
+ panic(err)
+ }
+ return filepath.ToSlash(absPath)
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/data.go b/vendor/github.com/99designs/gqlgen/codegen/data.go
new file mode 100644
index 00000000..f2ea70b4
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/data.go
@@ -0,0 +1,168 @@
+package codegen
+
+import (
+ "fmt"
+ "sort"
+
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
+)
+
+// Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement
+// resolvers or directives automatically (eg grpc, validation)
+type Data struct {
+ Config *config.Config
+ Schema *ast.Schema
+ SchemaStr map[string]string
+ Directives map[string]*Directive
+ Objects Objects
+ Inputs Objects
+ Interfaces map[string]*Interface
+ ReferencedTypes map[string]*config.TypeReference
+ ComplexityRoots map[string]*Object
+
+ QueryRoot *Object
+ MutationRoot *Object
+ SubscriptionRoot *Object
+}
+
+type builder struct {
+ Config *config.Config
+ Schema *ast.Schema
+ SchemaStr map[string]string
+ Binder *config.Binder
+ Directives map[string]*Directive
+}
+
+func BuildData(cfg *config.Config) (*Data, error) {
+ b := builder{
+ Config: cfg,
+ }
+
+ var err error
+ b.Schema, b.SchemaStr, err = cfg.LoadSchema()
+ if err != nil {
+ return nil, err
+ }
+
+ err = cfg.Check()
+ if err != nil {
+ return nil, err
+ }
+
+ cfg.InjectBuiltins(b.Schema)
+
+ b.Binder, err = b.Config.NewBinder(b.Schema)
+ if err != nil {
+ return nil, err
+ }
+
+ b.Directives, err = b.buildDirectives()
+ if err != nil {
+ return nil, err
+ }
+
+ dataDirectives := make(map[string]*Directive)
+ for name, d := range b.Directives {
+ if !d.Builtin {
+ dataDirectives[name] = d
+ }
+ }
+
+ s := Data{
+ Config: cfg,
+ Directives: dataDirectives,
+ Schema: b.Schema,
+ SchemaStr: b.SchemaStr,
+ Interfaces: map[string]*Interface{},
+ }
+
+ for _, schemaType := range b.Schema.Types {
+ switch schemaType.Kind {
+ case ast.Object:
+ obj, err := b.buildObject(schemaType)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to build object definition")
+ }
+
+ s.Objects = append(s.Objects, obj)
+ case ast.InputObject:
+ input, err := b.buildObject(schemaType)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to build input definition")
+ }
+
+ s.Inputs = append(s.Inputs, input)
+
+ case ast.Union, ast.Interface:
+ s.Interfaces[schemaType.Name] = b.buildInterface(schemaType)
+ }
+ }
+
+ if s.Schema.Query != nil {
+ s.QueryRoot = s.Objects.ByName(s.Schema.Query.Name)
+ } else {
+ return nil, fmt.Errorf("query entry point missing")
+ }
+
+ if s.Schema.Mutation != nil {
+ s.MutationRoot = s.Objects.ByName(s.Schema.Mutation.Name)
+ }
+
+ if s.Schema.Subscription != nil {
+ s.SubscriptionRoot = s.Objects.ByName(s.Schema.Subscription.Name)
+ }
+
+ if err := b.injectIntrospectionRoots(&s); err != nil {
+ return nil, err
+ }
+
+ s.ReferencedTypes, err = b.buildTypes()
+ if err != nil {
+ return nil, err
+ }
+
+ sort.Slice(s.Objects, func(i, j int) bool {
+ return s.Objects[i].Definition.Name < s.Objects[j].Definition.Name
+ })
+
+ sort.Slice(s.Inputs, func(i, j int) bool {
+ return s.Inputs[i].Definition.Name < s.Inputs[j].Definition.Name
+ })
+
+ return &s, nil
+}
+
+func (b *builder) injectIntrospectionRoots(s *Data) error {
+ obj := s.Objects.ByName(b.Schema.Query.Name)
+ if obj == nil {
+ return fmt.Errorf("root query type must be defined")
+ }
+
+ __type, err := b.buildField(obj, &ast.FieldDefinition{
+ Name: "__type",
+ Type: ast.NamedType("__Type", nil),
+ Arguments: []*ast.ArgumentDefinition{
+ {
+ Name: "name",
+ Type: ast.NonNullNamedType("String", nil),
+ },
+ },
+ })
+ if err != nil {
+ return err
+ }
+
+ __schema, err := b.buildField(obj, &ast.FieldDefinition{
+ Name: "__schema",
+ Type: ast.NamedType("__Schema", nil),
+ })
+ if err != nil {
+ return err
+ }
+
+ obj.Fields = append(obj.Fields, __type, __schema)
+
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive.go b/vendor/github.com/99designs/gqlgen/codegen/directive.go
index 8017da06..5a27e8ac 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/directive.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/directive.go
@@ -4,11 +4,101 @@ import (
"fmt"
"strconv"
"strings"
+
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
)
type Directive struct {
- Name string
- Args []FieldArgument
+ Name string
+ Args []*FieldArgument
+ Builtin bool
+}
+
+func (b *builder) buildDirectives() (map[string]*Directive, error) {
+ directives := make(map[string]*Directive, len(b.Schema.Directives))
+
+ for name, dir := range b.Schema.Directives {
+ if _, ok := directives[name]; ok {
+ return nil, errors.Errorf("directive with name %s already exists", name)
+ }
+
+ var builtin bool
+ if name == "skip" || name == "include" || name == "deprecated" {
+ builtin = true
+ }
+
+ var args []*FieldArgument
+ for _, arg := range dir.Arguments {
+ tr, err := b.Binder.TypeReference(arg.Type, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ newArg := &FieldArgument{
+ ArgumentDefinition: arg,
+ TypeReference: tr,
+ VarName: templates.ToGoPrivate(arg.Name),
+ }
+
+ if arg.DefaultValue != nil {
+ var err error
+ newArg.Default, err = arg.DefaultValue.Value(nil)
+ if err != nil {
+ return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error())
+ }
+ }
+ args = append(args, newArg)
+ }
+
+ directives[name] = &Directive{
+ Name: name,
+ Args: args,
+ Builtin: builtin,
+ }
+ }
+
+ return directives, nil
+}
+
+func (b *builder) getDirectives(list ast.DirectiveList) ([]*Directive, error) {
+ dirs := make([]*Directive, len(list))
+ for i, d := range list {
+ argValues := make(map[string]interface{}, len(d.Arguments))
+ for _, da := range d.Arguments {
+ val, err := da.Value.Value(nil)
+ if err != nil {
+ return nil, err
+ }
+ argValues[da.Name] = val
+ }
+ def, ok := b.Directives[d.Name]
+ if !ok {
+ return nil, fmt.Errorf("directive %s not found", d.Name)
+ }
+
+ var args []*FieldArgument
+ for _, a := range def.Args {
+ value := a.Default
+ if argValue, ok := argValues[a.Name]; ok {
+ value = argValue
+ }
+ args = append(args, &FieldArgument{
+ ArgumentDefinition: a.ArgumentDefinition,
+ Value: value,
+ VarName: a.VarName,
+ TypeReference: a.TypeReference,
+ })
+ }
+ dirs[i] = &Directive{
+ Name: d.Name,
+ Args: args,
+ }
+
+ }
+
+ return dirs, nil
}
func (d *Directive) ArgsFunc() string {
@@ -23,7 +113,28 @@ func (d *Directive) CallArgs() string {
args := []string{"ctx", "obj", "n"}
for _, arg := range d.Args {
- args = append(args, "args["+strconv.Quote(arg.GQLName)+"].("+arg.Signature()+")")
+ args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
+ }
+
+ return strings.Join(args, ", ")
+}
+
+func (d *Directive) ResolveArgs(obj string, next string) string {
+ args := []string{"ctx", obj, next}
+
+ for _, arg := range d.Args {
+ dArg := "&" + arg.VarName
+ if !arg.TypeReference.IsPtr() {
+ if arg.Value != nil {
+ dArg = templates.Dump(arg.Value)
+ } else {
+ dArg = templates.Dump(arg.Default)
+ }
+ } else if arg.Value == nil && arg.Default == nil {
+ dArg = "nil"
+ }
+
+ args = append(args, dArg)
}
return strings.Join(args, ", ")
@@ -33,7 +144,7 @@ func (d *Directive) Declaration() string {
res := ucFirst(d.Name) + " func(ctx context.Context, obj interface{}, next graphql.Resolver"
for _, arg := range d.Args {
- res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
+ res += fmt.Sprintf(", %s %s", arg.Name, templates.CurrentImports.LookupType(arg.TypeReference.GO))
}
res += ") (res interface{}, err error)"
diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go b/vendor/github.com/99designs/gqlgen/codegen/directive_build.go
deleted file mode 100644
index af77dc44..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package codegen
-
-import (
- "sort"
-
- "github.com/pkg/errors"
-)
-
-func (cfg *Config) buildDirectives(types NamedTypes) ([]*Directive, error) {
- var directives []*Directive
-
- for name, dir := range cfg.schema.Directives {
- if name == "skip" || name == "include" || name == "deprecated" {
- continue
- }
-
- var args []FieldArgument
- for _, arg := range dir.Arguments {
- newArg := FieldArgument{
- GQLName: arg.Name,
- Type: types.getType(arg.Type),
- GoVarName: sanitizeArgName(arg.Name),
- }
-
- if !newArg.Type.IsInput && !newArg.Type.IsScalar {
- return nil, errors.Errorf("%s cannot be used as argument of directive %s(%s) only input and scalar types are allowed", arg.Type, dir.Name, arg.Name)
- }
-
- if arg.DefaultValue != nil {
- var err error
- newArg.Default, err = arg.DefaultValue.Value(nil)
- if err != nil {
- return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error())
- }
- }
- args = append(args, newArg)
- }
-
- directives = append(directives, &Directive{
- Name: name,
- Args: args,
- })
- }
-
- sort.Slice(directives, func(i, j int) bool { return directives[i].Name < directives[j].Name })
-
- return directives, nil
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/enum.go b/vendor/github.com/99designs/gqlgen/codegen/enum.go
deleted file mode 100644
index 7804971c..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/enum.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package codegen
-
-type Enum struct {
- *NamedType
- Description string
- Values []EnumValue
-}
-
-type EnumValue struct {
- Name string
- Description string
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/enum_build.go b/vendor/github.com/99designs/gqlgen/codegen/enum_build.go
deleted file mode 100644
index 457d923f..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/enum_build.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package codegen
-
-import (
- "sort"
- "strings"
-
- "github.com/99designs/gqlgen/codegen/templates"
- "github.com/vektah/gqlparser/ast"
-)
-
-func (cfg *Config) buildEnums(types NamedTypes) []Enum {
- var enums []Enum
-
- for _, typ := range cfg.schema.Types {
- namedType := types[typ.Name]
- if typ.Kind != ast.Enum || strings.HasPrefix(typ.Name, "__") || namedType.IsUserDefined {
- continue
- }
-
- var values []EnumValue
- for _, v := range typ.EnumValues {
- values = append(values, EnumValue{v.Name, v.Description})
- }
-
- enum := Enum{
- NamedType: namedType,
- Values: values,
- Description: typ.Description,
- }
- enum.GoType = templates.ToCamel(enum.GQLType)
- enums = append(enums, enum)
- }
-
- sort.Slice(enums, func(i, j int) bool {
- return enums[i].GQLType < enums[j].GQLType
- })
-
- return enums
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.go b/vendor/github.com/99designs/gqlgen/codegen/field.go
new file mode 100644
index 00000000..f5f7b221
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/field.go
@@ -0,0 +1,394 @@
+package codegen
+
+import (
+ "fmt"
+ "go/types"
+ "log"
+ "reflect"
+ "strconv"
+ "strings"
+
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
+)
+
+type Field struct {
+ *ast.FieldDefinition
+
+ TypeReference *config.TypeReference
+ 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
+ IsResolver bool // Does this field need a resolver
+ Args []*FieldArgument // A list of arguments to be passed to this field
+ MethodHasContext bool // If this is bound to a go method, does the method also take a context
+ NoErr bool // If this is bound to a go method, does that method have an error as the second argument
+ Object *Object // A link back to the parent object
+ Default interface{} // The default value
+ Directives []*Directive
+}
+
+func (b *builder) buildField(obj *Object, field *ast.FieldDefinition) (*Field, error) {
+ dirs, err := b.getDirectives(field.Directives)
+ if err != nil {
+ return nil, err
+ }
+
+ f := Field{
+ FieldDefinition: field,
+ Object: obj,
+ Directives: dirs,
+ GoFieldName: templates.ToGo(field.Name),
+ GoFieldType: GoFieldVariable,
+ GoReceiverName: "obj",
+ }
+
+ if field.DefaultValue != nil {
+ var err error
+ f.Default, err = field.DefaultValue.Value(nil)
+ if err != nil {
+ return nil, errors.Errorf("default value %s is not valid: %s", field.Name, err.Error())
+ }
+ }
+
+ for _, arg := range field.Arguments {
+ newArg, err := b.buildArg(obj, arg)
+ if err != nil {
+ return nil, err
+ }
+ f.Args = append(f.Args, newArg)
+ }
+
+ if err = b.bindField(obj, &f); err != nil {
+ f.IsResolver = true
+ log.Println(err.Error())
+ }
+
+ if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() {
+ f.TypeReference = b.Binder.PointerTo(f.TypeReference)
+ }
+
+ return &f, nil
+}
+
+func (b *builder) bindField(obj *Object, f *Field) error {
+ defer func() {
+ if f.TypeReference == nil {
+ tr, err := b.Binder.TypeReference(f.Type, nil)
+ if err != nil {
+ panic(err)
+ }
+ f.TypeReference = tr
+ }
+ }()
+
+ switch {
+ case f.Name == "__schema":
+ f.GoFieldType = GoFieldMethod
+ f.GoReceiverName = "ec"
+ f.GoFieldName = "introspectSchema"
+ return nil
+ case f.Name == "__type":
+ f.GoFieldType = GoFieldMethod
+ f.GoReceiverName = "ec"
+ f.GoFieldName = "introspectType"
+ return nil
+ case obj.Root:
+ f.IsResolver = true
+ return nil
+ case b.Config.Models[obj.Name].Fields[f.Name].Resolver:
+ f.IsResolver = true
+ return nil
+ case obj.Type == config.MapType:
+ f.GoFieldType = GoFieldMap
+ return nil
+ case b.Config.Models[obj.Name].Fields[f.Name].FieldName != "":
+ f.GoFieldName = b.Config.Models[obj.Name].Fields[f.Name].FieldName
+ }
+
+ target, err := b.findBindTarget(obj.Type.(*types.Named), f.GoFieldName)
+ if err != nil {
+ return err
+ }
+
+ pos := b.Binder.ObjectPosition(target)
+
+ switch target := target.(type) {
+ case nil:
+ objPos := b.Binder.TypePosition(obj.Type)
+ return fmt.Errorf(
+ "%s:%d adding resolver method for %s.%s, nothing matched",
+ objPos.Filename,
+ objPos.Line,
+ obj.Name,
+ f.Name,
+ )
+
+ case *types.Func:
+ sig := target.Type().(*types.Signature)
+ if sig.Results().Len() == 1 {
+ f.NoErr = true
+ } else if sig.Results().Len() != 2 {
+ return fmt.Errorf("method has wrong number of args")
+ }
+ 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" {
+ f.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...)
+ }
+
+ if err = b.bindArgs(f, params); err != nil {
+ return errors.Wrapf(err, "%s:%d", pos.Filename, pos.Line)
+ }
+
+ result := sig.Results().At(0)
+ tr, err := b.Binder.TypeReference(f.Type, result.Type())
+ if err != nil {
+ return err
+ }
+
+ // success, args and return type match. Bind to method
+ f.GoFieldType = GoFieldMethod
+ f.GoReceiverName = "obj"
+ f.GoFieldName = target.Name()
+ f.TypeReference = tr
+
+ return nil
+
+ case *types.Var:
+ tr, err := b.Binder.TypeReference(f.Type, target.Type())
+ if err != nil {
+ return err
+ }
+
+ // success, bind to var
+ f.GoFieldType = GoFieldVariable
+ f.GoReceiverName = "obj"
+ f.GoFieldName = target.Name()
+ f.TypeReference = tr
+
+ return nil
+ default:
+ panic(fmt.Errorf("unknown bind target %T for %s", target, f.Name))
+ }
+}
+
+// findField attempts to match the name to a struct field with the following
+// priorites:
+// 1. Any method with a matching name
+// 2. Any Fields with a struct tag (see config.StructTag)
+// 3. Any fields with a matching name
+// 4. Same logic again for embedded fields
+func (b *builder) findBindTarget(named *types.Named, name string) (types.Object, error) {
+ for i := 0; i < named.NumMethods(); i++ {
+ method := named.Method(i)
+ if !method.Exported() {
+ continue
+ }
+
+ if !strings.EqualFold(method.Name(), name) {
+ continue
+ }
+
+ return method, nil
+ }
+
+ strukt, ok := named.Underlying().(*types.Struct)
+ if !ok {
+ return nil, fmt.Errorf("not a struct")
+ }
+ return b.findBindStructTarget(strukt, name)
+}
+
+func (b *builder) findBindStructTarget(strukt *types.Struct, name string) (types.Object, error) {
+ // struct tags have the highest priority
+ if b.Config.StructTag != "" {
+ var foundField *types.Var
+ for i := 0; i < strukt.NumFields(); i++ {
+ field := strukt.Field(i)
+ if !field.Exported() {
+ continue
+ }
+ tags := reflect.StructTag(strukt.Tag(i))
+ if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) {
+ if foundField != nil {
+ return nil, errors.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val)
+ }
+
+ foundField = field
+ }
+ }
+ if foundField != nil {
+ return foundField, nil
+ }
+ }
+
+ // Then matching field names
+ for i := 0; i < strukt.NumFields(); i++ {
+ field := strukt.Field(i)
+ if !field.Exported() {
+ continue
+ }
+ if equalFieldName(field.Name(), name) { // aqui!
+ return field, nil
+ }
+ }
+
+ // Then look in embedded structs
+ for i := 0; i < strukt.NumFields(); i++ {
+ field := strukt.Field(i)
+ if !field.Exported() {
+ continue
+ }
+
+ if !field.Anonymous() {
+ continue
+ }
+
+ fieldType := field.Type()
+ if ptr, ok := fieldType.(*types.Pointer); ok {
+ fieldType = ptr.Elem()
+ }
+
+ switch fieldType := fieldType.(type) {
+ case *types.Named:
+ f, err := b.findBindTarget(fieldType, name)
+ if err != nil {
+ return nil, err
+ }
+ if f != nil {
+ return f, nil
+ }
+ case *types.Struct:
+ f, err := b.findBindStructTarget(fieldType, name)
+ if err != nil {
+ return nil, err
+ }
+ if f != nil {
+ return f, nil
+ }
+ default:
+ panic(fmt.Errorf("unknown embedded field type %T", field.Type()))
+ }
+ }
+
+ return nil, nil
+}
+
+func (f *Field) HasDirectives() bool {
+ return len(f.Directives) > 0
+}
+
+func (f *Field) IsReserved() bool {
+ return strings.HasPrefix(f.Name, "__")
+}
+
+func (f *Field) IsMethod() bool {
+ return f.GoFieldType == GoFieldMethod
+}
+
+func (f *Field) IsVariable() bool {
+ return f.GoFieldType == GoFieldVariable
+}
+
+func (f *Field) IsMap() bool {
+ return f.GoFieldType == GoFieldMap
+}
+
+func (f *Field) IsConcurrent() bool {
+ if f.Object.DisableConcurrency {
+ return false
+ }
+ return f.MethodHasContext || f.IsResolver
+}
+
+func (f *Field) GoNameUnexported() string {
+ return templates.ToGoPrivate(f.Name)
+}
+
+func (f *Field) ShortInvocation() string {
+ return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
+}
+
+func (f *Field) ArgsFunc() string {
+ if len(f.Args) == 0 {
+ return ""
+ }
+
+ return "field_" + f.Object.Definition.Name + "_" + f.Name + "_args"
+}
+
+func (f *Field) ResolverType() string {
+ if !f.IsResolver {
+ return ""
+ }
+
+ return fmt.Sprintf("%s().%s(%s)", f.Object.Definition.Name, f.GoFieldName, f.CallArgs())
+}
+
+func (f *Field) ShortResolverDeclaration() string {
+ res := "(ctx context.Context"
+
+ if !f.Object.Root {
+ res += fmt.Sprintf(", obj *%s", templates.CurrentImports.LookupType(f.Object.Type))
+ }
+ for _, arg := range f.Args {
+ res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO))
+ }
+
+ result := templates.CurrentImports.LookupType(f.TypeReference.GO)
+ if f.Object.Stream {
+ result = "<-chan " + result
+ }
+
+ res += fmt.Sprintf(") (%s, error)", result)
+ return res
+}
+
+func (f *Field) ComplexitySignature() string {
+ res := fmt.Sprintf("func(childComplexity int")
+ for _, arg := range f.Args {
+ res += fmt.Sprintf(", %s %s", arg.VarName, templates.CurrentImports.LookupType(arg.TypeReference.GO))
+ }
+ res += ") int"
+ return res
+}
+
+func (f *Field) ComplexityArgs() string {
+ var args []string
+ for _, arg := range f.Args {
+ args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
+ }
+
+ return strings.Join(args, ", ")
+}
+
+func (f *Field) CallArgs() string {
+ var args []string
+
+ if f.IsResolver {
+ 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 {
+ args = append(args, "args["+strconv.Quote(arg.Name)+"].("+templates.CurrentImports.LookupType(arg.TypeReference.GO)+")")
+ }
+
+ return strings.Join(args, ", ")
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl
index 3df847fa..9718a08a 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl
@@ -1,19 +1,19 @@
-{{ $field := . }}
-{{ $object := $field.Object }}
+{{- range $object := .Objects }}{{- range $field := $object.Fields }}
{{- if $object.Stream }}
- func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {
+ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Field: field,
+ Args: nil,
+ })
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
- args, err := {{ $field.ArgsFunc }}(rawArgs)
+ args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
if err != nil {
ec.Error(ctx, err)
return nil
}
{{- end }}
- 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
@@ -27,35 +27,51 @@
if !ok {
return nil
}
- var out graphql.OrderedMap
- out.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())
- return &out
+ return graphql.WriterFunc(func(w io.Writer) {
+ w.Write([]byte{'{'})
+ graphql.MarshalString(field.Alias).MarshalGQL(w)
+ w.Write([]byte{':'})
+ ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res).MarshalGQL(w)
+ w.Write([]byte{'}'})
+ })
}
}
{{ 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 {
+ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func () { ec.Tracer.EndFieldExecution(ctx) }()
+ rctx := &graphql.ResolverContext{
+ Object: {{$object.Name|quote}},
+ Field: field,
+ Args: nil,
+ IsMethod: {{or $field.IsMethod $field.IsResolver}},
+ }
+ ctx = graphql.WithResolverContext(ctx, rctx)
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
- args, err := {{ $field.ArgsFunc }}(rawArgs)
+ args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
+ rctx.Args = args
{{- end }}
- rctx := &graphql.ResolverContext{
- Object: {{$object.GQLType|quote}},
- Args: {{if $field.Args }}args{{else}}nil{{end}},
- Field: field,
- }
- ctx = graphql.WithResolverContext(ctx, rctx)
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.IsMap }}
+ switch v := {{$field.GoReceiverName}}[{{$field.Name|quote}}].(type) {
+ case {{$field.TypeReference.GO | ref}}:
+ return v, nil
+ case {{$field.TypeReference.Elem.GO | ref}}:
+ return &v, nil
+ case nil:
+ return ({{$field.TypeReference.GO | ref}})(nil), nil
+ default:
+ return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ $field.Name | quote}})
+ }
{{- else if $field.IsMethod }}
{{- if $field.NoErr }}
return {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil
@@ -67,16 +83,18 @@
{{- end }}
})
if resTmp == nil {
- {{- if $field.ASTType.NonNull }}
+ {{- if $field.TypeReference.GQL.NonNull }}
if !ec.HasError(rctx) {
ec.Errorf(ctx, "must not be null")
}
{{- end }}
return graphql.Null
}
- res := resTmp.({{$field.Signature}})
+ res := resTmp.({{$field.TypeReference.GO | ref}})
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
- {{ $field.WriteJson }}
+ return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
}
{{ end }}
+
+{{- end }}{{- end}}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/generate.go b/vendor/github.com/99designs/gqlgen/codegen/generate.go
new file mode 100644
index 00000000..eafa3f87
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/generate.go
@@ -0,0 +1,15 @@
+package codegen
+
+import (
+ "github.com/99designs/gqlgen/codegen/templates"
+)
+
+func GenerateCode(data *Data) error {
+ return templates.Render(templates.Options{
+ PackageName: data.Config.Exec.Package,
+ Filename: data.Config.Exec.Filename,
+ Data: data,
+ RegionTags: true,
+ GeneratedHeader: true,
+ })
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl b/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
index a37a1613..dce8ce97 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/generated!.gotpl
@@ -1,24 +1,17 @@
-// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
+{{ reserveImport "context" }}
+{{ reserveImport "fmt" }}
+{{ reserveImport "io" }}
+{{ reserveImport "strconv" }}
+{{ reserveImport "time" }}
+{{ reserveImport "sync" }}
+{{ reserveImport "errors" }}
+{{ reserveImport "bytes" }}
-package {{ .PackageName }}
+{{ reserveImport "github.com/vektah/gqlparser" }}
+{{ reserveImport "github.com/vektah/gqlparser/ast" }}
+{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
+{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
-import (
- %%%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.
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
@@ -38,7 +31,7 @@ type Config struct {
type ResolverRoot interface {
{{- range $object := .Objects -}}
{{ if $object.HasResolvers -}}
- {{$object.GQLType}}() {{$object.GQLType}}Resolver
+ {{$object.Name}}() {{$object.Name}}Resolver
{{ end }}
{{- end }}
}
@@ -52,10 +45,10 @@ type DirectiveRoot struct {
type ComplexityRoot struct {
{{ range $object := .Objects }}
{{ if not $object.IsReserved -}}
- {{ $object.GQLType|toCamel }} struct {
- {{ range $field := $object.Fields -}}
+ {{ $object.Name|go }} struct {
+ {{ range $field := $object.UniqueFields -}}
{{ if not $field.IsReserved -}}
- {{ $field.GQLName|toCamel }} {{ $field.ComplexitySignature }}
+ {{ $field.GoFieldName }} {{ $field.ComplexitySignature }}
{{ end }}
{{- end }}
}
@@ -65,32 +58,16 @@ type ComplexityRoot struct {
{{ range $object := .Objects -}}
{{ if $object.HasResolvers }}
- type {{$object.GQLType}}Resolver interface {
+ type {{$object.Name}}Resolver interface {
{{ range $field := $object.Fields -}}
- {{ $field.ShortResolverDeclaration }}
+ {{- if $field.IsResolver }}
+ {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }}
+ {{- end }}
{{ end }}
}
{{- end }}
{{- end }}
-{{ range $object := .Objects -}}
- {{ range $field := $object.Fields -}}
- {{ if $field.Args }}
- func {{ $field.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {
- {{ template "args.gotpl" $field.Args }}
- }
- {{ end }}
- {{ end }}
-{{- end }}
-
-{{ range $directive := .Directives }}
- {{ if $directive.Args }}
- func {{ $directive.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {
- {{ template "args.gotpl" $directive.Args }}
- }
- {{ end }}
-{{ end }}
-
type executableSchema struct {
resolvers ResolverRoot
directives DirectiveRoot
@@ -102,22 +79,24 @@ func (e *executableSchema) Schema() *ast.Schema {
}
func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
+ ec := executionContext{nil, e}
+ _ = ec
switch typeName + "." + field {
{{ range $object := .Objects }}
{{ if not $object.IsReserved }}
- {{ range $field := $object.Fields }}
+ {{ range $field := $object.UniqueFields }}
{{ if not $field.IsReserved }}
- case "{{$object.GQLType}}.{{$field.GQLName}}":
- if e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}} == nil {
+ case "{{$object.Name}}.{{$field.GoFieldName}}":
+ if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil {
break
}
{{ if $field.Args }}
- args, err := {{ $field.ArgsFunc }}(rawArgs)
+ args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs)
if err != nil {
return 0, false
}
{{ end }}
- return e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true
+ return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true
{{ end }}
{{ end }}
{{ end }}
@@ -131,7 +110,7 @@ func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinitio
ec := executionContext{graphql.GetRequestContext(ctx), e}
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
- data := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)
+ data := ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
return buf.Bytes()
@@ -140,7 +119,8 @@ func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinitio
return &graphql.Response{
Data: buf,
Errors: ec.Errors,
- Extensions: ec.Extensions, }
+ Extensions: ec.Extensions,
+ }
{{- else }}
return graphql.ErrorResponse(ctx, "queries are not supported")
{{- end }}
@@ -151,7 +131,7 @@ func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefini
ec := executionContext{graphql.GetRequestContext(ctx), e}
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
- data := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)
+ data := ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet)
var buf bytes.Buffer
data.MarshalGQL(&buf)
return buf.Bytes()
@@ -171,7 +151,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe
{{- if .SubscriptionRoot }}
ec := executionContext{graphql.GetRequestContext(ctx), e}
- next := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)
+ next := ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet)
if ec.Errors != nil {
return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors})
}
@@ -209,22 +189,6 @@ type executionContext struct {
*executableSchema
}
-{{- range $object := .Objects }}
- {{ template "object.gotpl" $object }}
-
- {{- range $field := $object.Fields }}
- {{ template "field.gotpl" $field }}
- {{ end }}
-{{- end}}
-
-{{- range $interface := .Interfaces }}
- {{ template "interface.gotpl" $interface }}
-{{- end }}
-
-{{- range $input := .Inputs }}
- {{ template "input.gotpl" $input }}
-{{- end }}
-
func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {
defer func() {
if r := recover(); r != nil {
@@ -241,7 +205,7 @@ func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}
if ec.directives.{{$directive.Name|ucFirst}} != nil {
{{- if $directive.Args }}
rawArgs := d.ArgumentMap(ec.Variables)
- args, err := {{ $directive.ArgsFunc }}(rawArgs)
+ args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
if err != nil {
ec.Error(ctx, err)
return nil
@@ -279,7 +243,7 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er
}
var parsedSchema = gqlparser.MustLoadSchema(
- {{- range $filename, $schema := .SchemaRaw }}
+ {{- range $filename, $schema := .SchemaStr }}
&ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},
{{- end }}
)
diff --git a/vendor/github.com/99designs/gqlgen/codegen/input.gotpl b/vendor/github.com/99designs/gqlgen/codegen/input.gotpl
new file mode 100644
index 00000000..c8ac7ad3
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/input.gotpl
@@ -0,0 +1,56 @@
+{{- range $input := .Inputs }}
+ {{- if not .HasUnmarshal }}
+ func (ec *executionContext) unmarshalInput{{ .Name }}(ctx context.Context, v interface{}) ({{.Type | ref}}, error) {
+ var it {{.Type | ref}}
+ var asMap = v.(map[string]interface{})
+ {{ range $field := .Fields}}
+ {{- if $field.Default}}
+ if _, present := asMap[{{$field.Name|quote}}] ; !present {
+ asMap[{{$field.Name|quote}}] = {{ $field.Default | dump }}
+ }
+ {{- end}}
+ {{- end }}
+
+ for k, v := range asMap {
+ switch k {
+ {{- range $field := .Fields }}
+ case {{$field.Name|quote}}:
+ var err error
+ {{- if $field.Directives }}
+ getField0 := func(ctx context.Context) (interface{}, error) { return ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) }
+
+ {{- range $i, $directive := $field.Directives }}
+ getField{{add $i 1}} := func(ctx context.Context) (res interface{}, err error) {
+ {{- range $dArg := $directive.Args }}
+ {{- if and $dArg.TypeReference.IsPtr ( notNil "Value" $dArg ) }}
+ {{ $dArg.VarName }} := {{ $dArg.Value | dump }}
+ {{- end }}
+ {{- end }}
+ n := getField{{$i}}
+ return ec.directives.{{$directive.Name|ucFirst}}({{$directive.ResolveArgs "it" "n" }})
+ }
+ {{- end }}
+
+ tmp, err := getField{{$field.Directives|len}}(ctx)
+ if err != nil {
+ return it, err
+ }
+ if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok {
+ it.{{$field.GoFieldName}} = data
+ } else {
+ return it, fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp)
+ }
+ {{- else }}
+ it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v)
+ if err != nil {
+ return it, err
+ }
+ {{- end }}
+ {{- end }}
+ }
+ }
+
+ return it, nil
+ }
+ {{- end }}
+{{ end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/input_build.go b/vendor/github.com/99designs/gqlgen/codegen/input_build.go
deleted file mode 100644
index 70fa564d..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/input_build.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package codegen
-
-import (
- "go/types"
- "sort"
-
- "github.com/pkg/errors"
- "github.com/vektah/gqlparser/ast"
- "golang.org/x/tools/go/loader"
-)
-
-func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program) (Objects, error) {
- var inputs Objects
-
- for _, typ := range cfg.schema.Types {
- switch typ.Kind {
- case ast.InputObject:
- input, err := cfg.buildInput(namedTypes, typ)
- if err != nil {
- return nil, err
- }
-
- def, err := findGoType(prog, input.Package, input.GoType)
- if err != nil {
- return nil, errors.Wrap(err, "cannot find type")
- }
- if def != nil {
- input.Marshaler = buildInputMarshaler(typ, def)
- bindErrs := bindObject(def.Type(), input, cfg.StructTag)
- if len(bindErrs) > 0 {
- return nil, bindErrs
- }
- }
-
- inputs = append(inputs, input)
- }
- }
-
- sort.Slice(inputs, func(i, j int) bool {
- return inputs[i].GQLType < inputs[j].GQLType
- })
-
- return inputs, nil
-}
-
-func (cfg *Config) buildInput(types NamedTypes, typ *ast.Definition) (*Object, error) {
- obj := &Object{NamedType: types[typ.Name]}
- typeEntry, entryExists := cfg.Models[typ.Name]
-
- for _, field := range typ.Fields {
- newField := Field{
- GQLName: field.Name,
- Type: types.getType(field.Type),
- Object: obj,
- }
-
- if entryExists {
- if typeField, ok := typeEntry.Fields[field.Name]; ok {
- newField.GoFieldName = typeField.FieldName
- }
- }
-
- if field.DefaultValue != nil {
- var err error
- newField.Default, err = field.DefaultValue.Value(nil)
- if err != nil {
- return nil, errors.Errorf("default value for %s.%s is not valid: %s", typ.Name, field.Name, err.Error())
- }
- }
-
- if !newField.Type.IsInput && !newField.Type.IsScalar {
- return nil, errors.Errorf("%s cannot be used as a field of %s. only input and scalar types are allowed", newField.GQLType, obj.GQLType)
- }
-
- obj.Fields = append(obj.Fields, newField)
-
- }
- return obj, nil
-}
-
-// if user has implemented an UnmarshalGQL method on the input type manually, use it
-// otherwise we will generate one.
-func buildInputMarshaler(typ *ast.Definition, def types.Object) *Ref {
- switch def := def.(type) {
- case *types.TypeName:
- namedType := def.Type().(*types.Named)
- for i := 0; i < namedType.NumMethods(); i++ {
- method := namedType.Method(i)
- if method.Name() == "UnmarshalGQL" {
- return nil
- }
- }
- }
-
- return &Ref{GoType: typ.Name}
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.go b/vendor/github.com/99designs/gqlgen/codegen/interface.go
index 2de0c88a..f59e8ed0 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/interface.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/interface.go
@@ -1,13 +1,63 @@
package codegen
-type Interface struct {
- *NamedType
+import (
+ "go/types"
+
+ "github.com/vektah/gqlparser/ast"
+)
+type Interface struct {
+ *ast.Definition
+ Type types.Type
Implementors []InterfaceImplementor
+ InTypemap bool
}
type InterfaceImplementor struct {
- ValueReceiver bool
+ *ast.Definition
+
+ Interface *Interface
+ Type types.Type
+}
+
+func (b *builder) buildInterface(typ *ast.Definition) *Interface {
+ obj, err := b.Binder.DefaultUserObject(typ.Name)
+ if err != nil {
+ panic(err)
+ }
+
+ i := &Interface{
+ Definition: typ,
+ Type: obj,
+ InTypemap: b.Config.Models.UserDefined(typ.Name),
+ }
+
+ for _, implementor := range b.Schema.GetPossibleTypes(typ) {
+ obj, err := b.Binder.DefaultUserObject(implementor.Name)
+ if err != nil {
+ panic(err)
+ }
+
+ i.Implementors = append(i.Implementors, InterfaceImplementor{
+ Definition: implementor,
+ Type: obj,
+ Interface: i,
+ })
+ }
+
+ return i
+}
+
+func (i *InterfaceImplementor) ValueReceiver() bool {
+ interfaceType, err := findGoInterface(i.Interface.Type)
+ if interfaceType == nil || err != nil {
+ return true
+ }
+
+ implementorType, err := findGoNamedType(i.Type)
+ if implementorType == nil || err != nil {
+ return true
+ }
- *NamedType
+ return types.Implements(implementorType, interfaceType)
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl b/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl
new file mode 100644
index 00000000..81a58076
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/interface.gotpl
@@ -0,0 +1,20 @@
+{{- range $interface := .Interfaces }}
+
+func (ec *executionContext) _{{$interface.Name}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.Type | ref}}) graphql.Marshaler {
+ switch obj := (*obj).(type) {
+ case nil:
+ return graphql.Null
+ {{- range $implementor := $interface.Implementors }}
+ {{- if $implementor.ValueReceiver }}
+ case {{$implementor.Type | ref}}:
+ return ec._{{$implementor.Name}}(ctx, sel, &obj)
+ {{- end}}
+ case *{{$implementor.Type | ref}}:
+ return ec._{{$implementor.Name}}(ctx, sel, obj)
+ {{- end }}
+ default:
+ panic(fmt.Errorf("unexpected type %T", obj))
+ }
+}
+
+{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go
deleted file mode 100644
index 92052ba6..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go
+++ /dev/null
@@ -1,53 +0,0 @@
-package codegen
-
-import (
- "go/types"
- "sort"
-
- "github.com/vektah/gqlparser/ast"
- "golang.org/x/tools/go/loader"
-)
-
-func (cfg *Config) buildInterfaces(types NamedTypes, prog *loader.Program) []*Interface {
- var interfaces []*Interface
- for _, typ := range cfg.schema.Types {
- if typ.Kind == ast.Union || typ.Kind == ast.Interface {
- interfaces = append(interfaces, cfg.buildInterface(types, typ, prog))
- }
- }
-
- sort.Slice(interfaces, func(i, j int) bool {
- return interfaces[i].GQLType < interfaces[j].GQLType
- })
-
- return interfaces
-}
-
-func (cfg *Config) buildInterface(types NamedTypes, typ *ast.Definition, prog *loader.Program) *Interface {
- i := &Interface{NamedType: types[typ.Name]}
-
- for _, implementor := range cfg.schema.GetPossibleTypes(typ) {
- t := types[implementor.Name]
-
- i.Implementors = append(i.Implementors, InterfaceImplementor{
- NamedType: t,
- ValueReceiver: cfg.isValueReceiver(types[typ.Name], t, prog),
- })
- }
-
- return i
-}
-
-func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog *loader.Program) bool {
- interfaceType, err := findGoInterface(prog, intf.Package, intf.GoType)
- if interfaceType == nil || err != nil {
- return true
- }
-
- implementorType, err := findGoNamedType(prog, implementor.Package, implementor.GoType)
- if implementorType == nil || err != nil {
- 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
deleted file mode 100644
index bcdc8703..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/model.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package codegen
-
-type Model struct {
- *NamedType
- Description string
- Fields []ModelField
- Implements []*NamedType
-}
-
-type ModelField struct {
- *Type
- GQLName string
- GoFieldName string
- GoFKName string
- GoFKType string
- Description string
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/models_build.go b/vendor/github.com/99designs/gqlgen/codegen/models_build.go
deleted file mode 100644
index 56d2ff1f..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/models_build.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package codegen
-
-import (
- "sort"
-
- "github.com/vektah/gqlparser/ast"
- "golang.org/x/tools/go/loader"
-)
-
-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)
- if err != nil {
- return nil, err
- }
- if obj.Root || obj.IsUserDefined {
- continue
- }
- model = cfg.obj2Model(obj)
- case ast.InputObject:
- obj, err := cfg.buildInput(types, typ)
- if err != nil {
- return nil, err
- }
- if obj.IsUserDefined {
- continue
- }
- model = cfg.obj2Model(obj)
- case ast.Interface, ast.Union:
- intf := cfg.buildInterface(types, typ, prog)
- if intf.IsUserDefined {
- continue
- }
- model = int2Model(intf)
- default:
- continue
- }
- model.Description = typ.Description // It's this or change both obj2Model and buildObject
-
- models = append(models, model)
- }
-
- sort.Slice(models, func(i, j int) bool {
- return models[i].GQLType < models[j].GQLType
- })
-
- return models, nil
-}
-
-func (cfg *Config) obj2Model(obj *Object) Model {
- model := Model{
- NamedType: obj.NamedType,
- Implements: obj.Implements,
- Fields: []ModelField{},
- }
-
- model.GoType = ucFirst(obj.GQLType)
- model.Marshaler = &Ref{GoType: obj.GoType}
-
- for i := range obj.Fields {
- field := &obj.Fields[i]
- mf := ModelField{Type: field.Type, GQLName: field.GQLName}
-
- if field.GoFieldName != "" {
- mf.GoFieldName = field.GoFieldName
- } else {
- mf.GoFieldName = field.GoNameExported()
- }
-
- model.Fields = append(model.Fields, mf)
- }
-
- return model
-}
-
-func int2Model(obj *Interface) Model {
- model := Model{
- NamedType: obj.NamedType,
- Fields: []ModelField{},
- }
-
- model.GoType = ucFirst(obj.GQLType)
- model.Marshaler = &Ref{GoType: obj.GoType}
-
- return model
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.go b/vendor/github.com/99designs/gqlgen/codegen/object.go
index 656af297..539c3164 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/object.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/object.go
@@ -1,13 +1,13 @@
package codegen
import (
- "bytes"
- "fmt"
+ "go/types"
"strconv"
"strings"
- "text/template"
"unicode"
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/pkg/errors"
"github.com/vektah/gqlparser/ast"
)
@@ -17,337 +17,150 @@ const (
GoFieldUndefined GoFieldType = iota
GoFieldMethod
GoFieldVariable
+ GoFieldMap
)
type Object struct {
- *NamedType
+ *ast.Definition
- Fields []Field
- Satisfies []string
- Implements []*NamedType
- ResolverInterface *Ref
+ Type types.Type
+ ResolverInterface types.Type
Root bool
+ Fields []*Field
+ Implements []*ast.Definition
DisableConcurrency bool
Stream bool
+ Directives []*Directive
}
-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
- 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 {
- *Type
-
- GQLName string // The name of the argument in graphql
- GoVarName string // The name of the var in go
- Object *Object // A link back to the parent object
- Default interface{} // The default value
-}
-
-type Objects []*Object
-
-func (o *Object) Implementors() string {
- satisfiedBy := strconv.Quote(o.GQLType)
- for _, s := range o.Satisfies {
- satisfiedBy += ", " + strconv.Quote(s)
- }
- return "[]string{" + satisfiedBy + "}"
-}
-
-func (o *Object) HasResolvers() bool {
- for _, f := range o.Fields {
- if f.IsResolver() {
- return true
+func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
+ dirs, err := b.getDirectives(typ.Directives)
+ if err != nil {
+ return nil, errors.Wrap(err, typ.Name)
+ }
+
+ obj := &Object{
+ Definition: typ,
+ Root: b.Schema.Query == typ || b.Schema.Mutation == typ || b.Schema.Subscription == typ,
+ DisableConcurrency: typ == b.Schema.Mutation,
+ Stream: typ == b.Schema.Subscription,
+ Directives: dirs,
+ ResolverInterface: types.NewNamed(
+ types.NewTypeName(0, b.Config.Exec.Pkg(), typ.Name+"Resolver", nil),
+ nil,
+ nil,
+ ),
+ }
+
+ if !obj.Root {
+ goObject, err := b.Binder.DefaultUserObject(typ.Name)
+ if err != nil {
+ return nil, err
}
+ obj.Type = goObject
}
- return false
-}
-func (o *Object) IsConcurrent() bool {
- for _, f := range o.Fields {
- if f.IsConcurrent() {
- return true
- }
+ for _, intf := range b.Schema.GetImplements(typ) {
+ obj.Implements = append(obj.Implements, b.Schema.Types[intf.Name])
}
- return false
-}
-
-func (o *Object) IsReserved() bool {
- return strings.HasPrefix(o.GQLType, "__")
-}
-func (f *Field) IsResolver() bool {
- return f.GoFieldName == ""
-}
-
-func (f *Field) IsReserved() bool {
- return strings.HasPrefix(f.GQLName, "__")
-}
-
-func (f *Field) IsMethod() bool {
- return f.GoFieldType == GoFieldMethod
-}
+ for _, field := range typ.Fields {
+ if strings.HasPrefix(field.Name, "__") {
+ continue
+ }
-func (f *Field) IsVariable() bool {
- return f.GoFieldType == GoFieldVariable
-}
+ var f *Field
+ f, err = b.buildField(obj, field)
+ if err != nil {
+ return nil, err
+ }
-func (f *Field) IsConcurrent() bool {
- if f.Object.DisableConcurrency {
- return false
+ obj.Fields = append(obj.Fields, f)
}
- return f.MethodHasContext || f.IsResolver()
-}
-func (f *Field) GoNameExported() string {
- return lintName(ucFirst(f.GQLName))
+ return obj, nil
}
-func (f *Field) GoNameUnexported() string {
- return lintName(f.GQLName)
-}
-
-func (f *Field) ShortInvocation() string {
- if !f.IsResolver() {
- return ""
+func (o *Object) Reference() types.Type {
+ switch o.Type.(type) {
+ case *types.Pointer, *types.Slice, *types.Map:
+ return o.Type
}
- return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, f.GoNameExported(), f.CallArgs())
+ return types.NewPointer(o.Type)
}
-func (f *Field) ArgsFunc() string {
- if len(f.Args) == 0 {
- return ""
- }
-
- return "field_" + f.Object.GQLType + "_" + f.GQLName + "_args"
-}
+type Objects []*Object
-func (f *Field) ResolverType() string {
- if !f.IsResolver() {
- return ""
+func (o *Object) Implementors() string {
+ satisfiedBy := strconv.Quote(o.Name)
+ for _, s := range o.Implements {
+ satisfiedBy += ", " + strconv.Quote(s.Name)
}
-
- return fmt.Sprintf("%s().%s(%s)", f.Object.GQLType, f.GoNameExported(), f.CallArgs())
+ return "[]string{" + satisfiedBy + "}"
}
-func (f *Field) ShortResolverDeclaration() string {
- if !f.IsResolver() {
- return ""
- }
- res := fmt.Sprintf("%s(ctx context.Context", f.GoNameExported())
-
- if !f.Object.Root {
- res += fmt.Sprintf(", obj *%s", f.Object.FullName())
- }
- for _, arg := range f.Args {
- res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
- }
-
- result := f.Signature()
- if f.Object.Stream {
- result = "<-chan " + result
+func (o *Object) HasResolvers() bool {
+ for _, f := range o.Fields {
+ if f.IsResolver {
+ return true
+ }
}
-
- res += fmt.Sprintf(") (%s, error)", result)
- return res
+ return false
}
-func (f *Field) ResolverDeclaration() string {
- if !f.IsResolver() {
- return ""
- }
- res := fmt.Sprintf("%s_%s(ctx context.Context", f.Object.GQLType, f.GoNameUnexported())
-
- if !f.Object.Root {
- res += fmt.Sprintf(", obj *%s", f.Object.FullName())
+func (o *Object) HasUnmarshal() bool {
+ if o.Type == config.MapType {
+ return true
}
- for _, arg := range f.Args {
- res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
- }
-
- result := f.Signature()
- if f.Object.Stream {
- result = "<-chan " + result
+ for i := 0; i < o.Type.(*types.Named).NumMethods(); i++ {
+ switch o.Type.(*types.Named).Method(i).Name() {
+ case "UnmarshalGQL":
+ return true
+ }
}
-
- res += fmt.Sprintf(") (%s, error)", result)
- return res
+ return false
}
-func (f *Field) ComplexitySignature() string {
- res := fmt.Sprintf("func(childComplexity int")
- for _, arg := range f.Args {
- res += fmt.Sprintf(", %s %s", arg.GoVarName, arg.Signature())
+func (o *Object) HasDirectives() bool {
+ if len(o.Directives) > 0 {
+ return true
}
- res += ") int"
- return res
-}
-
-func (f *Field) ComplexityArgs() string {
- var args []string
- for _, arg := range f.Args {
- args = append(args, "args["+strconv.Quote(arg.GQLName)+"].("+arg.Signature()+")")
+ for _, f := range o.Fields {
+ if f.HasDirectives() {
+ return true
+ }
}
- return strings.Join(args, ", ")
+ return false
}
-func (f *Field) CallArgs() string {
- var args []string
-
- if f.IsResolver() {
- args = append(args, "rctx")
-
- if !f.Object.Root {
- args = append(args, "obj")
- }
- } else {
- if f.MethodHasContext {
- args = append(args, "ctx")
+func (o *Object) IsConcurrent() bool {
+ for _, f := range o.Fields {
+ if f.IsConcurrent() {
+ return true
}
}
-
- for _, arg := range f.Args {
- args = append(args, "args["+strconv.Quote(arg.GQLName)+"].("+arg.Signature()+")")
- }
-
- return strings.Join(args, ", ")
-}
-
-// should be in the template, but its recursive and has a bunch of args
-func (f *Field) WriteJson() string {
- return f.doWriteJson("res", f.Type.Modifiers, f.ASTType, false, 1)
+ return false
}
-func (f *Field) doWriteJson(val string, remainingMods []string, astType *ast.Type, isPtr bool, depth int) string {
- switch {
- case len(remainingMods) > 0 && remainingMods[0] == modPtr:
- return tpl(`
- if {{.val}} == nil {
- {{- if .nonNull }}
- if !ec.HasError(rctx) {
- ec.Errorf(ctx, "must not be null")
- }
- {{- end }}
- return graphql.Null
- }
- {{.next }}`, map[string]interface{}{
- "val": val,
- "nonNull": astType.NonNull,
- "next": f.doWriteJson(val, remainingMods[1:], astType, true, depth+1),
- })
-
- case len(remainingMods) > 0 && remainingMods[0] == modList:
- if isPtr {
- val = "*" + val
- }
- var arr = "arr" + strconv.Itoa(depth)
- var index = "idx" + strconv.Itoa(depth)
- var usePtr bool
- if len(remainingMods) == 1 && !isPtr {
- usePtr = true
- }
-
- return tpl(`
- {{.arr}} := make(graphql.Array, len({{.val}}))
- {{ if and .top (not .isScalar) }} var wg sync.WaitGroup {{ end }}
- {{ if not .isScalar }}
- isLen1 := len({{.val}}) == 1
- if !isLen1 {
- wg.Add(len({{.val}}))
- }
- {{ end }}
- for {{.index}} := range {{.val}} {
- {{- if not .isScalar }}
- {{.index}} := {{.index}}
- rctx := &graphql.ResolverContext{
- Index: &{{.index}},
- Result: {{ if .usePtr }}&{{end}}{{.val}}[{{.index}}],
- }
- ctx := graphql.WithResolverContext(ctx, rctx)
- f := func({{.index}} int) {
- if !isLen1 {
- defer wg.Done()
- }
- {{.arr}}[{{.index}}] = func() graphql.Marshaler {
- {{ .next }}
- }()
- }
- if isLen1 {
- f({{.index}})
- } else {
- go f({{.index}})
- }
- {{ else }}
- {{.arr}}[{{.index}}] = func() graphql.Marshaler {
- {{ .next }}
- }()
- {{- end}}
- }
- {{ if and .top (not .isScalar) }} wg.Wait() {{ end }}
- return {{.arr}}`, map[string]interface{}{
- "val": val,
- "arr": arr,
- "index": index,
- "top": depth == 1,
- "arrayLen": len(val),
- "isScalar": f.IsScalar,
- "usePtr": usePtr,
- "next": f.doWriteJson(val+"["+index+"]", remainingMods[1:], astType.Elem, false, depth+1),
- })
-
- case f.IsScalar:
- if isPtr {
- val = "*" + val
- }
- return f.Marshal(val)
-
- default:
- if !isPtr {
- val = "&" + val
- }
- return tpl(`
- return ec._{{.type}}(ctx, field.Selections, {{.val}})`, map[string]interface{}{
- "type": f.GQLType,
- "val": val,
- })
- }
+func (o *Object) IsReserved() bool {
+ return strings.HasPrefix(o.Definition.Name, "__")
}
-func (f *FieldArgument) Stream() bool {
- return f.Object != nil && f.Object.Stream
+func (o *Object) Description() string {
+ return o.Definition.Description
}
func (os Objects) ByName(name string) *Object {
for i, o := range os {
- if strings.EqualFold(o.GQLType, name) {
+ if strings.EqualFold(o.Definition.Name, name) {
return os[i]
}
}
return nil
}
-func tpl(tpl string, vars map[string]interface{}) string {
- b := &bytes.Buffer{}
- err := template.Must(template.New("inline").Parse(tpl)).Execute(b, vars)
- if err != nil {
- panic(err)
- }
- return b.String()
-}
-
func ucFirst(s string) string {
if s == "" {
return ""
@@ -357,117 +170,3 @@ func ucFirst(s string) string {
r[0] = unicode.ToUpper(r[0])
return string(r)
}
-
-// copy from https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679
-
-// lintName returns a different name if it should be different.
-func lintName(name string) (should string) {
- // Fast path for simple cases: "_" and all lowercase.
- if name == "_" {
- return name
- }
- allLower := true
- for _, r := range name {
- if !unicode.IsLower(r) {
- allLower = false
- break
- }
- }
- if allLower {
- return name
- }
-
- // Split camelCase at any lower->upper transition, and split on underscores.
- // Check each word for common initialisms.
- runes := []rune(name)
- w, i := 0, 0 // index of start of word, scan
- for i+1 <= len(runes) {
- eow := false // whether we hit the end of a word
- if i+1 == len(runes) {
- eow = true
- } else if runes[i+1] == '_' {
- // underscore; shift the remainder forward over any run of underscores
- eow = true
- n := 1
- for i+n+1 < len(runes) && runes[i+n+1] == '_' {
- n++
- }
-
- // Leave at most one underscore if the underscore is between two digits
- if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
- n--
- }
-
- copy(runes[i+1:], runes[i+n+1:])
- runes = runes[:len(runes)-n]
- } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
- // lower->non-lower
- eow = true
- }
- i++
- if !eow {
- continue
- }
-
- // [w,i) is a word.
- word := string(runes[w:i])
- if u := strings.ToUpper(word); commonInitialisms[u] {
- // Keep consistent case, which is lowercase only at the start.
- if w == 0 && unicode.IsLower(runes[w]) {
- u = strings.ToLower(u)
- }
- // All the common initialisms are ASCII,
- // so we can replace the bytes exactly.
- copy(runes[w:], []rune(u))
- } else if w > 0 && strings.ToLower(word) == word {
- // already all lowercase, and not the first word, so uppercase the first character.
- runes[w] = unicode.ToUpper(runes[w])
- }
- w = i
- }
- return string(runes)
-}
-
-// commonInitialisms is a set of common initialisms.
-// Only add entries that are highly unlikely to be non-initialisms.
-// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
-var commonInitialisms = map[string]bool{
- "ACL": true,
- "API": true,
- "ASCII": true,
- "CPU": true,
- "CSS": true,
- "DNS": true,
- "EOF": true,
- "GUID": true,
- "HTML": true,
- "HTTP": true,
- "HTTPS": true,
- "ID": true,
- "IP": true,
- "JSON": true,
- "LHS": true,
- "QPS": true,
- "RAM": true,
- "RHS": true,
- "RPC": true,
- "SLA": true,
- "SMTP": true,
- "SQL": true,
- "SSH": true,
- "TCP": true,
- "TLS": true,
- "TTL": true,
- "UDP": true,
- "UI": true,
- "UID": true,
- "UUID": true,
- "URI": true,
- "URL": true,
- "UTF8": true,
- "VM": true,
- "XML": true,
- "XMPP": true,
- "XSRF": true,
- "XSS": true,
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl
new file mode 100644
index 00000000..19da1b19
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl
@@ -0,0 +1,77 @@
+{{- range $object := .Objects }}
+
+var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}}
+
+{{- if .Stream }}
+func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {
+ fields := graphql.CollectFields(ctx, sel, {{$object.Name|lcFirst}}Implementors)
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: {{$object.Name|quote}},
+ })
+ if len(fields) != 1 {
+ ec.Errorf(ctx, "must subscribe to exactly one stream")
+ return nil
+ }
+
+ switch fields[0].Name {
+ {{- range $field := $object.Fields }}
+ case "{{$field.Name}}":
+ return ec._{{$object.Name}}_{{$field.Name}}(ctx, fields[0])
+ {{- end }}
+ default:
+ panic("unknown field " + strconv.Quote(fields[0].Name))
+ }
+}
+{{- else }}
+func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
+ fields := graphql.CollectFields(ctx, sel, {{$object.Name|lcFirst}}Implementors)
+ {{if $object.Root}}
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: {{$object.Name|quote}},
+ })
+ {{end}}
+
+ out := graphql.NewFieldSet(fields)
+ invalid := false
+ for i, field := range fields {
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString({{$object.Name|quote}})
+ {{- range $field := $object.Fields }}
+ case "{{$field.Name}}":
+ {{- if $field.IsConcurrent }}
+ field := field
+ out.Concurrently(i, func() (res graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ }
+ }()
+ res = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
+ {{- if $field.TypeReference.GQL.NonNull }}
+ if res == graphql.Null {
+ invalid = true
+ }
+ {{- end }}
+ return res
+ })
+ {{- else }}
+ out.Values[i] = ec._{{$object.Name}}_{{$field.Name}}(ctx, field{{if not $object.Root}}, obj{{end}})
+ {{- if $field.TypeReference.GQL.NonNull }}
+ if out.Values[i] == graphql.Null {
+ invalid = true
+ }
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+ out.Dispatch()
+ if invalid { return graphql.Null }
+ return out
+}
+{{- end }}
+
+{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object_build.go b/vendor/github.com/99designs/gqlgen/codegen/object_build.go
deleted file mode 100644
index 279d1eb6..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/object_build.go
+++ /dev/null
@@ -1,181 +0,0 @@
-package codegen
-
-import (
- "log"
- "sort"
-
- "github.com/pkg/errors"
- "github.com/vektah/gqlparser/ast"
- "golang.org/x/tools/go/loader"
-)
-
-func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program) (Objects, error) {
- var objects Objects
-
- for _, typ := range cfg.schema.Types {
- if typ.Kind != ast.Object {
- continue
- }
-
- obj, err := cfg.buildObject(types, typ)
- if err != nil {
- return nil, err
- }
-
- def, err := findGoType(prog, obj.Package, obj.GoType)
- if err != nil {
- return nil, err
- }
- if def != nil {
- for _, bindErr := range bindObject(def.Type(), obj, cfg.StructTag) {
- log.Println(bindErr.Error())
- log.Println(" Adding resolver method")
- }
- }
-
- objects = append(objects, obj)
- }
-
- sort.Slice(objects, func(i, j int) bool {
- return objects[i].GQLType < objects[j].GQLType
- })
-
- return objects, nil
-}
-
-var keywords = []string{
- "break",
- "default",
- "func",
- "interface",
- "select",
- "case",
- "defer",
- "go",
- "map",
- "struct",
- "chan",
- "else",
- "goto",
- "package",
- "switch",
- "const",
- "fallthrough",
- "if",
- "range",
- "type",
- "continue",
- "for",
- "import",
- "return",
- "var",
-}
-
-// sanitizeArgName prevents collisions with go keywords for arguments to resolver functions
-func sanitizeArgName(name string) string {
- for _, k := range keywords {
- if name == k {
- return name + "Arg"
- }
- }
- return name
-}
-
-func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition) (*Object, error) {
- obj := &Object{NamedType: types[typ.Name]}
- typeEntry, entryExists := cfg.Models[typ.Name]
-
- obj.ResolverInterface = &Ref{GoType: obj.GQLType + "Resolver"}
-
- if typ == cfg.schema.Query {
- obj.Root = true
- }
-
- if typ == cfg.schema.Mutation {
- obj.Root = true
- obj.DisableConcurrency = true
- }
-
- if typ == cfg.schema.Subscription {
- obj.Root = true
- obj.Stream = true
- }
-
- 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",
- GoFieldType: GoFieldMethod,
- GoReceiverName: "ec",
- GoFieldName: "introspectSchema",
- Object: obj,
- Description: field.Description,
- })
- continue
- }
- if typ == cfg.schema.Query && field.Name == "__schema" {
- obj.Fields = append(obj.Fields, Field{
- Type: &Type{types["__Type"], []string{modPtr}, ast.NamedType("__Schema", nil), nil},
- GQLName: "__type",
- GoFieldType: GoFieldMethod,
- GoReceiverName: "ec",
- GoFieldName: "introspectType",
- Args: []FieldArgument{
- {GQLName: "name", Type: &Type{types["String"], []string{}, ast.NamedType("String", nil), nil}, Object: &Object{}},
- },
- Object: obj,
- })
- continue
- }
-
- var forceResolver bool
- var goName string
- if entryExists {
- if typeField, ok := typeEntry.Fields[field.Name]; ok {
- goName = typeField.FieldName
- forceResolver = typeField.Resolver
- }
- }
-
- var args []FieldArgument
- for _, arg := range field.Arguments {
- newArg := FieldArgument{
- GQLName: arg.Name,
- Type: types.getType(arg.Type),
- Object: obj,
- GoVarName: sanitizeArgName(arg.Name),
- }
-
- if !newArg.Type.IsInput && !newArg.Type.IsScalar {
- return nil, errors.Errorf("%s cannot be used as argument of %s.%s. only input and scalar types are allowed", arg.Type, obj.GQLType, field.Name)
- }
-
- if arg.DefaultValue != nil {
- var err error
- newArg.Default, err = arg.DefaultValue.Value(nil)
- if err != nil {
- return nil, errors.Errorf("default value for %s.%s is not valid: %s", typ.Name, field.Name, err.Error())
- }
- }
- args = append(args, newArg)
- }
-
- obj.Fields = append(obj.Fields, Field{
- GQLName: field.Name,
- Type: types.getType(field.Type),
- Args: args,
- Object: obj,
- GoFieldName: goName,
- ForceResolver: forceResolver,
- })
- }
-
- return obj, nil
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/args.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/args.gotpl
deleted file mode 100644
index 870a99ed..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/args.gotpl
+++ /dev/null
@@ -1,13 +0,0 @@
- args := map[string]interface{}{}
- {{- range $i, $arg := . }}
- var arg{{$i}} {{$arg.Signature }}
- if tmp, ok := rawArgs[{{$arg.GQLName|quote}}]; ok {
- var err error
- {{$arg.Unmarshal (print "arg" $i) "tmp" }}
- if err != nil {
- return nil, err
- }
- }
- args[{{$arg.GQLName|quote}}] = arg{{$i}}
- {{- end }}
- return args, nil
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go b/vendor/github.com/99designs/gqlgen/codegen/templates/data.go
deleted file mode 100644
index d3098aaa..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go
+++ /dev/null
@@ -1,13 +0,0 @@
-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\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\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": "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/import.go b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go
index c9db2d96..effe9a0d 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go
@@ -2,10 +2,10 @@ package templates
import (
"fmt"
- "go/build"
+ "go/types"
"strconv"
- "github.com/99designs/gqlgen/internal/gopath"
+ "github.com/99designs/gqlgen/internal/code"
)
type Import struct {
@@ -38,43 +38,42 @@ func (s *Imports) String() string {
return res
}
-func (s *Imports) Reserve(path string, aliases ...string) string {
+func (s *Imports) Reserve(path string, aliases ...string) (string, error) {
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)
+ if code.ImportPathForDir(s.destDir) == path {
+ return "", nil
}
+ name := code.NameForPackage(path)
var alias string
if len(aliases) != 1 {
- alias = pkg.Name
+ alias = name
} else {
alias = aliases[0]
}
if existing := s.findByPath(path); existing != nil {
- panic("ambient import already exists")
+ if existing.Alias == alias {
+ return "", nil
+ }
+ return "", fmt.Errorf("ambient import already exists")
}
if alias := s.findByAlias(alias); alias != nil {
- panic("ambient import collides on an alias")
+ return "", fmt.Errorf("ambient import collides on an alias")
}
s.imports = append(s.imports, &Import{
- Name: pkg.Name,
+ Name: name,
Path: path,
Alias: alias,
})
- return ""
+ return "", nil
}
func (s *Imports) Lookup(path string) string {
@@ -82,8 +81,10 @@ func (s *Imports) Lookup(path string) string {
return ""
}
+ path = code.NormalizeVendor(path)
+
// if we are referencing our own package we dont need an import
- if gopath.MustDir2Import(s.destDir) == path {
+ if code.ImportPathForDir(s.destDir) == path {
return ""
}
@@ -91,13 +92,8 @@ func (s *Imports) Lookup(path string) string {
return existing.Alias
}
- pkg, err := build.Default.Import(path, s.destDir, 0)
- if err != nil {
- panic(err)
- }
-
imp := &Import{
- Name: pkg.Name,
+ Name: code.NameForPackage(path),
Path: path,
}
s.imports = append(s.imports, imp)
@@ -116,6 +112,12 @@ func (s *Imports) Lookup(path string) string {
return imp.Alias
}
+func (s *Imports) LookupType(t types.Type) string {
+ return types.TypeString(t, func(i *types.Package) string {
+ return s.Lookup(i.Path())
+ })
+}
+
func (s Imports) findByPath(importPath string) *Import {
for _, imp := range s.imports {
if imp.Path == importPath {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/input.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/input.gotpl
deleted file mode 100644
index f543608d..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/input.gotpl
+++ /dev/null
@@ -1,28 +0,0 @@
- {{- if .IsMarshaled }}
- func Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {
- var it {{.FullName}}
- var asMap = v.(map[string]interface{})
- {{ range $field := .Fields}}
- {{- if $field.Default}}
- if _, present := asMap[{{$field.GQLName|quote}}] ; !present {
- asMap[{{$field.GQLName|quote}}] = {{ $field.Default | dump }}
- }
- {{- end}}
- {{- end }}
-
- for k, v := range asMap {
- switch k {
- {{- range $field := .Fields }}
- case {{$field.GQLName|quote}}:
- var err error
- {{ $field.Unmarshal (print "it." $field.GoFieldName) "v" }}
- if err != nil {
- return it, err
- }
- {{- end }}
- }
- }
-
- return it, nil
- }
- {{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/interface.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/interface.gotpl
deleted file mode 100644
index 84cbe500..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/interface.gotpl
+++ /dev/null
@@ -1,18 +0,0 @@
-{{- $interface := . }}
-
-func (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.FullName}}) graphql.Marshaler {
- switch obj := (*obj).(type) {
- case nil:
- return graphql.Null
- {{- range $implementor := $interface.Implementors }}
- {{- if $implementor.ValueReceiver }}
- case {{$implementor.FullName}}:
- return ec._{{$implementor.GQLType}}(ctx, sel, &obj)
- {{- end}}
- case *{{$implementor.FullName}}:
- return ec._{{$implementor.GQLType}}(ctx, sel, obj)
- {{- end }}
- default:
- panic(fmt.Errorf("unexpected type %T", obj))
- }
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl
deleted file mode 100644
index db63a996..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl
+++ /dev/null
@@ -1,91 +0,0 @@
-// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
-
-package {{ .PackageName }}
-
-import (
- %%%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 {
- Is{{.GoType}}()
- }
- {{- else }}
- type {{.GoType}} struct {
- {{- range $field := .Fields }}
- {{- with .Description}}
- {{.|prefixLines "// "}}
- {{- end}}
- {{- if $field.GoFieldName }}
- {{ $field.GoFieldName }} {{$field.Signature}} `json:"{{$field.GQLName}}"`
- {{- else }}
- {{ $field.GoFKName }} {{$field.GoFKType}}
- {{- end }}
- {{- end }}
- }
-
- {{- range $iface := .Implements }}
- func ({{$model.GoType}}) Is{{$iface.GoType}}() {}
- {{- end }}
-
- {{- end }}
-{{- end}}
-
-{{ range $enum := .Enums }}
- {{with .Description}}{{.|prefixLines "// "}} {{end}}
- type {{.GoType}} string
- const (
- {{- range $value := .Values}}
- {{- with .Description}}
- {{.|prefixLines "// "}}
- {{- end}}
- {{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}
- {{- end }}
- )
-
- func (e {{.GoType}}) IsValid() bool {
- switch e {
- case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:
- return true
- }
- return false
- }
-
- func (e {{.GoType}}) String() string {
- return string(e)
- }
-
- func (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {
- str, ok := v.(string)
- if !ok {
- return fmt.Errorf("enums must be strings")
- }
-
- *e = {{.GoType}}(str)
- if !e.IsValid() {
- return fmt.Errorf("%s is not a valid {{.GQLType}}", str)
- }
- return nil
- }
-
- func (e {{.GoType}}) MarshalGQL(w io.Writer) {
- fmt.Fprint(w, strconv.Quote(e.String()))
- }
-
-{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/object.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/object.gotpl
deleted file mode 100644
index e98cbe1e..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/object.gotpl
+++ /dev/null
@@ -1,69 +0,0 @@
-{{ $object := . }}
-
-var {{ $object.GQLType|lcFirst}}Implementors = {{$object.Implementors}}
-
-// nolint: gocyclo, errcheck, gas, goconst
-{{- if .Stream }}
-func (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {
- fields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)
- ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
- Object: {{$object.GQLType|quote}},
- })
- if len(fields) != 1 {
- ec.Errorf(ctx, "must subscribe to exactly one stream")
- return nil
- }
-
- switch fields[0].Name {
- {{- range $field := $object.Fields }}
- case "{{$field.GQLName}}":
- return ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, fields[0])
- {{- end }}
- default:
- panic("unknown field " + strconv.Quote(fields[0].Name))
- }
-}
-{{- else }}
-func (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {
- fields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)
- {{if $object.Root}}
- ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
- Object: {{$object.GQLType|quote}},
- })
- {{end}}
-
- {{if $object.IsConcurrent}} var wg sync.WaitGroup {{end}}
- out := graphql.NewOrderedMap(len(fields))
- invalid := false
- for i, field := range fields {
- out.Keys[i] = field.Alias
-
- switch field.Name {
- case "__typename":
- out.Values[i] = graphql.MarshalString({{$object.GQLType|quote}})
- {{- range $field := $object.Fields }}
- case "{{$field.GQLName}}":
- {{- if $field.IsConcurrent }}
- wg.Add(1)
- go func(i int, field graphql.CollectedField) {
- {{- end }}
- out.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, field{{if not $object.Root}}, obj{{end}})
- {{- if $field.ASTType.NonNull }}
- if out.Values[i] == graphql.Null {
- invalid = true
- }
- {{- end }}
- {{- if $field.IsConcurrent }}
- wg.Done()
- }(i, field)
- {{- end }}
- {{- end }}
- default:
- panic("unknown field " + strconv.Quote(field.Name))
- }
- }
- {{if $object.IsConcurrent}} wg.Wait() {{end}}
- if invalid { return graphql.Null }
- return out
-}
-{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl
deleted file mode 100644
index 53ba8c43..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl
+++ /dev/null
@@ -1,44 +0,0 @@
-package {{ .PackageName }}
-
-import (
- %%%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 {}
-
-{{ range $object := .Objects -}}
- {{- if $object.HasResolvers -}}
- func (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {
- return &{{lcFirst $object.GQLType}}Resolver{r}
- }
- {{ end -}}
-{{ end }}
-
-{{ range $object := .Objects -}}
- {{- if $object.HasResolvers -}}
- type {{lcFirst $object.GQLType}}Resolver struct { *Resolver }
-
- {{ range $field := $object.Fields -}}
- {{- if $field.IsResolver -}}
- func (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {
- panic("not implemented")
- }
- {{ end -}}
- {{ end -}}
- {{ end -}}
-{{ end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
index 22e5d739..4c292732 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
@@ -1,13 +1,14 @@
-//go:generate go run ./inliner/inliner.go
-
package templates
import (
"bytes"
"fmt"
+ "go/types"
"io/ioutil"
"os"
"path/filepath"
+ "reflect"
+ "runtime"
"sort"
"strconv"
"strings"
@@ -15,40 +16,141 @@ import (
"unicode"
"github.com/99designs/gqlgen/internal/imports"
-
"github.com/pkg/errors"
)
// 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,
- "reserveImport": CurrentImports.Reserve,
- "lookupImport": CurrentImports.Lookup,
+type Options struct {
+ PackageName string
+ Filename string
+ RegionTags bool
+ GeneratedHeader bool
+ Data interface{}
+ Funcs template.FuncMap
+}
+
+func Render(cfg Options) error {
+ if CurrentImports != nil {
+ panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected"))
+ }
+ CurrentImports = &Imports{destDir: filepath.Dir(cfg.Filename)}
+
+ // load path relative to calling source file
+ _, callerFile, _, _ := runtime.Caller(1)
+ rootDir := filepath.Dir(callerFile)
+
+ funcs := Funcs()
+ for n, f := range cfg.Funcs {
+ funcs[n] = f
+ }
+ t := template.New("").Funcs(funcs)
+
+ var roots []string
+ // load all the templates in the directory
+ err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ name := filepath.ToSlash(strings.TrimPrefix(path, rootDir+string(os.PathSeparator)))
+ if !strings.HasSuffix(info.Name(), ".gotpl") {
+ return nil
+ }
+ b, err := ioutil.ReadFile(path)
+ if err != nil {
+ return err
+ }
+
+ t, err = t.New(name).Parse(string(b))
+ if err != nil {
+ return errors.Wrap(err, cfg.Filename)
+ }
+
+ roots = append(roots, name)
+
+ return nil
})
+ if err != nil {
+ return errors.Wrap(err, "locating templates")
+ }
- for filename, data := range data {
- _, err := t.New(filename).Parse(data)
+ // then execute all the important looking ones in order, adding them to the same file
+ sort.Slice(roots, func(i, j int) bool {
+ // important files go first
+ if strings.HasSuffix(roots[i], "!.gotpl") {
+ return true
+ }
+ if strings.HasSuffix(roots[j], "!.gotpl") {
+ return false
+ }
+ return roots[i] < roots[j]
+ })
+ var buf bytes.Buffer
+ for _, root := range roots {
+ if cfg.RegionTags {
+ buf.WriteString("\n// region " + center(70, "*", " "+root+" ") + "\n")
+ }
+ err = t.Lookup(root).Execute(&buf, cfg.Data)
if err != nil {
- panic(err)
+ return errors.Wrap(err, root)
+ }
+ if cfg.RegionTags {
+ buf.WriteString("\n// endregion " + center(70, "*", " "+root+" ") + "\n")
}
}
- buf := &bytes.Buffer{}
- err := t.Lookup(name).Execute(buf, tpldata)
+ var result bytes.Buffer
+ if cfg.GeneratedHeader {
+ result.WriteString("// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\n")
+ }
+ result.WriteString("package ")
+ result.WriteString(cfg.PackageName)
+ result.WriteString("\n\n")
+ result.WriteString("import (\n")
+ result.WriteString(CurrentImports.String())
+ result.WriteString(")\n")
+ _, err = buf.WriteTo(&result)
if err != nil {
- return nil, err
+ return err
}
+ CurrentImports = nil
- return buf, nil
+ return write(cfg.Filename, result.Bytes())
+}
+
+func center(width int, pad string, s string) string {
+ if len(s)+2 > width {
+ return s
+ }
+ lpad := (width - len(s)) / 2
+ rpad := width - (lpad + len(s))
+ return strings.Repeat(pad, lpad) + s + strings.Repeat(pad, rpad)
+}
+
+func Funcs() template.FuncMap {
+ return template.FuncMap{
+ "ucFirst": ucFirst,
+ "lcFirst": lcFirst,
+ "quote": strconv.Quote,
+ "rawQuote": rawQuote,
+ "dump": Dump,
+ "ref": ref,
+ "ts": TypeIdentifier,
+ "call": Call,
+ "prefixLines": prefixLines,
+ "notNil": notNil,
+ "reserveImport": CurrentImports.Reserve,
+ "lookupImport": CurrentImports.Lookup,
+ "go": ToGo,
+ "goPrivate": ToGoPrivate,
+ "add": func(a, b int) int {
+ return a + b
+ },
+ "render": func(filename string, tpldata interface{}) (*bytes.Buffer, error) {
+ return render(resolveName(filename, 0), tpldata)
+ },
+ }
}
func ucFirst(s string) string {
@@ -74,37 +176,276 @@ func isDelimiter(c rune) bool {
return c == '-' || c == '_' || unicode.IsSpace(c)
}
-func ToCamel(s string) string {
- buffer := make([]rune, 0, len(s))
- upper := true
- lastWasUpper := false
+func ref(p types.Type) string {
+ return CurrentImports.LookupType(p)
+}
- for _, c := range s {
- if isDelimiter(c) {
- upper = true
+var pkgReplacer = strings.NewReplacer(
+ "/", "ᚋ",
+ ".", "ᚗ",
+ "-", "ᚑ",
+)
+
+func TypeIdentifier(t types.Type) string {
+ res := ""
+ for {
+ switch it := t.(type) {
+ case *types.Pointer:
+ t.Underlying()
+ res += "ᚖ"
+ t = it.Elem()
+ case *types.Slice:
+ res += "ᚕ"
+ t = it.Elem()
+ case *types.Named:
+ res += pkgReplacer.Replace(it.Obj().Pkg().Path())
+ res += "ᚐ"
+ res += it.Obj().Name()
+ return res
+ case *types.Basic:
+ res += it.Name()
+ return res
+ case *types.Map:
+ res += "map"
+ return res
+ case *types.Interface:
+ res += "interface"
+ return res
+ default:
+ panic(fmt.Errorf("unexpected type %T", it))
+ }
+ }
+}
+
+func Call(p *types.Func) string {
+ pkg := CurrentImports.Lookup(p.Pkg().Path())
+
+ if pkg != "" {
+ pkg += "."
+ }
+
+ if p.Type() != nil {
+ // make sure the returned type is listed in our imports.
+ ref(p.Type().(*types.Signature).Results().At(0).Type())
+ }
+
+ return pkg + p.Name()
+}
+
+func ToGo(name string) string {
+ runes := make([]rune, 0, len(name))
+
+ wordWalker(name, func(info *wordInfo) {
+ word := info.Word
+ if info.MatchCommonInitial {
+ word = strings.ToUpper(word)
+ } else if !info.HasCommonInitial {
+ if strings.ToUpper(word) == word || strings.ToLower(word) == word {
+ // FOO or foo → Foo
+ // FOo → FOo
+ word = ucFirst(strings.ToLower(word))
+ }
+ }
+ runes = append(runes, []rune(word)...)
+ })
+
+ return string(runes)
+}
+
+func ToGoPrivate(name string) string {
+ runes := make([]rune, 0, len(name))
+
+ first := true
+ wordWalker(name, func(info *wordInfo) {
+ word := info.Word
+ if first {
+ if strings.ToUpper(word) == word || strings.ToLower(word) == word {
+ // ID → id, CAMEL → camel
+ word = strings.ToLower(info.Word)
+ } else {
+ // ITicket → iTicket
+ word = lcFirst(info.Word)
+ }
+ first = false
+ } else if info.MatchCommonInitial {
+ word = strings.ToUpper(word)
+ } else if !info.HasCommonInitial {
+ word = ucFirst(strings.ToLower(word))
+ }
+ runes = append(runes, []rune(word)...)
+ })
+
+ return sanitizeKeywords(string(runes))
+}
+
+type wordInfo struct {
+ Word string
+ MatchCommonInitial bool
+ HasCommonInitial bool
+}
+
+// This function is based on the following code.
+// https://github.com/golang/lint/blob/06c8688daad7faa9da5a0c2f163a3d14aac986ca/lint.go#L679
+func wordWalker(str string, f func(*wordInfo)) {
+ runes := []rune(str)
+ w, i := 0, 0 // index of start of word, scan
+ hasCommonInitial := false
+ for i+1 <= len(runes) {
+ eow := false // whether we hit the end of a word
+ if i+1 == len(runes) {
+ eow = true
+ } else if isDelimiter(runes[i+1]) {
+ // underscore; shift the remainder forward over any run of underscores
+ eow = true
+ n := 1
+ for i+n+1 < len(runes) && isDelimiter(runes[i+n+1]) {
+ n++
+ }
+
+ // Leave at most one underscore if the underscore is between two digits
+ if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
+ n--
+ }
+
+ copy(runes[i+1:], runes[i+n+1:])
+ runes = runes[:len(runes)-n]
+ } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
+ // lower->non-lower
+ eow = true
+ }
+ i++
+
+ // [w,i) is a word.
+ word := string(runes[w:i])
+ if !eow && commonInitialisms[word] && !unicode.IsLower(runes[i]) {
+ // through
+ // split IDFoo → ID, Foo
+ // but URLs → URLs
+ } else if !eow {
+ if commonInitialisms[word] {
+ hasCommonInitial = true
+ }
continue
}
- if !lastWasUpper && unicode.IsUpper(c) {
- upper = true
+
+ matchCommonInitial := false
+ if commonInitialisms[strings.ToUpper(word)] {
+ hasCommonInitial = true
+ matchCommonInitial = true
}
- if upper {
- buffer = append(buffer, unicode.ToUpper(c))
- } else {
- buffer = append(buffer, unicode.ToLower(c))
+ f(&wordInfo{
+ Word: word,
+ MatchCommonInitial: matchCommonInitial,
+ HasCommonInitial: hasCommonInitial,
+ })
+ hasCommonInitial = false
+ w = i
+ }
+}
+
+var keywords = []string{
+ "break",
+ "default",
+ "func",
+ "interface",
+ "select",
+ "case",
+ "defer",
+ "go",
+ "map",
+ "struct",
+ "chan",
+ "else",
+ "goto",
+ "package",
+ "switch",
+ "const",
+ "fallthrough",
+ "if",
+ "range",
+ "type",
+ "continue",
+ "for",
+ "import",
+ "return",
+ "var",
+ "_",
+}
+
+// sanitizeKeywords prevents collisions with go keywords for arguments to resolver functions
+func sanitizeKeywords(name string) string {
+ for _, k := range keywords {
+ if name == k {
+ return name + "Arg"
}
- upper = false
- lastWasUpper = unicode.IsUpper(c)
}
+ return name
+}
- return string(buffer)
+// commonInitialisms is a set of common initialisms.
+// Only add entries that are highly unlikely to be non-initialisms.
+// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
+var commonInitialisms = map[string]bool{
+ "ACL": true,
+ "API": true,
+ "ASCII": true,
+ "CPU": true,
+ "CSS": true,
+ "DNS": true,
+ "EOF": true,
+ "GUID": true,
+ "HTML": true,
+ "HTTP": true,
+ "HTTPS": true,
+ "ID": true,
+ "IP": true,
+ "JSON": true,
+ "LHS": true,
+ "QPS": true,
+ "RAM": true,
+ "RHS": true,
+ "RPC": true,
+ "SLA": true,
+ "SMTP": true,
+ "SQL": true,
+ "SSH": true,
+ "TCP": true,
+ "TLS": true,
+ "TTL": true,
+ "UDP": true,
+ "UI": true,
+ "UID": true,
+ "UUID": true,
+ "URI": true,
+ "URL": true,
+ "UTF8": true,
+ "VM": true,
+ "XML": true,
+ "XMPP": true,
+ "XSRF": true,
+ "XSS": true,
}
func rawQuote(s string) string {
return "`" + strings.Replace(s, "`", "`+\"`\"+`", -1) + "`"
}
-func dump(val interface{}) string {
+func notNil(field string, data interface{}) bool {
+ v := reflect.ValueOf(data)
+
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ if v.Kind() != reflect.Struct {
+ return false
+ }
+ val := v.FieldByName(field)
+
+ return val.IsValid() && !val.IsNil()
+}
+
+func Dump(val interface{}) string {
switch val := val.(type) {
case int:
return strconv.Itoa(val)
@@ -121,7 +462,7 @@ func dump(val interface{}) string {
case []interface{}:
var parts []string
for _, part := range val {
- parts = append(parts, dump(part))
+ parts = append(parts, Dump(part))
}
return "[]interface{}{" + strings.Join(parts, ",") + "}"
case map[string]interface{}:
@@ -138,7 +479,7 @@ func dump(val interface{}) string {
buf.WriteString(strconv.Quote(key))
buf.WriteString(":")
- buf.WriteString(dump(data))
+ buf.WriteString(Dump(data))
buf.WriteString(",")
}
buf.WriteString("}")
@@ -152,22 +493,33 @@ func prefixLines(prefix, s string) string {
return prefix + strings.Replace(s, "\n", "\n"+prefix, -1)
}
-func RenderToFile(tpl string, filename string, data interface{}) error {
- if CurrentImports != nil {
- panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected"))
+func resolveName(name string, skip int) string {
+ if name[0] == '.' {
+ // load path relative to calling source file
+ _, callerFile, _, _ := runtime.Caller(skip + 1)
+ return filepath.Join(filepath.Dir(callerFile), name[1:])
}
- CurrentImports = &Imports{destDir: filepath.Dir(filename)}
- var buf *bytes.Buffer
- buf, err := Run(tpl, data)
+ // load path relative to this directory
+ _, callerFile, _, _ := runtime.Caller(0)
+ return filepath.Join(filepath.Dir(callerFile), name)
+}
+
+func render(filename string, tpldata interface{}) (*bytes.Buffer, error) {
+ t := template.New("").Funcs(Funcs())
+
+ b, err := ioutil.ReadFile(filename)
if err != nil {
- return errors.Wrap(err, filename+" generation failed")
+ return nil, err
}
- b := bytes.Replace(buf.Bytes(), []byte("%%%IMPORTS%%%"), []byte(CurrentImports.String()), -1)
- CurrentImports = nil
+ t, err = t.New(filepath.Base(filename)).Parse(string(b))
+ if err != nil {
+ panic(err)
+ }
- return write(filename, b)
+ buf := &bytes.Buffer{}
+ return buf, t.Execute(buf, tpldata)
}
func write(filename string, b []byte) error {
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.go b/vendor/github.com/99designs/gqlgen/codegen/type.go
index 04d9bb2f..e0083732 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/type.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/type.go
@@ -1,174 +1,18 @@
package codegen
import (
- "strconv"
- "strings"
-
- "github.com/99designs/gqlgen/codegen/templates"
-
- "github.com/vektah/gqlparser/ast"
-)
-
-type NamedTypes map[string]*NamedType
-
-type NamedType struct {
- Ref
- IsScalar bool
- IsInterface bool
- IsInput bool
- GQLType string // Name of the graphql type
- Marshaler *Ref // If this type has an external marshaler this will be set
-}
-
-type Ref struct {
- 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 {
- *NamedType
-
- Modifiers []string
- ASTType *ast.Type
- AliasedType *Ref
-}
-
-const (
- modList = "[]"
- modPtr = "*"
+ "github.com/99designs/gqlgen/codegen/config"
)
-func (t Ref) FullName() string {
- return t.PkgDot() + t.GoType
-}
-
-func (t Ref) PkgDot() string {
- name := templates.CurrentImports.Lookup(t.Package)
- if name == "" {
- return ""
-
- }
-
- return name + "."
-}
-
-func (t Type) Signature() string {
- if t.AliasedType != nil {
- return strings.Join(t.Modifiers, "") + t.AliasedType.FullName()
- }
- return strings.Join(t.Modifiers, "") + t.FullName()
-}
-
-func (t Type) FullSignature() string {
- pkg := ""
- if t.Package != "" {
- pkg = t.Package + "."
- }
-
- return strings.Join(t.Modifiers, "") + pkg + t.GoType
-}
+func (b *builder) buildTypes() (map[string]*config.TypeReference, error) {
+ ret := map[string]*config.TypeReference{}
-func (t Type) IsPtr() bool {
- return len(t.Modifiers) > 0 && t.Modifiers[0] == modPtr
-}
+ for _, ref := range b.Binder.References {
+ for ref != nil {
+ ret[ref.UniquenessKey()] = ref
-func (t *Type) StripPtr() {
- if !t.IsPtr() {
- return
+ ref = ref.Elem()
+ }
}
- t.Modifiers = t.Modifiers[0 : len(t.Modifiers)-1]
-}
-
-func (t Type) IsSlice() bool {
- return len(t.Modifiers) > 0 && t.Modifiers[0] == modList ||
- len(t.Modifiers) > 1 && t.Modifiers[0] == modPtr && t.Modifiers[1] == modList
-}
-
-func (t NamedType) IsMarshaled() bool {
- return t.Marshaler != nil
-}
-
-func (t Type) Unmarshal(result, raw string) string {
- return t.unmarshal(result, raw, t.Modifiers, 1)
-}
-
-func (t Type) unmarshal(result, raw string, remainingMods []string, depth int) string {
- switch {
- case len(remainingMods) > 0 && remainingMods[0] == modPtr:
- ptr := "ptr" + strconv.Itoa(depth)
- return tpl(`var {{.ptr}} {{.mods}}{{.t.FullName}}
- if {{.raw}} != nil {
- {{.next}}
- {{.result}} = &{{.ptr -}}
- }
- `, map[string]interface{}{
- "ptr": ptr,
- "t": t,
- "raw": raw,
- "result": result,
- "mods": strings.Join(remainingMods[1:], ""),
- "next": t.unmarshal(ptr, raw, remainingMods[1:], depth+1),
- })
-
- case len(remainingMods) > 0 && remainingMods[0] == modList:
- var rawIf = "rawIf" + strconv.Itoa(depth)
- var index = "idx" + strconv.Itoa(depth)
-
- return tpl(`var {{.rawSlice}} []interface{}
- if {{.raw}} != nil {
- if tmp1, ok := {{.raw}}.([]interface{}); ok {
- {{.rawSlice}} = tmp1
- } else {
- {{.rawSlice}} = []interface{}{ {{.raw}} }
- }
- }
- {{.result}} = make({{.type}}, len({{.rawSlice}}))
- for {{.index}} := range {{.rawSlice}} {
- {{ .next -}}
- }`, map[string]interface{}{
- "raw": raw,
- "rawSlice": rawIf,
- "index": index,
- "result": result,
- "type": strings.Join(remainingMods, "") + t.NamedType.FullName(),
- "next": t.unmarshal(result+"["+index+"]", rawIf+"["+index+"]", remainingMods[1:], depth+1),
- })
- }
-
- realResult := result
- if t.AliasedType != nil {
- result = "castTmp"
- }
-
- return tpl(`{{- if .t.AliasedType }}
- var castTmp {{.t.FullName}}
- {{ end }}
- {{- if eq .t.GoType "map[string]interface{}" }}
- {{- .result }} = {{.raw}}.(map[string]interface{})
- {{- else if .t.Marshaler }}
- {{- .result }}, err = {{ .t.Marshaler.PkgDot }}Unmarshal{{.t.Marshaler.GoType}}({{.raw}})
- {{- else -}}
- err = (&{{.result}}).UnmarshalGQL({{.raw}})
- {{- end }}
- {{- if .t.AliasedType }}
- {{ .realResult }} = {{.t.AliasedType.FullName}}(castTmp)
- {{- end }}`, map[string]interface{}{
- "realResult": realResult,
- "result": result,
- "raw": raw,
- "t": t,
- })
-}
-
-func (t Type) Marshal(val string) string {
- if t.AliasedType != nil {
- val = t.GoType + "(" + val + ")"
- }
-
- if t.Marshaler != nil {
- return "return " + t.Marshaler.PkgDot() + "Marshal" + t.Marshaler.GoType + "(" + val + ")"
- }
-
- return "return " + val
+ return ret, nil
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl
new file mode 100644
index 00000000..f727baac
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl
@@ -0,0 +1,131 @@
+{{- range $type := .ReferencedTypes }}
+ {{ with $type.UnmarshalFunc }}
+ func (ec *executionContext) {{ . }}(ctx context.Context, v interface{}) ({{ $type.GO | ref }}, error) {
+ {{- if $type.IsNilable }}
+ if v == nil { return nil, nil }
+ {{- end }}
+ {{- if $type.IsPtr }}
+ res, err := ec.{{ $type.Elem.UnmarshalFunc }}(ctx, v)
+ return &res, err
+ {{- else if $type.IsSlice }}
+ var vSlice []interface{}
+ if v != nil {
+ if tmp1, ok := v.([]interface{}); ok {
+ vSlice = tmp1
+ } else {
+ vSlice = []interface{}{ v }
+ }
+ }
+ var err error
+ res := make([]{{$type.GO.Elem | ref}}, len(vSlice))
+ for i := range vSlice {
+ res[i], err = ec.{{ $type.Elem.UnmarshalFunc }}(ctx, vSlice[i])
+ if err != nil {
+ return nil, err
+ }
+ }
+ return res, nil
+ {{- else }}
+ {{- if $type.Unmarshaler }}
+ {{- if $type.CastType }}
+ tmp, err := {{ $type.Unmarshaler | call }}(v)
+ return {{ $type.GO | ref }}(tmp), err
+ {{- else}}
+ return {{ $type.Unmarshaler | call }}(v)
+ {{- end }}
+ {{- else if eq ($type.GO | ref) "map[string]interface{}" }}
+ return v.(map[string]interface{}), nil
+ {{- else if $type.IsMarshaler -}}
+ var res {{ $type.GO | ref }}
+ return res, res.UnmarshalGQL(v)
+ {{- else }}
+ return ec.unmarshalInput{{ $type.GQL.Name }}(ctx, v)
+ {{- end }}
+ {{- end }}
+ }
+ {{- end }}
+
+ {{ with $type.MarshalFunc }}
+ func (ec *executionContext) {{ . }}(ctx context.Context, sel ast.SelectionSet, v {{ $type.GO | ref }}) graphql.Marshaler {
+ {{- if $type.IsNilable }}
+ if v == nil {
+ {{- if $type.GQL.NonNull }}
+ if !ec.HasError(graphql.GetResolverContext(ctx)) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ {{- end }}
+ return graphql.Null
+ }
+ {{- else if $type.HasIsZero }}
+ if v.IsZero() {
+ {{- if $type.GQL.NonNull }}
+ if !ec.HasError(graphql.GetResolverContext(ctx)) {
+ ec.Errorf(ctx, "must not be null")
+ }
+ {{- end }}
+ return graphql.Null
+ }
+ {{- end }}
+
+ {{- if $type.IsSlice }}
+ {{- if not $type.GQL.NonNull }}
+ if v == nil {
+ return graphql.Null
+ }
+ {{- end }}
+ ret := make(graphql.Array, len(v))
+ {{- if not $type.IsScalar }}
+ var wg sync.WaitGroup
+ isLen1 := len(v) == 1
+ if !isLen1 {
+ wg.Add(len(v))
+ }
+ {{- end }}
+ for i := range v {
+ {{- if not $type.IsScalar }}
+ i := i
+ rctx := &graphql.ResolverContext{
+ Index: &i,
+ Result: &v[i],
+ }
+ ctx := graphql.WithResolverContext(ctx, rctx)
+ f := func(i int) {
+ defer func() {
+ if r := recover(); r != nil {
+ ec.Error(ctx, ec.Recover(ctx, r))
+ ret = nil
+ }
+ }()
+ if !isLen1 {
+ defer wg.Done()
+ }
+ ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i])
+ }
+ if isLen1 {
+ f(i)
+ } else {
+ go f(i)
+ }
+ {{ else }}
+ ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i])
+ {{- end}}
+ }
+ {{ if not $type.IsScalar }} wg.Wait() {{ end }}
+ return ret
+ {{- else }}
+
+ {{- if $type.IsMarshaler }}
+ return v
+ {{- else if $type.Marshaler }}
+ {{- if $type.IsPtr }}
+ return ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, *v)
+ {{- else }}
+ return {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}(v){{else}}v{{- end }})
+ {{- end }}
+ {{- else }}
+ return ec._{{$type.Definition.Name}}(ctx, sel, {{ if not $type.IsNilable}}&{{end}} v)
+ {{- end }}
+ {{- end }}
+ }
+ {{- end }}
+{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type_build.go b/vendor/github.com/99designs/gqlgen/codegen/type_build.go
deleted file mode 100644
index 586b0db2..00000000
--- a/vendor/github.com/99designs/gqlgen/codegen/type_build.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package codegen
-
-import (
- "go/types"
- "strings"
-
- "github.com/vektah/gqlparser/ast"
- "golang.org/x/tools/go/loader"
-)
-
-// namedTypeFromSchema objects for every graphql type, including scalars. There should only be one instance of Type for each thing
-func (cfg *Config) buildNamedTypes() NamedTypes {
- types := map[string]*NamedType{}
- for _, schemaType := range cfg.schema.Types {
- t := namedTypeFromSchema(schemaType)
-
- if userEntry, ok := cfg.Models[t.GQLType]; ok && userEntry.Model != "" {
- t.IsUserDefined = true
- t.Package, t.GoType = pkgAndType(userEntry.Model)
- } else if t.IsScalar {
- t.Package = "github.com/99designs/gqlgen/graphql"
- t.GoType = "String"
- }
-
- types[t.GQLType] = t
- }
- return types
-}
-
-func (cfg *Config) bindTypes(namedTypes NamedTypes, destDir string, prog *loader.Program) {
- for _, t := range namedTypes {
- if t.Package == "" {
- continue
- }
-
- def, _ := findGoType(prog, t.Package, "Marshal"+t.GoType)
- switch def := def.(type) {
- case *types.Func:
- sig := def.Type().(*types.Signature)
- cpy := t.Ref
- t.Marshaler = &cpy
-
- t.Package, t.GoType = pkgAndType(sig.Params().At(0).Type().String())
- }
- }
-}
-
-// namedTypeFromSchema objects for every graphql type, including primitives.
-// don't recurse into object fields or interfaces yet, lets make sure we have collected everything first.
-func namedTypeFromSchema(schemaType *ast.Definition) *NamedType {
- switch schemaType.Kind {
- case ast.Scalar, ast.Enum:
- return &NamedType{GQLType: schemaType.Name, IsScalar: true}
- case ast.Interface, ast.Union:
- return &NamedType{GQLType: schemaType.Name, IsInterface: true}
- case ast.InputObject:
- return &NamedType{GQLType: schemaType.Name, IsInput: true}
- default:
- return &NamedType{GQLType: schemaType.Name}
- }
-}
-
-// take a string in the form github.com/package/blah.Type and split it into package and type
-func pkgAndType(name string) (string, string) {
- parts := strings.Split(name, ".")
- if len(parts) == 1 {
- return "", name
- }
-
- return normalizeVendor(strings.Join(parts[:len(parts)-1], ".")), parts[len(parts)-1]
-}
-
-func (n NamedTypes) getType(t *ast.Type) *Type {
- orig := t
- var modifiers []string
- for {
- if t.Elem != nil {
- modifiers = append(modifiers, modList)
- t = t.Elem
- } else {
- if !t.NonNull {
- modifiers = append(modifiers, modPtr)
- }
- if n[t.NamedType] == nil {
- panic("missing type " + t.NamedType)
- }
- res := &Type{
- NamedType: n[t.NamedType],
- Modifiers: modifiers,
- ASTType: orig,
- }
-
- if res.IsInterface {
- res.StripPtr()
- }
-
- return res
- }
- }
-}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/util.go b/vendor/github.com/99designs/gqlgen/codegen/util.go
index cc6246fd..59dfde08 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/util.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/util.go
@@ -1,65 +1,30 @@
package codegen
import (
- "fmt"
"go/types"
- "reflect"
- "regexp"
"strings"
"github.com/pkg/errors"
- "golang.org/x/tools/go/loader"
)
-func findGoType(prog *loader.Program, pkgName string, typeName string) (types.Object, error) {
- if pkgName == "" {
- return nil, nil
- }
- fullName := typeName
- if pkgName != "" {
- fullName = pkgName + "." + typeName
- }
-
- pkgName, err := resolvePkg(pkgName)
- if err != nil {
- return nil, errors.Errorf("unable to resolve package for %s: %s\n", fullName, err.Error())
- }
-
- pkg := prog.Imported[pkgName]
- if pkg == nil {
- return nil, errors.Errorf("required package was not loaded: %s", fullName)
- }
-
- for astNode, def := range pkg.Defs {
- if astNode.Name != typeName || def.Parent() == nil || def.Parent() != pkg.Pkg.Scope() {
- continue
- }
-
- return def, nil
- }
-
- return nil, errors.Errorf("unable to find type %s\n", fullName)
-}
-
-func findGoNamedType(prog *loader.Program, pkgName string, typeName string) (*types.Named, error) {
- def, err := findGoType(prog, pkgName, typeName)
- if err != nil {
- return nil, err
- }
+func findGoNamedType(def types.Type) (*types.Named, error) {
if def == nil {
return nil, nil
}
- namedType, ok := def.Type().(*types.Named)
+ namedType, ok := def.(*types.Named)
if !ok {
- return nil, errors.Errorf("expected %s to be a named type, instead found %T\n", typeName, def.Type())
+ return nil, errors.Errorf("expected %s to be a named type, instead found %T\n", def.String(), def)
}
return namedType, nil
}
-func findGoInterface(prog *loader.Program, pkgName string, typeName string) (*types.Interface, error) {
- namedType, err := findGoNamedType(prog, pkgName, typeName)
+func findGoInterface(def types.Type) (*types.Interface, error) {
+ if def == nil {
+ return nil, nil
+ }
+ namedType, err := findGoNamedType(def)
if err != nil {
return nil, err
}
@@ -69,319 +34,14 @@ func findGoInterface(prog *loader.Program, pkgName string, typeName string) (*ty
underlying, ok := namedType.Underlying().(*types.Interface)
if !ok {
- return nil, errors.Errorf("expected %s to be a named interface, instead found %s", typeName, namedType.String())
+ return nil, errors.Errorf("expected %s to be a named interface, instead found %s", def.String(), namedType.String())
}
return underlying, nil
}
-func findMethod(typ *types.Named, name string) *types.Func {
- for i := 0; i < typ.NumMethods(); i++ {
- method := typ.Method(i)
- if !method.Exported() {
- continue
- }
-
- if strings.EqualFold(method.Name(), name) {
- return method
- }
- }
-
- if s, ok := typ.Underlying().(*types.Struct); ok {
- for i := 0; i < s.NumFields(); i++ {
- field := s.Field(i)
- if !field.Anonymous() {
- continue
- }
-
- if named, ok := field.Type().(*types.Named); ok {
- if f := findMethod(named, name); f != nil {
- return f
- }
- }
- }
- }
-
- 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
-// 2. Field in an embedded struct
-// 3. Actual Field name
-func findField(typ *types.Struct, name, structTag string) (*types.Var, error) {
- var foundField *types.Var
- foundFieldWasTag := false
-
- for i := 0; i < typ.NumFields(); i++ {
- field := typ.Field(i)
-
- if structTag != "" {
- tags := reflect.StructTag(typ.Tag(i))
- if val, ok := tags.Lookup(structTag); ok {
- 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)
- }
-
- foundField = field
- foundFieldWasTag = true
- }
- }
- }
-
- if field.Anonymous() {
-
- fieldType := field.Type()
-
- if ptr, ok := fieldType.(*types.Pointer); ok {
- fieldType = ptr.Elem()
- }
-
- // 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
- }
- if f != nil && foundField == nil {
- foundField = f
- }
- }
- }
-
- if !field.Exported() {
- continue
- }
-
- if equalFieldName(field.Name(), name) && foundField == nil { // aqui!
- foundField = field
- }
- }
-
- if foundField == nil {
- return nil, fmt.Errorf("no field named %s", name)
- }
-
- return foundField, nil
-}
-
-type BindError struct {
- object *Object
- field *Field
- typ types.Type
- methodErr error
- varErr error
-}
-
-func (b BindError) Error() string {
- return fmt.Sprintf(
- "Unable to bind %s.%s to %s\n %s\n %s",
- b.object.GQLType,
- b.field.GQLName,
- b.typ.String(),
- b.methodErr.Error(),
- b.varErr.Error(),
- )
-}
-
-type BindErrors []BindError
-
-func (b BindErrors) Error() string {
- var errs []string
- for _, err := range b {
- errs = append(errs, err.Error())
- }
- return strings.Join(errs, "\n\n")
-}
-
-func bindObject(t types.Type, object *Object, structTag string) BindErrors {
- var errs BindErrors
- for i := range object.Fields {
- field := &object.Fields[i]
-
- if field.ForceResolver {
- continue
- }
-
- // first try binding to a method
- methodErr := bindMethod(t, field)
- if methodErr == nil {
- continue
- }
-
- // otherwise try binding to a var
- varErr := bindVar(t, field, structTag)
-
- if varErr != nil {
- errs = append(errs, BindError{
- object: object,
- typ: t,
- field: field,
- varErr: varErr,
- methodErr: methodErr,
- })
- }
- }
- return errs
-}
-
-func bindMethod(t types.Type, field *Field) error {
- namedType, ok := t.(*types.Named)
- if !ok {
- return fmt.Errorf("not a named type")
- }
-
- goName := field.GQLName
- if field.GoFieldName != "" {
- goName = field.GoFieldName
- }
- method := findMethod(namedType, goName)
- if method == nil {
- return fmt.Errorf("no method named %s", field.GQLName)
- }
- sig := method.Type().(*types.Signature)
-
- if sig.Results().Len() == 1 {
- field.NoErr = true
- } else if sig.Results().Len() != 2 {
- return fmt.Errorf("method has wrong number of args")
- }
- 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(field, result.Type()); err != nil {
- return errors.Wrap(err, "method has wrong return type")
- }
-
- // success, args and return type match. Bind to method
- field.GoFieldType = GoFieldMethod
- field.GoReceiverName = "obj"
- field.GoFieldName = method.Name()
- field.Args = newArgs
- return nil
-}
-
-func bindVar(t types.Type, field *Field, structTag string) error {
- underlying, ok := t.Underlying().(*types.Struct)
- if !ok {
- return fmt.Errorf("not a struct")
- }
-
- goName := field.GQLName
- if field.GoFieldName != "" {
- goName = field.GoFieldName
- }
- structField, err := findField(underlying, goName, structTag)
- if err != nil {
- return err
- }
-
- if err := validateTypeBinding(field, structField.Type()); err != nil {
- return errors.Wrap(err, "field has wrong type")
- }
-
- // success, bind to var
- field.GoFieldType = GoFieldVariable
- field.GoReceiverName = "obj"
- field.GoFieldName = structField.Name()
- return nil
-}
-
-func matchArgs(field *Field, params *types.Tuple) ([]FieldArgument, error) {
- var newArgs []FieldArgument
-
-nextArg:
- for j := 0; j < params.Len(); j++ {
- param := params.At(j)
- for _, oldArg := range field.Args {
- if strings.EqualFold(oldArg.GQLName, param.Name()) {
- if !field.ForceResolver {
- oldArg.Type.Modifiers = modifiersFromGoType(param.Type())
- }
- newArgs = append(newArgs, oldArg)
- continue nextArg
- }
- }
-
- // no matching arg found, abort
- return nil, fmt.Errorf("arg %s not found on method", param.Name())
- }
- return newArgs, nil
-}
-
-func validateTypeBinding(field *Field, goType types.Type) error {
- gqlType := normalizeVendor(field.Type.FullSignature())
- goTypeStr := normalizeVendor(goType.String())
-
- if equalTypes(goTypeStr, gqlType) {
- field.Type.Modifiers = modifiersFromGoType(goType)
- return nil
- }
-
- // deal with type aliases
- underlyingStr := normalizeVendor(goType.Underlying().String())
- if equalTypes(underlyingStr, gqlType) {
- field.Type.Modifiers = modifiersFromGoType(goType)
- pkg, typ := pkgAndType(goType.String())
- field.AliasedType = &Ref{GoType: typ, Package: pkg}
- return nil
- }
-
- return fmt.Errorf("%s is not compatible with %s", gqlType, goTypeStr)
-}
-
-func modifiersFromGoType(t types.Type) []string {
- var modifiers []string
- for {
- switch val := t.(type) {
- case *types.Pointer:
- modifiers = append(modifiers, modPtr)
- t = val.Elem()
- case *types.Array:
- modifiers = append(modifiers, modList)
- t = val.Elem()
- case *types.Slice:
- modifiers = append(modifiers, modList)
- t = val.Elem()
- default:
- return modifiers
- }
- }
-}
-
-var modsRegex = regexp.MustCompile(`^(\*|\[\])*`)
-
-func normalizeVendor(pkg string) string {
- modifiers := modsRegex.FindAllString(pkg, 1)[0]
- pkg = strings.TrimPrefix(pkg, modifiers)
- 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/docs/content/_introduction.md b/vendor/github.com/99designs/gqlgen/docs/content/_introduction.md
new file mode 120000
index 00000000..fe840054
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/docs/content/_introduction.md
@@ -0,0 +1 @@
+../../README.md \ No newline at end of file
diff --git a/vendor/github.com/99designs/gqlgen/graphql/bool.go b/vendor/github.com/99designs/gqlgen/graphql/bool.go
index 7053bbca..b175ca98 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/bool.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/bool.go
@@ -19,7 +19,7 @@ func MarshalBoolean(b bool) Marshaler {
func UnmarshalBoolean(v interface{}) (bool, error) {
switch v := v.(type) {
case string:
- return "true" == strings.ToLower(v), nil
+ return strings.ToLower(v) == "true", nil
case int:
return v != 0, nil
case bool:
diff --git a/vendor/github.com/99designs/gqlgen/graphql/context.go b/vendor/github.com/99designs/gqlgen/graphql/context.go
index f83fa36f..58d3c741 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/context.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/context.go
@@ -12,6 +12,7 @@ import (
type Resolver func(ctx context.Context) (res interface{}, err error)
type FieldMiddleware func(ctx context.Context, next Resolver) (res interface{}, err error)
type RequestMiddleware func(ctx context.Context, next func(ctx context.Context) []byte) []byte
+type ComplexityLimitFunc func(ctx context.Context) int
type RequestContext struct {
RawQuery string
@@ -71,12 +72,10 @@ const (
)
func GetRequestContext(ctx context.Context) *RequestContext {
- val := ctx.Value(request)
- if val == nil {
- return nil
+ if val, ok := ctx.Value(request).(*RequestContext); ok {
+ return val
}
-
- return val.(*RequestContext)
+ return nil
}
func WithRequestContext(ctx context.Context, rc *RequestContext) context.Context {
@@ -95,6 +94,8 @@ type ResolverContext struct {
Index *int
// The result object of resolver
Result interface{}
+ // IsMethod indicates if the resolver is a method
+ IsMethod bool
}
func (r *ResolverContext) Path() []interface{} {
@@ -117,8 +118,10 @@ func (r *ResolverContext) Path() []interface{} {
}
func GetResolverContext(ctx context.Context) *ResolverContext {
- val, _ := ctx.Value(resolver).(*ResolverContext)
- return val
+ if val, ok := ctx.Value(resolver).(*ResolverContext); ok {
+ return val
+ }
+ return nil
}
func WithResolverContext(ctx context.Context, rc *ResolverContext) context.Context {
@@ -132,6 +135,24 @@ func CollectFieldsCtx(ctx context.Context, satisfies []string) []CollectedField
return CollectFields(ctx, resctx.Field.Selections, satisfies)
}
+// CollectAllFields returns a slice of all GraphQL field names that were selected for the current resolver context.
+// The slice will contain the unique set of all field names requested regardless of fragment type conditions.
+func CollectAllFields(ctx context.Context) []string {
+ resctx := GetResolverContext(ctx)
+ collected := CollectFields(ctx, resctx.Field.Selections, nil)
+ uniq := make([]string, 0, len(collected))
+Next:
+ for _, f := range collected {
+ for _, name := range uniq {
+ if name == f.Name {
+ continue Next
+ }
+ }
+ uniq = append(uniq, f.Name)
+ }
+ return uniq
+}
+
// Errorf sends an error string to the client, passing it through the formatter.
func (c *RequestContext) Errorf(ctx context.Context, format string, args ...interface{}) {
c.errorsMu.Lock()
@@ -217,3 +238,37 @@ func (c *RequestContext) RegisterExtension(key string, value interface{}) error
c.Extensions[key] = value
return nil
}
+
+// ChainFieldMiddleware add chain by FieldMiddleware
+func ChainFieldMiddleware(handleFunc ...FieldMiddleware) FieldMiddleware {
+ n := len(handleFunc)
+
+ if n > 1 {
+ lastI := n - 1
+ return func(ctx context.Context, next Resolver) (interface{}, error) {
+ var (
+ chainHandler Resolver
+ curI int
+ )
+ chainHandler = func(currentCtx context.Context) (interface{}, error) {
+ if curI == lastI {
+ return next(currentCtx)
+ }
+ curI++
+ res, err := handleFunc[curI](currentCtx, chainHandler)
+ curI--
+ return res, err
+
+ }
+ return handleFunc[0](ctx, chainHandler)
+ }
+ }
+
+ if n == 1 {
+ return handleFunc[0]
+ }
+
+ return func(ctx context.Context, next Resolver) (interface{}, error) {
+ return next(ctx)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/error.go b/vendor/github.com/99designs/gqlgen/graphql/error.go
index 7f161a43..af8b4ce4 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/error.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/error.go
@@ -14,7 +14,9 @@ type ExtendedError interface {
func DefaultErrorPresenter(ctx context.Context, err error) *gqlerror.Error {
if gqlerr, ok := err.(*gqlerror.Error); ok {
- gqlerr.Path = GetResolverContext(ctx).Path()
+ if gqlerr.Path == nil {
+ gqlerr.Path = GetResolverContext(ctx).Path()
+ }
return gqlerr
}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/exec.go b/vendor/github.com/99designs/gqlgen/graphql/exec.go
index 9beb3149..17c57bf6 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/exec.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/exec.go
@@ -16,6 +16,9 @@ type ExecutableSchema interface {
Subscription(ctx context.Context, op *ast.OperationDefinition) func() *Response
}
+// CollectFields returns the set of fields from an ast.SelectionSet where all collected fields satisfy at least one of the GraphQL types
+// passed through satisfies. Providing an empty or nil slice for satisfies will return collect all fields regardless of fragment
+// type conditions.
func CollectFields(ctx context.Context, selSet ast.SelectionSet, satisfies []string) []CollectedField {
return collectFields(GetRequestContext(ctx), selSet, satisfies, map[string]bool{})
}
@@ -35,7 +38,10 @@ func collectFields(reqCtx *RequestContext, selSet ast.SelectionSet, satisfies []
f.Selections = append(f.Selections, sel.SelectionSet...)
case *ast.InlineFragment:
- if !shouldIncludeNode(sel.Directives, reqCtx.Variables) || !instanceOf(sel.TypeCondition, satisfies) {
+ if !shouldIncludeNode(sel.Directives, reqCtx.Variables) {
+ continue
+ }
+ if len(satisfies) > 0 && !instanceOf(sel.TypeCondition, satisfies) {
continue
}
for _, childField := range collectFields(reqCtx, sel.SelectionSet, satisfies, visited) {
@@ -59,7 +65,7 @@ func collectFields(reqCtx *RequestContext, selSet ast.SelectionSet, satisfies []
panic(fmt.Errorf("missing fragment %s", fragmentName))
}
- if !instanceOf(fragment.TypeCondition, satisfies) {
+ if len(satisfies) > 0 && !instanceOf(fragment.TypeCondition, satisfies) {
continue
}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/fieldset.go b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go
new file mode 100644
index 00000000..351e266f
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/fieldset.go
@@ -0,0 +1,63 @@
+package graphql
+
+import (
+ "io"
+ "sync"
+)
+
+type FieldSet struct {
+ fields []CollectedField
+ Values []Marshaler
+ delayed []delayedResult
+}
+
+type delayedResult struct {
+ i int
+ f func() Marshaler
+}
+
+func NewFieldSet(fields []CollectedField) *FieldSet {
+ return &FieldSet{
+ fields: fields,
+ Values: make([]Marshaler, len(fields)),
+ }
+}
+
+func (m *FieldSet) Concurrently(i int, f func() Marshaler) {
+ m.delayed = append(m.delayed, delayedResult{i: i, f: f})
+}
+
+func (m *FieldSet) Dispatch() {
+ if len(m.delayed) == 1 {
+ // only one concurrent task, no need to spawn a goroutine or deal create waitgroups
+ d := m.delayed[0]
+ m.Values[d.i] = d.f()
+ } else if len(m.delayed) > 1 {
+ // more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others
+
+ var wg sync.WaitGroup
+ for _, d := range m.delayed[1:] {
+ wg.Add(1)
+ go func(d delayedResult) {
+ m.Values[d.i] = d.f()
+ wg.Done()
+ }(d)
+ }
+
+ m.Values[m.delayed[0].i] = m.delayed[0].f()
+ wg.Wait()
+ }
+}
+
+func (m *FieldSet) MarshalGQL(writer io.Writer) {
+ writer.Write(openBrace)
+ for i, field := range m.fields {
+ if i != 0 {
+ writer.Write(comma)
+ }
+ writeQuotedString(writer, field.Alias)
+ writer.Write(colon)
+ m.Values[i].MarshalGQL(writer)
+ }
+ writer.Write(closeBrace)
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go
index a5a7960f..4f532037 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/id.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/id.go
@@ -34,3 +34,24 @@ func UnmarshalID(v interface{}) (string, error) {
return "", fmt.Errorf("%T is not a string", v)
}
}
+
+func MarshalIntID(i int) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ writeQuotedString(w, strconv.Itoa(i))
+ })
+}
+
+func UnmarshalIntID(v interface{}) (int, error) {
+ switch v := v.(type) {
+ case string:
+ return strconv.Atoi(v)
+ case int:
+ return v, nil
+ case int64:
+ return int(v), nil
+ case json.Number:
+ return strconv.Atoi(string(v))
+ default:
+ return 0, fmt.Errorf("%T is not an int", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/int.go b/vendor/github.com/99designs/gqlgen/graphql/int.go
index ff87574c..57d0d589 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/int.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/int.go
@@ -27,3 +27,53 @@ func UnmarshalInt(v interface{}) (int, error) {
return 0, fmt.Errorf("%T is not an int", v)
}
}
+
+func MarshalInt64(i int64) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, strconv.FormatInt(i, 10))
+ })
+}
+
+func UnmarshalInt64(v interface{}) (int64, error) {
+ switch v := v.(type) {
+ case string:
+ return strconv.ParseInt(v, 10, 64)
+ case int:
+ return int64(v), nil
+ case int64:
+ return v, nil
+ case json.Number:
+ return strconv.ParseInt(string(v), 10, 64)
+ default:
+ return 0, fmt.Errorf("%T is not an int", v)
+ }
+}
+
+func MarshalInt32(i int32) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ io.WriteString(w, strconv.FormatInt(int64(i), 10))
+ })
+}
+
+func UnmarshalInt32(v interface{}) (int32, error) {
+ switch v := v.(type) {
+ case string:
+ iv, err := strconv.ParseInt(v, 10, 32)
+ if err != nil {
+ return 0, err
+ }
+ return int32(iv), nil
+ case int:
+ return int32(v), nil
+ case int64:
+ return int32(v), nil
+ case json.Number:
+ iv, err := strconv.ParseInt(string(v), 10, 32)
+ if err != nil {
+ return 0, err
+ }
+ return int32(iv), nil
+ default:
+ return 0, fmt.Errorf("%T is not an int", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
index b963aa0e..f1228edf 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/introspection/type.go
@@ -62,9 +62,9 @@ func (t *Type) Description() string {
func (t *Type) Fields(includeDeprecated bool) []Field {
if t.def == nil || (t.def.Kind != ast.Object && t.def.Kind != ast.Interface) {
- return nil
+ return []Field{}
}
- var fields []Field
+ fields := []Field{}
for _, f := range t.def.Fields {
if strings.HasPrefix(f.Name, "__") {
continue
@@ -93,10 +93,10 @@ func (t *Type) Fields(includeDeprecated bool) []Field {
func (t *Type) InputFields() []InputValue {
if t.def == nil || t.def.Kind != ast.InputObject {
- return nil
+ return []InputValue{}
}
- var res []InputValue
+ res := []InputValue{}
for _, f := range t.def.Fields {
res = append(res, InputValue{
Name: f.Name,
@@ -118,10 +118,10 @@ func defaultValue(value *ast.Value) *string {
func (t *Type) Interfaces() []Type {
if t.def == nil || t.def.Kind != ast.Object {
- return nil
+ return []Type{}
}
- var res []Type
+ res := []Type{}
for _, intf := range t.def.Interfaces {
res = append(res, *WrapTypeFromDef(t.schema, t.schema.Types[intf]))
}
@@ -131,10 +131,10 @@ func (t *Type) Interfaces() []Type {
func (t *Type) PossibleTypes() []Type {
if t.def == nil || (t.def.Kind != ast.Interface && t.def.Kind != ast.Union) {
- return nil
+ return []Type{}
}
- var res []Type
+ res := []Type{}
for _, pt := range t.schema.GetPossibleTypes(t.def) {
res = append(res, *WrapTypeFromDef(t.schema, pt))
}
@@ -143,10 +143,10 @@ func (t *Type) PossibleTypes() []Type {
func (t *Type) EnumValues(includeDeprecated bool) []EnumValue {
if t.def == nil || t.def.Kind != ast.Enum {
- return nil
+ return []EnumValue{}
}
- var res []EnumValue
+ res := []EnumValue{}
for _, val := range t.def.EnumValues {
res = append(res, EnumValue{
Name: val.Name,
diff --git a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go
index c112444a..db95d8e4 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/jsonw.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/jsonw.go
@@ -2,7 +2,6 @@ package graphql
import (
"io"
- "strconv"
)
var nullLit = []byte(`null`)
@@ -27,42 +26,12 @@ type Unmarshaler interface {
UnmarshalGQL(v interface{}) error
}
-type OrderedMap struct {
- Keys []string
- Values []Marshaler
-}
-
type WriterFunc func(writer io.Writer)
func (f WriterFunc) MarshalGQL(w io.Writer) {
f(w)
}
-func NewOrderedMap(len int) *OrderedMap {
- return &OrderedMap{
- Keys: make([]string, len),
- Values: make([]Marshaler, len),
- }
-}
-
-func (m *OrderedMap) Add(key string, value Marshaler) {
- m.Keys = append(m.Keys, key)
- m.Values = append(m.Values, value)
-}
-
-func (m *OrderedMap) MarshalGQL(writer io.Writer) {
- writer.Write(openBrace)
- for i, key := range m.Keys {
- if i != 0 {
- writer.Write(comma)
- }
- io.WriteString(writer, strconv.Quote(key))
- writer.Write(colon)
- m.Values[i].MarshalGQL(writer)
- }
- writer.Write(closeBrace)
-}
-
type Array []Marshaler
func (a Array) MarshalGQL(writer io.Writer) {
diff --git a/vendor/github.com/99designs/gqlgen/graphql/root.go b/vendor/github.com/99designs/gqlgen/graphql/root.go
new file mode 100644
index 00000000..3405d180
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/graphql/root.go
@@ -0,0 +1,7 @@
+package graphql
+
+type Query struct{}
+
+type Mutation struct{}
+
+type Subscription struct{}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/string.go b/vendor/github.com/99designs/gqlgen/graphql/string.go
index d5fb3294..7c1b7d95 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/string.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/string.go
@@ -10,37 +10,42 @@ const encodeHex = "0123456789ABCDEF"
func MarshalString(s string) Marshaler {
return WriterFunc(func(w io.Writer) {
- start := 0
- io.WriteString(w, `"`)
-
- for i, c := range s {
- if c < 0x20 || c == '\\' || c == '"' {
- io.WriteString(w, s[start:i])
-
- switch c {
- case '\t':
- io.WriteString(w, `\t`)
- case '\r':
- io.WriteString(w, `\r`)
- case '\n':
- io.WriteString(w, `\n`)
- case '\\':
- io.WriteString(w, `\\`)
- case '"':
- io.WriteString(w, `\"`)
- default:
- io.WriteString(w, `\u00`)
- w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
- }
-
- start = i + 1
+ writeQuotedString(w, s)
+ })
+}
+
+func writeQuotedString(w io.Writer, s string) {
+ start := 0
+ io.WriteString(w, `"`)
+
+ for i, c := range s {
+ if c < 0x20 || c == '\\' || c == '"' {
+ io.WriteString(w, s[start:i])
+
+ switch c {
+ case '\t':
+ io.WriteString(w, `\t`)
+ case '\r':
+ io.WriteString(w, `\r`)
+ case '\n':
+ io.WriteString(w, `\n`)
+ case '\\':
+ io.WriteString(w, `\\`)
+ case '"':
+ io.WriteString(w, `\"`)
+ default:
+ io.WriteString(w, `\u00`)
+ w.Write([]byte{encodeHex[c>>4], encodeHex[c&0xf]})
}
+
+ start = i + 1
}
+ }
- io.WriteString(w, s[start:])
- io.WriteString(w, `"`)
- })
+ io.WriteString(w, s[start:])
+ io.WriteString(w, `"`)
}
+
func UnmarshalString(v interface{}) (string, error) {
switch v := v.(type) {
case string:
diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go
index 490ff3ff..88014abf 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.7.2"
+const Version = "v0.8.3"
diff --git a/vendor/github.com/99designs/gqlgen/handler/graphql.go b/vendor/github.com/99designs/gqlgen/handler/graphql.go
index 7c5f70cf..92a0471c 100644
--- a/vendor/github.com/99designs/gqlgen/handler/graphql.go
+++ b/vendor/github.com/99designs/gqlgen/handler/graphql.go
@@ -34,6 +34,7 @@ type Config struct {
requestHook graphql.RequestMiddleware
tracer graphql.Tracer
complexityLimit int
+ complexityLimitFunc graphql.ComplexityLimitFunc
disableIntrospection bool
connectionKeepAlivePingInterval time.Duration
}
@@ -60,11 +61,9 @@ func (c *Config) newRequestContext(es graphql.ExecutableSchema, doc *ast.QueryDo
if hook := c.tracer; hook != nil {
reqCtx.Tracer = hook
- } else {
- reqCtx.Tracer = &graphql.NopTracer{}
}
- if c.complexityLimit > 0 {
+ if c.complexityLimit > 0 || c.complexityLimitFunc != nil {
reqCtx.ComplexityLimit = c.complexityLimit
operationComplexity := complexity.Calculate(es, op, variables)
reqCtx.OperationComplexity = operationComplexity
@@ -112,6 +111,15 @@ func ComplexityLimit(limit int) Option {
}
}
+// ComplexityLimitFunc allows you to define a function to dynamically set the 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 ComplexityLimitFunc(complexityLimitFunc graphql.ComplexityLimitFunc) Option {
+ return func(cfg *Config) {
+ cfg.complexityLimitFunc = complexityLimitFunc
+ }
+}
+
// ResolverMiddleware allows you to define a function that will be called around every resolver,
// useful for logging.
func ResolverMiddleware(middleware graphql.FieldMiddleware) Option {
@@ -243,19 +251,23 @@ func CacheSize(size int) Option {
}
}
-const DefaultCacheSize = 1000
-
-// WebsocketKeepAliveDuration allows you to reconfigure the keepAlive behavior.
-// By default, keep-alive is disabled.
+// WebsocketKeepAliveDuration allows you to reconfigure the keepalive behavior.
+// By default, keepalive is enabled with a DefaultConnectionKeepAlivePingInterval
+// duration. Set handler.connectionKeepAlivePingInterval = 0 to disable keepalive
+// altogether.
func WebsocketKeepAliveDuration(duration time.Duration) Option {
return func(cfg *Config) {
cfg.connectionKeepAlivePingInterval = duration
}
}
+const DefaultCacheSize = 1000
+const DefaultConnectionKeepAlivePingInterval = 25 * time.Second
+
func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc {
cfg := &Config{
- cacheSize: DefaultCacheSize,
+ cacheSize: DefaultCacheSize,
+ connectionKeepAlivePingInterval: DefaultConnectionKeepAlivePingInterval,
upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
@@ -269,7 +281,7 @@ func GraphQL(exec graphql.ExecutableSchema, options ...Option) http.HandlerFunc
var cache *lru.Cache
if cfg.cacheSize > 0 {
var err error
- cache, err = lru.New(DefaultCacheSize)
+ cache, err = lru.New(cfg.cacheSize)
if err != nil {
// An error is only returned for non-positive cache size
// and we already checked for that.
@@ -305,10 +317,11 @@ func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
if strings.Contains(r.Header.Get("Upgrade"), "websocket") {
- connectWs(gh.exec, w, r, gh.cfg)
+ connectWs(gh.exec, w, r, gh.cfg, gh.cache)
return
}
+ w.Header().Set("Content-Type", "application/json")
var reqParams params
switch r.Method {
case http.MethodGet:
@@ -330,7 +343,6 @@ func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
- w.Header().Set("Content-Type", "application/json")
ctx := r.Context()
@@ -379,6 +391,10 @@ func (gh *graphqlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}()
+ if gh.cfg.complexityLimitFunc != nil {
+ reqCtx.ComplexityLimit = gh.cfg.complexityLimitFunc(ctx)
+ }
+
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
diff --git a/vendor/github.com/99designs/gqlgen/handler/playground.go b/vendor/github.com/99designs/gqlgen/handler/playground.go
index f1687def..0e1ca768 100644
--- a/vendor/github.com/99designs/gqlgen/handler/playground.go
+++ b/vendor/github.com/99designs/gqlgen/handler/playground.go
@@ -11,9 +11,12 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
<meta charset=utf-8/>
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<link rel="shortcut icon" href="https://graphcool-playground.netlify.com/favicon.png">
- <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/css/index.css"/>
- <link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/favicon.png"/>
- <script src="//cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/js/middleware.js"></script>
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/css/index.css"
+ integrity="{{ .cssSRI }}" crossorigin="anonymous"/>
+ <link rel="shortcut icon" href="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/favicon.png"
+ integrity="{{ .faviconSRI }}" crossorigin="anonymous"/>
+ <script src="https://cdn.jsdelivr.net/npm/graphql-playground-react@{{ .version }}/build/static/js/middleware.js"
+ integrity="{{ .jsSRI }}" crossorigin="anonymous"></script>
<title>{{.title}}</title>
</head>
<body>
@@ -42,10 +45,14 @@ var page = template.Must(template.New("graphiql").Parse(`<!DOCTYPE html>
func Playground(title string, endpoint string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
+ w.Header().Add("Content-Type", "text/html")
err := page.Execute(w, map[string]string{
- "title": title,
- "endpoint": endpoint,
- "version": "1.7.8",
+ "title": title,
+ "endpoint": endpoint,
+ "version": "1.7.20",
+ "cssSRI": "sha256-cS9Vc2OBt9eUf4sykRWukeFYaInL29+myBmFDSa7F/U=",
+ "faviconSRI": "sha256-GhTyE+McTU79R4+pRO6ih+4TfsTOrpPwD8ReKFzb3PM=",
+ "jsSRI": "sha256-4QG1Uza2GgGdlBL3RCBCGtGeZB6bDbsw8OltCMGeJsA=",
})
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 09800c17..58f38e5d 100644
--- a/vendor/github.com/99designs/gqlgen/handler/websocket.go
+++ b/vendor/github.com/99designs/gqlgen/handler/websocket.go
@@ -12,6 +12,7 @@ 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"
@@ -44,12 +45,13 @@ type wsConnection struct {
active map[string]context.CancelFunc
mu sync.Mutex
cfg *Config
+ cache *lru.Cache
keepAliveTicker *time.Ticker
initPayload InitPayload
}
-func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Request, cfg *Config) {
+func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Request, cfg *Config, cache *lru.Cache) {
ws, err := cfg.upgrader.Upgrade(w, r, http.Header{
"Sec-Websocket-Protocol": []string{"graphql-ws"},
})
@@ -65,6 +67,7 @@ func connectWs(exec graphql.ExecutableSchema, w http.ResponseWriter, r *http.Req
conn: ws,
ctx: r.Context(),
cfg: cfg,
+ cache: cache,
}
if !conn.init() {
@@ -176,10 +179,27 @@ func (c *wsConnection) subscribe(message *operationMessage) bool {
return false
}
- doc, qErr := gqlparser.LoadQuery(c.exec.Schema(), reqParams.Query)
- if qErr != nil {
- c.sendError(message.ID, qErr...)
- return true
+ var (
+ doc *ast.QueryDocument
+ cacheHit bool
+ )
+ if c.cache != nil {
+ val, ok := c.cache.Get(reqParams.Query)
+ if ok {
+ doc = val.(*ast.QueryDocument)
+ cacheHit = true
+ }
+ }
+ if !cacheHit {
+ var qErr gqlerror.List
+ doc, qErr = gqlparser.LoadQuery(c.exec.Schema(), reqParams.Query)
+ if qErr != nil {
+ c.sendError(message.ID, qErr...)
+ return true
+ }
+ if c.cache != nil {
+ c.cache.Add(reqParams.Query, doc)
+ }
}
op := doc.Operations.ForName(reqParams.OperationName)
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/compare.go b/vendor/github.com/99designs/gqlgen/internal/code/compare.go
new file mode 100644
index 00000000..dce9aea5
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/compare.go
@@ -0,0 +1,163 @@
+package code
+
+import (
+ "fmt"
+ "go/types"
+)
+
+// CompatibleTypes isnt a strict comparison, it allows for pointer differences
+func CompatibleTypes(expected types.Type, actual types.Type) error {
+ //fmt.Println("Comparing ", expected.String(), actual.String())
+
+ // Special case to deal with pointer mismatches
+ {
+ expectedPtr, expectedIsPtr := expected.(*types.Pointer)
+ actualPtr, actualIsPtr := actual.(*types.Pointer)
+
+ if expectedIsPtr && actualIsPtr {
+ return CompatibleTypes(expectedPtr.Elem(), actualPtr.Elem())
+ }
+ if expectedIsPtr && !actualIsPtr {
+ return CompatibleTypes(expectedPtr.Elem(), actual)
+ }
+ if !expectedIsPtr && actualIsPtr {
+ return CompatibleTypes(expected, actualPtr.Elem())
+ }
+ }
+
+ switch expected := expected.(type) {
+ case *types.Slice:
+ if actual, ok := actual.(*types.Slice); ok {
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Array:
+ if actual, ok := actual.(*types.Array); ok {
+ if expected.Len() != actual.Len() {
+ return fmt.Errorf("array length differs")
+ }
+
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Basic:
+ if actual, ok := actual.(*types.Basic); ok {
+ if actual.Kind() != expected.Kind() {
+ return fmt.Errorf("basic kind differs, %s != %s", expected.Name(), actual.Name())
+ }
+
+ return nil
+ }
+
+ case *types.Struct:
+ if actual, ok := actual.(*types.Struct); ok {
+ if expected.NumFields() != actual.NumFields() {
+ return fmt.Errorf("number of struct fields differ")
+ }
+
+ for i := 0; i < expected.NumFields(); i++ {
+ if expected.Field(i).Name() != actual.Field(i).Name() {
+ return fmt.Errorf("struct field %d name differs, %s != %s", i, expected.Field(i).Name(), actual.Field(i).Name())
+ }
+ if err := CompatibleTypes(expected.Field(i).Type(), actual.Field(i).Type()); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ case *types.Tuple:
+ if actual, ok := actual.(*types.Tuple); ok {
+ if expected.Len() != actual.Len() {
+ return fmt.Errorf("tuple length differs, %d != %d", expected.Len(), actual.Len())
+ }
+
+ for i := 0; i < expected.Len(); i++ {
+ if err := CompatibleTypes(expected.At(i).Type(), actual.At(i).Type()); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ }
+
+ case *types.Signature:
+ if actual, ok := actual.(*types.Signature); ok {
+ if err := CompatibleTypes(expected.Params(), actual.Params()); err != nil {
+ return err
+ }
+ if err := CompatibleTypes(expected.Results(), actual.Results()); err != nil {
+ return err
+ }
+
+ return nil
+ }
+ case *types.Interface:
+ if actual, ok := actual.(*types.Interface); ok {
+ if expected.NumMethods() != actual.NumMethods() {
+ return fmt.Errorf("interface method count differs, %d != %d", expected.NumMethods(), actual.NumMethods())
+ }
+
+ for i := 0; i < expected.NumMethods(); i++ {
+ if expected.Method(i).Name() != actual.Method(i).Name() {
+ return fmt.Errorf("interface method %d name differs, %s != %s", i, expected.Method(i).Name(), actual.Method(i).Name())
+ }
+ if err := CompatibleTypes(expected.Method(i).Type(), actual.Method(i).Type()); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ }
+
+ case *types.Map:
+ if actual, ok := actual.(*types.Map); ok {
+ if err := CompatibleTypes(expected.Key(), actual.Key()); err != nil {
+ return err
+ }
+
+ if err := CompatibleTypes(expected.Elem(), actual.Elem()); err != nil {
+ return err
+ }
+
+ return nil
+ }
+
+ case *types.Chan:
+ if actual, ok := actual.(*types.Chan); ok {
+ return CompatibleTypes(expected.Elem(), actual.Elem())
+ }
+
+ case *types.Named:
+ if actual, ok := actual.(*types.Named); ok {
+ if NormalizeVendor(expected.Obj().Pkg().Path()) != NormalizeVendor(actual.Obj().Pkg().Path()) {
+ return fmt.Errorf(
+ "package name of named type differs, %s != %s",
+ NormalizeVendor(expected.Obj().Pkg().Path()),
+ NormalizeVendor(actual.Obj().Pkg().Path()),
+ )
+ }
+
+ if expected.Obj().Name() != actual.Obj().Name() {
+ return fmt.Errorf(
+ "named type name differs, %s != %s",
+ NormalizeVendor(expected.Obj().Name()),
+ NormalizeVendor(actual.Obj().Name()),
+ )
+ }
+
+ return nil
+ }
+
+ // Before models are generated all missing references will be Invalid Basic references.
+ // lets assume these are valid too.
+ if actual, ok := actual.(*types.Basic); ok && actual.Kind() == types.Invalid {
+ return nil
+ }
+
+ default:
+ return fmt.Errorf("missing support for %T", expected)
+ }
+
+ return fmt.Errorf("type mismatch %T != %T", expected, actual)
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/imports.go b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
new file mode 100644
index 00000000..2384e87d
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/imports.go
@@ -0,0 +1,60 @@
+package code
+
+import (
+ "errors"
+ "path/filepath"
+ "sync"
+
+ "golang.org/x/tools/go/packages"
+)
+
+var pathForDirCache = sync.Map{}
+
+// ImportPathFromDir takes an *absolute* path and returns a golang import path for the package, and returns an error if it isn't on the gopath
+func ImportPathForDir(dir string) string {
+ if v, ok := pathForDirCache.Load(dir); ok {
+ return v.(string)
+ }
+
+ p, _ := packages.Load(&packages.Config{
+ Dir: dir,
+ }, ".")
+
+ // If the dir dosent exist yet, keep walking up the directory tree trying to find a match
+ if len(p) != 1 {
+ parent, err := filepath.Abs(filepath.Join(dir, ".."))
+ if err != nil {
+ panic(err)
+ }
+ // Walked all the way to the root and didnt find anything :'(
+ if parent == dir {
+ return ""
+ }
+ return ImportPathForDir(parent) + "/" + filepath.Base(dir)
+ }
+
+ pathForDirCache.Store(dir, p[0].PkgPath)
+
+ return p[0].PkgPath
+}
+
+var nameForPackageCache = sync.Map{}
+
+func NameForPackage(importPath string) string {
+ if importPath == "" {
+ panic(errors.New("import path can not be empty"))
+ }
+ if v, ok := nameForPackageCache.Load(importPath); ok {
+ return v.(string)
+ }
+ importPath = QualifyPackagePath(importPath)
+ p, _ := packages.Load(nil, importPath)
+
+ if len(p) != 1 || p[0].Name == "" {
+ return SanitizePackageName(filepath.Base(importPath))
+ }
+
+ nameForPackageCache.Store(importPath, p[0].Name)
+
+ return p[0].Name
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/util.go b/vendor/github.com/99designs/gqlgen/internal/code/util.go
new file mode 100644
index 00000000..2be83a23
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/internal/code/util.go
@@ -0,0 +1,56 @@
+package code
+
+import (
+ "go/build"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+// take a string in the form github.com/package/blah.Type and split it into package and type
+func PkgAndType(name string) (string, string) {
+ parts := strings.Split(name, ".")
+ if len(parts) == 1 {
+ return "", name
+ }
+
+ return strings.Join(parts[:len(parts)-1], "."), parts[len(parts)-1]
+}
+
+var modsRegex = regexp.MustCompile(`^(\*|\[\])*`)
+
+// NormalizeVendor takes a qualified package path and turns it into normal one.
+// eg .
+// github.com/foo/vendor/github.com/99designs/gqlgen/graphql becomes
+// github.com/99designs/gqlgen/graphql
+func NormalizeVendor(pkg string) string {
+ modifiers := modsRegex.FindAllString(pkg, 1)[0]
+ pkg = strings.TrimPrefix(pkg, modifiers)
+ parts := strings.Split(pkg, "/vendor/")
+ return modifiers + parts[len(parts)-1]
+}
+
+// QualifyPackagePath takes an import and fully qualifies it with a vendor dir, if one is required.
+// eg .
+// github.com/99designs/gqlgen/graphql becomes
+// github.com/foo/vendor/github.com/99designs/gqlgen/graphql
+//
+// x/tools/packages only supports 'qualified package paths' so this will need to be done prior to calling it
+// See https://github.com/golang/go/issues/30289
+func QualifyPackagePath(importPath string) string {
+ wd, _ := os.Getwd()
+
+ pkg, err := build.Import(importPath, wd, 0)
+ if err != nil {
+ return importPath
+ }
+
+ return pkg.ImportPath
+}
+
+var invalidPackageNameChar = regexp.MustCompile(`[^\w]`)
+
+func SanitizePackageName(pkg string) string {
+ return invalidPackageNameChar.ReplaceAllLiteralString(filepath.Base(pkg), "_")
+}
diff --git a/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go b/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go
deleted file mode 100644
index c9b66167..00000000
--- a/vendor/github.com/99designs/gqlgen/internal/gopath/gopath.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package gopath
-
-import (
- "fmt"
- "go/build"
- "path/filepath"
- "strings"
-)
-
-var NotFound = fmt.Errorf("not on GOPATH")
-
-// Contains returns true if the given directory is in the GOPATH
-func Contains(dir string) bool {
- _, err := Dir2Import(dir)
- return err == nil
-}
-
-// Dir2Import takes an *absolute* path and returns a golang import path for the package, and returns an error if it isn't on the gopath
-func Dir2Import(dir string) (string, error) {
- dir = filepath.ToSlash(dir)
- for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
- gopath = filepath.ToSlash(filepath.Join(gopath, "src"))
- if len(gopath) < len(dir) && strings.EqualFold(gopath, dir[0:len(gopath)]) {
- return dir[len(gopath)+1:], nil
- }
- }
- return "", NotFound
-}
-
-// MustDir2Import takes an *absolute* path and returns a golang import path for the package, and panics if it isn't on the gopath
-func MustDir2Import(dir string) string {
- pkg, err := Dir2Import(dir)
- if err != nil {
- panic(err)
- }
- return pkg
-}
diff --git a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
index d2469e83..d678870e 100644
--- a/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
+++ b/vendor/github.com/99designs/gqlgen/internal/imports/prune.go
@@ -5,16 +5,15 @@ package imports
import (
"bytes"
"go/ast"
- "go/build"
"go/parser"
"go/printer"
"go/token"
- "path/filepath"
"strings"
- "golang.org/x/tools/imports"
+ "github.com/99designs/gqlgen/internal/code"
"golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/imports"
)
type visitFn func(node ast.Node)
@@ -54,12 +53,6 @@ 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
@@ -75,7 +68,7 @@ func getUnusedImports(file ast.Node, filename string) (map[string]string, error)
break
}
- local := importPathToName(ipath, srcDir)
+ local := code.NameForPackage(ipath)
imported[local] = v
case *ast.SelectorExpr:
@@ -108,12 +101,3 @@ func getUnusedImports(file ast.Node, filename string) (map[string]string, error)
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
-}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
new file mode 100644
index 00000000..508cc14d
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
@@ -0,0 +1,207 @@
+package modelgen
+
+import (
+ "go/types"
+ "sort"
+
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/99designs/gqlgen/internal/code"
+ "github.com/99designs/gqlgen/plugin"
+ "github.com/vektah/gqlparser/ast"
+)
+
+type ModelBuild struct {
+ PackageName string
+ Interfaces []*Interface
+ Models []*Object
+ Enums []*Enum
+ Scalars []string
+}
+
+type Interface struct {
+ Description string
+ Name string
+}
+
+type Object struct {
+ Description string
+ Name string
+ Fields []*Field
+ Implements []string
+}
+
+type Field struct {
+ Description string
+ Name string
+ Type types.Type
+ Tag string
+}
+
+type Enum struct {
+ Description string
+ Name string
+ Values []*EnumValue
+}
+
+type EnumValue struct {
+ Description string
+ Name string
+}
+
+func New() plugin.Plugin {
+ return &Plugin{}
+}
+
+type Plugin struct{}
+
+var _ plugin.ConfigMutator = &Plugin{}
+
+func (m *Plugin) Name() string {
+ return "modelgen"
+}
+
+func (m *Plugin) MutateConfig(cfg *config.Config) error {
+ if err := cfg.Check(); err != nil {
+ return err
+ }
+
+ schema, _, err := cfg.LoadSchema()
+ if err != nil {
+ return err
+ }
+
+ cfg.InjectBuiltins(schema)
+
+ binder, err := cfg.NewBinder(schema)
+ if err != nil {
+ return err
+ }
+
+ b := &ModelBuild{
+ PackageName: cfg.Model.Package,
+ }
+
+ for _, schemaType := range schema.Types {
+ if cfg.Models.UserDefined(schemaType.Name) {
+ continue
+ }
+
+ switch schemaType.Kind {
+ case ast.Interface, ast.Union:
+ it := &Interface{
+ Description: schemaType.Description,
+ Name: schemaType.Name,
+ }
+
+ b.Interfaces = append(b.Interfaces, it)
+ case ast.Object, ast.InputObject:
+ if schemaType == schema.Query || schemaType == schema.Mutation || schemaType == schema.Subscription {
+ continue
+ }
+ it := &Object{
+ Description: schemaType.Description,
+ Name: schemaType.Name,
+ }
+
+ for _, implementor := range schema.GetImplements(schemaType) {
+ it.Implements = append(it.Implements, implementor.Name)
+ }
+
+ for _, field := range schemaType.Fields {
+ var typ types.Type
+
+ if cfg.Models.UserDefined(field.Type.Name()) {
+ pkg, typeName := code.PkgAndType(cfg.Models[field.Type.Name()].Model[0])
+ typ, err = binder.FindType(pkg, typeName)
+ if err != nil {
+ return err
+ }
+ } else {
+ fieldDef := schema.Types[field.Type.Name()]
+ switch fieldDef.Kind {
+ case ast.Scalar:
+ // no user defined model, referencing a default scalar
+ typ = types.NewNamed(
+ types.NewTypeName(0, cfg.Model.Pkg(), "string", nil),
+ nil,
+ nil,
+ )
+ case ast.Interface, ast.Union:
+ // no user defined model, referencing a generated interface type
+ typ = types.NewNamed(
+ types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
+ types.NewInterfaceType([]*types.Func{}, []types.Type{}),
+ nil,
+ )
+ default:
+ // no user defined model, must reference another generated model
+ typ = types.NewNamed(
+ types.NewTypeName(0, cfg.Model.Pkg(), templates.ToGo(field.Type.Name()), nil),
+ nil,
+ nil,
+ )
+ }
+ }
+
+ name := field.Name
+ if nameOveride := cfg.Models[schemaType.Name].Fields[field.Name].FieldName; nameOveride != "" {
+ name = nameOveride
+ }
+
+ it.Fields = append(it.Fields, &Field{
+ Name: name,
+ Type: binder.CopyModifiersFromAst(field.Type, typ),
+ Description: field.Description,
+ Tag: `json:"` + field.Name + `"`,
+ })
+ }
+
+ b.Models = append(b.Models, it)
+ case ast.Enum:
+ it := &Enum{
+ Name: schemaType.Name,
+ Description: schemaType.Description,
+ }
+
+ for _, v := range schemaType.EnumValues {
+ it.Values = append(it.Values, &EnumValue{
+ Name: v.Name,
+ Description: v.Description,
+ })
+ }
+
+ b.Enums = append(b.Enums, it)
+ case ast.Scalar:
+ b.Scalars = append(b.Scalars, schemaType.Name)
+ }
+ }
+
+ sort.Slice(b.Enums, func(i, j int) bool { return b.Enums[i].Name < b.Enums[j].Name })
+ sort.Slice(b.Models, func(i, j int) bool { return b.Models[i].Name < b.Models[j].Name })
+ sort.Slice(b.Interfaces, func(i, j int) bool { return b.Interfaces[i].Name < b.Interfaces[j].Name })
+
+ for _, it := range b.Enums {
+ cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
+ }
+ for _, it := range b.Models {
+ cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
+ }
+ for _, it := range b.Interfaces {
+ cfg.Models.Add(it.Name, cfg.Model.ImportPath()+"."+templates.ToGo(it.Name))
+ }
+ for _, it := range b.Scalars {
+ cfg.Models.Add(it, "github.com/99designs/gqlgen/graphql.String")
+ }
+
+ if len(b.Models) == 0 && len(b.Enums) == 0 {
+ return nil
+ }
+
+ return templates.Render(templates.Options{
+ PackageName: cfg.Model.Package,
+ Filename: cfg.Model.Filename,
+ Data: b,
+ GeneratedHeader: true,
+ })
+}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
new file mode 100644
index 00000000..d06cf050
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.gotpl
@@ -0,0 +1,85 @@
+{{ 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 := .Interfaces }}
+ {{ with .Description }} {{.|prefixLines "// "}} {{ end }}
+ type {{.Name|go }} interface {
+ Is{{.Name|go }}()
+ }
+{{- end }}
+
+{{ range $model := .Models }}
+ {{with .Description }} {{.|prefixLines "// "}} {{end}}
+ type {{ .Name|go }} struct {
+ {{- range $field := .Fields }}
+ {{- with .Description }}
+ {{.|prefixLines "// "}}
+ {{- end}}
+ {{ $field.Name|go }} {{$field.Type | ref}} `{{$field.Tag}}`
+ {{- end }}
+ }
+
+ {{- range $iface := .Implements }}
+ func ({{ $model.Name|go }}) Is{{ $iface }}() {}
+ {{- end }}
+{{- end}}
+
+{{ range $enum := .Enums }}
+ {{ with .Description|go }} {{.|prefixLines "// "}} {{end}}
+ type {{.Name|go }} string
+ const (
+ {{- range $value := .Values}}
+ {{- with .Description}}
+ {{.|prefixLines "// "}}
+ {{- end}}
+ {{ $enum.Name|go }}{{ .Name|go }} {{$enum.Name|go }} = {{.Name|quote}}
+ {{- end }}
+ )
+
+ var All{{.Name|go }} = []{{ .Name|go }}{
+ {{- range $value := .Values}}
+ {{$enum.Name|go }}{{ .Name|go }},
+ {{- end }}
+ }
+
+ func (e {{.Name|go }}) IsValid() bool {
+ switch e {
+ case {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.Name|go }}{{ $element.Name|go }}{{end}}:
+ return true
+ }
+ return false
+ }
+
+ func (e {{.Name|go }}) String() string {
+ return string(e)
+ }
+
+ func (e *{{.Name|go }}) UnmarshalGQL(v interface{}) error {
+ str, ok := v.(string)
+ if !ok {
+ return fmt.Errorf("enums must be strings")
+ }
+
+ *e = {{ .Name|go }}(str)
+ if !e.IsValid() {
+ return fmt.Errorf("%s is not a valid {{ .Name }}", str)
+ }
+ return nil
+ }
+
+ func (e {{.Name|go }}) MarshalGQL(w io.Writer) {
+ fmt.Fprint(w, strconv.Quote(e.String()))
+ }
+
+{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/plugin.go b/vendor/github.com/99designs/gqlgen/plugin/plugin.go
new file mode 100644
index 00000000..a84bfd32
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/plugin.go
@@ -0,0 +1,20 @@
+// plugin package interfaces are EXPERIMENTAL.
+
+package plugin
+
+import (
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/codegen/config"
+)
+
+type Plugin interface {
+ Name() string
+}
+
+type ConfigMutator interface {
+ MutateConfig(cfg *config.Config) error
+}
+
+type CodeGenerator interface {
+ GenerateCode(cfg *codegen.Data) error
+}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
new file mode 100644
index 00000000..00a6d5c9
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
@@ -0,0 +1,53 @@
+package resolvergen
+
+import (
+ "log"
+ "os"
+
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/99designs/gqlgen/plugin"
+ "github.com/pkg/errors"
+)
+
+func New() plugin.Plugin {
+ return &Plugin{}
+}
+
+type Plugin struct{}
+
+var _ plugin.CodeGenerator = &Plugin{}
+
+func (m *Plugin) Name() string {
+ return "resovlergen"
+}
+func (m *Plugin) GenerateCode(data *codegen.Data) error {
+ if !data.Config.Resolver.IsDefined() {
+ return nil
+ }
+
+ resolverBuild := &ResolverBuild{
+ Data: data,
+ PackageName: data.Config.Resolver.Package,
+ ResolverType: data.Config.Resolver.Type,
+ }
+ filename := data.Config.Resolver.Filename
+
+ if _, err := os.Stat(filename); os.IsNotExist(errors.Cause(err)) {
+ return templates.Render(templates.Options{
+ PackageName: data.Config.Resolver.Package,
+ Filename: data.Config.Resolver.Filename,
+ Data: resolverBuild,
+ })
+ }
+
+ log.Printf("Skipped resolver: %s already exists\n", filename)
+ return nil
+}
+
+type ResolverBuild struct {
+ *codegen.Data
+
+ PackageName string
+ ResolverType string
+}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
new file mode 100644
index 00000000..7d95e690
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.gotpl
@@ -0,0 +1,40 @@
+// THIS CODE IS A STARTING POINT ONLY. IT WILL NOT BE UPDATED WITH SCHEMA CHANGES.
+
+{{ 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 {}
+
+{{ range $object := .Objects -}}
+ {{- if $object.HasResolvers -}}
+ func (r *{{$.ResolverType}}) {{$object.Name}}() {{ $object.ResolverInterface | ref }} {
+ return &{{lcFirst $object.Name}}Resolver{r}
+ }
+ {{ end -}}
+{{ end }}
+
+{{ range $object := .Objects -}}
+ {{- if $object.HasResolvers -}}
+ type {{lcFirst $object.Name}}Resolver struct { *Resolver }
+
+ {{ range $field := $object.Fields -}}
+ {{- if $field.IsResolver -}}
+ func (r *{{lcFirst $object.Name}}Resolver) {{$field.GoFieldName}}{{ $field.ShortResolverDeclaration }} {
+ panic("not implemented")
+ }
+ {{ end -}}
+ {{ end -}}
+ {{ end -}}
+{{ end }}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go
new file mode 100644
index 00000000..22289c02
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.go
@@ -0,0 +1,49 @@
+package servergen
+
+import (
+ "log"
+ "os"
+
+ "github.com/99designs/gqlgen/codegen"
+ "github.com/99designs/gqlgen/codegen/templates"
+ "github.com/99designs/gqlgen/plugin"
+ "github.com/pkg/errors"
+)
+
+func New(filename string) plugin.Plugin {
+ return &Plugin{filename}
+}
+
+type Plugin struct {
+ filename string
+}
+
+var _ plugin.CodeGenerator = &Plugin{}
+
+func (m *Plugin) Name() string {
+ return "servergen"
+}
+func (m *Plugin) GenerateCode(data *codegen.Data) error {
+ serverBuild := &ServerBuild{
+ ExecPackageName: data.Config.Exec.ImportPath(),
+ ResolverPackageName: data.Config.Resolver.ImportPath(),
+ }
+
+ if _, err := os.Stat(m.filename); os.IsNotExist(errors.Cause(err)) {
+ return templates.Render(templates.Options{
+ PackageName: "main",
+ Filename: m.filename,
+ Data: serverBuild,
+ })
+ }
+
+ log.Printf("Skipped server: %s already exists\n", m.filename)
+ return nil
+}
+
+type ServerBuild struct {
+ codegen.Data
+
+ ExecPackageName string
+ ResolverPackageName string
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl
index 38dc0d18..fca71c53 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl
+++ b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl
@@ -1,14 +1,8 @@
-package main
-
-import (
- %%%IMPORTS%%%
-
- {{ reserveImport "context" }}
- {{ reserveImport "log" }}
- {{ reserveImport "net/http" }}
- {{ reserveImport "os" }}
- {{ reserveImport "github.com/99designs/gqlgen/handler" }}
-)
+{{ reserveImport "context" }}
+{{ reserveImport "log" }}
+{{ reserveImport "net/http" }}
+{{ reserveImport "os" }}
+{{ reserveImport "github.com/99designs/gqlgen/handler" }}
const defaultPort = "8080"