graphql 1.13.10 → 2.0.2

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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  3. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  4. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  5. data/lib/graphql/analysis/ast/visitor.rb +1 -1
  6. data/lib/graphql/analysis/ast.rb +0 -10
  7. data/lib/graphql/analysis.rb +0 -7
  8. data/lib/graphql/backtrace/table.rb +0 -18
  9. data/lib/graphql/backtrace/tracer.rb +1 -2
  10. data/lib/graphql/backtrace.rb +2 -8
  11. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  12. data/lib/graphql/dig.rb +1 -1
  13. data/lib/graphql/execution/errors.rb +1 -9
  14. data/lib/graphql/execution/interpreter/runtime.rb +17 -31
  15. data/lib/graphql/execution/interpreter.rb +0 -22
  16. data/lib/graphql/execution/lazy.rb +1 -1
  17. data/lib/graphql/execution/lookahead.rb +6 -13
  18. data/lib/graphql/execution/multiplex.rb +50 -107
  19. data/lib/graphql/execution.rb +11 -3
  20. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  21. data/lib/graphql/introspection/entry_points.rb +2 -15
  22. data/lib/graphql/language/document_from_schema_definition.rb +0 -17
  23. data/lib/graphql/pagination/connections.rb +2 -28
  24. data/lib/graphql/query/context.rb +97 -194
  25. data/lib/graphql/query/input_validation_result.rb +10 -1
  26. data/lib/graphql/query/validation_pipeline.rb +8 -37
  27. data/lib/graphql/query/variables.rb +22 -18
  28. data/lib/graphql/query.rb +5 -36
  29. data/lib/graphql/railtie.rb +0 -104
  30. data/lib/graphql/relay.rb +0 -15
  31. data/lib/graphql/schema/addition.rb +1 -8
  32. data/lib/graphql/schema/argument.rb +5 -26
  33. data/lib/graphql/schema/build_from_definition.rb +0 -1
  34. data/lib/graphql/schema/directive.rb +0 -21
  35. data/lib/graphql/schema/enum.rb +4 -23
  36. data/lib/graphql/schema/enum_value.rb +0 -22
  37. data/lib/graphql/schema/field.rb +70 -230
  38. data/lib/graphql/schema/input_object.rb +21 -68
  39. data/lib/graphql/schema/interface.rb +0 -25
  40. data/lib/graphql/schema/introspection_system.rb +3 -8
  41. data/lib/graphql/schema/late_bound_type.rb +2 -2
  42. data/lib/graphql/schema/list.rb +2 -7
  43. data/lib/graphql/schema/loader.rb +0 -1
  44. data/lib/graphql/schema/member/base_dsl_methods.rb +0 -5
  45. data/lib/graphql/schema/member/build_type.rb +4 -6
  46. data/lib/graphql/schema/member/has_arguments.rb +50 -24
  47. data/lib/graphql/schema/member/has_fields.rb +2 -2
  48. data/lib/graphql/schema/member/has_interfaces.rb +1 -3
  49. data/lib/graphql/schema/member/validates_input.rb +2 -2
  50. data/lib/graphql/schema/member.rb +0 -6
  51. data/lib/graphql/schema/mutation.rb +0 -9
  52. data/lib/graphql/schema/non_null.rb +1 -7
  53. data/lib/graphql/schema/object.rb +7 -42
  54. data/lib/graphql/schema/relay_classic_mutation.rb +49 -42
  55. data/lib/graphql/schema/resolver/has_payload_type.rb +11 -1
  56. data/lib/graphql/schema/resolver.rb +23 -45
  57. data/lib/graphql/schema/scalar.rb +4 -19
  58. data/lib/graphql/schema/subscription.rb +0 -7
  59. data/lib/graphql/schema/union.rb +0 -16
  60. data/lib/graphql/schema/warden.rb +2 -2
  61. data/lib/graphql/schema/wrapper.rb +0 -5
  62. data/lib/graphql/schema.rb +106 -944
  63. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  64. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  65. data/lib/graphql/static_validation/validator.rb +2 -24
  66. data/lib/graphql/static_validation.rb +0 -2
  67. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  68. data/lib/graphql/subscriptions/event.rb +1 -1
  69. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  70. data/lib/graphql/subscriptions.rb +14 -16
  71. data/lib/graphql/tracing/platform_tracing.rb +0 -23
  72. data/lib/graphql/tracing.rb +0 -1
  73. data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
  74. data/lib/graphql/types/relay/default_relay.rb +0 -10
  75. data/lib/graphql/types/relay/node_behaviors.rb +5 -1
  76. data/lib/graphql/types/relay.rb +0 -2
  77. data/lib/graphql/version.rb +1 -1
  78. data/lib/graphql.rb +1 -65
  79. metadata +2 -128
  80. data/lib/graphql/analysis/analyze_query.rb +0 -98
  81. data/lib/graphql/analysis/field_usage.rb +0 -45
  82. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  83. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  84. data/lib/graphql/analysis/query_complexity.rb +0 -88
  85. data/lib/graphql/analysis/query_depth.rb +0 -43
  86. data/lib/graphql/analysis/reducer_state.rb +0 -48
  87. data/lib/graphql/argument.rb +0 -131
  88. data/lib/graphql/authorization.rb +0 -82
  89. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  90. data/lib/graphql/backwards_compatibility.rb +0 -61
  91. data/lib/graphql/base_type.rb +0 -232
  92. data/lib/graphql/boolean_type.rb +0 -2
  93. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  94. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  95. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  96. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  97. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  98. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  99. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  100. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  101. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  102. data/lib/graphql/compatibility.rb +0 -5
  103. data/lib/graphql/define/assign_argument.rb +0 -12
  104. data/lib/graphql/define/assign_connection.rb +0 -13
  105. data/lib/graphql/define/assign_enum_value.rb +0 -18
  106. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  107. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  108. data/lib/graphql/define/assign_object_field.rb +0 -42
  109. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  110. data/lib/graphql/define/instance_definable.rb +0 -240
  111. data/lib/graphql/define/no_definition_error.rb +0 -7
  112. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  113. data/lib/graphql/define/type_definer.rb +0 -31
  114. data/lib/graphql/define.rb +0 -31
  115. data/lib/graphql/deprecated_dsl.rb +0 -55
  116. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  117. data/lib/graphql/directive/include_directive.rb +0 -2
  118. data/lib/graphql/directive/skip_directive.rb +0 -2
  119. data/lib/graphql/directive.rb +0 -107
  120. data/lib/graphql/enum_type.rb +0 -133
  121. data/lib/graphql/execution/execute.rb +0 -333
  122. data/lib/graphql/execution/flatten.rb +0 -40
  123. data/lib/graphql/execution/typecast.rb +0 -50
  124. data/lib/graphql/field/resolve.rb +0 -59
  125. data/lib/graphql/field.rb +0 -226
  126. data/lib/graphql/float_type.rb +0 -2
  127. data/lib/graphql/function.rb +0 -128
  128. data/lib/graphql/id_type.rb +0 -2
  129. data/lib/graphql/input_object_type.rb +0 -138
  130. data/lib/graphql/int_type.rb +0 -2
  131. data/lib/graphql/interface_type.rb +0 -72
  132. data/lib/graphql/internal_representation/document.rb +0 -27
  133. data/lib/graphql/internal_representation/node.rb +0 -206
  134. data/lib/graphql/internal_representation/print.rb +0 -51
  135. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  136. data/lib/graphql/internal_representation/scope.rb +0 -88
  137. data/lib/graphql/internal_representation/visit.rb +0 -36
  138. data/lib/graphql/internal_representation.rb +0 -7
  139. data/lib/graphql/list_type.rb +0 -80
  140. data/lib/graphql/non_null_type.rb +0 -71
  141. data/lib/graphql/object_type.rb +0 -130
  142. data/lib/graphql/query/arguments.rb +0 -189
  143. data/lib/graphql/query/arguments_cache.rb +0 -24
  144. data/lib/graphql/query/executor.rb +0 -52
  145. data/lib/graphql/query/literal_input.rb +0 -136
  146. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  147. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  148. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  149. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  150. data/lib/graphql/query/serial_execution.rb +0 -40
  151. data/lib/graphql/relay/array_connection.rb +0 -83
  152. data/lib/graphql/relay/base_connection.rb +0 -189
  153. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  154. data/lib/graphql/relay/connection_resolve.rb +0 -43
  155. data/lib/graphql/relay/connection_type.rb +0 -54
  156. data/lib/graphql/relay/edge.rb +0 -27
  157. data/lib/graphql/relay/edge_type.rb +0 -19
  158. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  159. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  160. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  161. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  162. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  163. data/lib/graphql/relay/mutation/result.rb +0 -38
  164. data/lib/graphql/relay/mutation.rb +0 -106
  165. data/lib/graphql/relay/node.rb +0 -39
  166. data/lib/graphql/relay/page_info.rb +0 -7
  167. data/lib/graphql/relay/relation_connection.rb +0 -188
  168. data/lib/graphql/relay/type_extensions.rb +0 -32
  169. data/lib/graphql/scalar_type.rb +0 -91
  170. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  171. data/lib/graphql/schema/default_parse_error.rb +0 -10
  172. data/lib/graphql/schema/default_type_error.rb +0 -17
  173. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  174. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  175. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  176. data/lib/graphql/schema/middleware_chain.rb +0 -82
  177. data/lib/graphql/schema/possible_types.rb +0 -44
  178. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  179. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  180. data/lib/graphql/schema/traversal.rb +0 -228
  181. data/lib/graphql/schema/validation.rb +0 -313
  182. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  183. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  184. data/lib/graphql/string_type.rb +0 -2
  185. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  186. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  187. data/lib/graphql/types/relay/node_field.rb +0 -24
  188. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  189. data/lib/graphql/union_type.rb +0 -115
  190. data/lib/graphql/upgrader/member.rb +0 -937
  191. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -5,49 +5,10 @@ module GraphQL
