aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/vektah/gqlgen/graphql/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vektah/gqlgen/graphql/exec.go')
-rw-r--r--vendor/github.com/vektah/gqlgen/graphql/exec.go118
1 files changed, 118 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlgen/graphql/exec.go b/vendor/github.com/vektah/gqlgen/graphql/exec.go
new file mode 100644
index 00000000..2c034888
--- /dev/null
+++ b/vendor/github.com/vektah/gqlgen/graphql/exec.go
@@ -0,0 +1,118 @@
+package graphql
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/vektah/gqlgen/neelance/common"
+ "github.com/vektah/gqlgen/neelance/query"
+ "github.com/vektah/gqlgen/neelance/schema"
+)
+
+type ExecutableSchema interface {
+ Schema() *schema.Schema
+
+ Query(ctx context.Context, op *query.Operation) *Response
+ Mutation(ctx context.Context, op *query.Operation) *Response
+ Subscription(ctx context.Context, op *query.Operation) func() *Response
+}
+
+func CollectFields(doc *query.Document, selSet []query.Selection, satisfies []string, variables map[string]interface{}) []CollectedField {
+ return collectFields(doc, selSet, satisfies, variables, map[string]bool{})
+}
+
+func collectFields(doc *query.Document, selSet []query.Selection, satisfies []string, variables map[string]interface{}, visited map[string]bool) []CollectedField {
+ var groupedFields []CollectedField
+
+ for _, sel := range selSet {
+ switch sel := sel.(type) {
+ case *query.Field:
+ f := getOrCreateField(&groupedFields, sel.Alias.Name, func() CollectedField {
+ f := CollectedField{
+ Alias: sel.Alias.Name,
+ Name: sel.Name.Name,
+ }
+ if len(sel.Arguments) > 0 {
+ f.Args = map[string]interface{}{}
+ for _, arg := range sel.Arguments {
+ if variable, ok := arg.Value.(*common.Variable); ok {
+ if val, ok := variables[variable.Name]; ok {
+ f.Args[arg.Name.Name] = val
+ }
+ } else {
+ f.Args[arg.Name.Name] = arg.Value.Value(variables)
+ }
+ }
+ }
+ return f
+ })
+
+ f.Selections = append(f.Selections, sel.Selections...)
+ case *query.InlineFragment:
+ if !instanceOf(sel.On.Ident.Name, satisfies) {
+ continue
+ }
+
+ for _, childField := range collectFields(doc, sel.Selections, satisfies, variables, visited) {
+ f := getOrCreateField(&groupedFields, childField.Name, func() CollectedField { return childField })
+ f.Selections = append(f.Selections, childField.Selections...)
+ }
+
+ case *query.FragmentSpread:
+ fragmentName := sel.Name.Name
+ if _, seen := visited[fragmentName]; seen {
+ continue
+ }
+ visited[fragmentName] = true
+
+ fragment := doc.Fragments.Get(fragmentName)
+ if fragment == nil {
+ // should never happen, validator has already run
+ panic(fmt.Errorf("missing fragment %s", fragmentName))
+ }
+
+ if !instanceOf(fragment.On.Ident.Name, satisfies) {
+ continue
+ }
+
+ for _, childField := range collectFields(doc, fragment.Selections, satisfies, variables, visited) {
+ f := getOrCreateField(&groupedFields, childField.Name, func() CollectedField { return childField })
+ f.Selections = append(f.Selections, childField.Selections...)
+ }
+
+ default:
+ panic(fmt.Errorf("unsupported %T", sel))
+ }
+ }
+
+ return groupedFields
+}
+
+type CollectedField struct {
+ Alias string
+ Name string
+ Args map[string]interface{}
+ Selections []query.Selection
+}
+
+func instanceOf(val string, satisfies []string) bool {
+ for _, s := range satisfies {
+ if val == s {
+ return true
+ }
+ }
+ return false
+}
+
+func getOrCreateField(c *[]CollectedField, name string, creator func() CollectedField) *CollectedField {
+ for i, cf := range *c {
+ if cf.Alias == name {
+ return &(*c)[i]
+ }
+ }
+
+ f := creator()
+
+ *c = append(*c, f)
+ return &(*c)[len(*c)-1]
+}