graphql 2.0.27 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  3. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  4. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  5. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  6. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  7. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  8. data/lib/generators/graphql/templates/base_field.erb +2 -0
  9. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  10. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  11. data/lib/generators/graphql/templates/base_object.erb +2 -0
  12. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  13. data/lib/generators/graphql/templates/base_union.erb +2 -0
  14. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  15. data/lib/generators/graphql/templates/loader.erb +2 -0
  16. data/lib/generators/graphql/templates/mutation.erb +2 -0
  17. data/lib/generators/graphql/templates/node_type.erb +2 -0
  18. data/lib/generators/graphql/templates/query_type.erb +2 -0
  19. data/lib/generators/graphql/templates/schema.erb +2 -0
  20. data/lib/graphql/analysis/ast/analyzer.rb +7 -0
  21. data/lib/graphql/analysis/ast/query_depth.rb +7 -2
  22. data/lib/graphql/analysis/ast/visitor.rb +2 -2
  23. data/lib/graphql/analysis/ast.rb +15 -11
  24. data/lib/graphql/dataloader/source.rb +7 -0
  25. data/lib/graphql/dataloader.rb +38 -10
  26. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
  27. data/lib/graphql/execution/interpreter/runtime.rb +95 -254
  28. data/lib/graphql/execution/interpreter.rb +0 -6
  29. data/lib/graphql/execution/lookahead.rb +1 -1
  30. data/lib/graphql/introspection/dynamic_fields.rb +1 -1
  31. data/lib/graphql/introspection/entry_points.rb +2 -2
  32. data/lib/graphql/language/block_string.rb +28 -16
  33. data/lib/graphql/language/definition_slice.rb +1 -1
  34. data/lib/graphql/language/document_from_schema_definition.rb +36 -35
  35. data/lib/graphql/language/nodes.rb +2 -2
  36. data/lib/graphql/language/printer.rb +294 -145
  37. data/lib/graphql/language/sanitized_printer.rb +20 -22
  38. data/lib/graphql/language/static_visitor.rb +167 -0
  39. data/lib/graphql/language/visitor.rb +20 -81
  40. data/lib/graphql/language.rb +1 -0
  41. data/lib/graphql/pagination/connection.rb +23 -1
  42. data/lib/graphql/query/context/scoped_context.rb +101 -0
  43. data/lib/graphql/query/context.rb +32 -98
  44. data/lib/graphql/query.rb +2 -19
  45. data/lib/graphql/rake_task.rb +3 -12
  46. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  47. data/lib/graphql/schema/field/connection_extension.rb +1 -15
  48. data/lib/graphql/schema/field/scope_extension.rb +7 -1
  49. data/lib/graphql/schema/field.rb +7 -4
  50. data/lib/graphql/schema/has_single_input_argument.rb +156 -0
  51. data/lib/graphql/schema/introspection_system.rb +2 -0
  52. data/lib/graphql/schema/member/base_dsl_methods.rb +2 -1
  53. data/lib/graphql/schema/member/has_arguments.rb +19 -4
  54. data/lib/graphql/schema/member/has_fields.rb +4 -1
  55. data/lib/graphql/schema/member/has_interfaces.rb +21 -7
  56. data/lib/graphql/schema/member/scoped.rb +19 -0
  57. data/lib/graphql/schema/object.rb +8 -0
  58. data/lib/graphql/schema/printer.rb +8 -7
  59. data/lib/graphql/schema/relay_classic_mutation.rb +6 -128
  60. data/lib/graphql/schema/resolver.rb +4 -0
  61. data/lib/graphql/schema/scalar.rb +3 -3
  62. data/lib/graphql/schema/subscription.rb +11 -4
  63. data/lib/graphql/schema/warden.rb +87 -89
  64. data/lib/graphql/schema.rb +125 -55
  65. data/lib/graphql/static_validation/all_rules.rb +1 -1
  66. data/lib/graphql/static_validation/base_visitor.rb +1 -1
  67. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  68. data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
  69. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
  70. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
  71. data/lib/graphql/static_validation/validation_context.rb +5 -5
  72. data/lib/graphql/static_validation.rb +0 -1
  73. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
  74. data/lib/graphql/subscriptions.rb +11 -6
  75. data/lib/graphql/tracing/appoptics_trace.rb +2 -2
  76. data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
  77. data/lib/graphql/types/relay/connection_behaviors.rb +19 -2
  78. data/lib/graphql/types/relay/edge_behaviors.rb +7 -0
  79. data/lib/graphql/version.rb +1 -1
  80. data/lib/graphql.rb +1 -2
  81. metadata +23 -20
  82. data/lib/graphql/filter.rb +0 -59
  83. data/lib/graphql/static_validation/type_stack.rb +0 -216