5
5
  # It delegates `[]` to the hash that's passed to `GraphQL::Query#initialize`.
6
6
  class Context
7
7
  module SharedMethods
8
- # @return [Object] The target for field resolution
9
- attr_accessor :object
10
-
11
- # @return [Hash, Array, String, Integer, Float, Boolean, nil] The resolved value for this field
12
- attr_reader :value
13
-
14
- # @return [Boolean] were any fields of this selection skipped?
15
- attr_reader :skipped
16
- alias :skipped? :skipped
17
-
18
- # @api private
19
- attr_writer :skipped
20
-
21
8
  # Return this value to tell the runtime
22
9
  # to exclude this field from the response altogether
23
10
  def skip
24
- GraphQL::Execution::Execute::SKIP
25
- end
26
-
27
- # @return [Boolean] True if this selection has been nullified by a null child
28
- def invalid_null?
29
- @invalid_null
30
- end
31
-
32
- # Remove this child from the result value
33
- # (used for null propagation and skip)
34
- # @api private
35
- def delete_child(child_ctx)
36
- @value.delete(child_ctx.key)
37
- end
38
-
39
- # Create a child context to use for `key`
40
- # @param key [String, Integer] The key in the response (name or index)
41
- # @param irep_node [InternalRepresentation::Node] The node being evaluated
42
- # @api private
43
- def spawn_child(key:, irep_node:, object:)
44
- FieldResolutionContext.new(
45
- @context,
46
- key,
47
- irep_node,
48
- self,
49
- object
50
- )
11
+ GraphQL::Execution::SKIP
51
12
  end
