diff options
author | Michael Muré <batolettre@gmail.com> | 2018-12-23 17:11:37 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2018-12-23 17:11:37 +0100 |
commit | 1410a1af75b1ab9ea3f980a7e372728f9a123abf (patch) | |
tree | e24db8f84c48b20158b1f1fd6d281d700421279c /vendor/github.com/99designs/gqlgen/codegen | |
parent | 8fc15a032f021c855abf66ed303c003d57c340ea (diff) | |
download | git-bug-1410a1af75b1ab9ea3f980a7e372728f9a123abf.tar.gz |
upgrade gqlgen to v0.7.1
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/codegen')
24 files changed, 483 insertions, 346 deletions
diff --git a/vendor/github.com/99designs/gqlgen/codegen/ambient.go b/vendor/github.com/99designs/gqlgen/codegen/ambient.go new file mode 100644 index 00000000..c9909fcc --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/ambient.go @@ -0,0 +1,10 @@ +package codegen + +import ( + // Import and ignore the ambient imports listed below so dependency managers + // don't prune unused code for us. Both lists should be kept in sync. + _ "github.com/99designs/gqlgen/graphql" + _ "github.com/99designs/gqlgen/graphql/introspection" + _ "github.com/vektah/gqlparser" + _ "github.com/vektah/gqlparser/ast" +) diff --git a/vendor/github.com/99designs/gqlgen/codegen/build.go b/vendor/github.com/99designs/gqlgen/codegen/build.go index 42dedbf8..582689a7 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/build.go @@ -15,25 +15,22 @@ type Build struct { Objects Objects Inputs Objects Interfaces []*Interface - Imports []*Import QueryRoot *Object MutationRoot *Object SubscriptionRoot *Object - SchemaRaw string - SchemaFilename string + SchemaRaw map[string]string + SchemaFilename SchemaFilenames Directives []*Directive } type ModelBuild struct { PackageName string - Imports []*Import Models []Model Enums []Enum } type ResolverBuild struct { PackageName string - Imports []*Import ResolverType string Objects Objects ResolverFound bool @@ -41,7 +38,6 @@ type ResolverBuild struct { type ServerBuild struct { PackageName string - Imports []*Import ExecPackageName string ResolverPackageName string } @@ -50,16 +46,16 @@ type ServerBuild struct { func (cfg *Config) models() (*ModelBuild, error) { namedTypes := cfg.buildNamedTypes() - progLoader := newLoader(namedTypes, true) + progLoader := cfg.newLoaderWithoutErrors() + prog, err := progLoader.Load() if err != nil { return nil, errors.Wrap(err, "loading failed") } - imports := buildImports(namedTypes, cfg.Model.Dir()) - cfg.bindTypes(imports, namedTypes, cfg.Model.Dir(), prog) + cfg.bindTypes(namedTypes, cfg.Model.Dir(), prog) - models, err := cfg.buildModels(namedTypes, prog, imports) + models, err := cfg.buildModels(namedTypes, prog) if err != nil { return nil, err } @@ -67,13 +63,12 @@ func (cfg *Config) models() (*ModelBuild, error) { PackageName: cfg.Model.Package, Models: models, Enums: cfg.buildEnums(namedTypes), - Imports: imports.finalize(), }, nil } // bind a schema together with some code to generate a Build func (cfg *Config) resolver() (*ResolverBuild, error) { - progLoader := newLoader(cfg.buildNamedTypes(), true) + progLoader := cfg.newLoaderWithoutErrors() progLoader.Import(cfg.Resolver.ImportPath()) prog, err := progLoader.Load() @@ -84,13 +79,10 @@ func (cfg *Config) resolver() (*ResolverBuild, error) { destDir := cfg.Resolver.Dir() namedTypes := cfg.buildNamedTypes() - imports := buildImports(namedTypes, destDir) - imports.add(cfg.Exec.ImportPath()) - imports.add("github.com/99designs/gqlgen/handler") // avoid import github.com/vektah/gqlgen/handler - cfg.bindTypes(imports, namedTypes, destDir, prog) + cfg.bindTypes(namedTypes, destDir, prog) - objects, err := cfg.buildObjects(namedTypes, prog, imports) + objects, err := cfg.buildObjects(namedTypes, prog) if err != nil { return nil, err } @@ -100,7 +92,6 @@ func (cfg *Config) resolver() (*ResolverBuild, error) { return &ResolverBuild{ PackageName: cfg.Resolver.Package, - Imports: imports.finalize(), Objects: objects, ResolverType: cfg.Resolver.Type, ResolverFound: resolverFound, @@ -108,15 +99,10 @@ func (cfg *Config) resolver() (*ResolverBuild, error) { } func (cfg *Config) server(destDir string) *ServerBuild { - imports := buildImports(NamedTypes{}, destDir) - imports.add(cfg.Exec.ImportPath()) - imports.add(cfg.Resolver.ImportPath()) - return &ServerBuild{ PackageName: cfg.Resolver.Package, - Imports: imports.finalize(), - ExecPackageName: cfg.Exec.Package, - ResolverPackageName: cfg.Resolver.Package, + ExecPackageName: cfg.Exec.ImportPath(), + ResolverPackageName: cfg.Resolver.ImportPath(), } } @@ -124,21 +110,20 @@ func (cfg *Config) server(destDir string) *ServerBuild { func (cfg *Config) bind() (*Build, error) { namedTypes := cfg.buildNamedTypes() - progLoader := newLoader(namedTypes, true) + progLoader := cfg.newLoaderWithoutErrors() prog, err := progLoader.Load() if err != nil { return nil, errors.Wrap(err, "loading failed") } - imports := buildImports(namedTypes, cfg.Exec.Dir()) - cfg.bindTypes(imports, namedTypes, cfg.Exec.Dir(), prog) + cfg.bindTypes(namedTypes, cfg.Exec.Dir(), prog) - objects, err := cfg.buildObjects(namedTypes, prog, imports) + objects, err := cfg.buildObjects(namedTypes, prog) if err != nil { return nil, err } - inputs, err := cfg.buildInputs(namedTypes, prog, imports) + inputs, err := cfg.buildInputs(namedTypes, prog) if err != nil { return nil, err } @@ -152,7 +137,6 @@ func (cfg *Config) bind() (*Build, error) { Objects: objects, Interfaces: cfg.buildInterfaces(namedTypes, prog), Inputs: inputs, - Imports: imports.finalize(), SchemaRaw: cfg.SchemaStr, SchemaFilename: cfg.SchemaFilename, Directives: directives, @@ -175,29 +159,25 @@ func (cfg *Config) bind() (*Build, error) { } func (cfg *Config) validate() error { - progLoader := newLoader(cfg.buildNamedTypes(), false) + progLoader := cfg.newLoaderWithErrors() _, err := progLoader.Load() return err } -func newLoader(namedTypes NamedTypes, allowErrors bool) loader.Config { +func (cfg *Config) newLoaderWithErrors() loader.Config { conf := loader.Config{} - if allowErrors { - conf = loader.Config{ - AllowErrors: true, - TypeChecker: types.Config{ - Error: func(e error) {}, - }, - } - } - for _, imp := range ambientImports { - conf.Import(imp) - } - - for _, imp := range namedTypes { - if imp.Package != "" { - conf.Import(imp.Package) - } + + for _, pkg := range cfg.Models.referencedPackages() { + conf.Import(pkg) + } + return conf +} + +func (cfg *Config) newLoaderWithoutErrors() loader.Config { + conf := cfg.newLoaderWithErrors() + conf.AllowErrors = true + conf.TypeChecker = types.Config{ + Error: func(e error) {}, } return conf } diff --git a/vendor/github.com/99designs/gqlgen/codegen/codegen.go b/vendor/github.com/99designs/gqlgen/codegen/codegen.go index 27873400..773e3db7 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/codegen.go +++ b/vendor/github.com/99designs/gqlgen/codegen/codegen.go @@ -151,8 +151,13 @@ func (cfg *Config) normalize() error { } } + var sources []*ast.Source + for _, filename := range cfg.SchemaFilename { + sources = append(sources, &ast.Source{Name: filename, Input: cfg.SchemaStr[filename]}) + } + var err *gqlerror.Error - cfg.schema, err = gqlparser.LoadSchema(&ast.Source{Name: cfg.SchemaFilename, Input: cfg.SchemaStr}) + cfg.schema, err = gqlparser.LoadSchema(sources...) if err != nil { return err } diff --git a/vendor/github.com/99designs/gqlgen/codegen/config.go b/vendor/github.com/99designs/gqlgen/codegen/config.go index db0e467b..f9df24fb 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/config.go +++ b/vendor/github.com/99designs/gqlgen/codegen/config.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "sort" "strings" "github.com/99designs/gqlgen/internal/gopath" @@ -19,7 +20,8 @@ var cfgFilenames = []string{".gqlgen.yml", "gqlgen.yml", "gqlgen.yaml"} // DefaultConfig creates a copy of the default config func DefaultConfig() *Config { return &Config{ - SchemaFilename: "schema.graphql", + SchemaFilename: SchemaFilenames{"schema.graphql"}, + SchemaStr: map[string]string{}, Model: PackageConfig{Filename: "models_gen.go"}, Exec: PackageConfig{Filename: "generated.go"}, } @@ -53,19 +55,36 @@ func LoadConfig(filename string) (*Config, error) { return nil, errors.Wrap(err, "unable to parse config") } + preGlobbing := config.SchemaFilename + config.SchemaFilename = SchemaFilenames{} + for _, f := range preGlobbing { + matches, err := filepath.Glob(f) + if err != nil { + return nil, errors.Wrapf(err, "failed to glob schema filename %s", f) + } + + for _, m := range matches { + if config.SchemaFilename.Has(m) { + continue + } + config.SchemaFilename = append(config.SchemaFilename, m) + } + } + config.FilePath = filename + config.SchemaStr = map[string]string{} return config, nil } type Config struct { - SchemaFilename string `yaml:"schema,omitempty"` - SchemaStr string `yaml:"-"` - Exec PackageConfig `yaml:"exec"` - Model PackageConfig `yaml:"model"` - Resolver PackageConfig `yaml:"resolver,omitempty"` - Models TypeMap `yaml:"models,omitempty"` - StructTag string `yaml:"struct_tag,omitempty"` + SchemaFilename SchemaFilenames `yaml:"schema,omitempty"` + SchemaStr map[string]string `yaml:"-"` + Exec PackageConfig `yaml:"exec"` + Model PackageConfig `yaml:"model"` + Resolver PackageConfig `yaml:"resolver,omitempty"` + Models TypeMap `yaml:"models,omitempty"` + StructTag string `yaml:"struct_tag,omitempty"` FilePath string `yaml:"-"` @@ -84,8 +103,37 @@ type TypeMapEntry struct { } type TypeMapField struct { - Resolver bool `yaml:"resolver"` - FieldName string `yaml:"fieldName"` + Resolver bool `yaml:"resolver"` + FieldName string `yaml:"fieldName"` +} + +type SchemaFilenames []string + +func (a *SchemaFilenames) UnmarshalYAML(unmarshal func(interface{}) error) error { + var single string + err := unmarshal(&single) + if err == nil { + *a = []string{single} + return nil + } + + var multi []string + err = unmarshal(&multi) + if err != nil { + return err + } + + *a = multi + return nil +} + +func (a SchemaFilenames) Has(file string) bool { + for _, existing := range a { + if existing == file { + return true + } + } + return false } func (c *PackageConfig) normalize() error { @@ -162,6 +210,36 @@ func (tm TypeMap) Check() error { return nil } +func (tm TypeMap) referencedPackages() []string { + var pkgs []string + + for _, typ := range tm { + if typ.Model == "map[string]interface{}" { + continue + } + pkg, _ := pkgAndType(typ.Model) + if pkg == "" || inStrSlice(pkgs, pkg) { + continue + } + pkgs = append(pkgs, pkg) + } + + sort.Slice(pkgs, func(i, j int) bool { + return pkgs[i] > pkgs[j] + }) + return pkgs +} + +func inStrSlice(haystack []string, needle string) bool { + for _, v := range haystack { + if needle == v { + return true + } + } + + return false +} + // findCfg searches for the config file in this directory and all parents up the tree // looking for the closest match func findCfg() (string, error) { diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go b/vendor/github.com/99designs/gqlgen/codegen/directive_build.go index 32828841..af77dc44 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/directive_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/directive_build.go @@ -32,7 +32,6 @@ func (cfg *Config) buildDirectives(types NamedTypes) ([]*Directive, error) { if err != nil { return nil, errors.Errorf("default value for directive argument %s(%s) is not valid: %s", dir.Name, arg.Name, err.Error()) } - newArg.StripPtr() } args = append(args, newArg) } diff --git a/vendor/github.com/99designs/gqlgen/codegen/import.go b/vendor/github.com/99designs/gqlgen/codegen/import.go deleted file mode 100644 index b511e8f6..00000000 --- a/vendor/github.com/99designs/gqlgen/codegen/import.go +++ /dev/null @@ -1,29 +0,0 @@ -package codegen - -import ( - "strconv" -) - -type Import struct { - Name string - Path string - - alias string -} - -type Imports struct { - imports []*Import - destDir string -} - -func (i *Import) Write() string { - return i.Alias() + " " + strconv.Quote(i.Path) -} - -func (i *Import) Alias() string { - if i.alias == "" { - panic("alias called before imports are finalized") - } - - return i.alias -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/import_build.go b/vendor/github.com/99designs/gqlgen/codegen/import_build.go deleted file mode 100644 index d634834e..00000000 --- a/vendor/github.com/99designs/gqlgen/codegen/import_build.go +++ /dev/null @@ -1,120 +0,0 @@ -package codegen - -import ( - "fmt" - "go/build" - "sort" - "strconv" - - // Import and ignore the ambient imports listed below so dependency managers - // don't prune unused code for us. Both lists should be kept in sync. - _ "github.com/99designs/gqlgen/graphql" - _ "github.com/99designs/gqlgen/graphql/introspection" - "github.com/99designs/gqlgen/internal/gopath" - _ "github.com/vektah/gqlparser" - _ "github.com/vektah/gqlparser/ast" -) - -// These imports are referenced by the generated code, and are assumed to have the -// default alias. So lets make sure they get added first, and any later collisions get -// renamed. -var ambientImports = []string{ - "context", - "fmt", - "io", - "strconv", - "time", - "sync", - "errors", - - "github.com/vektah/gqlparser", - "github.com/vektah/gqlparser/ast", - "github.com/99designs/gqlgen/graphql", - "github.com/99designs/gqlgen/graphql/introspection", -} - -func buildImports(types NamedTypes, destDir string) *Imports { - imports := Imports{ - destDir: destDir, - } - - for _, ambient := range ambientImports { - imports.add(ambient) - } - - // Imports from top level user types - for _, t := range types { - t.Import = imports.add(t.Package) - } - - return &imports -} - -func (s *Imports) add(path string) *Import { - if path == "" { - return nil - } - - // if we are referencing our own package we dont need an import - if gopath.MustDir2Import(s.destDir) == path { - return nil - } - - if existing := s.findByPath(path); existing != nil { - return existing - } - - pkg, err := build.Default.Import(path, s.destDir, 0) - if err != nil { - panic(err) - } - - imp := &Import{ - Name: pkg.Name, - Path: path, - } - s.imports = append(s.imports, imp) - - return imp -} - -func (s Imports) finalize() []*Import { - // ensure stable ordering by sorting - sort.Slice(s.imports, func(i, j int) bool { - return s.imports[i].Path > s.imports[j].Path - }) - - for _, imp := range s.imports { - alias := imp.Name - - i := 1 - for s.findByAlias(alias) != nil { - alias = imp.Name + strconv.Itoa(i) - i++ - if i > 10 { - panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) - } - } - imp.alias = alias - } - - return s.imports -} - -func (s Imports) findByPath(importPath string) *Import { - for _, imp := range s.imports { - if imp.Path == importPath { - return imp - } - } - return nil -} - -func (s Imports) findByAlias(alias string) *Import { - for _, imp := range s.imports { - if imp.alias == alias { - return imp - } - } - return nil -} diff --git a/vendor/github.com/99designs/gqlgen/codegen/input_build.go b/vendor/github.com/99designs/gqlgen/codegen/input_build.go index 06ff37a0..70fa564d 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/input_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/input_build.go @@ -9,7 +9,7 @@ import ( "golang.org/x/tools/go/loader" ) -func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, imports *Imports) (Objects, error) { +func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program) (Objects, error) { var inputs Objects for _, typ := range cfg.schema.Types { @@ -26,7 +26,7 @@ func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, impo } if def != nil { input.Marshaler = buildInputMarshaler(typ, def) - bindErrs := bindObject(def.Type(), input, imports, cfg.StructTag) + bindErrs := bindObject(def.Type(), input, cfg.StructTag) if len(bindErrs) > 0 { return nil, bindErrs } diff --git a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go index 9f4a4ff4..92052ba6 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/interface_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/interface_build.go @@ -1,9 +1,7 @@ package codegen import ( - "fmt" "go/types" - "os" "sort" "github.com/vektah/gqlparser/ast" @@ -51,20 +49,5 @@ func (cfg *Config) isValueReceiver(intf *NamedType, implementor *NamedType, prog return true } - for i := 0; i < interfaceType.NumMethods(); i++ { - intfMethod := interfaceType.Method(i) - - implMethod := findMethod(implementorType, intfMethod.Name()) - if implMethod == nil { - fmt.Fprintf(os.Stderr, "missing method %s on %s\n", intfMethod.Name(), implementor.GoType) - return false - } - - sig := implMethod.Type().(*types.Signature) - if _, isPtr := sig.Recv().Type().(*types.Pointer); isPtr { - return false - } - } - - return true + return types.Implements(implementorType, interfaceType) } diff --git a/vendor/github.com/99designs/gqlgen/codegen/model.go b/vendor/github.com/99designs/gqlgen/codegen/model.go index 5ba50337..bcdc8703 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/model.go +++ b/vendor/github.com/99designs/gqlgen/codegen/model.go @@ -4,6 +4,7 @@ type Model struct { *NamedType Description string Fields []ModelField + Implements []*NamedType } type ModelField struct { diff --git a/vendor/github.com/99designs/gqlgen/codegen/models_build.go b/vendor/github.com/99designs/gqlgen/codegen/models_build.go index 9f98a07d..56d2ff1f 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/models_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/models_build.go @@ -7,14 +7,14 @@ import ( "golang.org/x/tools/go/loader" ) -func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports *Imports) ([]Model, error) { +func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program) ([]Model, error) { var models []Model for _, typ := range cfg.schema.Types { var model Model switch typ.Kind { case ast.Object: - obj, err := cfg.buildObject(types, typ, imports) + obj, err := cfg.buildObject(types, typ) if err != nil { return nil, err } @@ -54,8 +54,9 @@ func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports * func (cfg *Config) obj2Model(obj *Object) Model { model := Model{ - NamedType: obj.NamedType, - Fields: []ModelField{}, + NamedType: obj.NamedType, + Implements: obj.Implements, + Fields: []ModelField{}, } model.GoType = ucFirst(obj.GQLType) diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.go b/vendor/github.com/99designs/gqlgen/codegen/object.go index d9f610f4..656af297 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/object.go +++ b/vendor/github.com/99designs/gqlgen/codegen/object.go @@ -24,6 +24,7 @@ type Object struct { Fields []Field Satisfies []string + Implements []*NamedType ResolverInterface *Ref Root bool DisableConcurrency bool @@ -32,16 +33,17 @@ type Object struct { type Field struct { *Type - Description string // Description of a field - GQLName string // The name of the field in graphql - GoFieldType GoFieldType // The field type in go, if any - GoReceiverName string // The name of method & var receiver in go, if any - GoFieldName string // The name of the method or var in go, if any - Args []FieldArgument // A list of arguments to be passed to this field - ForceResolver bool // Should be emit Resolver method - NoErr bool // If this is bound to a go method, does that method have an error as the second argument - Object *Object // A link back to the parent object - Default interface{} // The default value + Description string // Description of a field + GQLName string // The name of the field in graphql + GoFieldType GoFieldType // The field type in go, if any + GoReceiverName string // The name of method & var receiver in go, if any + GoFieldName string // The name of the method or var in go, if any + Args []FieldArgument // A list of arguments to be passed to this field + ForceResolver bool // Should be emit Resolver method + MethodHasContext bool // If this is bound to a go method, does the method also take a context + NoErr bool // If this is bound to a go method, does that method have an error as the second argument + Object *Object // A link back to the parent object + Default interface{} // The default value } type FieldArgument struct { @@ -102,7 +104,10 @@ func (f *Field) IsVariable() bool { } func (f *Field) IsConcurrent() bool { - return f.IsResolver() && !f.Object.DisableConcurrency + if f.Object.DisableConcurrency { + return false + } + return f.MethodHasContext || f.IsResolver() } func (f *Field) GoNameExported() string { @@ -203,11 +208,15 @@ func (f *Field) CallArgs() string { var args []string if f.IsResolver() { - args = append(args, "ctx") + args = append(args, "rctx") if !f.Object.Root { args = append(args, "obj") } + } else { + if f.MethodHasContext { + args = append(args, "ctx") + } } for _, arg := range f.Args { diff --git a/vendor/github.com/99designs/gqlgen/codegen/object_build.go b/vendor/github.com/99designs/gqlgen/codegen/object_build.go index ee2b2f1c..279d1eb6 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/object_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/object_build.go @@ -9,7 +9,7 @@ import ( "golang.org/x/tools/go/loader" ) -func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports *Imports) (Objects, error) { +func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program) (Objects, error) { var objects Objects for _, typ := range cfg.schema.Types { @@ -17,7 +17,7 @@ func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports continue } - obj, err := cfg.buildObject(types, typ, imports) + obj, err := cfg.buildObject(types, typ) if err != nil { return nil, err } @@ -27,7 +27,7 @@ func (cfg *Config) buildObjects(types NamedTypes, prog *loader.Program, imports return nil, err } if def != nil { - for _, bindErr := range bindObject(def.Type(), obj, imports, cfg.StructTag) { + for _, bindErr := range bindObject(def.Type(), obj, cfg.StructTag) { log.Println(bindErr.Error()) log.Println(" Adding resolver method") } @@ -81,12 +81,11 @@ func sanitizeArgName(name string) string { return name } -func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *Imports) (*Object, error) { +func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition) (*Object, error) { obj := &Object{NamedType: types[typ.Name]} typeEntry, entryExists := cfg.Models[typ.Name] - imp := imports.findByPath(cfg.Exec.ImportPath()) - obj.ResolverInterface = &Ref{GoType: obj.GQLType + "Resolver", Import: imp} + obj.ResolverInterface = &Ref{GoType: obj.GQLType + "Resolver"} if typ == cfg.schema.Query { obj.Root = true @@ -104,12 +103,15 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I obj.Satisfies = append(obj.Satisfies, typ.Interfaces...) + for _, intf := range cfg.schema.GetImplements(typ) { + obj.Implements = append(obj.Implements, types[intf.Name]) + } + for _, field := range typ.Fields { if typ == cfg.schema.Query && field.Name == "__type" { obj.Fields = append(obj.Fields, Field{ Type: &Type{types["__Schema"], []string{modPtr}, ast.NamedType("__Schema", nil), nil}, GQLName: "__schema", - NoErr: true, GoFieldType: GoFieldMethod, GoReceiverName: "ec", GoFieldName: "introspectSchema", @@ -122,7 +124,6 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I obj.Fields = append(obj.Fields, Field{ Type: &Type{types["__Type"], []string{modPtr}, ast.NamedType("__Schema", nil), nil}, GQLName: "__type", - NoErr: true, GoFieldType: GoFieldMethod, GoReceiverName: "ec", GoFieldName: "introspectType", @@ -162,7 +163,6 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I if err != nil { return nil, errors.Errorf("default value for %s.%s is not valid: %s", typ.Name, field.Name, err.Error()) } - newArg.StripPtr() } args = append(args, newArg) } diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go b/vendor/github.com/99designs/gqlgen/codegen/templates/data.go index d168fa31..d3098aaa 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/data.go +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/data.go @@ -2,12 +2,12 @@ package templates var data = map[string]string{ "args.gotpl": "\targs := map[string]interface{}{}\n\t{{- range $i, $arg := . }}\n\t\tvar arg{{$i}} {{$arg.Signature }}\n\t\tif tmp, ok := rawArgs[{{$arg.GQLName|quote}}]; ok {\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\targs[{{$arg.GQLName|quote}}] = arg{{$i}}\n\t{{- end }}\n\treturn args, nil\n", - "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t{{- end }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tField: field,\n\t\t})\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\t// nolint: vetshadow\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t{{- end }}\n\t\trctx := &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\tField: field,\n\t\t}\n\t\tctx = graphql.WithResolverContext(ctx, rctx)\n\t\tresTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(ctx context.Context) (interface{}, error) {\n\t\t\t{{- if $field.IsResolver }}\n\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t{{- else if $field.IsMethod }}\n\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }})\n\t\t\t\t{{- end }}\n\t\t\t{{- else if $field.IsVariable }}\n\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil\n\t\t\t{{- end }}\n\t\t})\n\t\tif resTmp == nil {\n\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\tif !ec.HasError(rctx) {\n\t\t\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\treturn graphql.Null\n\t\t}\n\t\tres := resTmp.({{$field.Signature}})\n\t\trctx.Result = res\n\t\t{{ $field.WriteJson }}\n\t}\n{{ end }}\n", - "generated.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers: cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t\tcomplexity: cfg.Complexity,\n\t}\n}\n\ntype Config struct {\n\tResolvers ResolverRoot\n\tDirectives DirectiveRoot\n\tComplexity ComplexityRoot\n}\n\ntype ResolverRoot interface {\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers -}}\n\t\t{{$object.GQLType}}() {{$object.GQLType}}Resolver\n\t{{ end }}\n{{- end }}\n}\n\ntype DirectiveRoot struct {\n{{ range $directive := .Directives }}\n\t{{ $directive.Declaration }}\n{{ end }}\n}\n\ntype ComplexityRoot struct {\n{{ range $object := .Objects }}\n\t{{ if not $object.IsReserved -}}\n\t\t{{ $object.GQLType|toCamel }} struct {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ if not $field.IsReserved -}}\n\t\t\t\t{{ $field.GQLName|toCamel }} {{ $field.ComplexitySignature }}\n\t\t\t{{ end }}\n\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{ end }}\n}\n\n{{ range $object := .Objects -}}\n\t{{ if $object.HasResolvers }}\n\t\ttype {{$object.GQLType}}Resolver interface {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ $field.ShortResolverDeclaration }}\n\t\t{{ end }}\n\t\t}\n\t{{- end }}\n{{- end }}\n\n{{ range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ if $field.Args }}\n\t\t\tfunc {{ $field.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t\t{{ template \"args.gotpl\" $field.Args }}\n\t\t\t}\n\t\t{{ end }}\n\t{{ end }}\n{{- end }}\n\n{{ range $directive := .Directives }}\n\t{{ if $directive.Args }}\n\t\tfunc {{ $directive.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t{{ template \"args.gotpl\" $directive.Args }}\n\t\t}\n\t{{ end }}\n{{ end }}\n\ntype executableSchema struct {\n\tresolvers ResolverRoot\n\tdirectives DirectiveRoot\n\tcomplexity ComplexityRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {\n\tswitch typeName + \".\" + field {\n\t{{ range $object := .Objects }}\n\t\t{{ if not $object.IsReserved }}\n\t\t\t{{ range $field := $object.Fields }}\n\t\t\t\t{{ if not $field.IsReserved }}\n\t\t\t\t\tcase \"{{$object.GQLType}}.{{$field.GQLName}}\":\n\t\t\t\t\t\tif e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}} == nil {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ if $field.Args }}\n\t\t\t\t\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn 0, false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ end }}\n\t\t\t\t\t\treturn e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true\n\t\t\t\t{{ end }}\n\t\t\t{{ end }}\n\t\t{{ end }}\n\t{{ end }}\n\t}\n\treturn 0, false\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"queries are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"mutations are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\t\tbuf.Reset()\n\t\t\t\tdata := next()\n\n\t\t\t\tif data == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tdata.MarshalGQL(&buf)\n\t\t\t\treturn buf.Bytes()\n\t\t\t})\n\n\t\t\tif buf == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf,\n\t\t\t\tErrors: ec.Errors,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"subscriptions are not supported\"))\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\t*executableSchema\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = nil\n\t\t}\n\t}()\n\t{{- if .Directives }}\n\trctx := graphql.GetResolverContext(ctx)\n\tfor _, d := range rctx.Field.Definition.Directives {\n\t\tswitch d.Name {\n\t\t{{- range $directive := .Directives }}\n\t\tcase \"{{$directive.Name}}\":\n\t\t\tif ec.directives.{{$directive.Name|ucFirst}} != nil {\n\t\t\t\t{{- if $directive.Args }}\n\t\t\t\t\trawArgs := d.ArgumentMap(ec.Variables)\n\t\t\t\t\targs, err := {{ $directive.ArgsFunc }}(rawArgs)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tec.Error(ctx, err)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t\tn := next\n\t\t\t\tnext = func(ctx context.Context) (interface{}, error) {\n\t\t\t\t\treturn ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})\n\t\t\t\t}\n\t\t\t}\n\t\t{{- end }}\n\t\t}\n\t}\n\t{{- end }}\n\tres, err := ec.ResolverMiddleware(ctx, next)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn nil\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) introspectSchema() *introspection.Schema {\n\treturn introspection.WrapSchema(parsedSchema)\n}\n\nfunc (ec *executionContext) introspectType(name string) *introspection.Type {\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name])\n}\n\nvar parsedSchema = gqlparser.MustLoadSchema(\n\t&ast.Source{Name: {{.SchemaFilename|quote}}, Input: {{.SchemaRaw|rawQuote}}},\n)\n", + "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t{{- end }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tField: field,\n\t\t})\n\t\t// FIXME: subscriptions are missing request middleware stack https://github.com/99designs/gqlgen/issues/259\n\t\t// and Tracer stack\n\t\trctx := ctx\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\t// nolint: vetshadow\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\tctx = ec.Tracer.StartFieldExecution(ctx, field)\n\t\tdefer func () { ec.Tracer.EndFieldExecution(ctx) }()\n\t\t{{- if $field.Args }}\n\t\t\trawArgs := field.ArgumentMap(ec.Variables)\n\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t{{- end }}\n\t\trctx := &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\tField: field,\n\t\t}\n\t\tctx = graphql.WithResolverContext(ctx, rctx)\n\t\tctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)\n\t\tresTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {\n\t\t\tctx = rctx // use context from middleware stack in children\n\t\t\t{{- if $field.IsResolver }}\n\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t{{- else if $field.IsMethod }}\n\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }})\n\t\t\t\t{{- end }}\n\t\t\t{{- else if $field.IsVariable }}\n\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil\n\t\t\t{{- end }}\n\t\t})\n\t\tif resTmp == nil {\n\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\tif !ec.HasError(rctx) {\n\t\t\t\t\tec.Errorf(ctx, \"must not be null\")\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\treturn graphql.Null\n\t\t}\n\t\tres := resTmp.({{$field.Signature}})\n\t\trctx.Result = res\n\t\tctx = ec.Tracer.StartFieldChildExecution(ctx)\n\t\t{{ $field.WriteJson }}\n\t}\n{{ end }}\n", + "generated.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers: cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t\tcomplexity: cfg.Complexity,\n\t}\n}\n\ntype Config struct {\n\tResolvers ResolverRoot\n\tDirectives DirectiveRoot\n\tComplexity ComplexityRoot\n}\n\ntype ResolverRoot interface {\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers -}}\n\t\t{{$object.GQLType}}() {{$object.GQLType}}Resolver\n\t{{ end }}\n{{- end }}\n}\n\ntype DirectiveRoot struct {\n{{ range $directive := .Directives }}\n\t{{ $directive.Declaration }}\n{{ end }}\n}\n\ntype ComplexityRoot struct {\n{{ range $object := .Objects }}\n\t{{ if not $object.IsReserved -}}\n\t\t{{ $object.GQLType|toCamel }} struct {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ if not $field.IsReserved -}}\n\t\t\t\t{{ $field.GQLName|toCamel }} {{ $field.ComplexitySignature }}\n\t\t\t{{ end }}\n\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{ end }}\n}\n\n{{ range $object := .Objects -}}\n\t{{ if $object.HasResolvers }}\n\t\ttype {{$object.GQLType}}Resolver interface {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ $field.ShortResolverDeclaration }}\n\t\t{{ end }}\n\t\t}\n\t{{- end }}\n{{- end }}\n\n{{ range $object := .Objects -}}\n\t{{ range $field := $object.Fields -}}\n\t\t{{ if $field.Args }}\n\t\t\tfunc {{ $field.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t\t{{ template \"args.gotpl\" $field.Args }}\n\t\t\t}\n\t\t{{ end }}\n\t{{ end }}\n{{- end }}\n\n{{ range $directive := .Directives }}\n\t{{ if $directive.Args }}\n\t\tfunc {{ $directive.ArgsFunc }}(rawArgs map[string]interface{}) (map[string]interface{}, error) {\n\t\t{{ template \"args.gotpl\" $directive.Args }}\n\t\t}\n\t{{ end }}\n{{ end }}\n\ntype executableSchema struct {\n\tresolvers ResolverRoot\n\tdirectives DirectiveRoot\n\tcomplexity ComplexityRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {\n\tswitch typeName + \".\" + field {\n\t{{ range $object := .Objects }}\n\t\t{{ if not $object.IsReserved }}\n\t\t\t{{ range $field := $object.Fields }}\n\t\t\t\t{{ if not $field.IsReserved }}\n\t\t\t\t\tcase \"{{$object.GQLType}}.{{$field.GQLName}}\":\n\t\t\t\t\t\tif e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}} == nil {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ if $field.Args }}\n\t\t\t\t\t\t\targs, err := {{ $field.ArgsFunc }}(rawArgs)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn 0, false\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t{{ end }}\n\t\t\t\t\t\treturn e.complexity.{{$object.GQLType|toCamel}}.{{$field.GQLName|toCamel}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true\n\t\t\t\t{{ end }}\n\t\t\t{{ end }}\n\t\t{{ end }}\n\t{{ end }}\n\t}\n\treturn 0, false\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t\tExtensions: ec.Extensions,\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"queries are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t\tExtensions: ec.Extensions,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"mutations are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\t\tbuf.Reset()\n\t\t\t\tdata := next()\n\n\t\t\t\tif data == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tdata.MarshalGQL(&buf)\n\t\t\t\treturn buf.Bytes()\n\t\t\t})\n\n\t\t\tif buf == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf,\n\t\t\t\tErrors: ec.Errors,\n\t\t\t\tExtensions: ec.Extensions,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"subscriptions are not supported\"))\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\t*executableSchema\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tec.Error(ctx, ec.Recover(ctx, r))\n\t\t\tret = nil\n\t\t}\n\t}()\n\t{{- if .Directives }}\n\trctx := graphql.GetResolverContext(ctx)\n\tfor _, d := range rctx.Field.Definition.Directives {\n\t\tswitch d.Name {\n\t\t{{- range $directive := .Directives }}\n\t\tcase \"{{$directive.Name}}\":\n\t\t\tif ec.directives.{{$directive.Name|ucFirst}} != nil {\n\t\t\t\t{{- if $directive.Args }}\n\t\t\t\t\trawArgs := d.ArgumentMap(ec.Variables)\n\t\t\t\t\targs, err := {{ $directive.ArgsFunc }}(rawArgs)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tec.Error(ctx, err)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t\tn := next\n\t\t\t\tnext = func(ctx context.Context) (interface{}, error) {\n\t\t\t\t\treturn ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})\n\t\t\t\t}\n\t\t\t}\n\t\t{{- end }}\n\t\t}\n\t}\n\t{{- end }}\n\tres, err := ec.ResolverMiddleware(ctx, next)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn nil\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) introspectSchema() (*introspection.Schema, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapSchema(parsedSchema), nil\n}\n\nfunc (ec *executionContext) introspectType(name string) (*introspection.Type, error) {\n\tif ec.DisableIntrospection {\n\t\treturn nil, errors.New(\"introspection disabled\")\n\t}\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil\n}\n\nvar parsedSchema = gqlparser.MustLoadSchema(\n\t{{- range $filename, $schema := .SchemaRaw }}\n\t\t&ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},\n\t{{- end }}\n)\n", "input.gotpl": "\t{{- if .IsMarshaled }}\n\tfunc Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {\n\t\tvar it {{.FullName}}\n\t\tvar asMap = v.(map[string]interface{})\n\t\t{{ range $field := .Fields}}\n\t\t\t{{- if $field.Default}}\n\t\t\t\tif _, present := asMap[{{$field.GQLName|quote}}] ; !present {\n\t\t\t\t\tasMap[{{$field.GQLName|quote}}] = {{ $field.Default | dump }}\n\t\t\t\t}\n\t\t\t{{- end}}\n\t\t{{- end }}\n\n\t\tfor k, v := range asMap {\n\t\t\tswitch k {\n\t\t\t{{- range $field := .Fields }}\n\t\t\tcase {{$field.GQLName|quote}}:\n\t\t\t\tvar err error\n\t\t\t\t{{ $field.Unmarshal (print \"it.\" $field.GoFieldName) \"v\" }}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn it, err\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\n\t\treturn it, nil\n\t}\n\t{{- end }}\n", "interface.gotpl": "{{- $interface := . }}\n\nfunc (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.FullName}}) graphql.Marshaler {\n\tswitch obj := (*obj).(type) {\n\tcase nil:\n\t\treturn graphql.Null\n\t{{- range $implementor := $interface.Implementors }}\n\t\t{{- if $implementor.ValueReceiver }}\n\t\t\tcase {{$implementor.FullName}}:\n\t\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, &obj)\n\t\t{{- end}}\n\t\tcase *{{$implementor.FullName}}:\n\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, obj)\n\t{{- end }}\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type %T\", obj))\n\t}\n}\n", - "models.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n{{ range $model := .Models }}\n\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- with .Description}}\n\t\t\t\t\t{{.|prefixLines \"// \"}}\n\t\t\t\t{{- end}}\n\t\t\t\t{{- if $field.GoFieldName }}\n\t\t\t\t\t{{ $field.GoFieldName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\t{{with .Description}}{{.|prefixLines \"// \"}} {{end}}\n\ttype {{.GoType}} string\n\tconst (\n\t{{- range $value := .Values}}\n\t\t{{- with .Description}}\n\t\t\t{{.|prefixLines \"// \"}}\n\t\t{{- end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n", + "models.gotpl": "// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\n{{ range $model := .Models }}\n\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {\n\t\t\tIs{{.GoType}}()\n\t\t}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- with .Description}}\n\t\t\t\t\t{{.|prefixLines \"// \"}}\n\t\t\t\t{{- end}}\n\t\t\t\t{{- if $field.GoFieldName }}\n\t\t\t\t\t{{ $field.GoFieldName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\n\t\t{{- range $iface := .Implements }}\n\t\t\tfunc ({{$model.GoType}}) Is{{$iface.GoType}}() {}\n\t\t{{- end }}\n\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\t{{with .Description}}{{.|prefixLines \"// \"}} {{end}}\n\ttype {{.GoType}} string\n\tconst (\n\t{{- range $value := .Values}}\n\t\t{{- with .Description}}\n\t\t\t{{.|prefixLines \"// \"}}\n\t\t{{- end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n", "object.gotpl": "{{ $object := . }}\n\nvar {{ $object.GQLType|lcFirst}}Implementors = {{$object.Implementors}}\n\n// nolint: gocyclo, errcheck, gas, goconst\n{{- if .Stream }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\tObject: {{$object.GQLType|quote}},\n\t})\n\tif len(fields) != 1 {\n\t\tec.Errorf(ctx, \"must subscribe to exactly one stream\")\n\t\treturn nil\n\t}\n\n\tswitch fields[0].Name {\n\t{{- range $field := $object.Fields }}\n\tcase \"{{$field.GQLName}}\":\n\t\treturn ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, fields[0])\n\t{{- end }}\n\tdefault:\n\t\tpanic(\"unknown field \" + strconv.Quote(fields[0].Name))\n\t}\n}\n{{- else }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\t{{if $object.Root}}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t})\n\t{{end}}\n\n\t{{if $object.IsConcurrent}} var wg sync.WaitGroup {{end}}\n\tout := graphql.NewOrderedMap(len(fields))\n\tinvalid := false\n\tfor i, field := range fields {\n\t\tout.Keys[i] = field.Alias\n\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString({{$object.GQLType|quote}})\n\t\t{{- range $field := $object.Fields }}\n\t\tcase \"{{$field.GQLName}}\":\n\t\t\t{{- if $field.IsConcurrent }}\n\t\t\t\twg.Add(1)\n\t\t\t\tgo func(i int, field graphql.CollectedField) {\n\t\t\t{{- end }}\n\t\t\t\tout.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, field{{if not $object.Root}}, obj{{end}})\n\t\t\t\t{{- if $field.ASTType.NonNull }}\n\t\t\t\t\tif out.Values[i] == graphql.Null {\n\t\t\t\t\t\tinvalid = true\n\t\t\t\t\t}\n\t\t\t\t{{- end }}\n\t\t\t{{- if $field.IsConcurrent }}\n\t\t\t\t\twg.Done()\n\t\t\t\t}(i, field)\n\t\t\t{{- end }}\n\t\t{{- end }}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\t{{if $object.IsConcurrent}} wg.Wait() {{end}}\n\tif invalid { return graphql.Null }\n\treturn out\n}\n{{- end }}\n", - "resolver.gotpl": "//go:generate gorunpkg github.com/99designs/gqlgen\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\ntype {{.ResolverType}} struct {}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\tfunc (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {\n\t\t\treturn &{{lcFirst $object.GQLType}}Resolver{r}\n\t\t}\n\t{{ end -}}\n{{ end }}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\ttype {{lcFirst $object.GQLType}}Resolver struct { *Resolver }\n\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{- if $field.IsResolver -}}\n\t\t\tfunc (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {\n\t\t\t\tpanic(\"not implemented\")\n\t\t\t}\n\t\t\t{{ end -}}\n\t\t{{ end -}}\n\t{{ end -}}\n{{ end }}\n", - "server.gotpl": "package main\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\nconst defaultPort = \"8080\"\n\nfunc main() {\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = defaultPort\n\t}\n\n\thttp.Handle(\"/\", handler.Playground(\"GraphQL playground\", \"/query\"))\n\thttp.Handle(\"/query\", handler.GraphQL({{.ExecPackageName}}.NewExecutableSchema({{.ExecPackageName}}.Config{Resolvers: &{{.ResolverPackageName}}.Resolver{}})))\n\n\tlog.Printf(\"connect to http://localhost:%s/ for GraphQL playground\", port)\n\tlog.Fatal(http.ListenAndServe(\":\" + port, nil))\n}\n", + "resolver.gotpl": "package {{ .PackageName }}\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"fmt\" }}\n\t{{ reserveImport \"io\" }}\n\t{{ reserveImport \"strconv\" }}\n\t{{ reserveImport \"time\" }}\n\t{{ reserveImport \"sync\" }}\n\t{{ reserveImport \"errors\" }}\n\t{{ reserveImport \"bytes\" }}\n\n\t{{ reserveImport \"github.com/99designs/gqlgen/handler\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser\" }}\n\t{{ reserveImport \"github.com/vektah/gqlparser/ast\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/graphql/introspection\" }}\n)\n\ntype {{.ResolverType}} struct {}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\tfunc (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {\n\t\t\treturn &{{lcFirst $object.GQLType}}Resolver{r}\n\t\t}\n\t{{ end -}}\n{{ end }}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\ttype {{lcFirst $object.GQLType}}Resolver struct { *Resolver }\n\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{- if $field.IsResolver -}}\n\t\t\tfunc (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {\n\t\t\t\tpanic(\"not implemented\")\n\t\t\t}\n\t\t\t{{ end -}}\n\t\t{{ end -}}\n\t{{ end -}}\n{{ end }}\n", + "server.gotpl": "package main\n\nimport (\n\t%%%IMPORTS%%%\n\n\t{{ reserveImport \"context\" }}\n\t{{ reserveImport \"log\" }}\n\t{{ reserveImport \"net/http\" }}\n\t{{ reserveImport \"os\" }}\n\t{{ reserveImport \"github.com/99designs/gqlgen/handler\" }}\n)\n\nconst defaultPort = \"8080\"\n\nfunc main() {\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = defaultPort\n\t}\n\n\thttp.Handle(\"/\", handler.Playground(\"GraphQL playground\", \"/query\"))\n\thttp.Handle(\"/query\", handler.GraphQL({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}})))\n\n\tlog.Printf(\"connect to http://localhost:%s/ for GraphQL playground\", port)\n\tlog.Fatal(http.ListenAndServe(\":\" + port, nil))\n}\n", } diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl index b33f2123..3df847fa 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/field.gotpl @@ -14,6 +14,9 @@ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ Field: field, }) + // FIXME: subscriptions are missing request middleware stack https://github.com/99designs/gqlgen/issues/259 + // and Tracer stack + rctx := ctx results, err := ec.resolvers.{{ $field.ShortInvocation }} if err != nil { ec.Error(ctx, err) @@ -32,6 +35,8 @@ {{ else }} // nolint: vetshadow func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func () { ec.Tracer.EndFieldExecution(ctx) }() {{- if $field.Args }} rawArgs := field.ArgumentMap(ec.Variables) args, err := {{ $field.ArgsFunc }}(rawArgs) @@ -46,7 +51,9 @@ Field: field, } ctx = graphql.WithResolverContext(ctx, rctx) - resTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(ctx context.Context) (interface{}, error) { + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children {{- if $field.IsResolver }} return ec.resolvers.{{ $field.ShortInvocation }} {{- else if $field.IsMethod }} @@ -69,6 +76,7 @@ } res := resTmp.({{$field.Signature}}) rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) {{ $field.WriteJson }} } {{ end }} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl index 8250bc7a..a37a1613 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/generated.gotpl @@ -3,9 +3,21 @@ package {{ .PackageName }} import ( -{{- range $import := .Imports }} - {{- $import.Write }} -{{ end }} + %%%IMPORTS%%% + + {{ reserveImport "context" }} + {{ reserveImport "fmt" }} + {{ reserveImport "io" }} + {{ reserveImport "strconv" }} + {{ reserveImport "time" }} + {{ reserveImport "sync" }} + {{ reserveImport "errors" }} + {{ reserveImport "bytes" }} + + {{ reserveImport "github.com/vektah/gqlparser" }} + {{ reserveImport "github.com/vektah/gqlparser/ast" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} ) // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. @@ -126,9 +138,9 @@ func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinitio }) return &graphql.Response{ - Data: buf, - Errors: ec.Errors, - } + Data: buf, + Errors: ec.Errors, + Extensions: ec.Extensions, } {{- else }} return graphql.ErrorResponse(ctx, "queries are not supported") {{- end }} @@ -146,8 +158,9 @@ func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefini }) return &graphql.Response{ - Data: buf, - Errors: ec.Errors, + Data: buf, + Errors: ec.Errors, + Extensions: ec.Extensions, } {{- else }} return graphql.ErrorResponse(ctx, "mutations are not supported") @@ -181,8 +194,9 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe } return &graphql.Response{ - Data: buf, - Errors: ec.Errors, + Data: buf, + Errors: ec.Errors, + Extensions: ec.Extensions, } } {{- else }} @@ -250,14 +264,22 @@ func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{} return res } -func (ec *executionContext) introspectSchema() *introspection.Schema { - return introspection.WrapSchema(parsedSchema) +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil } -func (ec *executionContext) introspectType(name string) *introspection.Type { - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]) +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil } var parsedSchema = gqlparser.MustLoadSchema( - &ast.Source{Name: {{.SchemaFilename|quote}}, Input: {{.SchemaRaw|rawQuote}}}, + {{- range $filename, $schema := .SchemaRaw }} + &ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}}, + {{- end }} ) diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/import.go b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go new file mode 100644 index 00000000..c9db2d96 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/import.go @@ -0,0 +1,135 @@ +package templates + +import ( + "fmt" + "go/build" + "strconv" + + "github.com/99designs/gqlgen/internal/gopath" +) + +type Import struct { + Name string + Path string + Alias string +} + +type Imports struct { + imports []*Import + destDir string +} + +func (i *Import) String() string { + if i.Alias == i.Name { + return strconv.Quote(i.Path) + } + + return i.Alias + " " + strconv.Quote(i.Path) +} + +func (s *Imports) String() string { + res := "" + for i, imp := range s.imports { + if i != 0 { + res += "\n" + } + res += imp.String() + } + return res +} + +func (s *Imports) Reserve(path string, aliases ...string) string { + if path == "" { + panic("empty ambient import") + } + + // if we are referencing our own package we dont need an import + if gopath.MustDir2Import(s.destDir) == path { + return "" + } + + pkg, err := build.Default.Import(path, s.destDir, 0) + if err != nil { + panic(err) + } + + var alias string + if len(aliases) != 1 { + alias = pkg.Name + } else { + alias = aliases[0] + } + + if existing := s.findByPath(path); existing != nil { + panic("ambient import already exists") + } + + if alias := s.findByAlias(alias); alias != nil { + panic("ambient import collides on an alias") + } + + s.imports = append(s.imports, &Import{ + Name: pkg.Name, + Path: path, + Alias: alias, + }) + + return "" +} + +func (s *Imports) Lookup(path string) string { + if path == "" { + return "" + } + + // if we are referencing our own package we dont need an import + if gopath.MustDir2Import(s.destDir) == path { + return "" + } + + if existing := s.findByPath(path); existing != nil { + return existing.Alias + } + + pkg, err := build.Default.Import(path, s.destDir, 0) + if err != nil { + panic(err) + } + + imp := &Import{ + Name: pkg.Name, + Path: path, + } + s.imports = append(s.imports, imp) + + alias := imp.Name + i := 1 + for s.findByAlias(alias) != nil { + alias = imp.Name + strconv.Itoa(i) + i++ + if i > 10 { + panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) + } + } + imp.Alias = alias + + return imp.Alias +} + +func (s Imports) findByPath(importPath string) *Import { + for _, imp := range s.imports { + if imp.Path == importPath { + return imp + } + } + return nil +} + +func (s Imports) findByAlias(alias string) *Import { + for _, imp := range s.imports { + if imp.Alias == alias { + return imp + } + } + return nil +} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl index 7427d71d..db63a996 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/models.gotpl @@ -3,15 +3,29 @@ package {{ .PackageName }} import ( -{{- range $import := .Imports }} - {{- $import.Write }} -{{ end }} + %%%IMPORTS%%% + + {{ reserveImport "context" }} + {{ reserveImport "fmt" }} + {{ reserveImport "io" }} + {{ reserveImport "strconv" }} + {{ reserveImport "time" }} + {{ reserveImport "sync" }} + {{ reserveImport "errors" }} + {{ reserveImport "bytes" }} + + {{ reserveImport "github.com/vektah/gqlparser" }} + {{ reserveImport "github.com/vektah/gqlparser/ast" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} ) {{ range $model := .Models }} {{with .Description}} {{.|prefixLines "// "}} {{end}} {{- if .IsInterface }} - type {{.GoType}} interface {} + type {{.GoType}} interface { + Is{{.GoType}}() + } {{- else }} type {{.GoType}} struct { {{- range $field := .Fields }} @@ -25,6 +39,11 @@ import ( {{- end }} {{- end }} } + + {{- range $iface := .Implements }} + func ({{$model.GoType}}) Is{{$iface.GoType}}() {} + {{- end }} + {{- end }} {{- end}} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl index dd8acf24..53ba8c43 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/resolver.gotpl @@ -1,11 +1,22 @@ -//go:generate gorunpkg github.com/99designs/gqlgen - package {{ .PackageName }} import ( -{{- range $import := .Imports }} - {{- $import.Write }} -{{ end }} + %%%IMPORTS%%% + + {{ reserveImport "context" }} + {{ reserveImport "fmt" }} + {{ reserveImport "io" }} + {{ reserveImport "strconv" }} + {{ reserveImport "time" }} + {{ reserveImport "sync" }} + {{ reserveImport "errors" }} + {{ reserveImport "bytes" }} + + {{ reserveImport "github.com/99designs/gqlgen/handler" }} + {{ reserveImport "github.com/vektah/gqlparser" }} + {{ reserveImport "github.com/vektah/gqlparser/ast" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql" }} + {{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }} ) type {{.ResolverType}} struct {} diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl b/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl index f23b30e1..38dc0d18 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/server.gotpl @@ -1,9 +1,13 @@ package main import ( -{{- range $import := .Imports }} - {{- $import.Write }} -{{ end }} + %%%IMPORTS%%% + + {{ reserveImport "context" }} + {{ reserveImport "log" }} + {{ reserveImport "net/http" }} + {{ reserveImport "os" }} + {{ reserveImport "github.com/99designs/gqlgen/handler" }} ) const defaultPort = "8080" @@ -15,7 +19,7 @@ func main() { } http.Handle("/", handler.Playground("GraphQL playground", "/query")) - http.Handle("/query", handler.GraphQL({{.ExecPackageName}}.NewExecutableSchema({{.ExecPackageName}}.Config{Resolvers: &{{.ResolverPackageName}}.Resolver{}}))) + http.Handle("/query", handler.GraphQL({{ lookupImport .ExecPackageName }}.NewExecutableSchema({{ lookupImport .ExecPackageName}}.Config{Resolvers: &{{ lookupImport .ResolverPackageName}}.Resolver{}}))) log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) log.Fatal(http.ListenAndServe(":" + port, nil)) diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go index df909cb5..22e5d739 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go +++ b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go @@ -14,21 +14,25 @@ import ( "text/template" "unicode" - "log" + "github.com/99designs/gqlgen/internal/imports" "github.com/pkg/errors" - "golang.org/x/tools/imports" ) +// this is done with a global because subtemplates currently get called in functions. Lets aim to remove this eventually. +var CurrentImports *Imports + func Run(name string, tpldata interface{}) (*bytes.Buffer, error) { t := template.New("").Funcs(template.FuncMap{ - "ucFirst": ucFirst, - "lcFirst": lcFirst, - "quote": strconv.Quote, - "rawQuote": rawQuote, - "toCamel": ToCamel, - "dump": dump, - "prefixLines": prefixLines, + "ucFirst": ucFirst, + "lcFirst": lcFirst, + "quote": strconv.Quote, + "rawQuote": rawQuote, + "toCamel": ToCamel, + "dump": dump, + "prefixLines": prefixLines, + "reserveImport": CurrentImports.Reserve, + "lookupImport": CurrentImports.Lookup, }) for filename, data := range data { @@ -149,27 +153,21 @@ func prefixLines(prefix, s string) string { } func RenderToFile(tpl string, filename string, data interface{}) error { + if CurrentImports != nil { + panic(fmt.Errorf("recursive or concurrent call to RenderToFile detected")) + } + CurrentImports = &Imports{destDir: filepath.Dir(filename)} + var buf *bytes.Buffer buf, err := Run(tpl, data) if err != nil { return errors.Wrap(err, filename+" generation failed") } - if err := write(filename, buf.Bytes()); err != nil { - return err - } - - log.Println(filename) + b := bytes.Replace(buf.Bytes(), []byte("%%%IMPORTS%%%"), []byte(CurrentImports.String()), -1) + CurrentImports = nil - return nil -} - -func gofmt(filename string, b []byte) ([]byte, error) { - out, err := imports.Process(filename, b, nil) - if err != nil { - return b, errors.Wrap(err, "unable to gofmt") - } - return out, nil + return write(filename, b) } func write(filename string, b []byte) error { @@ -178,9 +176,9 @@ func write(filename string, b []byte) error { return errors.Wrap(err, "failed to create directory") } - formatted, err := gofmt(filename, b) + formatted, err := imports.Prune(filename, b) if err != nil { - fmt.Fprintf(os.Stderr, "gofmt failed: %s\n", err.Error()) + fmt.Fprintf(os.Stderr, "gofmt failed on %s: %s\n", filepath.Base(filename), err.Error()) formatted = b } diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.go b/vendor/github.com/99designs/gqlgen/codegen/type.go index 8c53fe55..04d9bb2f 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/type.go +++ b/vendor/github.com/99designs/gqlgen/codegen/type.go @@ -4,6 +4,8 @@ import ( "strconv" "strings" + "github.com/99designs/gqlgen/codegen/templates" + "github.com/vektah/gqlparser/ast" ) @@ -19,10 +21,9 @@ type NamedType struct { } type Ref struct { - GoType string // Name of the go type - Package string // the package the go type lives in - Import *Import // the resolved import with alias - IsUserDefined bool // does the type exist in the typemap + GoType string // Name of the go type + Package string // the package the go type lives in + IsUserDefined bool // does the type exist in the typemap } type Type struct { @@ -43,10 +44,13 @@ func (t Ref) FullName() string { } func (t Ref) PkgDot() string { - if t.Import == nil || t.Import.Alias() == "" { + name := templates.CurrentImports.Lookup(t.Package) + if name == "" { return "" + } - return t.Import.Alias() + "." + + return name + "." } func (t Type) Signature() string { diff --git a/vendor/github.com/99designs/gqlgen/codegen/type_build.go b/vendor/github.com/99designs/gqlgen/codegen/type_build.go index f0ec6785..586b0db2 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/type_build.go +++ b/vendor/github.com/99designs/gqlgen/codegen/type_build.go @@ -27,7 +27,7 @@ func (cfg *Config) buildNamedTypes() NamedTypes { return types } -func (cfg *Config) bindTypes(imports *Imports, namedTypes NamedTypes, destDir string, prog *loader.Program) { +func (cfg *Config) bindTypes(namedTypes NamedTypes, destDir string, prog *loader.Program) { for _, t := range namedTypes { if t.Package == "" { continue @@ -41,7 +41,6 @@ func (cfg *Config) bindTypes(imports *Imports, namedTypes NamedTypes, destDir st t.Marshaler = &cpy t.Package, t.GoType = pkgAndType(sig.Params().At(0).Type().String()) - t.Import = imports.add(t.Package) } } } diff --git a/vendor/github.com/99designs/gqlgen/codegen/util.go b/vendor/github.com/99designs/gqlgen/codegen/util.go index 1849f100..cc6246fd 100644 --- a/vendor/github.com/99designs/gqlgen/codegen/util.go +++ b/vendor/github.com/99designs/gqlgen/codegen/util.go @@ -105,6 +105,12 @@ func findMethod(typ *types.Named, name string) *types.Func { return nil } +func equalFieldName(source, target string) bool { + source = strings.Replace(source, "_", "", -1) + target = strings.Replace(target, "_", "", -1) + return strings.EqualFold(source, target) +} + // findField attempts to match the name to a struct field with the following // priorites: // 1. If struct tag is passed then struct tag has highest priority @@ -120,7 +126,7 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) { if structTag != "" { tags := reflect.StructTag(typ.Tag(i)) if val, ok := tags.Lookup(structTag); ok { - if strings.EqualFold(val, name) { + if equalFieldName(val, name) { if foundField != nil && foundFieldWasTag { return nil, errors.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", structTag, val) } @@ -132,17 +138,16 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) { } if field.Anonymous() { - if named, ok := field.Type().(*types.Struct); ok { - f, err := findField(named, name, structTag) - if err != nil && !strings.HasPrefix(err.Error(), "no field named") { - return nil, err - } - if f != nil && foundField == nil { - foundField = f - } + + fieldType := field.Type() + + if ptr, ok := fieldType.(*types.Pointer); ok { + fieldType = ptr.Elem() } - if named, ok := field.Type().Underlying().(*types.Struct); ok { + // Type.Underlying() returns itself for all types except types.Named, where it returns a struct type. + // It should be safe to always call. + if named, ok := fieldType.Underlying().(*types.Struct); ok { f, err := findField(named, name, structTag) if err != nil && !strings.HasPrefix(err.Error(), "no field named") { return nil, err @@ -157,7 +162,7 @@ func findField(typ *types.Struct, name, structTag string) (*types.Var, error) { continue } - if strings.EqualFold(field.Name(), name) && foundField == nil { + if equalFieldName(field.Name(), name) && foundField == nil { // aqui! foundField = field } } @@ -198,7 +203,7 @@ func (b BindErrors) Error() string { return strings.Join(errs, "\n\n") } -func bindObject(t types.Type, object *Object, imports *Imports, structTag string) BindErrors { +func bindObject(t types.Type, object *Object, structTag string) BindErrors { var errs BindErrors for i := range object.Fields { field := &object.Fields[i] @@ -208,13 +213,13 @@ func bindObject(t types.Type, object *Object, imports *Imports, structTag string } // first try binding to a method - methodErr := bindMethod(imports, t, field) + methodErr := bindMethod(t, field) if methodErr == nil { continue } // otherwise try binding to a var - varErr := bindVar(imports, t, field, structTag) + varErr := bindVar(t, field, structTag) if varErr != nil { errs = append(errs, BindError{ @@ -229,7 +234,7 @@ func bindObject(t types.Type, object *Object, imports *Imports, structTag string return errs } -func bindMethod(imports *Imports, t types.Type, field *Field) error { +func bindMethod(t types.Type, field *Field) error { namedType, ok := t.(*types.Named) if !ok { return fmt.Errorf("not a named type") @@ -250,13 +255,25 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error { } else if sig.Results().Len() != 2 { return fmt.Errorf("method has wrong number of args") } - newArgs, err := matchArgs(field, sig.Params()) + params := sig.Params() + // If the first argument is the context, remove it from the comparison and set + // the MethodHasContext flag so that the context will be passed to this model's method + if params.Len() > 0 && params.At(0).Type().String() == "context.Context" { + field.MethodHasContext = true + vars := make([]*types.Var, params.Len()-1) + for i := 1; i < params.Len(); i++ { + vars[i-1] = params.At(i) + } + params = types.NewTuple(vars...) + } + + newArgs, err := matchArgs(field, params) if err != nil { return err } result := sig.Results().At(0) - if err := validateTypeBinding(imports, field, result.Type()); err != nil { + if err := validateTypeBinding(field, result.Type()); err != nil { return errors.Wrap(err, "method has wrong return type") } @@ -268,7 +285,7 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error { return nil } -func bindVar(imports *Imports, t types.Type, field *Field, structTag string) error { +func bindVar(t types.Type, field *Field, structTag string) error { underlying, ok := t.Underlying().(*types.Struct) if !ok { return fmt.Errorf("not a struct") @@ -283,7 +300,7 @@ func bindVar(imports *Imports, t types.Type, field *Field, structTag string) err return err } - if err := validateTypeBinding(imports, field, structField.Type()); err != nil { + if err := validateTypeBinding(field, structField.Type()); err != nil { return errors.Wrap(err, "field has wrong type") } @@ -316,22 +333,21 @@ nextArg: return newArgs, nil } -func validateTypeBinding(imports *Imports, field *Field, goType types.Type) error { +func validateTypeBinding(field *Field, goType types.Type) error { gqlType := normalizeVendor(field.Type.FullSignature()) goTypeStr := normalizeVendor(goType.String()) - if goTypeStr == gqlType || "*"+goTypeStr == gqlType || goTypeStr == "*"+gqlType { + if equalTypes(goTypeStr, gqlType) { field.Type.Modifiers = modifiersFromGoType(goType) return nil } // deal with type aliases underlyingStr := normalizeVendor(goType.Underlying().String()) - if underlyingStr == gqlType || "*"+underlyingStr == gqlType || underlyingStr == "*"+gqlType { + if equalTypes(underlyingStr, gqlType) { field.Type.Modifiers = modifiersFromGoType(goType) pkg, typ := pkgAndType(goType.String()) - imp := imports.findByPath(pkg) - field.AliasedType = &Ref{GoType: typ, Import: imp} + field.AliasedType = &Ref{GoType: typ, Package: pkg} return nil } @@ -365,3 +381,7 @@ func normalizeVendor(pkg string) string { parts := strings.Split(pkg, "/vendor/") return modifiers + parts[len(parts)-1] } + +func equalTypes(goType string, gqlType string) bool { + return goType == gqlType || "*"+goType == gqlType || goType == "*"+gqlType || strings.Replace(goType, "[]*", "[]", -1) == gqlType +} |