aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/99designs/gqlgen/codegen/data.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/99designs/gqlgen/codegen/data.go')
-rw-r--r--vendor/github.com/99designs/gqlgen/codegen/data.go168
1 files changed, 168 insertions, 0 deletions
diff --git a/vendor/github.com/99designs/gqlgen/codegen/data.go b/vendor/github.com/99designs/gqlgen/codegen/data.go
new file mode 100644
index 00000000..f2ea70b4
--- /dev/null
+++ b/vendor/github.com/99designs/gqlgen/codegen/data.go
@@ -0,0 +1,168 @@
+package codegen
+
+import (
+ "fmt"
+ "sort"
+
+ "github.com/99designs/gqlgen/codegen/config"
+ "github.com/pkg/errors"
+ "github.com/vektah/gqlparser/ast"
+)
+
+// Data is a unified model of the code to be generated. Plugins may modify this structure to do things like implement
+// resolvers or directives automatically (eg grpc, validation)
+type Data struct {
+ Config *config.Config
+ Schema *ast.Schema
+ SchemaStr map[string]string
+ Directives map[string]*Directive
+ Objects Objects
+ Inputs Objects
+ Interfaces map[string]*Interface
+ ReferencedTypes map[string]*config.TypeReference
+ ComplexityRoots map[string]*Object
+
+ QueryRoot *Object
+ MutationRoot *Object
+ SubscriptionRoot *Object
+}
+
+type builder struct {
+ Config *config.Config
+ Schema *ast.Schema
+ SchemaStr map[string]string
+ Binder *config.Binder
+ Directives map[string]*Directive
+}
+
+func BuildData(cfg *config.Config) (*Data, error) {
+ b := builder{
+ Config: cfg,
+ }
+
+ var err error
+ b.Schema, b.SchemaStr, err = cfg.LoadSchema()
+ if err != nil {
+ return nil, err
+ }
+
+ err = cfg.Check()
+ if err != nil {
+ return nil, err
+ }
+
+ cfg.InjectBuiltins(b.Schema)
+
+ b.Binder, err = b.Config.NewBinder(b.Schema)
+ if err != nil {
+ return nil, err
+ }
+
+ b.Directives, err = b.buildDirectives()
+ if err != nil {
+ return nil, err
+ }
+
+ dataDirectives := make(map[string]*Directive)
+ for name, d := range b.Directives {
+ if !d.Builtin {
+ dataDirectives[name] = d
+ }
+ }
+
+ s := Data{
+ Config: cfg,
+ Directives: dataDirectives,
+ Schema: b.Schema,
+ SchemaStr: b.SchemaStr,
+ Interfaces: map[string]*Interface{},
+ }
+
+ for _, schemaType := range b.Schema.Types {
+ switch schemaType.Kind {
+ case ast.Object:
+ obj, err := b.buildObject(schemaType)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to build object definition")
+ }
+
+ s.Objects = append(s.Objects, obj)
+ case ast.InputObject:
+ input, err := b.buildObject(schemaType)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to build input definition")
+ }
+
+ s.Inputs = append(s.Inputs, input)
+
+ case ast.Union, ast.Interface:
+ s.Interfaces[schemaType.Name] = b.buildInterface(schemaType)
+ }
+ }
+
+ if s.Schema.Query != nil {
+ s.QueryRoot = s.Objects.ByName(s.Schema.Query.Name)
+ } else {
+ return nil, fmt.Errorf("query entry point missing")
+ }
+
+ if s.Schema.Mutation != nil {
+ s.MutationRoot = s.Objects.ByName(s.Schema.Mutation.Name)
+ }
+
+ if s.Schema.Subscription != nil {
+ s.SubscriptionRoot = s.Objects.ByName(s.Schema.Subscription.Name)
+ }
+
+ if err := b.injectIntrospectionRoots(&s); err != nil {
+ return nil, err
+ }
+
+ s.ReferencedTypes, err = b.buildTypes()
+ if err != nil {
+ return nil, err
+ }
+
+ sort.Slice(s.Objects, func(i, j int) bool {
+ return s.Objects[i].Definition.Name < s.Objects[j].Definition.Name
+ })
+
+ sort.Slice(s.Inputs, func(i, j int) bool {
+ return s.Inputs[i].Definition.Name < s.Inputs[j].Definition.Name
+ })
+
+ return &s, nil
+}
+
+func (b *builder) injectIntrospectionRoots(s *Data) error {
+ obj := s.Objects.ByName(b.Schema.Query.Name)
+ if obj == nil {
+ return fmt.Errorf("root query type must be defined")
+ }
+
+ __type, err := b.buildField(obj, &ast.FieldDefinition{
+ Name: "__type",
+ Type: ast.NamedType("__Type", nil),
+ Arguments: []*ast.ArgumentDefinition{
+ {
+ Name: "name",
+ Type: ast.NonNullNamedType("String", nil),
+ },
+ },
+ })
+ if err != nil {
+ return err
+ }
+
+ __schema, err := b.buildField(obj, &ast.FieldDefinition{
+ Name: "__schema",
+ Type: ast.NamedType("__Schema", nil),
+ })
+ if err != nil {
+ return err
+ }
+
+ obj.Fields = append(obj.Fields, __type, __schema)
+
+ return nil
+}