52
13
 
53
14
  # Add error at query-level.
@@ -72,12 +33,6 @@ module GraphQL
72
33
  def execution_errors
73
34
  @execution_errors ||= ExecutionErrors.new(self)
74
35
  end
75
-
76
- def lookahead
77
- ast_nodes = irep_node.ast_nodes
78
- field = irep_node.definition.metadata[:type_class] || raise("Lookahead is only compatible with class-based schemas")
79
- Execution::Lookahead.new(query: query, ast_nodes: ast_nodes, field: field)
80
- end
81
36
  end
82
37
 
83
38
  class ExecutionErrors
@@ -105,27 +60,6 @@ module GraphQL
105
60
  include SharedMethods
106
61
  extend Forwardable
107
62
 
108
- attr_reader :execution_strategy
109
- # `strategy` is required by GraphQL::Batch
110
- alias_method :strategy, :execution_strategy
111
-
112
- def execution_strategy=(new_strategy)
113
- # GraphQL::Batch re-assigns this value but it was previously not used
114
- # (ExecutionContext#strategy was used instead)
115
- # now it _is_ used, but it breaks GraphQL::Batch tests
116
- @execution_strategy ||= new_strategy
117
- end
118
-
119
- # @return [GraphQL::InternalRepresentation::Node] The internal representation for this query node
120
- def irep_node
121
- @irep_node ||= query.irep_selection
122
- end
123
-
124
- # @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
125
- def ast_node
126
- @irep_node.ast_node
127
- end
128
-
129
63
  # @return [Array<GraphQL::ExecutionError>] errors returned during execution
