graphql 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +2 -0
- data/lib/graphql/analysis/ast/analyzer.rb +7 -0
- data/lib/graphql/analysis/ast/visitor.rb +2 -2
- data/lib/graphql/analysis/ast.rb +15 -11
- data/lib/graphql/dataloader/source.rb +7 -0
- data/lib/graphql/dataloader.rb +9 -0
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
- data/lib/graphql/execution/interpreter/runtime.rb +90 -251
- data/lib/graphql/execution/interpreter.rb +0 -6
- data/lib/graphql/execution/lookahead.rb +1 -1
- data/lib/graphql/introspection/dynamic_fields.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/language/block_string.rb +28 -16
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +30 -19
- data/lib/graphql/language/nodes.rb +1 -1
- data/lib/graphql/language/printer.rb +88 -27
- data/lib/graphql/language/sanitized_printer.rb +6 -1
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/visitor.rb +2 -0
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +32 -98
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/field/connection_extension.rb +1 -15
- data/lib/graphql/schema/field.rb +6 -3
- data/lib/graphql/schema/has_single_input_argument.rb +156 -0
- data/lib/graphql/schema/introspection_system.rb +2 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +2 -1
- data/lib/graphql/schema/member/has_arguments.rb +14 -2
- data/lib/graphql/schema/member/has_fields.rb +4 -1
- data/lib/graphql/schema/member/has_interfaces.rb +21 -7
- data/lib/graphql/schema/relay_classic_mutation.rb +6 -128
- data/lib/graphql/schema/resolver.rb +4 -0
- data/lib/graphql/schema/scalar.rb +3 -3
- data/lib/graphql/schema/warden.rb +20 -3
- data/lib/graphql/schema.rb +19 -2
- data/lib/graphql/static_validation/all_rules.rb +1 -1
- data/lib/graphql/static_validation/base_visitor.rb +1 -1
- data/lib/graphql/static_validation/literal_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
- data/lib/graphql/static_validation/validation_context.rb +5 -2
- data/lib/graphql/tracing/appoptics_trace.rb +2 -2
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -1
- metadata +7 -2
@@ -59,40 +59,52 @@ module GraphQL
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.print(str, indent: '')
|
62
|
-
|
62
|
+
line_length = 120 - indent.length
|
63
|
+
block_str = "".dup
|
64
|
+
triple_quotes = "\"\"\"\n"
|
65
|
+
block_str << indent
|
66
|
+
block_str << triple_quotes
|
63
67
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
if str.include?("\n")
|
69
|
+
str.split("\n") do |line|
|
70
|
+
if line == ''
|
71
|
+
block_str << "\n"
|
72
|
+
else
|
73
|
+
break_line(line, line_length) do |subline|
|
74
|
+
block_str << indent
|
75
|
+
block_str << subline
|
76
|
+
block_str << "\n"
|
77
|
+
end
|
73
78
|
end
|
74
79
|
end
|
80
|
+
else
|
81
|
+
break_line(str, line_length) do |subline|
|
82
|
+
block_str << indent
|
83
|
+
block_str << subline
|
84
|
+
block_str << "\n"
|
85
|
+
end
|
75
86
|
end
|
76
87
|
|
77
|
-
block_str <<
|
88
|
+
block_str << indent
|
89
|
+
block_str << triple_quotes
|
78
90
|
end
|
79
91
|
|
80
92
|
private
|
81
93
|
|
82
94
|
def self.break_line(line, length)
|
83
|
-
return
|
95
|
+
return yield(line) if line.length < length + 5
|
84
96
|
|
85
97
|
parts = line.split(Regexp.new("((?: |^).{15,#{length - 40}}(?= |$))"))
|
86
|
-
return
|
98
|
+
return yield(line) if parts.length < 4
|
87
99
|
|
88
|
-
|
100
|
+
yield(parts.slice!(0, 3).join)
|
89
101
|
|
90
102
|
parts.each_with_index do |part, i|
|
91
103
|
next if i % 2 == 1
|
92
|
-
|
104
|
+
yield "#{part[1..-1]}#{parts[i + 1]}"
|
93
105
|
end
|
94
106
|
|
95
|
-
|
107
|
+
nil
|
96
108
|
end
|
97
109
|
end
|
98
110
|
end
|
@@ -42,24 +42,30 @@ module GraphQL
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def build_schema_node
|
45
|
-
schema_options = {
|
46
|
-
# `@schema.directives` is covered by `build_definition_nodes`
|
47
|
-
directives: definition_directives(@schema, :schema_directives),
|
48
|
-
}
|
49
45
|
if !schema_respects_root_name_conventions?(@schema)
|
50
|
-
|
46
|
+
GraphQL::Language::Nodes::SchemaDefinition.new(
|
51
47
|
query: (q = warden.root_type_for_operation("query")) && q.graphql_name,
|
52
48
|
mutation: (m = warden.root_type_for_operation("mutation")) && m.graphql_name,
|
53
49
|
subscription: (s = warden.root_type_for_operation("subscription")) && s.graphql_name,
|
54
|
-
|
50
|
+
directives: definition_directives(@schema, :schema_directives)
|
51
|
+
)
|
52
|
+
else
|
53
|
+
# A plain `schema ...` _must_ include root type definitions.
|
54
|
+
# If the only difference is directives, then you have to use `extend schema`
|
55
|
+
GraphQL::Language::Nodes::SchemaExtension.new(directives: definition_directives(@schema, :schema_directives))
|
55
56
|
end
|
56
|
-
GraphQL::Language::Nodes::SchemaDefinition.new(schema_options)
|
57
57
|
end
|
58
58
|
|
59
59
|
def build_object_type_node(object_type)
|
60
|
+
ints = warden.interfaces(object_type)
|
61
|
+
if ints.any?
|
62
|
+
ints.sort_by!(&:graphql_name)
|
63
|
+
ints.map! { |iface| build_type_name_node(iface) }
|
64
|
+
end
|
65
|
+
|
60
66
|
GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
61
67
|
name: object_type.graphql_name,
|
62
|
-
interfaces:
|
68
|
+
interfaces: ints,
|
63
69
|
fields: build_field_nodes(warden.fields(object_type)),
|
64
70
|
description: object_type.description,
|
65
71
|
directives: directives(object_type),
|
@@ -180,7 +186,8 @@ module GraphQL
|
|
180
186
|
of_type: build_type_name_node(type.of_type)
|
181
187
|
)
|
182
188
|
else
|
183
|
-
|
189
|
+
@cached_type_name_nodes ||= {}
|
190
|
+
@cached_type_name_nodes[type.graphql_name] ||= GraphQL::Language::Nodes::TypeName.new(name: type.graphql_name)
|
184
191
|
end
|
185
192
|
end
|
186
193
|
|
@@ -237,9 +244,13 @@ module GraphQL
|
|
237
244
|
end
|
238
245
|
|
239
246
|
def build_argument_nodes(arguments)
|
240
|
-
arguments
|
241
|
-
.map { |arg| build_argument_node(arg) }
|
242
|
-
.sort_by(&:name)
|
247
|
+
if arguments.any?
|
248
|
+
nodes = arguments.map { |arg| build_argument_node(arg) }
|
249
|
+
nodes.sort_by!(&:name)
|
250
|
+
nodes
|
251
|
+
else
|
252
|
+
arguments
|
253
|
+
end
|
243
254
|
end
|
244
255
|
|
245
256
|
def build_directive_nodes(directives)
|
@@ -253,16 +264,16 @@ module GraphQL
|
|
253
264
|
if !include_built_in_directives
|
254
265
|
dirs_to_build = dirs_to_build.reject { |directive| directive.default_directive? }
|
255
266
|
end
|
256
|
-
|
267
|
+
definitions = build_directive_nodes(dirs_to_build)
|
257
268
|
|
258
269
|
type_nodes = build_type_definition_nodes(warden.reachable_types)
|
259
270
|
|
260
271
|
if @include_one_of
|
261
272
|
# This may have been set to true when iterating over all types
|
262
|
-
|
273
|
+
definitions.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
263
274
|
end
|
264
275
|
|
265
|
-
definitions
|
276
|
+
definitions.concat(type_nodes)
|
266
277
|
if include_schema_node?
|
267
278
|
definitions.unshift(build_schema_node)
|
268
279
|
end
|
@@ -285,9 +296,9 @@ module GraphQL
|
|
285
296
|
end
|
286
297
|
|
287
298
|
def build_field_nodes(fields)
|
288
|
-
fields
|
289
|
-
|
290
|
-
|
299
|
+
f_nodes = fields.map { |field| build_field_node(field) }
|
300
|
+
f_nodes.sort_by!(&:name)
|
301
|
+
f_nodes
|
291
302
|
end
|
292
303
|
|
293
304
|
private
|
@@ -310,7 +321,7 @@ module GraphQL
|
|
310
321
|
|
311
322
|
def definition_directives(member, directives_method)
|
312
323
|
dirs = if !member.respond_to?(directives_method) || member.directives.empty?
|
313
|
-
|
324
|
+
EmptyObjects::EMPTY_ARRAY
|
314
325
|
else
|
315
326
|
member.public_send(directives_method).map do |dir|
|
316
327
|
args = []
|
@@ -323,7 +323,7 @@ module GraphQL
|
|
323
323
|
# @return [String, Float, Integer, Boolean, Array, InputObject, VariableIdentifier] The value passed for this key
|
324
324
|
|
325
325
|
def children
|
326
|
-
@children ||= Array(value).flatten.select { |v| v.is_a?(AbstractNode) }
|
326
|
+
@children ||= Array(value).flatten.tap { _1.select! { |v| v.is_a?(AbstractNode) } }
|
327
327
|
end
|
328
328
|
end
|
329
329
|
|
@@ -74,7 +74,8 @@ module GraphQL
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def print_argument(argument)
|
77
|
-
print_string(
|
77
|
+
print_string(argument.name)
|
78
|
+
print_string(": ")
|
78
79
|
print_node(argument.value)
|
79
80
|
end
|
80
81
|
|
@@ -88,7 +89,8 @@ module GraphQL
|
|
88
89
|
end
|
89
90
|
|
90
91
|
def print_directive(directive)
|
91
|
-
print_string("
|
92
|
+
print_string("@")
|
93
|
+
print_string(directive.name)
|
92
94
|
|
93
95
|
if directive.arguments.any?
|
94
96
|
print_string("(")
|
@@ -110,7 +112,10 @@ module GraphQL
|
|
110
112
|
|
111
113
|
def print_field(field, indent: "")
|
112
114
|
print_string(indent)
|
113
|
-
|
115
|
+
if field.alias
|
116
|
+
print_string(field.alias)
|
117
|
+
print_string(": ")
|
118
|
+
end
|
114
119
|
print_string(field.name)
|
115
120
|
if field.arguments.any?
|
116
121
|
print_string("(")
|
@@ -125,7 +130,13 @@ module GraphQL
|
|
125
130
|
end
|
126
131
|
|
127
132
|
def print_fragment_definition(fragment_def, indent: "")
|
128
|
-
print_string(
|
133
|
+
print_string(indent)
|
134
|
+
print_string("fragment")
|
135
|
+
if fragment_def.name
|
136
|
+
print_string(" ")
|
137
|
+
print_string(fragment_def.name)
|
138
|
+
end
|
139
|
+
|
129
140
|
if fragment_def.type
|
130
141
|
print_string(" on ")
|
131
142
|
print_node(fragment_def.type)
|
@@ -135,12 +146,15 @@ module GraphQL
|
|
135
146
|
end
|
136
147
|
|
137
148
|
def print_fragment_spread(fragment_spread, indent: "")
|
138
|
-
print_string(
|
149
|
+
print_string(indent)
|
150
|
+
print_string("...")
|
151
|
+
print_string(fragment_spread.name)
|
139
152
|
print_directives(fragment_spread.directives)
|
140
153
|
end
|
141
154
|
|
142
155
|
def print_inline_fragment(inline_fragment, indent: "")
|
143
|
-
print_string(
|
156
|
+
print_string(indent)
|
157
|
+
print_string("...")
|
144
158
|
if inline_fragment.type
|
145
159
|
print_string(" on ")
|
146
160
|
print_node(inline_fragment.type)
|
@@ -161,8 +175,12 @@ module GraphQL
|
|
161
175
|
end
|
162
176
|
|
163
177
|
def print_operation_definition(operation_definition, indent: "")
|
164
|
-
print_string(
|
165
|
-
print_string(
|
178
|
+
print_string(indent)
|
179
|
+
print_string(operation_definition.operation_type)
|
180
|
+
if operation_definition.name
|
181
|
+
print_string(" ")
|
182
|
+
print_string(operation_definition.name)
|
183
|
+
end
|
166
184
|
|
167
185
|
if operation_definition.variables.any?
|
168
186
|
print_string("(")
|
@@ -182,7 +200,9 @@ module GraphQL
|
|
182
200
|
end
|
183
201
|
|
184
202
|
def print_variable_definition(variable_definition)
|
185
|
-
print_string("
|
203
|
+
print_string("$")
|
204
|
+
print_string(variable_definition.name)
|
205
|
+
print_string(": ")
|
186
206
|
print_node(variable_definition.type)
|
187
207
|
unless variable_definition.default_value.nil?
|
188
208
|
print_string(" = ")
|
@@ -191,7 +211,8 @@ module GraphQL
|
|
191
211
|
end
|
192
212
|
|
193
213
|
def print_variable_identifier(variable_identifier)
|
194
|
-
print_string("
|
214
|
+
print_string("$")
|
215
|
+
print_string(variable_identifier.name)
|
195
216
|
end
|
196
217
|
|
197
218
|
def print_schema_definition(schema, extension: false)
|
@@ -231,24 +252,35 @@ module GraphQL
|
|
231
252
|
|
232
253
|
def print_scalar_type_definition(scalar_type, extension: false)
|
233
254
|
extension ? print_string("extend ") : print_description(scalar_type)
|
234
|
-
print_string("scalar
|
255
|
+
print_string("scalar ")
|
256
|
+
print_string(scalar_type.name)
|
235
257
|
print_directives(scalar_type.directives)
|
236
258
|
end
|
237
259
|
|
238
260
|
def print_object_type_definition(object_type, extension: false)
|
239
261
|
extension ? print_string("extend ") : print_description(object_type)
|
240
|
-
print_string("type
|
262
|
+
print_string("type ")
|
263
|
+
print_string(object_type.name)
|
241
264
|
print_implements(object_type) unless object_type.interfaces.empty?
|
242
265
|
print_directives(object_type.directives)
|
243
266
|
print_field_definitions(object_type.fields)
|
244
267
|
end
|
245
268
|
|
246
269
|
def print_implements(type)
|
247
|
-
print_string(" implements
|
270
|
+
print_string(" implements ")
|
271
|
+
i = 0
|
272
|
+
type.interfaces.each do |int|
|
273
|
+
if i > 0
|
274
|
+
print_string(" & ")
|
275
|
+
end
|
276
|
+
print_string(int.name)
|
277
|
+
i += 1
|
278
|
+
end
|
248
279
|
end
|
249
280
|
|
250
281
|
def print_input_value_definition(input_value)
|
251
|
-
print_string(
|
282
|
+
print_string(input_value.name)
|
283
|
+
print_string(": ")
|
252
284
|
print_node(input_value.type)
|
253
285
|
unless input_value.default_value.nil?
|
254
286
|
print_string(" = ")
|
@@ -271,11 +303,14 @@ module GraphQL
|
|
271
303
|
print_string("(\n")
|
272
304
|
arguments.each_with_index do |arg, i|
|
273
305
|
print_description(arg, indent: " " + indent, first_in_block: i == 0)
|
274
|
-
print_string("
|
306
|
+
print_string(" ")
|
307
|
+
print_string(indent)
|
275
308
|
print_input_value_definition(arg)
|
276
309
|
print_string("\n") if i < arguments.size - 1
|
277
310
|
end
|
278
|
-
print_string("\n
|
311
|
+
print_string("\n")
|
312
|
+
print_string(indent)
|
313
|
+
print_string(")")
|
279
314
|
end
|
280
315
|
|
281
316
|
def print_field_definition(field)
|
@@ -290,7 +325,8 @@ module GraphQL
|
|
290
325
|
|
291
326
|
def print_interface_type_definition(interface_type, extension: false)
|
292
327
|
extension ? print_string("extend ") : print_description(interface_type)
|
293
|
-
print_string("interface
|
328
|
+
print_string("interface ")
|
329
|
+
print_string(interface_type.name)
|
294
330
|
print_implements(interface_type) if interface_type.interfaces.any?
|
295
331
|
print_directives(interface_type.directives)
|
296
332
|
print_field_definitions(interface_type.fields)
|
@@ -298,14 +334,24 @@ module GraphQL
|
|
298
334
|
|
299
335
|
def print_union_type_definition(union_type, extension: false)
|
300
336
|
extension ? print_string("extend ") : print_description(union_type)
|
301
|
-
print_string("union
|
337
|
+
print_string("union ")
|
338
|
+
print_string(union_type.name)
|
302
339
|
print_directives(union_type.directives)
|
303
|
-
print_string(" =
|
340
|
+
print_string(" = ")
|
341
|
+
i = 0
|
342
|
+
union_type.types.each do |t|
|
343
|
+
if i > 0
|
344
|
+
print_string(" | ")
|
345
|
+
end
|
346
|
+
print_string(t.name)
|
347
|
+
i += 1
|
348
|
+
end
|
304
349
|
end
|
305
350
|
|
306
351
|
def print_enum_type_definition(enum_type, extension: false)
|
307
352
|
extension ? print_string("extend ") : print_description(enum_type)
|
308
|
-
print_string("enum
|
353
|
+
print_string("enum ")
|
354
|
+
print_string(enum_type.name)
|
309
355
|
print_directives(enum_type.directives)
|
310
356
|
print_string(" {\n")
|
311
357
|
enum_type.values.each.with_index do |value, i|
|
@@ -316,14 +362,16 @@ module GraphQL
|
|
316
362
|
end
|
317
363
|
|
318
364
|
def print_enum_value_definition(enum_value)
|
319
|
-
print_string("
|
365
|
+
print_string(" ")
|
366
|
+
print_string(enum_value.name)
|
320
367
|
print_directives(enum_value.directives)
|
321
368
|
print_string("\n")
|
322
369
|
end
|
323
370
|
|
324
371
|
def print_input_object_type_definition(input_object_type, extension: false)
|
325
372
|
extension ? print_string("extend ") : print_description(input_object_type)
|
326
|
-
print_string("input
|
373
|
+
print_string("input ")
|
374
|
+
print_string(input_object_type.name)
|
327
375
|
print_directives(input_object_type.directives)
|
328
376
|
if !input_object_type.fields.empty?
|
329
377
|
print_string(" {\n")
|
@@ -339,7 +387,8 @@ module GraphQL
|
|
339
387
|
|
340
388
|
def print_directive_definition(directive)
|
341
389
|
print_description(directive)
|
342
|
-
print_string("directive
|
390
|
+
print_string("directive @")
|
391
|
+
print_string(directive.name)
|
343
392
|
|
344
393
|
if directive.arguments.any?
|
345
394
|
print_arguments(directive.arguments)
|
@@ -349,7 +398,15 @@ module GraphQL
|
|
349
398
|
print_string(" repeatable")
|
350
399
|
end
|
351
400
|
|
352
|
-
print_string(" on
|
401
|
+
print_string(" on ")
|
402
|
+
i = 0
|
403
|
+
directive.locations.each do |loc|
|
404
|
+
if i > 0
|
405
|
+
print_string(" | ")
|
406
|
+
end
|
407
|
+
print_string(loc.name)
|
408
|
+
i += 1
|
409
|
+
end
|
353
410
|
end
|
354
411
|
|
355
412
|
def print_description(node, indent: "", first_in_block: true)
|
@@ -363,11 +420,13 @@ module GraphQL
|
|
363
420
|
return if fields.empty?
|
364
421
|
|
365
422
|
print_string(" {\n")
|
366
|
-
|
423
|
+
i = 0
|
424
|
+
fields.each do |field|
|
367
425
|
print_description(field, indent: " ", first_in_block: i == 0)
|
368
426
|
print_string(" ")
|
369
427
|
print_field_definition(field)
|
370
428
|
print_string("\n")
|
429
|
+
i += 1
|
371
430
|
end
|
372
431
|
print_string("}")
|
373
432
|
end
|
@@ -389,7 +448,8 @@ module GraphQL
|
|
389
448
|
print_node(selection, indent: indent + " ")
|
390
449
|
print_string("\n")
|
391
450
|
end
|
392
|
-
print_string(
|
451
|
+
print_string(indent)
|
452
|
+
print_string("}")
|
393
453
|
end
|
394
454
|
|
395
455
|
def print_node(node, indent: "")
|
@@ -474,7 +534,8 @@ module GraphQL
|
|
474
534
|
when Hash
|
475
535
|
print_string("{")
|
476
536
|
node.each_with_index do |(k, v), i|
|
477
|
-
print_string(
|
537
|
+
print_string(k)
|
538
|
+
print_string(": ")
|
478
539
|
print_node(v)
|
479
540
|
print_string(", ") if i < node.length - 1
|
480
541
|
end
|
@@ -203,7 +203,12 @@ module GraphQL
|
|
203
203
|
[value].map { |v| value_to_ast(v, type.of_type) }
|
204
204
|
end
|
205
205
|
when "ENUM"
|
206
|
-
GraphQL::Language::Nodes::Enum
|
206
|
+
if value.is_a?(GraphQL::Language::Nodes::Enum)
|
207
|
+
# if it was a default value, it's already wrapped
|
208
|
+
value
|
209
|
+
else
|
210
|
+
GraphQL::Language::Nodes::Enum.new(name: value)
|
211
|
+
end
|
207
212
|
else
|
208
213
|
value
|
209
214
|
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Language
|
4
|
+
# Like `GraphQL::Language::Visitor` except it doesn't support
|
5
|
+
# making changes to the document -- only visiting it as-is.
|
6
|
+
class StaticVisitor
|
7
|
+
def initialize(document)
|
8
|
+
@document = document
|
9
|
+
end
|
10
|
+
|
11
|
+
# Visit `document` and all children
|
12
|
+
# @return [void]
|
13
|
+
def visit
|
14
|
+
# `@document` may be any kind of node:
|
15
|
+
visit_method = @document.visit_method
|
16
|
+
result = public_send(visit_method, @document, nil)
|
17
|
+
@result = if result.is_a?(Array)
|
18
|
+
result.first
|
19
|
+
else
|
20
|
+
# The node wasn't modified
|
21
|
+
@document
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# We don't use `alias` here because it breaks `super`
|
26
|
+
def self.make_visit_methods(ast_node_class)
|
27
|
+
node_method = ast_node_class.visit_method
|
28
|
+
children_of_type = ast_node_class.children_of_type
|
29
|
+
child_visit_method = :"#{node_method}_children"
|
30
|
+
|
31
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
32
|
+
# The default implementation for visiting an AST node.
|
33
|
+
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
34
|
+
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
35
|
+
# in your subclasses.
|
36
|
+
#
|
37
|
+
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
38
|
+
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
39
|
+
# @return [void]
|
40
|
+
def #{node_method}(node, parent)
|
41
|
+
#{
|
42
|
+
if method_defined?(child_visit_method)
|
43
|
+
"#{child_visit_method}(node)"
|
44
|
+
elsif children_of_type
|
45
|
+
children_of_type.map do |child_accessor, child_class|
|
46
|
+
"node.#{child_accessor}.each do |child_node|
|
47
|
+
#{child_class.visit_method}(child_node, node)
|
48
|
+
end"
|
49
|
+
end.join("\n")
|
50
|
+
else
|
51
|
+
""
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
|
58
|
+
def on_document_children(document_node)
|
59
|
+
document_node.children.each do |child_node|
|
60
|
+
visit_method = child_node.visit_method
|
61
|
+
public_send(visit_method, child_node, document_node)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def on_field_children(new_node)
|
66
|
+
new_node.arguments.each do |arg_node| # rubocop:disable Development/ContextIsPassedCop
|
67
|
+
on_argument(arg_node, new_node)
|
68
|
+
end
|
69
|
+
visit_directives(new_node)
|
70
|
+
visit_selections(new_node)
|
71
|
+
end
|
72
|
+
|
73
|
+
def visit_directives(new_node)
|
74
|
+
new_node.directives.each do |dir_node|
|
75
|
+
on_directive(dir_node, new_node)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_selections(new_node)
|
80
|
+
new_node.selections.each do |selection|
|
81
|
+
case selection
|
82
|
+
when GraphQL::Language::Nodes::Field
|
83
|
+
on_field(selection, new_node)
|
84
|
+
when GraphQL::Language::Nodes::InlineFragment
|
85
|
+
on_inline_fragment(selection, new_node)
|
86
|
+
when GraphQL::Language::Nodes::FragmentSpread
|
87
|
+
on_fragment_spread(selection, new_node)
|
88
|
+
else
|
89
|
+
raise ArgumentError, "Invariant: unexpected field selection #{selection.class} (#{selection.inspect})"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def on_fragment_definition_children(new_node)
|
95
|
+
visit_directives(new_node)
|
96
|
+
visit_selections(new_node)
|
97
|
+
end
|
98
|
+
|
99
|
+
alias :on_inline_fragment_children :on_fragment_definition_children
|
100
|
+
|
101
|
+
def on_operation_definition_children(new_node)
|
102
|
+
new_node.variables.each do |arg_node|
|
103
|
+
on_variable_definition(arg_node, new_node)
|
104
|
+
end
|
105
|
+
visit_directives(new_node)
|
106
|
+
visit_selections(new_node)
|
107
|
+
end
|
108
|
+
|
109
|
+
def on_argument_children(new_node)
|
110
|
+
new_node.children.each do |value_node|
|
111
|
+
case value_node
|
112
|
+
when Language::Nodes::VariableIdentifier
|
113
|
+
on_variable_identifier(value_node, new_node)
|
114
|
+
when Language::Nodes::InputObject
|
115
|
+
on_input_object(value_node, new_node)
|
116
|
+
when Language::Nodes::Enum
|
117
|
+
on_enum(value_node, new_node)
|
118
|
+
when Language::Nodes::NullValue
|
119
|
+
on_null_value(value_node, new_node)
|
120
|
+
else
|
121
|
+
raise ArgumentError, "Invariant: unexpected argument value node #{value_node.class} (#{value_node.inspect})"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
[
|
127
|
+
Language::Nodes::Argument,
|
128
|
+
Language::Nodes::Directive,
|
129
|
+
Language::Nodes::DirectiveDefinition,
|
130
|
+
Language::Nodes::DirectiveLocation,
|
131
|
+
Language::Nodes::Document,
|
132
|
+
Language::Nodes::Enum,
|
133
|
+
Language::Nodes::EnumTypeDefinition,
|
134
|
+
Language::Nodes::EnumTypeExtension,
|
135
|
+
Language::Nodes::EnumValueDefinition,
|
136
|
+
Language::Nodes::Field,
|
137
|
+
Language::Nodes::FieldDefinition,
|
138
|
+
Language::Nodes::FragmentDefinition,
|
139
|
+
Language::Nodes::FragmentSpread,
|
140
|
+
Language::Nodes::InlineFragment,
|
141
|
+
Language::Nodes::InputObject,
|
142
|
+
Language::Nodes::InputObjectTypeDefinition,
|
143
|
+
Language::Nodes::InputObjectTypeExtension,
|
144
|
+
Language::Nodes::InputValueDefinition,
|
145
|
+
Language::Nodes::InterfaceTypeDefinition,
|
146
|
+
Language::Nodes::InterfaceTypeExtension,
|
147
|
+
Language::Nodes::ListType,
|
148
|
+
Language::Nodes::NonNullType,
|
149
|
+
Language::Nodes::NullValue,
|
150
|
+
Language::Nodes::ObjectTypeDefinition,
|
151
|
+
Language::Nodes::ObjectTypeExtension,
|
152
|
+
Language::Nodes::OperationDefinition,
|
153
|
+
Language::Nodes::ScalarTypeDefinition,
|
154
|
+
Language::Nodes::ScalarTypeExtension,
|
155
|
+
Language::Nodes::SchemaDefinition,
|
156
|
+
Language::Nodes::SchemaExtension,
|
157
|
+
Language::Nodes::TypeName,
|
158
|
+
Language::Nodes::UnionTypeDefinition,
|
159
|
+
Language::Nodes::UnionTypeExtension,
|
160
|
+
Language::Nodes::VariableDefinition,
|
161
|
+
Language::Nodes::VariableIdentifier,
|
162
|
+
].each do |ast_node_class|
|
163
|
+
make_visit_methods(ast_node_class)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
data/lib/graphql/language.rb
CHANGED
@@ -8,6 +8,7 @@ require "graphql/language/lexer"
|
|
8
8
|
require "graphql/language/nodes"
|
9
9
|
require "graphql/language/cache"
|
10
10
|
require "graphql/language/parser"
|
11
|
+
require "graphql/language/static_visitor"
|
11
12
|
require "graphql/language/token"
|
12
13
|
require "graphql/language/visitor"
|
13
14
|
require "graphql/language/definition_slice"
|