diff options
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/plugin')
7 files changed, 474 insertions, 0 deletions
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/plugin/servergen/server.gotpl b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl new file mode 100644 index 00000000..fca71c53 --- /dev/null +++ b/vendor/github.com/99designs/gqlgen/plugin/servergen/server.gotpl @@ -0,0 +1,20 @@ +{{ reserveImport "context" }} +{{ reserveImport "log" }} +{{ reserveImport "net/http" }} +{{ reserveImport "os" }} +{{ reserveImport "github.com/99designs/gqlgen/handler" }} + +const defaultPort = "8080" + +func main() { + port := os.Getenv("PORT") + if port == "" { + port = defaultPort + } + + http.Handle("/", handler.Playground("GraphQL playground", "/query")) + 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)) +} |