130
64
  attr_reader :errors
131
65
 
@@ -152,8 +86,83 @@ module GraphQL
152
86
  @errors = []
153
87
  @path = []
154
88
  @value = nil
155
- @context = self # for SharedMethods
156
- @scoped_context = {}
89
+ @context = self # for SharedMethods TODO delete sharedmethods
90
+ @scoped_context = ScopedContext.new(self)
91
+ end
92
+
93
+ class ScopedContext
94
+ def initialize(query_context)
95
+ @query_context = query_context
96
+ @path_contexts = {}
97
+ @no_path = [].freeze
98
+ end
99
+
100
+ def merged_context
101
+ merged_ctx = {}
102
+ each_present_path_ctx do |path_ctx|
103
+ merged_ctx = path_ctx.merge(merged_ctx)
104
+ end
105
+ merged_ctx
106
+ end
107
+
108
+ def merge!(hash)
109
+ current_ctx = @path_contexts[current_path] ||= {}
110
+ current_ctx.merge!(hash)
111
+ end
112
+
113
+ def current_path
114
+ @query_context.namespace(:interpreter)[:current_path] || @no_path
115
+ end
116
+
117
+ def key?(key)
118
+ each_present_path_ctx do |path_ctx|
119
+ if path_ctx.key?(key)
120
+ return true
121
+ end
122
+ end
123
+ false
124
+ end
125
+
126
+ def [](key)
127
+ each_present_path_ctx do |path_ctx|
128
+ if path_ctx.key?(key)
129
+ return path_ctx[key]
130
+ end
131
+ end
132
+ nil
133
+ end
134
+
135
+ def dig(key, *other_keys)
136
+ each_present_path_ctx do |path_ctx|
137
+ if path_ctx.key?(key)
138
+ found_value = path_ctx[key]
139
+ if other_keys.any?
140
+ return found_value.dig(*other_keys)
141
+ else
142
+ return found_value
143
+ end
144
+ end
145
+ end
146
+ nil
147
+ end
148
+
149
+ private
150
+
151
+ # Start at the current location,
152
+ # but look up the tree for previously-assigned scoped values
153
+ def each_present_path_ctx
154
+ search_path = current_path.dup
155
+ if (current_path_ctx = @path_contexts[search_path])
156
+ yield(current_path_ctx)
157
+ end
158
+
159
+ while search_path.size > 0
160
+ search_path.pop # look one level higher
161
+ if (search_path_ctx = @path_contexts[search_path])
162
+ yield(search_path_ctx)
163
+ end
164
+ end
165
+ end
157
166
  end
158
167
 
159
168
  # @return [Hash] A hash that will be added verbatim to the result hash, as `"extensions" => { ... }`
@@ -172,7 +181,7 @@ module GraphQL
172
181
  attr_writer :value
173
182
 
174
183
  # @api private
175
- attr_accessor :scoped_context
184
+ attr_reader :scoped_context
176
185
 
177
186
  def []=(key, value)
178
187
  @provided_values[key] = value
@@ -185,8 +194,11 @@ module GraphQL
185
194
 
186
195
  # Lookup `key` from the hash passed to {Schema#execute} as `context:`
187
196
  def [](key)
188
- return @scoped_context[key] if @scoped_context.key?(key)
189
- @provided_values[key]
197
+ if @scoped_context.key?(key)
198
+ @scoped_context[key]
199
+ else
200
+ @provided_values[key]
201
+ end
190
202
  end
