graphql 2.5.5 → 2.5.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 170be4878ee16ebea26a272dde50923d35e624c87e1154b34de61a10f6a9fae0
4
- data.tar.gz: 5ac223538670c8a24c2748e0819cab3b5e0627c14b4a4745559fdedfcd8440fb
3
+ metadata.gz: f669e7593a3d951ee74480991e79d6a10fcd4b069746cd6244897b32fb6373fa
4
+ data.tar.gz: decb90c238b320f288b9a672b068e543745b9f46f82249fe93771230f8096257
5
5
  SHA512:
6
- metadata.gz: 272a8d48f0ec1d0ad1a79021dc103aede933d34a35829512bf0d46bcbcbc3bafe3b3484cbd38c26ba8193144f3a4024c1c69bd732c9e4cf472307fd15c1d1a33
7
- data.tar.gz: b1a66e945b02251b72410c792a91ba5d28cbe82e3eba3891bd3a708382076c2da9e6cf1349c3b688a0f7f87ba06d9bb1b83d06e4c3282e47c0c9724d76cb187b
6
+ metadata.gz: f1afa8434158b861073704a39b1ce84ee76c2bd636669c734ab43af66cf15c396ddaadc2f7c1dcf1fa61c030a0bddc0fc362f6db1bc6ad144efcaa61142565fd
7
+ data.tar.gz: ef88e624f49aafc803c6acfef8e44e1336f3494ce83bdf5b074825450cc6bc10eafd5738b012e177ceb5581c0425b9e93466e84d50bcec28b00169dbbc82c9b5
@@ -21,15 +21,25 @@ module GraphQL
21
21
  @graphql_metadata = nil
22
22
  @graphql_selections = selections
23
23
  @graphql_is_eager = is_eager
24
+ @base_path = nil
24
25
  end
25
26
 
27
+ # TODO test full path in Partial
28
+ attr_writer :base_path
29
+
26
30
  def path
27
31
  @path ||= build_path([])
28
32
  end
29
33
 
30
34
  def build_path(path_array)
31
35
  graphql_result_name && path_array.unshift(graphql_result_name)
32
- @graphql_parent ? @graphql_parent.build_path(path_array) : path_array
36
+ if @graphql_parent
37
+ @graphql_parent.build_path(path_array)
38
+ elsif @base_path
39
+ @base_path + path_array
40
+ else
41
+ path_array
42
+ end
33
43
  end
34
44
 
35
45
  attr_accessor :graphql_dead
@@ -57,53 +57,142 @@ module GraphQL
57
57
  end
58
58
 
59
59
  def final_result
60
- @response && @response.graphql_result_data
60
+ @response.respond_to?(:graphql_result_data) ? @response.graphql_result_data : @response
61
61
  end
62
62
 
63
63
  def inspect
64
64
  "#<#{self.class.name} response=#{@response.inspect}>"
65
65
  end
66
66
 
67
- # This _begins_ the execution. Some deferred work
68
- # might be stored up in lazies.
69
67
  # @return [void]
70
68
  def run_eager
71
- root_operation = query.selected_operation
72
- root_op_type = root_operation.operation_type || "query"
73
- root_type = schema.root_type_for_operation(root_op_type)
74
- runtime_object = root_type.wrap(query.root_value, context)
75
- runtime_object = schema.sync_lazy(runtime_object)
76
- is_eager = root_op_type == "mutation"
77
- @response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, root_operation.selections, is_eager, root_operation, nil, nil)
78
- st = get_current_runtime_state
79
- st.current_result = @response
80
-
81
- if runtime_object.nil?
82
- # Root .authorized? returned false.
83
- @response = nil
69
+ root_type = query.root_type
70
+ case query
71
+ when GraphQL::Query
72
+ ast_node = query.selected_operation
73
+ selections = ast_node.selections
74
+ object = query.root_value
75
+ is_eager = ast_node.operation_type == "mutation"
76
+ base_path = nil
77
+ when GraphQL::Query::Partial
78
+ ast_node = query.ast_nodes.first
79
+ selections = query.ast_nodes.map(&:selections).inject(&:+)
80
+ object = query.object
81
+ is_eager = false
82
+ base_path = query.path
84
83
  else
