1package introspection
2
3import (
4 "sort"
5
6 "github.com/vektah/gqlgen/neelance/common"
7 "github.com/vektah/gqlgen/neelance/schema"
8)
9
10type Schema struct {
11 schema *schema.Schema
12}
13
14// WrapSchema is only used internally.
15func WrapSchema(schema *schema.Schema) *Schema {
16 return &Schema{schema}
17}
18
19func (r *Schema) Types() []Type {
20 var names []string
21 for name := range r.schema.Types {
22 names = append(names, name)
23 }
24 sort.Strings(names)
25
26 l := make([]Type, len(names))
27 for i, name := range names {
28 l[i] = Type{r.schema.Types[name]}
29 }
30 return l
31}
32
33func (r *Schema) Directives() []Directive {
34 var names []string
35 for name := range r.schema.Directives {
36 names = append(names, name)
37 }
38 sort.Strings(names)
39
40 l := make([]Directive, len(names))
41 for i, name := range names {
42 l[i] = Directive{r.schema.Directives[name]}
43 }
44 return l
45}
46
47func (r *Schema) QueryType() Type {
48 t, ok := r.schema.EntryPoints["query"]
49 if !ok {
50 return Type{}
51 }
52 return Type{t}
53}
54
55func (r *Schema) MutationType() *Type {
56 t, ok := r.schema.EntryPoints["mutation"]
57 if !ok {
58 return nil
59 }
60 return &Type{t}
61}
62
63func (r *Schema) SubscriptionType() *Type {
64 t, ok := r.schema.EntryPoints["subscription"]
65 if !ok {
66 return nil
67 }
68 return &Type{t}
69}
70
71type Type struct {
72 typ common.Type
73}
74
75// WrapType is only used internally.
76func WrapType(typ common.Type) *Type {
77 return &Type{typ}
78}
79
80func (r *Type) Kind() string {
81 return r.typ.Kind()
82}
83
84func (r *Type) Name() *string {
85 if named, ok := r.typ.(schema.NamedType); ok {
86 name := named.TypeName()
87 return &name
88 }
89 return nil
90}
91
92func (r *Type) Description() *string {
93 if named, ok := r.typ.(schema.NamedType); ok {
94 desc := named.Description()
95 if desc == "" {
96 return nil
97 }
98 return &desc
99 }
100 return nil
101}
102
103func (r *Type) Fields(includeDeprecated bool) []Field {
104 var fields schema.FieldList
105 switch t := r.typ.(type) {
106 case *schema.Object:
107 fields = t.Fields
108 case *schema.Interface:
109 fields = t.Fields
110 default:
111 return nil
112 }
113
114 var l []Field
115 for _, f := range fields {
116 if d := f.Directives.Get("deprecated"); d == nil || includeDeprecated {
117 l = append(l, Field{f})
118 }
119 }
120 return l
121}
122
123func (r *Type) Interfaces() []Type {
124 t, ok := r.typ.(*schema.Object)
125 if !ok {
126 return nil
127 }
128
129 l := make([]Type, len(t.Interfaces))
130 for i, intf := range t.Interfaces {
131 l[i] = Type{intf}
132 }
133 return l
134}
135
136func (r *Type) PossibleTypes() []Type {
137 var possibleTypes []*schema.Object
138 switch t := r.typ.(type) {
139 case *schema.Interface:
140 possibleTypes = t.PossibleTypes
141 case *schema.Union:
142 possibleTypes = t.PossibleTypes
143 default:
144 return nil
145 }
146
147 l := make([]Type, len(possibleTypes))
148 for i, intf := range possibleTypes {
149 l[i] = Type{intf}
150 }
151 return l
152}
153
154func (r *Type) EnumValues(includeDeprecated bool) []EnumValue {
155 t, ok := r.typ.(*schema.Enum)
156 if !ok {
157 return nil
158 }
159
160 var l []EnumValue
161 for _, v := range t.Values {
162 if d := v.Directives.Get("deprecated"); d == nil || includeDeprecated {
163 l = append(l, EnumValue{v})
164 }
165 }
166 return l
167}
168
169func (r *Type) InputFields() []InputValue {
170 t, ok := r.typ.(*schema.InputObject)
171 if !ok {
172 return nil
173 }
174
175 l := make([]InputValue, len(t.Values))
176 for i, v := range t.Values {
177 l[i] = InputValue{v}
178 }
179 return l
180}
181
182func (r *Type) OfType() *Type {
183 switch t := r.typ.(type) {
184 case *common.List:
185 return &Type{t.OfType}
186 case *common.NonNull:
187 return &Type{t.OfType}
188 default:
189 return nil
190 }
191}
192
193type Field struct {
194 field *schema.Field
195}
196
197func (r *Field) Name() string {
198 return r.field.Name
199}
200
201func (r *Field) Description() *string {
202 if r.field.Desc == "" {
203 return nil
204 }
205 return &r.field.Desc
206}
207
208func (r *Field) Args() []InputValue {
209 l := make([]InputValue, len(r.field.Args))
210 for i, v := range r.field.Args {
211 l[i] = InputValue{v}
212 }
213 return l
214}
215
216func (r *Field) Type() Type {
217 return Type{r.field.Type}
218}
219
220func (r *Field) IsDeprecated() bool {
221 return r.field.Directives.Get("deprecated") != nil
222}
223
224func (r *Field) DeprecationReason() *string {
225 d := r.field.Directives.Get("deprecated")
226 if d == nil {
227 return nil
228 }
229 reason := d.Args.MustGet("reason").Value(nil).(string)
230 return &reason
231}
232
233type InputValue struct {
234 value *common.InputValue
235}
236
237func (r *InputValue) Name() string {
238 return r.value.Name.Name
239}
240
241func (r *InputValue) Description() *string {
242 if r.value.Desc == "" {
243 return nil
244 }
245 return &r.value.Desc
246}
247
248func (r *InputValue) Type() Type {
249 return Type{r.value.Type}
250}
251
252func (r *InputValue) DefaultValue() *string {
253 if r.value.Default == nil {
254 return nil
255 }
256 s := r.value.Default.String()
257 return &s
258}
259
260type EnumValue struct {
261 value *schema.EnumValue
262}
263
264func (r *EnumValue) Name() string {
265 return r.value.Name
266}
267
268func (r *EnumValue) Description() *string {
269 if r.value.Desc == "" {
270 return nil
271 }
272 return &r.value.Desc
273}
274
275func (r *EnumValue) IsDeprecated() bool {
276 return r.value.Directives.Get("deprecated") != nil
277}
278
279func (r *EnumValue) DeprecationReason() *string {
280 d := r.value.Directives.Get("deprecated")
281 if d == nil {
282 return nil
283 }
284 reason := d.Args.MustGet("reason").Value(nil).(string)
285 return &reason
286}
287
288type Directive struct {
289 directive *schema.DirectiveDecl
290}
291
292func (r *Directive) Name() string {
293 return r.directive.Name
294}
295
296func (r *Directive) Description() *string {
297 if r.directive.Desc == "" {
298 return nil
299 }
300 return &r.directive.Desc
301}
302
303func (r *Directive) Locations() []string {
304 return r.directive.Locs
305}
306
307func (r *Directive) Args() []InputValue {
308 l := make([]InputValue, len(r.directive.Args))
309 for i, v := range r.directive.Args {
310 l[i] = InputValue{v}
311 }
312 return l
313}