191
203
 
192
204
  def delete(key)
@@ -201,7 +213,7 @@ module GraphQL
201
213
 
202
214
  def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
203
215
  if @scoped_context.key?(key)
204
- @scoped_context[key]
216
+ scoped_context[key]
205
217
  elsif @provided_values.key?(key)
206
218
  @provided_values[key]
207
219
  elsif default != UNSPECIFIED_FETCH_DEFAULT
@@ -214,12 +226,21 @@ module GraphQL
214
226
  end
215
227
 
216
228
  def dig(key, *other_keys)
217
- @scoped_context.key?(key) ? @scoped_context.dig(key, *other_keys) : @provided_values.dig(key, *other_keys)
229
+ if @scoped_context.key?(key)
230
+ @scoped_context.dig(key, *other_keys)
231
+ else
232
+ @provided_values.dig(key, *other_keys)
233
+ end
218
234
  end
219
235
 
220
236
  def to_h
221
- @provided_values.merge(@scoped_context)
237
+ if (current_scoped_context = @scoped_context.merged_context)
238
+ @provided_values.merge(current_scoped_context)
239
+ else
240
+ @provided_values
241
+ end
222
242
  end
243
+
223
244
  alias :to_hash :to_h
224
245
 
225
246
  def key?(key)
@@ -250,132 +271,14 @@ module GraphQL
250
271
  "#<Query::Context ...>"
251
272
  end
252
273
 
253
- # @api private
254
- def received_null_child
255
- @invalid_null = true
256
- @value = nil
257
- end
258
-
259
274
  def scoped_merge!(hash)
260
- @scoped_context = @scoped_context.merge(hash)
275
+ @scoped_context.merge!(hash)
261
276
  end
262
277
 
263
278
  def scoped_set!(key, value)
264
279
  scoped_merge!(key => value)
265
280
  nil
266
281
  end
267
-
268
- class FieldResolutionContext
269
- include SharedMethods
270
- include Tracing::Traceable
271
- extend Forwardable
272
-
273
- attr_reader :irep_node, :field, :parent_type, :query, :schema, :parent, :key, :type
274
- alias :selection :irep_node
275
-
276
- def initialize(context, key, irep_node, parent, object)
277
- @context = context
278
- @key = key
279
- @parent = parent
280
- @object = object
281
- @irep_node = irep_node
282
- @field = irep_node.definition
283
- @parent_type = irep_node.owner_type
284
- @type = field.type
285
- # This is needed constantly, so set it ahead of time:
286
- @query = context.query
287
- @schema = context.schema
288
- @tracers = @query.tracers
289
- # This hack flag is required by ConnectionResolve
290
- @wrapped_connection = false
291
- @wrapped_object = false
292
- end
293
-
294
- # @api private
295
- attr_accessor :wrapped_connection, :wrapped_object
296
-
297
- def path
298
- @path ||= @parent.path.dup << @key
299
- end
300
-
301
- def_delegators :@context,
302
- :[], :[]=, :key?, :fetch, :to_h, :namespace, :dig,
303
- :spawn, :warden, :errors,
304
- :execution_strategy, :strategy, :interpreter?
305
-
306
- # @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
307
- def ast_node
308
- @irep_node.ast_node
309
- end
310
-
311
- # Add error to current field resolution.
312
- # @param error [GraphQL::ExecutionError] an execution error
313
- # @return [void]
314
- def add_error(error)
315
- super
316
- error.ast_node ||= irep_node.ast_node
317
- error.path ||= path
318
- nil
319
- end
320
-
321
- def inspect
322
- "#<GraphQL Context @ #{irep_node.owner_type.name}.#{field.name}>"
323
- end
324
-
325
- # Set a new value for this field in the response.
326
- # It may be updated after resolving a {Lazy}.
327
- # If it is {Execute::PROPAGATE_NULL}, tell the owner to propagate null.
328
- # If it's {Execute::Execution::SKIP}, remove this field result from its parent
329
- # @param new_value [Any] The GraphQL-ready value
330
- # @api private
331
- def value=(new_value)
332
- case new_value
333
- when GraphQL::Execution::Execute::PROPAGATE_NULL, nil
334
- @invalid_null = true
335
- @value = nil
336
- if @type.kind.non_null?
337
- @parent.received_null_child
338
- end
339
- when GraphQL::Execution::Execute::SKIP
340
- @parent.skipped = true
341
- @parent.delete_child(self)
342
- else
343
- @value = new_value
344
- end
345
- end
346
-
347
- protected
348
-
349
- def received_null_child
350
- case @value
351
- when Hash
352
- self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
353
- when Array
354
- if list_of_non_null_items?(@type)
355
- self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
356
- end
357
- when nil
358
- # TODO This is a hack
359
- # It was already nulled out but it's getting reassigned
360
- else
361
- raise "Unexpected value for received_null_child (#{self.value.class}): #{value}"
362
- end
363
- end
364
-
365
- private
366
-
367
- def list_of_non_null_items?(type)
368
- case type
369
- when GraphQL::NonNullType
370
- # Unwrap [T]!
371
- list_of_non_null_items?(type.of_type)
372
- when GraphQL::ListType
373
- type.of_type.is_a?(GraphQL::NonNullType)
374
- else
375
- raise "Unexpected list_of_non_null_items check: #{type}"
376
- end
377
- end
378
- end
379
282
  end