85
- call_method_on_directives(:resolve, runtime_object, root_operation.directives) do # execute query level directives
86
- each_gathered_selections(@response) do |selections, is_selection_array, ordered_result_keys|
87
- @response.ordered_result_keys ||= ordered_result_keys
88
- if is_selection_array
89
- selection_response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, selections, is_eager, root_operation, nil, nil)
90
- selection_response.ordered_result_keys = ordered_result_keys
91
- final_response = @response
92
- else
93
- selection_response = @response
94
- final_response = nil
95
- end
84
+ raise ArgumentError, "Unexpected Runnable, can't execute: #{query.class} (#{query.inspect})"
85
+ end
86
+ object = schema.sync_lazy(object) # TODO test query partial with lazy root object
87
+ runtime_state = get_current_runtime_state
88
+ case root_type.kind.name
89
+ when "OBJECT"
90
+ object_proxy = root_type.wrap(object, context)
91
+ object_proxy = schema.sync_lazy(object_proxy)
92
+ if object_proxy.nil?
93
+ @response = nil
94
+ else
95
+ @response = GraphQLResultHash.new(nil, root_type, object_proxy, nil, false, selections, is_eager, ast_node, nil, nil)
96
+ @response.base_path = base_path
97
+ runtime_state.current_result = @response
98
+ call_method_on_directives(:resolve, object, ast_node.directives) do
99
+ each_gathered_selections(@response) do |selections, is_selection_array, ordered_result_keys|
100
+ @response.ordered_result_keys ||= ordered_result_keys
101
+ if is_selection_array
102
+ selection_response = GraphQLResultHash.new(nil, root_type, object_proxy, nil, false, selections, is_eager, ast_node, nil, nil)
103
+ selection_response.ordered_result_keys = ordered_result_keys
104
+ final_response = @response
105
+ else
106
+ selection_response = @response
107
+ final_response = nil
108
+ end
96
109
 
