graphql 2.0.27 → 2.1.3

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.

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