380
283
  end
381
284
  end
@@ -4,6 +4,12 @@ module GraphQL
4
4
  class InputValidationResult
5
5
  attr_accessor :problems
6
6
 
7
+ def self.from_problem(explanation, path = nil, extensions: nil, message: nil)
8
+ result = self.new
9
+ result.add_problem(explanation, path, extensions: extensions, message: message)
10
+ result
11
+ end
12
+
7
13
  def initialize(valid: true, problems: nil)
8
14
  @valid = valid
9
15
  @problems = problems
@@ -27,7 +33,7 @@ module GraphQL
27
33
  end
28
34
 
29
35
  def merge_result!(path, inner_result)
30
- return if inner_result.valid?
36
+ return if inner_result.nil? || inner_result.valid?
31
37
 
32
38
  if inner_result.problems
33
39
  inner_result.problems.each do |p|
@@ -38,6 +44,9 @@ module GraphQL
38
44
  # It could have been explicitly set on inner_result (if it had no problems)
39
45
  @valid = false
40
46
  end
47
+
48
+ VALID = self.new
49
+ VALID.freeze
41
50
  end
42
51
  end
43
52
  end
@@ -16,10 +16,8 @@ module GraphQL
16
16
  class ValidationPipeline
17
17
  attr_reader :max_depth, :max_complexity
18
18
 