97
- @dataloader.append_job {
98
- evaluate_selections(
99
- selections,
100
- selection_response,
101
- final_response,
102
- nil,
110
+ @dataloader.append_job {
111
+ evaluate_selections(
112
+ selections,
113
+ selection_response,
114
+ final_response,
115
+ nil,
116
+ )
117
+ }
118
+ end
119
+ end
120
+ end
121
+ when "LIST"
122
+ inner_type = root_type.unwrap
123
+ case inner_type.kind.name
124
+ when "SCALAR", "ENUM"
125
+ result_name = ast_node.alias || ast_node.name
126
+ owner_type = query.field_definition.owner
127
+ selection_result = GraphQLResultHash.new(nil, owner_type, nil, nil, false, EmptyObjects::EMPTY_ARRAY, false, ast_node, nil, nil)
128
+ selection_result.base_path = base_path
129
+ selection_result.ordered_result_keys = [result_name]
130
+ runtime_state = get_current_runtime_state
131
+ runtime_state.current_result = selection_result
132
+ runtime_state.current_result_name = result_name
133
+ field_defn = query.field_definition
134
+ continue_value = continue_value(object, field_defn, false, ast_node, result_name, selection_result)
135
+ if HALT != continue_value
136
+ continue_field(continue_value, owner_type, field_defn, root_type, ast_node, nil, false, nil, nil, result_name, selection_result, false, runtime_state) # rubocop:disable Metrics/ParameterLists
137
+ end
138
+ @response = selection_result[result_name]
139
+ else
140
+ @response = GraphQLResultArray.new(nil, root_type, nil, nil, false, selections, false, ast_node, nil, nil)
141
+ @response.base_path = base_path
142
+ idx = nil
143
+ object.each do |inner_value|
144
+ idx ||= 0
145
+ this_idx = idx
146
+ idx += 1
147
+ @dataloader.append_job do
148
+ runtime_state.current_result_name = this_idx
149
+ runtime_state.current_result = @response
150
+ continue_field(
151
+ inner_value, root_type, nil, inner_type, nil, @response.graphql_selections, false, object_proxy,
152
+ nil, this_idx, @response, false, runtime_state
103
153
  )
104
- }
154
+ end
155
+ end
156
+ end
157
+ when "SCALAR", "ENUM"
158
+ result_name = ast_node.alias || ast_node.name
159
+ owner_type = query.field_definition.owner
160
+ selection_result = GraphQLResultHash.new(nil, query.parent_type, nil, nil, false, EmptyObjects::EMPTY_ARRAY, false, ast_node, nil, nil)
161
+ selection_result.ordered_result_keys = [result_name]
162
+ selection_result.base_path = base_path
163
+ runtime_state = get_current_runtime_state
164
+ runtime_state.current_result = selection_result
165
+ runtime_state.current_result_name = result_name
166
+ field_defn = query.field_definition
167
+ continue_value = continue_value(object, field_defn, false, ast_node, result_name, selection_result)
168
+ if HALT != continue_value
169
+ continue_field(continue_value, owner_type, field_defn, query.root_type, ast_node, nil, false, nil, nil, result_name, selection_result, false, runtime_state) # rubocop:disable Metrics/ParameterLists
170
+ end
171
+ @response = selection_result[result_name]
172
+ when "UNION", "INTERFACE"
173
+ resolved_type, _resolved_obj = resolve_type(root_type, object)
174
+ resolved_type = schema.sync_lazy(resolved_type)
175
+ object_proxy = resolved_type.wrap(object, context)
176
+ object_proxy = schema.sync_lazy(object_proxy)
177
+ @response = GraphQLResultHash.new(nil, resolved_type, object_proxy, nil, false, selections, false, query.ast_nodes.first, nil, nil)
178
+ @response.base_path = base_path
179
+ each_gathered_selections(@response) do |selections, is_selection_array, ordered_result_keys|
180
+ @response.ordered_result_keys ||= ordered_result_keys
181
+ if is_selection_array == true
182
+ raise "This isn't supported yet"
105
183
  end
184
+
185
+ @dataloader.append_job {
186
+ evaluate_selections(
187
+ selections,
188
+ @response,
189
+ nil,
190
+ runtime_state,
191
+ )
192
+ }
106
193
  end
194
+ else
195
+ raise "Invariant: unsupported type kind for partial execution: #{root_type.kind.inspect} (#{root_type})"
107
196
  end
108
197
  nil
109
198
  end
@@ -26,7 +26,7 @@ module GraphQL
26
26
  query = case opts
27
27
  when Hash
28
28
  schema.query_class.new(schema, nil, **opts)
29
- when GraphQL::Query
29
+ when GraphQL::Query, GraphQL::Query::Partial
30
30
  opts
31
31
  else
32
32
  raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Query
4
+ # This class is _like_ a {GraphQL::Query}, except it can run on an arbitrary path within a query string.
5
+ #
6
+ # It depends on a "parent" {Query}.
7
+ #
8
+ # During execution, it calls query-related tracing hooks but passes itself as `query:`.
9
+ #
10
+ # The {Partial} will use your {Schema.resolve_type} hook to find the right GraphQL type to use for
11
+ # `object` in some cases.
12
+ #
13
+ # @see Query#run_partials Run via {Query#run_partials}
14
+ class Partial
15
+ include Query::Runnable
16
+
17
+ # @param path [Array<String, Integer>] A path in `query.query_string` to start executing from
18
+ # @param object [Object] A starting object for execution
19
+ # @param query [GraphQL::Query] A full query instance that this partial is based on. Caches are shared.
20
+ # @param context [Hash] Extra context values to merge into `query.context`, if provided
21
+ def initialize(path:, object:, query:, context: nil)
22
+ @path = path
23
+ @object = object
24
+ @query = query
25
+ @schema = query.schema
26
+ context_vals = @query.context.to_h
27
+ if context
28
+ context_vals = context_vals.merge(context)
29
+ end
30
+ @context = GraphQL::Query::Context.new(query: self, schema: @query.schema, values: context_vals)
31
+ @multiplex = nil
32
+ @result_values = nil
33
+ @result = nil
34
+ selections = [@query.selected_operation]
35
+ type = @query.root_type
36
+ parent_type = nil
37
+ field_defn = nil
38
+ @path.each do |name_in_doc|
39
+ if name_in_doc.is_a?(Integer)
40
+ if type.list?
41
+ type = type.unwrap
42
+ next
43
+ else
44
+ raise ArgumentError, "Received path with index `#{name_in_doc}`, but type wasn't a list. Type: #{type.to_type_signature}, path: #{@path}"
45
+ end
46
+ end
47
+
48
+ next_selections = []
49
+ selections.each do |selection|
50
+ selections_to_check = []
51
+ selections_to_check.concat(selection.selections)
52
+ while (sel = selections_to_check.shift)
53
+ case sel
54
+ when GraphQL::Language::Nodes::InlineFragment
55
+ selections_to_check.concat(sel.selections)
56
+ when GraphQL::Language::Nodes::FragmentSpread
57
+ fragment = @query.fragments[sel.name]
58
+ selections_to_check.concat(fragment.selections)
59
+ when GraphQL::Language::Nodes::Field
60
+ if sel.alias == name_in_doc || sel.name == name_in_doc
61
+ next_selections << sel
62
+ end
63
+ else
64
+ raise "Unexpected selection in partial path: #{sel.class}, #{sel.inspect}"
65
+ end
66
+ end
67
+ end
68
+
69
+ if next_selections.empty?
70
+ raise ArgumentError, "Path `#{@path.inspect}` is not present in this query. `#{name_in_doc.inspect}` was not found. Try a different path or rewrite the query to include it."
71
+ end
72
+ field_name = next_selections.first.name
73
+ field_defn = @schema.get_field(type, field_name, @query.context) || raise("Invariant: no field called #{field_name} on #{type.graphql_name}")
74
+ parent_type = type
75
+ type = field_defn.type
76
+ if type.non_null?
77
+ type = type.of_type
78
+ end
79
+ selections = next_selections
80
+ end
81
+ @parent_type = parent_type
82
+ @ast_nodes = selections
83
+ @root_type = type
84
+ @field_definition = field_defn
85
+ @leaf = @root_type.unwrap.kind.leaf?
86
+ end
87
+
88
+ def leaf?
89
+ @leaf
90
+ end
91
+
92
+ attr_reader :context, :query, :ast_nodes, :root_type, :object, :field_definition, :path, :parent_type, :schema
93
+
94
+ attr_accessor :multiplex, :result_values
95
+
96
+ class Result < GraphQL::Query::Result
97
+ def path
98
+ @query.path
99
+ end
100
+
101
+ # @return [GraphQL::Query::Partial]
102
+ def partial
103
+ @query
104
+ end
105
+ end
106
+
107
+ def result
108
+ @result ||= Result.new(query: self, values: result_values)
109
+ end
110
+
111
+ def current_trace
112
+ @query.current_trace
113
+ end
114
+
115
+ def types
116
+ @query.types
117
+ end
118
+
119
+ def resolve_type(...)
120
+ @query.resolve_type(...)
121
+ end
122
+
123
+ def variables
124
+ @query.variables
125
+ end
126
+
127
+ def fragments
128
+ @query.fragments
129
+ end
130
+
131
+ def valid?
132
+ @query.valid?
133
+ end
134
+
135
+ def analyzers
136
+ EmptyObjects::EMPTY_ARRAY
137
+ end
138
+
139
+ def analysis_errors=(_ignored)
140
+ # pass
141
+ end
142
+
143
+ def subscription?
144
+ @query.subscription?
145
+ end
146
+
147
+ def selected_operation
148
+ ast_nodes.first
149
+ end
150
+
151
+ def static_errors
152
+ @query.static_errors
153
+ end
154
+ end
155
+ end
156
+ end
data/lib/graphql/query.rb CHANGED
@@ -10,12 +10,47 @@ module GraphQL
10
10
  autoload :Context, "graphql/query/context"
11
11
  autoload :Fingerprint, "graphql/query/fingerprint"
12
12
  autoload :NullContext, "graphql/query/null_context"
13
+ autoload :Partial, "graphql/query/partial"
13
14
  autoload :Result, "graphql/query/result"
14
15
  autoload :Variables, "graphql/query/variables"
15
16
  autoload :InputValidationResult, "graphql/query/input_validation_result"
16
17
  autoload :VariableValidationError, "graphql/query/variable_validation_error"
17
18
  autoload :ValidationPipeline, "graphql/query/validation_pipeline"
18
19
 
20
+ # Code shared with {Partial}
21
+ module Runnable
22
+ def after_lazy(value, &block)
23
+ if !defined?(@runtime_instance)
24
+ @runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
25
+ end
26
+
27
+ if @runtime_instance
28
+ @runtime_instance.minimal_after_lazy(value, &block)
29
+ else
30
+ @schema.after_lazy(value, &block)
31
+ end
32
+ end
33
+
34
+ # Node-level cache for calculating arguments. Used during execution and query analysis.
35
+ # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
36
+ # @param definition [GraphQL::Schema::Field]
37
+ # @param parent_object [GraphQL::Schema::Object]
38
+ # @return [Hash{Symbol => Object}]
39
+ def arguments_for(ast_node, definition, parent_object: nil)
40
+ arguments_cache.fetch(ast_node, definition, parent_object)
41
+ end
42
+
43
+ def arguments_cache
44
+ @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
45
+ end
46
+
47
+ # @api private
48
+ def handle_or_reraise(err)
49
+ @schema.handle_or_reraise(context, err)
50
+ end
51
+ end
52
+
53
+ include Runnable
19
54
  class OperationNameMissingError < GraphQL::ExecutionError
20
55
  def initialize(name)
21
56
  msg = if name.nil?
@@ -198,19 +233,10 @@ module GraphQL
198
233
  # @return [GraphQL::Execution::Lookahead]
199
234
  def lookahead
200
235
  @lookahead ||= begin
201
- ast_node = selected_operation
202
- if ast_node.nil?
236
+ if selected_operation.nil?
203
237
  GraphQL::Execution::Lookahead::NULL_LOOKAHEAD
204
238
  else
205
- root_type = case ast_node.operation_type
206
- when nil, "query"
207
- types.query_root # rubocop:disable Development/ContextIsPassedCop
208
- when "mutation"
209
- types.mutation_root # rubocop:disable Development/ContextIsPassedCop
210
- when "subscription"
211
- types.subscription_root # rubocop:disable Development/ContextIsPassedCop
212
- end
213
- GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
239
+ GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [selected_operation])
214
240
  end
