1
1
# frozen_string_literal: true
2
+
2
3
require 'graphql'
3
4
4
5
module GraphQLDocs
@@ -10,13 +11,13 @@ class Parser
10
11
def initialize ( schema , options )
11
12
@options = options
12
13
13
- @options [ :notices ] ||= -> ( schema_member_path ) { [ ] }
14
+ @options [ :notices ] ||= -> ( _schema_member_path ) { [ ] }
14
15
15
- if schema . is_a? ( GraphQL :: Schema )
16
- @schema = schema
17
- else
18
- @schema = GraphQL :: Schema . from_definition ( schema )
19
- end
16
+ @schema = if schema . is_a? ( String )
17
+ GraphQL :: Schema . from_definition ( schema )
18
+ elsif schema < GraphQL :: Schema
19
+ schema
20
+ end
20
21
21
22
@processed_schema = {
22
23
operation_types : [ ] ,
@@ -27,80 +28,71 @@ def initialize(schema, options)
27
28
union_types : [ ] ,
28
29
input_object_types : [ ] ,
29
30
scalar_types : [ ] ,
30
- directive_types : [ ] ,
31
+ directive_types : [ ]
31
32
}
32
33
end
33
34
34
35
def parse
35
36
root_types = { }
36
- [ 'query' , 'mutation' ] . each do |operation |
37
- unless @schema . root_type_for_operation ( operation ) . nil?
38
- root_types [ operation ] = @schema . root_type_for_operation ( operation ) . name
39
- end
37
+ %w[ query mutation ] . each do |operation |
38
+ root_types [ operation ] = @schema . root_type_for_operation ( operation ) . graphql_name unless @schema . root_type_for_operation ( operation ) . nil?
40
39
end
41
40
@processed_schema [ :root_types ] = root_types
42
41
43
42
@schema . types . each_value do |object |
44
43
data = { }
45
44
46
- data [ :notices ] = @options [ :notices ] . call ( object . name )
45
+ data [ :notices ] = @options [ :notices ] . call ( object . graphql_name )
47
46
48
- case object
49
- when ::GraphQL ::ObjectType
50
- if object . name == root_types [ 'query' ]
51
- data [ :name ] = object . name
52
- data [ :description ] = object . description
47
+ if object < ::GraphQL ::Schema ::Object
48
+ data [ :name ] = object . graphql_name
49
+ data [ :description ] = object . description
53
50
54
- data [ :interfaces ] = object . interfaces . map ( &:name ) . sort
55
- data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . name )
51
+ if data [ :name ] == root_types [ 'query' ]
52
+ data [ :interfaces ] = object . interfaces . map ( &:graphql_name ) . sort
53
+ data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . graphql_name )
56
54
57
55
@processed_schema [ :operation_types ] << data
58
- elsif object . name == root_types [ 'mutation' ]
59
- data [ :name ] = object . name
60
- data [ :description ] = object . description
61
-
56
+ elsif data [ :name ] == root_types [ 'mutation' ]
62
57
@processed_schema [ :operation_types ] << data
63
58
64
59
object . fields . each_value do |mutation |
65
60
h = { }
66
61
67
- h [ :notices ] = @options [ :notices ] . call ( [ object . name , mutation . name ] . join ( '.' ) )
68
- h [ :name ] = mutation . name
62
+ h [ :notices ] = @options [ :notices ] . call ( [ object . graphql_name , mutation . graphql_name ] . join ( '.' ) )
63
+ h [ :name ] = mutation . graphql_name
69
64
h [ :description ] = mutation . description
70
- h [ :input_fields ] , _ = fetch_fields ( mutation . arguments , [ object . name , mutation . name ] . join ( '.' ) )
65
+ h [ :input_fields ] , = fetch_fields ( mutation . arguments , [ object . graphql_name , mutation . graphql_name ] . join ( '.' ) )
71
66
72
67
return_type = mutation . type
73
68
if return_type . unwrap . respond_to? ( :fields )
74
- h [ :return_fields ] , _ = fetch_fields ( return_type . unwrap . fields , return_type . name )
69
+ h [ :return_fields ] , = fetch_fields ( return_type . unwrap . fields , return_type . graphql_name )
75
70
else # it is a scalar return type
76
- h [ :return_fields ] , _ = fetch_fields ( { " #{ return_type . name } " => mutation } , return_type . name )
71
+ h [ :return_fields ] , = fetch_fields ( { return_type . graphql_name => mutation } , return_type . graphql_name )
77
72
end
78
73
79
74
@processed_schema [ :mutation_types ] << h
80
75
end
81
76
else
82
- data [ :name ] = object . name
83
- data [ :description ] = object . description
84
-
85
- data [ :interfaces ] = object . interfaces . map ( &:name ) . sort
86
- data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . name )
77
+ data [ :interfaces ] = object . interfaces . map ( &:graphql_name ) . sort
78
+ data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . graphql_name )
87
79
88
80
@processed_schema [ :object_types ] << data
89
81
end
90
- when ::GraphQL ::InterfaceType
91
- data [ :name ] = object . name
82
+ elsif object < ::GraphQL ::Schema :: Interface
83
+ data [ :name ] = object . graphql_name
92
84
data [ :description ] = object . description
93
- data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . name )
85
+ data [ :fields ] , data [ :connections ] = fetch_fields ( object . fields , object . graphql_name )
94
86
95
87
@processed_schema [ :interface_types ] << data
96
- when ::GraphQL ::EnumType
97
- data [ :name ] = object . name
88
+ elsif object < ::GraphQL ::Schema :: Enum
89
+ data [ :name ] = object . graphql_name
98
90
data [ :description ] = object . description
99
91
100
92
data [ :values ] = object . values . values . map do |val |
101
93
h = { }
102
- h [ :notices ] = @options [ :notices ] . call ( [ object . name , val . name ] . join ( '.' ) )
103
- h [ :name ] = val . name
94
+ h [ :notices ] = @options [ :notices ] . call ( [ object . graphql_name , val . graphql_name ] . join ( '.' ) )
95
+ h [ :name ] = val . graphql_name
104
96
h [ :description ] = val . description
105
97
unless val . deprecation_reason . nil?
106
98
h [ :is_deprecated ] = true
@@ -110,38 +102,38 @@ def parse
110
102
end
111
103
112
104
@processed_schema [ :enum_types ] << data
113
- when ::GraphQL ::UnionType
114
- data [ :name ] = object . name
105
+ elsif object < ::GraphQL ::Schema :: Union
106
+ data [ :name ] = object . graphql_name
115
107
data [ :description ] = object . description
116
- data [ :possible_types ] = object . possible_types . map ( &:name ) . sort
108
+ data [ :possible_types ] = object . possible_types . map ( &:graphql_name ) . sort
117
109
118
110
@processed_schema [ :union_types ] << data
119
- when :: GraphQL :: InputObjectType
120
- data [ :name ] = object . name
111
+ elsif object < GraphQL :: Schema :: InputObject
112
+ data [ :name ] = object . graphql_name
121
113
data [ :description ] = object . description
122
114
123
- data [ :input_fields ] , _ = fetch_fields ( object . input_fields , object . name )
115
+ data [ :input_fields ] , = fetch_fields ( object . arguments , object . graphql_name )
124
116
125
117
@processed_schema [ :input_object_types ] << data
126
- when :: GraphQL :: ScalarType
127
- data [ :name ] = object . name
118
+ elsif object < GraphQL :: Schema :: Scalar
119
+ data [ :name ] = object . graphql_name
128
120
data [ :description ] = object . description
129
121
130
122
@processed_schema [ :scalar_types ] << data
131
123
else
132
- raise TypeError , "I'm not sure what #{ object . class } is!"
124
+ raise TypeError , "I'm not sure what #{ object . class } < #{ object . superclass . name } is!"
133
125
end
134
126
end
135
127
136
128
@schema . directives . each_value do |directive |
137
129
data = { }
138
- data [ :notices ] = @options [ :notices ] . call ( directive . name )
130
+ data [ :notices ] = @options [ :notices ] . call ( directive . graphql_name )
139
131
140
- data [ :name ] = directive . name
132
+ data [ :name ] = directive . graphql_name
141
133
data [ :description ] = directive . description
142
134
data [ :locations ] = directive . locations
143
135
144
- data [ :arguments ] , _ = fetch_fields ( directive . arguments , directive . name )
136
+ data [ :arguments ] , = fetch_fields ( directive . arguments , directive . graphql_name )
145
137
146
138
@processed_schema [ :directive_types ] << data
147
139
end
@@ -151,9 +143,7 @@ def parse
151
143
@processed_schema [ :interface_types ] . each do |interface |
152
144
interface [ :implemented_by ] = [ ]
153
145
@processed_schema [ :object_types ] . each do |obj |
154
- if obj [ :interfaces ] . include? ( interface [ :name ] )
155
- interface [ :implemented_by ] << obj [ :name ]
156
- end
146
+ interface [ :implemented_by ] << obj [ :name ] if obj [ :interfaces ] . include? ( interface [ :name ] )
157
147
end
158
148
end
159
149
@@ -169,8 +159,8 @@ def fetch_fields(object_fields, parent_path)
169
159
object_fields . each_value do |field |
170
160
hash = { }
171
161
172
- hash [ :notices ] = @options [ :notices ] . call ( [ parent_path , field . name ] . join ( '.' ) )
173
- hash [ :name ] = field . name
162
+ hash [ :notices ] = @options [ :notices ] . call ( [ parent_path , field . graphql_name ] . join ( '.' ) )
163
+ hash [ :name ] = field . graphql_name
174
164
hash [ :description ] = field . description
175
165
if field . respond_to? ( :deprecation_reason ) && !field . deprecation_reason . nil?
176
166
hash [ :is_deprecated ] = true
@@ -183,17 +173,15 @@ def fetch_fields(object_fields, parent_path)
183
173
if field . respond_to? ( :arguments )
184
174
field . arguments . each_value do |arg |
185
175
h = { }
186
- h [ :name ] = arg . name
176
+ h [ :name ] = arg . graphql_name
187
177
h [ :description ] = arg . description
188
178
h [ :type ] = generate_type ( arg . type )
189
- if arg . default_value?
190
- h [ :default_value ] = arg . default_value
191
- end
179
+ h [ :default_value ] = arg . default_value if arg . default_value?
192
180
hash [ :arguments ] << h
193
181
end
194
182
end
195
183
196
- if !argument? ( field ) && field . connection?
184
+ if !argument? ( field ) && connection? ( field )
197
185
connections << hash
198
186
else
199
187
fields << hash
@@ -204,26 +192,26 @@ def fetch_fields(object_fields, parent_path)
204
192
end
205
193
206
194
def generate_type ( type )
207
- name = type . unwrap . to_s
208
- path = case type . unwrap
209
- when :: GraphQL :: ObjectType
195
+ name = type . unwrap . graphql_name
196
+
197
+ path = if type . unwrap < GraphQL :: Schema :: Object
210
198
if name == 'Query'
211
199
'operation'
212
200
else
213
201
'object'
214
202
end
215
- when :: GraphQL :: ScalarType
203
+ elsif type . unwrap < GraphQL :: Schema :: Scalar
216
204
'scalar'
217
- when :: GraphQL :: InterfaceType
205
+ elsif type . unwrap < GraphQL :: Schema :: Interface
218
206
'interface'
219
- when :: GraphQL :: EnumType
207
+ elsif type . unwrap < GraphQL :: Schema :: Enum
220
208
'enum'
221
- when :: GraphQL :: InputObjectType
209
+ elsif type . unwrap < GraphQL :: Schema :: InputObject
222
210
'input_object'
223
- when :: GraphQL :: UnionType
211
+ elsif type . unwrap < GraphQL :: Schema :: Union
224
212
'union'
225
213
else
226
- raise TypeError , "Unknown type: `#{ type . unwrap . class } `"
214
+ raise TypeError , "Unknown type for ` #{ name } ` : `#{ type . unwrap . class } `"
227
215
end
228
216
229
217
{
@@ -234,12 +222,18 @@ def generate_type(type)
234
222
end
235
223
236
224
def argument? ( field )
237
- field . is_a? ( ::GraphQL ::Argument )
225
+ field . is_a? ( ::GraphQL ::Schema ::Argument )
226
+ end
227
+
228
+ def connection? ( field )
229
+ field . respond_to? ( :connection? ) && field . connection?
238
230
end
239
231
240
232
def sort_by_name!
241
233
@processed_schema . each_pair do |key , value |
234
+ next if value . empty?
242
235
next if key == :operation_types || key == :root_types
236
+
243
237
value . sort_by! { |o | o [ :name ] }
244
238
end
245
239
end
0 commit comments