19
- def initialize(query:, validate:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
19
+ def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
20
20
  @validation_errors = []
21
- @internal_representation = nil
22
- @validate = validate
23
21
  @parse_error = parse_error
24
22
  @operation_name_error = operation_name_error
25
23
  @query = query
@@ -42,12 +40,6 @@ module GraphQL
42
40
  @validation_errors
43
41
  end
44
42
 
45
- # @return [Hash<String, nil => GraphQL::InternalRepresentation::Node] Operation name -> Irep node pairs
46
- def internal_representation
47
- ensure_has_validated
48
- @internal_representation
49
- end
50
-
51
43
  def analyzers
52
44
  ensure_has_validated
53
45
  @query_analyzers
@@ -63,7 +55,7 @@ module GraphQL
63
55
 
64
56
  if @parse_error
65
57
  # This is kind of crazy: we push the parse error into `ctx`
66
- # in {DefaultParseError} so that users can _opt out_ by redefining that hook.
58
+ # in `def self.parse_error` by default so that users can _opt out_ by redefining that hook.
67
59
  # That means we can't _re-add_ the error here (otherwise we'd either
68
60
  # add it twice _or_ override the user's choice to not add it).
69
61
  # So we just have to know that it was invalid and go from there.
@@ -72,9 +64,8 @@ module GraphQL
72
64
  elsif @operation_name_error
73
65
  @validation_errors << @operation_name_error
74
66
  else
75
- validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
67
+ validation_result = @schema.static_validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
76
68
  @validation_errors.concat(validation_result[:errors])
77
- @internal_representation = validation_result[:irep]
78
69
 
79
70
  if @validation_errors.empty?
80
71
  @validation_errors.concat(@query.variables.errors)
@@ -100,35 +91,15 @@ module GraphQL
100
91
  def build_analyzers(schema, max_depth, max_complexity)
101
92
  qa = schema.query_analyzers.dup
102
93
 
103
- # Filter out the built in authorization analyzer.
104
- # It is deprecated and does not have an AST analyzer alternative.
105
- qa = qa.select do |analyzer|
106
- if analyzer == GraphQL::Authorization::Analyzer && schema.using_ast_analysis?
107
- raise "The Authorization analyzer is not supported with AST Analyzers"
108
- else
109
- true
110
- end
111
- end
112
-
113
94
  if max_depth || max_complexity
114
95
  # Depending on the analysis engine, we must use different analyzers
115
96
  # remove this once everything has switched over to AST analyzers
116
- if schema.using_ast_analysis?
117
- if max_depth
118
- qa << GraphQL::Analysis::AST::MaxQueryDepth
119
- end
120
- if max_complexity
121
- qa << GraphQL::Analysis::AST::MaxQueryComplexity
122
- end
123
- else
124
- if max_depth
125
- qa << GraphQL::Analysis::MaxQueryDepth.new(max_depth)
126
- end
127
- if max_complexity
128
- qa << GraphQL::Analysis::MaxQueryComplexity.new(max_complexity)
129
- end
97
+ if max_depth
98
+ qa << GraphQL::Analysis::AST::MaxQueryDepth
99
+ end
100
+ if max_complexity
101
+ qa << GraphQL::Analysis::AST::MaxQueryComplexity
130
102
  end
131
-
132
103
  qa
133
104
  else
134
105
  qa
@@ -14,7 +14,7 @@ module GraphQL
14
14
  schema = ctx.schema
15
15
  @context = ctx
16
16
 
17
- @provided_variables = GraphQL::Argument.deep_stringify(provided_variables)
17
+ @provided_variables = deep_stringify(provided_variables)
18
18
  @errors = []
19
19
  @storage = ast_variables.each_with_object({}) do |ast_variable, memo|
20
20
  # Find the right value for this variable:
@@ -34,25 +34,12 @@ module GraphQL
34
34
  if validation_result.valid?
35
35
  if value_was_provided
36
36
  # Add the variable if a value was provided
37
- memo[variable_name] = if ctx.interpreter?
38
- provided_value
39
- elsif provided_value.nil?
40
- nil
41
- else
42
- schema.error_handler.with_error_handling(context) do
43
- variable_type.coerce_input(provided_value, ctx)
44
- end
45
- end
37
+ memo[variable_name] = provided_value
46
38
  elsif default_value != nil
47
- memo[variable_name] = if ctx.interpreter?
48
- if default_value.is_a?(Language::Nodes::NullValue)
49
- nil
50
- else
51
- default_value
52
- end
39
+ memo[variable_name] = if default_value.is_a?(Language::Nodes::NullValue)
40
+ nil
53
41
  else
54
- # Add the variable if it wasn't provided but it has a default value (including `null`)
55
- GraphQL::Query::LiteralInput.coerce(variable_type, default_value, self)
42
+ default_value
56
43
  end
57
44
  end
58
45
  end
@@ -73,6 +60,23 @@ module GraphQL
73
60
  end
74
61
 
75
62
  def_delegators :@storage, :length, :key?, :[], :fetch, :to_h
63
+
64
+ private
65
+
66
+ def deep_stringify(val)
67
+ case val
68
+ when Array
69
+ val.map { |v| deep_stringify(v) }
70
+ when Hash
71
+ new_val = {}
72
+ val.each do |k, v|
73
+ new_val[k.to_s] = deep_stringify(v)
74
+ end
75
+ new_val
76
+ else
77
+ val
78
+ end
79
+ end
76
80
  end
77
81
  end
78
82
  end
data/lib/graphql/query.rb CHANGED
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
- require "graphql/query/arguments"
3
- require "graphql/query/arguments_cache"
4
2
  require "graphql/query/context"
5
- require "graphql/query/executor"
6
3
  require "graphql/query/fingerprint"
7
- require "graphql/query/literal_input"
8
4
  require "graphql/query/null_context"
9
5
  require "graphql/query/result"
10
- require "graphql/query/serial_execution"
11
6
  require "graphql/query/variables"
12
7
  require "graphql/query/input_validation_result"
13
8
  require "graphql/query/variable_validation_error"
@@ -82,13 +77,7 @@ module GraphQL
82
77
  def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil, warden: nil)