215
241
  end
216
242
  end
@@ -236,6 +262,18 @@ module GraphQL
236
262
  with_prepared_ast { @operations }
237
263
  end
238
264
 
265
+ # Run subtree partials of this query and return their results.
266
+ # Each partial is identified with a `path:` and `object:`
267
+ # where the path references a field in the AST and the object will be treated
268
+ # as the return value from that field. Subfields of the field named by `path`
269
+ # will be executed with `object` as the starting point
270
+ # @param partials_hashes [Array<Hash{Symbol => Object}>] Hashes with `path:` and `object:` keys
271
+ # @return [Array<GraphQL::Query::Result>]
272
+ def run_partials(partials_hashes)
273
+ partials = partials_hashes.map { |partial_options| Partial.new(query: self, **partial_options) }
274
+ Execution::Interpreter.run_all(@schema, partials, context: @context)
275
+ end
276
+
239
277
  # Get the result for this query, executing it once
240
278
  # @return [GraphQL::Query::Result] A Hash-like GraphQL response, with `"data"` and/or `"errors"` keys
241
279
  def result
@@ -278,19 +316,6 @@ module GraphQL
278
316
  end
279
317
  end
280
318
 
281
- # Node-level cache for calculating arguments. Used during execution and query analysis.
282
- # @param ast_node [GraphQL::Language::Nodes::AbstractNode]
283
- # @param definition [GraphQL::Schema::Field]
284
- # @param parent_object [GraphQL::Schema::Object]
285
- # @return [Hash{Symbol => Object}]
286
- def arguments_for(ast_node, definition, parent_object: nil)
287
- arguments_cache.fetch(ast_node, definition, parent_object)
288
- end
289
-
290
- def arguments_cache
291
- @arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
292
- end
293
-
294
319
  # A version of the given query string, with:
295
320
  # - Variables inlined to the query
296
321
  # - Strings replaced with `<REDACTED>`
@@ -357,17 +382,21 @@ module GraphQL
357
382
 
358
383
  def root_type_for_operation(op_type)
359
384
  case op_type
360
- when "query"
385
+ when "query", nil
361
386
  types.query_root # rubocop:disable Development/ContextIsPassedCop
362
387
  when "mutation"
363
388
  types.mutation_root # rubocop:disable Development/ContextIsPassedCop
364
389
  when "subscription"
365
390
  types.subscription_root # rubocop:disable Development/ContextIsPassedCop
366
391
  else
367
- raise ArgumentError, "unexpected root type name: #{op_type.inspect}; expected 'query', 'mutation', or 'subscription'"
392
+ raise ArgumentError, "unexpected root type name: #{op_type.inspect}; expected nil, 'query', 'mutation', or 'subscription'"
368
393
  end
369
394
  end
370
395
 
396
+ def root_type
397
+ root_type_for_operation(selected_operation.operation_type)
398
+ end
399
+
371
400
  def types
372
401
  @visibility_profile || warden.visibility_profile
373
402
  end
@@ -400,23 +429,6 @@ module GraphQL
400
429
  with_prepared_ast { @subscription }
401
430
  end