@@ -2,6 +2,32 @@
2
2
  module GraphQL
3
3
  module Language
4
4
  class Printer
5
+ OMISSION = "... (truncated)"
6
+
7
+ class TruncatableBuffer
8
+ class TruncateSizeReached < StandardError; end
9
+
10
+ DEFAULT_INIT_CAPACITY = 500
11
+
12
+ def initialize(truncate_size: nil)
13
+ @out = String.new(capacity: truncate_size || DEFAULT_INIT_CAPACITY)
14
+ @truncate_size = truncate_size
15
+ end
16
+
17
+ def append(other)
18
+ if @truncate_size && (@out.size + other.size) > @truncate_size
19
+ @out << other.slice(0, @truncate_size - @out.size)
20
+ raise(TruncateSizeReached, "Truncate size reached")
21
+ else
22
+ @out << other
23
+ end
24
+ end
25
+
26
+ def to_string
27
+ @out
28
+ end
29
+ end
30
+
5
31
  # Turn an arbitrary AST node back into a string.
6
32
  #
7
33
  # @example Turning a document into a query string
@@ -14,121 +40,179 @@ module GraphQL
14
40
  #
15
41
  # class MyPrinter < GraphQL::Language::Printer
16
42
  # def print_argument(arg)
17
- # "#{arg.name}: <HIDDEN>"
43
+ # print_string("#{arg.name}: <HIDDEN>")
18
44
  # end
19
45
  # end
20
46
  #
21
47
  # MyPrinter.new.print(document)
22
48
  # # => "mutation { pay(creditCard: <HIDDEN>) { success } }"
23
49
  #
24
- #
50
+ # @param node [Nodes::AbstractNode]
25
51
  # @param indent [String] Whitespace to add to the printed node
52
+ # @param truncate_size [Integer, nil] The size to truncate to.
26
53
  # @return [String] Valid GraphQL for `node`
27
- def print(node, indent: "")
54
+ def print(node, indent: "", truncate_size: nil)
55
+ truncate_size = truncate_size ? [truncate_size - OMISSION.size, 0].max : nil
56
+ @out = TruncatableBuffer.new(truncate_size: truncate_size)
28
57
  print_node(node, indent: indent)
58
+ @out.to_string
59
+ rescue TruncatableBuffer::TruncateSizeReached
60
+ @out.to_string << OMISSION
29
61
  end
30
62
 
31
63
  protected
32
64
 
65
+ def print_string(str)
66
+ @out.append(str)
67
+ end
68
+
33
69
  def print_document(document)
34
- document.definitions.map { |d| print_node(d) }.join("\n\n")
70
+ document.definitions.each_with_index do |d, i|
71
+ print_node(d)
72
+ print_string("\n\n") if i < document.definitions.size - 1
73
+ end
35
74
  end
36
75
 
37
76
  def print_argument(argument)
38
- "#{argument.name}: #{print_node(argument.value)}".dup
77
+ print_string(argument.name)
78
+ print_string(": ")
79
+ print_node(argument.value)
80
+ end
81
+
82
+ def print_input_object(input_object)
83
+ print_string("{")
84
+ input_object.arguments.each_with_index do |a, i|
85
+ print_argument(a)
86
+ print_string(", ") if i < input_object.arguments.size - 1
87
+ end
88
+ print_string("}")
39
89
  end
40
90
 
41
91
  def print_directive(directive)
42
- out = "@#{directive.name}".dup
92
+ print_string("@")
93
+ print_string(directive.name)
43
94
 
44
95
  if directive.arguments.any?
45
- out << "(#{directive.arguments.map { |a| print_argument(a) }.join(", ")})"
96
+ print_string("(")
97
+ directive.arguments.each_with_index do |a, i|
98
+ print_argument(a)
99
+ print_string(", ") if i < directive.arguments.size - 1
100
+ end
101
+ print_string(")")
46
102
  end
47
-
48
- out
49
103
  end
50
104
 
51
105
  def print_enum(enum)
52
- "#{enum.name}".dup
106
+ print_string(enum.name)
53
107
  end
54
108
 
55
109
  def print_null_value
56
- "null".dup
110
+ print_string("null")
57
111
  end
58
112
 
