...
1 package federation
2
3 import (
4 "go/types"
5
6 "github.com/vektah/gqlparser/v2/ast"
7
8 "github.com/99designs/gqlgen/codegen/config"
9 "github.com/99designs/gqlgen/codegen/templates"
10 "github.com/99designs/gqlgen/plugin/federation/fieldset"
11 )
12
13
14
15 type Entity struct {
16 Name string
17 Def *ast.Definition
18 Resolvers []*EntityResolver
19 Requires []*Requires
20 Multi bool
21 Type types.Type
22 }
23
24 type EntityResolver struct {
25 ResolverName string
26 KeyFields []*KeyField
27 InputType types.Type
28 InputTypeName string
29 }
30
31 func (e *EntityResolver) LookupInputType() string {
32 return templates.CurrentImports.LookupType(e.InputType)
33 }
34
35 type KeyField struct {
36 Definition *ast.FieldDefinition
37 Field fieldset.Field
38 Type *config.TypeReference
39 }
40
41
42 type Requires struct {
43 Name string
44 Field fieldset.Field
45 Type *config.TypeReference
46 }
47
48 func (e *Entity) allFieldsAreExternal(federationVersion int) bool {
49 for _, field := range e.Def.Fields {
50 if !e.isFieldImplicitlyExternal(field, federationVersion) && field.Directives.ForName("external") == nil {
51 return false
52 }
53 }
54 return true
55 }
56
57
58 func (e *Entity) isFieldImplicitlyExternal(field *ast.FieldDefinition, federationVersion int) bool {
59
60 if federationVersion != 2 {
61 return false
62 }
63
64
65
66 if e.isResolvable() {
67 return false
68 }
69
70 if e.isKeyField(field) {
71 return true
72 }
73
74 return false
75 }
76
77
78 func (e *Entity) isResolvable() bool {
79 key := e.Def.Directives.ForName("key")
80 if key == nil {
81
82 return true
83 }
84 resolvable := key.Arguments.ForName("resolvable")
85 if resolvable == nil {
86
87 return true
88 }
89
90 return resolvable.Value.Raw != "false"
91 }
92
93
94 func (e *Entity) isKeyField(field *ast.FieldDefinition) bool {
95 for _, keyField := range e.keyFields() {
96 if keyField == field.Name {
97 return true
98 }
99 }
100 return false
101 }
102
103
104 func (e *Entity) keyFields() []string {
105 key := e.Def.Directives.ForName("key")
106 if key == nil {
107 return []string{}
108 }
109 fields := key.Arguments.ForName("fields")
110 if fields == nil {
111 return []string{}
112 }
113 fieldSet := fieldset.New(fields.Value.Raw, nil)
114 keyFields := make([]string, len(fieldSet))
115 for i, field := range fieldSet {
116 keyFields[i] = field[0]
117 }
118 return keyFields
119 }
120
121
122 func (e Entity) GetTypeInfo() string {
123 return templates.CurrentImports.LookupType(e.Type)
124 }
125
View as plain text