402
431
 
403
- # @api private
404
- def handle_or_reraise(err)
405
- schema.handle_or_reraise(context, err)
406
- end
407
-
408
- def after_lazy(value, &block)
409
- if !defined?(@runtime_instance)
410
- @runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
411
- end
412
-
413
- if @runtime_instance
414
- @runtime_instance.minimal_after_lazy(value, &block)
415
- else
416
- @schema.after_lazy(value, &block)
417
- end
418
- end
419
-
420
432
  attr_reader :logger
421
433
 
422
434
  private
@@ -1189,7 +1189,7 @@ module GraphQL
1189
1189
  # @param context [GraphQL::Query::Context] The query context for the currently-executing query
1190
1190
  # @return [Class<GraphQL::Schema::Object] The Object type definition to use for `obj`
1191
1191
  def resolve_type(abstract_type, application_object, context)
1192
- raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(abstract_type, application_object, context) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{abstract_type.name})"
1192
+ raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(abstract_type, application_object, context) must be implemented to use Union types, Interface types, `loads:`, or `run_partials` (tried to resolve: #{abstract_type.name})"
1193
1193
  end
1194
1194
  # rubocop:enable Lint/DuplicateMethods
1195
1195
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.5.5"
3
+ VERSION = "2.5.6"
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.5
4
+ version: 2.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-29 00:00:00.000000000 Z
10
+ date: 2025-05-05 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: base64
@@ -550,6 +550,7 @@ files:
550
550
  - lib/graphql/query/fingerprint.rb
551
551
  - lib/graphql/query/input_validation_result.rb
552
552
  - lib/graphql/query/null_context.rb
553
+ - lib/graphql/query/partial.rb
553
554
  - lib/graphql/query/result.rb
554
555
  - lib/graphql/query/validation_pipeline.rb
555
556
  - lib/graphql/query/variable_validation_error.rb