59
113
  def print_field(field, indent: "")
60
- out = "#{indent}".dup
61
- out << "#{field.alias}: " if field.alias
62
- out << "#{field.name}"
63
- out << "(#{field.arguments.map { |a| print_argument(a) }.join(", ")})" if field.arguments.any?
64
- out << print_directives(field.directives)
65
- out << print_selections(field.selections, indent: indent)
66
- out
114
+ print_string(indent)
115
+ if field.alias
116
+ print_string(field.alias)
117
+ print_string(": ")
118
+ end
119
+ print_string(field.name)
120
+ if field.arguments.any?
121
+ print_string("(")
122
+ field.arguments.each_with_index do |a, i|
123
+ print_argument(a)
124
+ print_string(", ") if i < field.arguments.size - 1
125
+ end
126
+ print_string(")")
127
+ end
128
+ print_directives(field.directives)
129
+ print_selections(field.selections, indent: indent)
67
130
  end
68
131
 
69
132
  def print_fragment_definition(fragment_def, indent: "")
70
- out = "#{indent}fragment #{fragment_def.name}".dup
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
+
71
140
  if fragment_def.type
72
- out << " on #{print_node(fragment_def.type)}"
141
+ print_string(" on ")
142
+ print_node(fragment_def.type)
73
143
  end
74
- out << print_directives(fragment_def.directives)
75
- out << print_selections(fragment_def.selections, indent: indent)
76
- out
144
+ print_directives(fragment_def.directives)
145
+ print_selections(fragment_def.selections, indent: indent)
77
146
  end
78
147
 
79
148
  def print_fragment_spread(fragment_spread, indent: "")
80
- out = "#{indent}...#{fragment_spread.name}".dup
81
- out << print_directives(fragment_spread.directives)
82
- out
149
+ print_string(indent)
150
+ print_string("...")
151
+ print_string(fragment_spread.name)
152
+ print_directives(fragment_spread.directives)
83
153
  end
84
154
 
85
155
  def print_inline_fragment(inline_fragment, indent: "")
86
- out = "#{indent}...".dup
156
+ print_string(indent)
157
+ print_string("...")
87
158
  if inline_fragment.type
88
- out << " on #{print_node(inline_fragment.type)}"
159
+ print_string(" on ")
160
+ print_node(inline_fragment.type)
89
161
  end
90
- out << print_directives(inline_fragment.directives)
91
- out << print_selections(inline_fragment.selections, indent: indent)
92
- out
93
- end
94
-
95
- def print_input_object(input_object)
96
- "{#{input_object.arguments.map { |a| print_argument(a) }.join(", ")}}"
162
+ print_directives(inline_fragment.directives)
163
+ print_selections(inline_fragment.selections, indent: indent)
97
164
  end
98
165
 
99
166
  def print_list_type(list_type)
100
- "[#{print_node(list_type.of_type)}]".dup
167
+ print_string("[")
168
+ print_node(list_type.of_type)
169
+ print_string("]")
101
170
  end
102
171
 
103
172
  def print_non_null_type(non_null_type)
104
- "#{print_node(non_null_type.of_type)}!".dup
173
+ print_node(non_null_type.of_type)
174
+ print_string("!")
105
175
  end
106
176
 
107
177
  def print_operation_definition(operation_definition, indent: "")
108
- out = "#{indent}#{operation_definition.operation_type}".dup
109
- out << " #{operation_definition.name}" if operation_definition.name
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
110
184
 
111
185
  if operation_definition.variables.any?
112
- out << "(#{operation_definition.variables.map { |v| print_variable_definition(v) }.join(", ")})"
186
+ print_string("(")
187
+ operation_definition.variables.each_with_index do |v, i|
188
+ print_variable_definition(v)
189
+ print_string(", ") if i < operation_definition.variables.size - 1
190
+ end
191
+ print_string(")")
113
192
  end
114
193
 
115
- out << print_directives(operation_definition.directives)
116
- out << print_selections(operation_definition.selections, indent: indent)
117
- out
194
+ print_directives(operation_definition.directives)
195
+ print_selections(operation_definition.selections, indent: indent)
118
196
  end
119
197
 
120
198
  def print_type_name(type_name)
121
- "#{type_name.name}".dup
199
+ print_string(type_name.name)
122
200
  end
123
201
 
124
202
  def print_variable_definition(variable_definition)