83
78
  # Even if `variables: nil` is passed, use an empty hash for simpler logic
84
79
  variables ||= {}
85
-
86
- # Use the `.graphql_definition` here which will return legacy types instead of classes
87
- if schema.is_a?(Class) && !schema.interpreter?
88
- schema = schema.graphql_definition
89
- end
90
80
  @schema = schema
91
- @interpreter = @schema.interpreter?
92
81
  @filter = schema.default_filter.merge(except: except, only: only)
93
82
  @context = schema.context_class.new(query: self, object: root_value, values: context)
94
83
  @warden = warden
@@ -154,7 +143,7 @@ module GraphQL
154
143
  end
155
144
 
156
145
  def interpreter?
157
- @interpreter
146
+ true
158
147
  end
159
148
 
160
149
  attr_accessor :multiplex
@@ -169,7 +158,6 @@ module GraphQL
169
158
  @lookahead ||= begin
170
159
  ast_node = selected_operation
171
160
  root_type = warden.root_type_for_operation(ast_node.operation_type || "query")
172
- root_type = root_type.type_class || raise("Invariant: `lookahead` only works with class-based types")
173
161
  GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
174
162
  end
175
163
  end
@@ -199,7 +187,7 @@ module GraphQL
199
187
  # @return [Hash] A GraphQL response, with `"data"` and/or `"errors"` keys
200
188
  def result
201
189
  if !@executed
202
- Execution::Multiplex.run_queries(@schema, [self], context: @context)
190
+ Execution::Multiplex.run_all(@schema, [self], context: @context)
203
191
  end
204
192
  @result ||= Query::Result.new(query: self, values: @result_values)
205
193
  end
@@ -237,35 +225,17 @@ module GraphQL
237
225
  end
238
226
  end
239
227
 
240
- def irep_selection
241
- @selection ||= begin
242
- if selected_operation && internal_representation
243
- internal_representation.operation_definitions[selected_operation.name]
244
- else
245
- nil
246
- end
247
- end
248
- end
249
-
250
228
  # Node-level cache for calculating arguments. Used during execution and query analysis.
251
229
  # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
252
230
  # @param definition [GraphQL::Schema::Field]
253
231
  # @param parent_object [GraphQL::Schema::Object]
254
232
  # @return Hash{Symbol => Object}
255
233
  def arguments_for(ast_node, definition, parent_object: nil)
256
- if interpreter?
257
- arguments_cache.fetch(ast_node, definition, parent_object)
258
- else
259
- arguments_cache[ast_node][definition]
260
- end
234
+ arguments_cache.fetch(ast_node, definition, parent_object)
261
235
  end
262
236
 
263
237
  def arguments_cache
264
- if interpreter?
265
- @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
266
- else
267
- @arguments_cache ||= ArgumentsCache.build(self)
268
- end
238
+ @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
269
239
  end
270
240
 
271
241
  # A version of the given query string, with:
@@ -308,7 +278,7 @@ module GraphQL
308
278
  with_prepared_ast { @validation_pipeline }
309
279
  end
310
280
 
311
- def_delegators :validation_pipeline, :validation_errors, :internal_representation,
281
+ def_delegators :validation_pipeline, :validation_errors,
312
282
  :analyzers, :ast_analyzers, :max_depth, :max_complexity
313
283
 
314
284
  attr_accessor :analysis_errors
@@ -434,7 +404,6 @@ module GraphQL
434
404
 
435
405
  @validation_pipeline = GraphQL::Query::ValidationPipeline.new(
436
406
  query: self,
437
- validate: @validate,
438
407
  parse_error: parse_error,
439
408
  operation_name_error: operation_name_error,
440
409
  max_depth: @max_depth,