125
- out = "$#{variable_definition.name}: #{print_node(variable_definition.type)}".dup
126
- out << " = #{print_node(variable_definition.default_value)}" unless variable_definition.default_value.nil?
127
- out
203
+ print_string("$")
204
+ print_string(variable_definition.name)
205
+ print_string(": ")
206
+ print_node(variable_definition.type)
207
+ unless variable_definition.default_value.nil?
208
+ print_string(" = ")
209
+ print_node(variable_definition.default_value)
210
+ end
128
211
  end
129
212
 
130
213
  def print_variable_identifier(variable_identifier)
131
- "$#{variable_identifier.name}".dup
214
+ print_string("$")
215
+ print_string(variable_identifier.name)
132
216
  end
133
217
 
134
218
  def print_schema_definition(schema, extension: false)
@@ -140,175 +224,232 @@ module GraphQL
140
224
  return
141
225
  end
142
226
 
143
- out = extension ? "extend schema".dup : "schema".dup
227
+ extension ? print_string("extend schema") : print_string("schema")
228
+
144
229
  if schema.directives.any?
145
230
  schema.directives.each do |dir|
146
- out << "\n "
147
- out << print_node(dir)
231
+ print_string("\n ")
232
+ print_node(dir)
148
233
  end
234
+
149
235
  if !has_conventional_names
150
- out << "\n"
236
+ print_string("\n")
151
237
  end
152
238
  end
153
239
 
154
240
  if !has_conventional_names
155
241
  if schema.directives.empty?
156
- out << " "
242
+ print_string(" ")
157
243
  end
158
- out << "{\n"
159
- out << " query: #{schema.query}\n" if schema.query
160
- out << " mutation: #{schema.mutation}\n" if schema.mutation
161
- out << " subscription: #{schema.subscription}\n" if schema.subscription
162
- out << "}"
244
+ print_string("{\n")
245
+ print_string(" query: #{schema.query}\n") if schema.query
246
+ print_string(" mutation: #{schema.mutation}\n") if schema.mutation
247
+ print_string(" subscription: #{schema.subscription}\n") if schema.subscription
248
+ print_string("}")
163
249
  end
164
- out
165
250
  end
166
251
 
252
+
167
253
  def print_scalar_type_definition(scalar_type, extension: false)
168
- out = extension ? "extend ".dup : print_description(scalar_type)
169
- out << "scalar #{scalar_type.name}"
170
- out << print_directives(scalar_type.directives)
254
+ extension ? print_string("extend ") : print_description(scalar_type)
255
+ print_string("scalar ")
256
+ print_string(scalar_type.name)
257
+ print_directives(scalar_type.directives)
171
258
  end
172
259
 
173
260
  def print_object_type_definition(object_type, extension: false)
174
- out = extension ? "extend ".dup : print_description(object_type)
175
- out << "type #{object_type.name}"
176
- out << print_implements(object_type) unless object_type.interfaces.empty?
177
- out << print_directives(object_type.directives)
178
- out << print_field_definitions(object_type.fields)
261
+ extension ? print_string("extend ") : print_description(object_type)
262
+ print_string("type ")
263
+ print_string(object_type.name)
264
+ print_implements(object_type) unless object_type.interfaces.empty?
265
+ print_directives(object_type.directives)
266
+ print_field_definitions(object_type.fields)
179
267
  end
180
268
 
181
269
  def print_implements(type)
182
- " implements #{type.interfaces.map(&:name).join(" & ")}"
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
183
279
  end
184
280
 
185
281
  def print_input_value_definition(input_value)
186
- out = "#{input_value.name}: #{print_node(input_value.type)}".dup
187
- out << " = #{print_node(input_value.default_value)}" unless input_value.default_value.nil?
188
- out << print_directives(input_value.directives)
282
+ print_string(input_value.name)
283
+ print_string(": ")
284
+ print_node(input_value.type)
285
+ unless input_value.default_value.nil?
286
+ print_string(" = ")
287
+ print_node(input_value.default_value)
288
+ end
289
+ print_directives(input_value.directives)
189
290
  end
190
291
 
191
292
  def print_arguments(arguments, indent: "")
192
- if arguments.all?{ |arg| !arg.description }
193
- return "(#{arguments.map{ |arg| print_input_value_definition(arg) }.join(", ")})"
293
+ if arguments.all? { |arg| !arg.description }
294
+ print_string("(")
295
+ arguments.each_with_index do |arg, i|
296
+ print_input_value_definition(arg)
297
+ print_string(", ") if i < arguments.size - 1
298
+ end
299
+ print_string(")")
300
+ return
194
301
  end
195
302
 
196
- out = "(\n".dup
197
- out << arguments.map.with_index{ |arg, i|
198
- "#{print_description(arg, indent: " " + indent, first_in_block: i == 0)} #{indent}"\
199
- "#{print_input_value_definition(arg)}"
200
- }.join("\n")
201
- out << "\n#{indent})"
303
+ print_string("(\n")
304
+ arguments.each_with_index do |arg, i|
305
+ print_description(arg, indent: " " + indent, first_in_block: i == 0)
306
+ print_string(" ")
307
+ print_string(indent)
308
+ print_input_value_definition(arg)
309
+ print_string("\n") if i < arguments.size - 1
310
+ end
311
+ print_string("\n")
312
+ print_string(indent)
313
+ print_string(")")
202
314
  end
203
315
 
204
316
  def print_field_definition(field)
205
- out = field.name.dup
317
+ print_string(field.name)
206
318
  unless field.arguments.empty?
207
- out << print_arguments(field.arguments, indent: " ")
319
+ print_arguments(field.arguments, indent: " ")
208
320
  end
209
- out << ": #{print_node(field.type)}"
210
- out << print_directives(field.directives)
321
+ print_string(": ")
322
+ print_node(field.type)
323
+ print_directives(field.directives)
211
324
  end
212
325
 
213
326
  def print_interface_type_definition(interface_type, extension: false)
214
- out = extension ? "extend ".dup : print_description(interface_type)
215
- out << "interface #{interface_type.name}"
216
- out << print_implements(interface_type) if interface_type.interfaces.any?
217
- out << print_directives(interface_type.directives)
218
- out << print_field_definitions(interface_type.fields)
327
+ extension ? print_string("extend ") : print_description(interface_type)
328
+ print_string("interface ")
329
+ print_string(interface_type.name)
330
+ print_implements(interface_type) if interface_type.interfaces.any?
331
+ print_directives(interface_type.directives)
332
+ print_field_definitions(interface_type.fields)
219
333
  end
220
334
 
221
335
  def print_union_type_definition(union_type, extension: false)
222
- out = extension ? "extend ".dup : print_description(union_type)
223
- out << "union #{union_type.name}"
224
- out << print_directives(union_type.directives)
225
- out << " = " + union_type.types.map(&:name).join(" | ")
336
+ extension ? print_string("extend ") : print_description(union_type)
337
+ print_string("union ")
338
+ print_string(union_type.name)
339
+ print_directives(union_type.directives)
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
226
349
  end
227
350
 
228
351
  def print_enum_type_definition(enum_type, extension: false)
229
- out = extension ? "extend ".dup : print_description(enum_type)
230
- out << "enum #{enum_type.name}#{print_directives(enum_type.directives)} {\n"
352
+ extension ? print_string("extend ") : print_description(enum_type)
353
+ print_string("enum ")
354
+ print_string(enum_type.name)
355
+ print_directives(enum_type.directives)
356
+ print_string(" {\n")
231
357
  enum_type.values.each.with_index do |value, i|
232
- out << print_description(value, indent: ' ', first_in_block: i == 0)
233
- out << print_enum_value_definition(value)
358
+ print_description(value, indent: " ", first_in_block: i == 0)
359
+ print_enum_value_definition(value)
234
360
  end
235
- out << "}"
361
+ print_string("}")
236
362
  end
237
363
 
238
364
  def print_enum_value_definition(enum_value)
239
- out = " #{enum_value.name}".dup
240
- out << print_directives(enum_value.directives)
241
- out << "\n"
365
+ print_string(" ")
366
+ print_string(enum_value.name)
367
+ print_directives(enum_value.directives)
368
+ print_string("\n")
242
369
  end
243
370
 
244
371
  def print_input_object_type_definition(input_object_type, extension: false)
245
- out = extension ? "extend ".dup : print_description(input_object_type)
246
- out << "input #{input_object_type.name}"
247
- out << print_directives(input_object_type.directives)
372
+ extension ? print_string("extend ") : print_description(input_object_type)
373
+ print_string("input ")
374
+ print_string(input_object_type.name)
375
+ print_directives(input_object_type.directives)
248
376
  if !input_object_type.fields.empty?
249
- out << " {\n"
377
+ print_string(" {\n")
250
378
  input_object_type.fields.each.with_index do |field, i|
251
- out << print_description(field, indent: ' ', first_in_block: i == 0)
252
- out << " #{print_input_value_definition(field)}\n"
379
+ print_description(field, indent: " ", first_in_block: i == 0)
380
+ print_string(" ")
381
+ print_input_value_definition(field)
382
+ print_string("\n")
253
383
  end
254
- out << "}"
384
+ print_string("}")
255
385
  end
256
- out
257
386
  end
258
387
 
259
388
  def print_directive_definition(directive)
260
- out = print_description(directive)
261
- out << "directive @#{directive.name}"
389
+ print_description(directive)
390
+ print_string("directive @")
391
+ print_string(directive.name)
262
392
 
263
393
  if directive.arguments.any?
264
- out << print_arguments(directive.arguments)
394
+ print_arguments(directive.arguments)
265
395
  end
266
396
 
267
397
  if directive.repeatable
268
- out << " repeatable"
398
+ print_string(" repeatable")
269
399
  end
270
400
 
271
- out << " on #{directive.locations.map(&:name).join(' | ')}"
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
272
410
  end
273
411
 
274
412
  def print_description(node, indent: "", first_in_block: true)
275
- return ''.dup unless node.description
413
+ return unless node.description
276
414
 
277
- description = indent != '' && !first_in_block ? "\n".dup : "".dup
278
- description << GraphQL::Language::BlockString.print(node.description, indent: indent)
415
+ print_string("\n") if indent != "" && !first_in_block
416
+ print_string(GraphQL::Language::BlockString.print(node.description, indent: indent))
279
417
  end
280
418
 
281
419
  def print_field_definitions(fields)
282
- if fields.empty?
283
- ""
284
- else
285
- out = " {\n".dup
286
- fields.each.with_index do |field, i|
287
- out << print_description(field, indent: ' ', first_in_block: i == 0)
288
- out << " #{print_field_definition(field)}\n"
289
- end
290
- out << "}"
420
+ return if fields.empty?
421
+
422
+ print_string(" {\n")
423
+ i = 0
424
+ fields.each do |field|
425
+ print_description(field, indent: " ", first_in_block: i == 0)
426
+ print_string(" ")
427
+ print_field_definition(field)
428
+ print_string("\n")
429
+ i += 1
291
430
  end
431
+ print_string("}")
292
432
  end
293
433
 
294
434
  def print_directives(directives)
295
- if directives.any?
296
- directives.map { |d| " #{print_directive(d)}" }.join
297
- else
298
- ""
435
+ return if directives.empty?
436
+
437
+ directives.each do |d|
438
+ print_string(" ")
439
+ print_directive(d)
299
440
  end
300
441
  end
301
442
 
302
443
  def print_selections(selections, indent: "")
303
- if selections.any?
304
- out = " {\n".dup
305
- selections.each do |selection|
306
- out << print_node(selection, indent: indent + " ") << "\n"
307
- end
308
- out << "#{indent}}"
309
- else
310
- ""
444
+ return if selections.empty?
445
+
446
+ print_string(" {\n")
447
+ selections.each do |selection|
448
+ print_node(selection, indent: indent + " ")
449
+ print_string("\n")
311
450
  end
451
+ print_string(indent)
452
+ print_string("}")
312
453
  end
313
454
 
314
455
  def print_node(node, indent: "")
@@ -382,19 +523,27 @@ module GraphQL
382
523
  when Nodes::DirectiveDefinition
383
524
  print_directive_definition(node)
384
525
  when FalseClass, Float, Integer, NilClass, String, TrueClass, Symbol
385
- GraphQL::Language.serialize(node)
526
+ print_string(GraphQL::Language.serialize(node))
386
527
  when Array
387
- "[#{node.map { |v| print_node(v) }.join(", ")}]".dup
528
+ print_string("[")
529
+ node.each_with_index do |v, i|
530
+ print_node(v)
531
+ print_string(", ") if i < node.length - 1
532
+ end
533
+ print_string("]")
388
534
  when Hash
389
- "{#{node.map { |k, v| "#{k}: #{print_node(v)}" }.join(", ")}}".dup
535
+ print_string("{")
536
+ node.each_with_index do |(k, v), i|
537
+ print_string(k)
538
+ print_string(": ")
539
+ print_node(v)
540
+ print_string(", ") if i < node.length - 1
541
+ end
542
+ print_string("}")
390
543
  else
391
- GraphQL::Language.serialize(node.to_s)
544
+ print_string(GraphQL::Language.serialize(node.to_s))
392
545
  end
393
546
  end
394
-
395
- private
396
-
397
- attr_reader :node
398
547
  end
399
548
  end
400
549
  end