graphql 1.13.19 → 2.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +3 -17
- data/lib/generators/graphql/templates/schema.erb +3 -0
- data/lib/graphql/analysis/ast/field_usage.rb +3 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +43 -36
- data/lib/graphql/analysis/ast.rb +2 -12
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +2 -20
- data/lib/graphql/backtrace/tracer.rb +2 -3
- data/lib/graphql/backtrace.rb +2 -8
- data/lib/graphql/dataloader/null_dataloader.rb +3 -1
- data/lib/graphql/dataloader/source.rb +9 -0
- data/lib/graphql/dataloader.rb +4 -1
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +12 -82
- data/lib/graphql/execution/interpreter/resolve.rb +26 -0
- data/lib/graphql/execution/interpreter/runtime.rb +162 -119
- data/lib/graphql/execution/interpreter.rb +187 -78
- data/lib/graphql/execution/lazy.rb +7 -21
- data/lib/graphql/execution/lookahead.rb +44 -40
- data/lib/graphql/execution/multiplex.rb +3 -174
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- data/lib/graphql/introspection/type_type.rb +8 -1
- data/lib/graphql/introspection.rb +4 -3
- data/lib/graphql/language/document_from_schema_definition.rb +18 -35
- data/lib/graphql/language/lexer.rb +216 -1488
- data/lib/graphql/language/lexer.ri +744 -0
- data/lib/graphql/language/nodes.rb +41 -33
- data/lib/graphql/language/parser.rb +375 -363
- data/lib/graphql/language/parser.y +48 -43
- data/lib/graphql/language/printer.rb +37 -21
- data/lib/graphql/language/visitor.rb +191 -83
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/array_connection.rb +4 -2
- data/lib/graphql/pagination/connection.rb +31 -4
- data/lib/graphql/pagination/connections.rb +3 -28
- data/lib/graphql/pagination/relation_connection.rb +2 -0
- data/lib/graphql/query/context.rb +155 -196
- data/lib/graphql/query/input_validation_result.rb +1 -1
- data/lib/graphql/query/null_context.rb +0 -3
- data/lib/graphql/query/validation_pipeline.rb +10 -34
- data/lib/graphql/query/variables.rb +7 -20
- data/lib/graphql/query.rb +32 -42
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +29 -1
- data/lib/graphql/relay/range_add.rb +9 -20
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +7 -9
- data/lib/graphql/schema/argument.rb +36 -43
- data/lib/graphql/schema/build_from_definition.rb +32 -18
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +11 -22
- data/lib/graphql/schema/enum.rb +28 -39
- data/lib/graphql/schema/enum_value.rb +5 -25
- data/lib/graphql/schema/field/connection_extension.rb +4 -0
- data/lib/graphql/schema/field.rb +214 -327
- data/lib/graphql/schema/input_object.rb +56 -67
- data/lib/graphql/schema/interface.rb +0 -35
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +0 -6
- data/lib/graphql/schema/loader.rb +1 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +5 -7
- data/lib/graphql/schema/member/has_arguments.rb +144 -53
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +71 -56
- data/lib/graphql/schema/member/has_fields.rb +15 -3
- data/lib/graphql/schema/member/has_interfaces.rb +47 -18
- data/lib/graphql/schema/member/has_validators.rb +31 -5
- data/lib/graphql/schema/member/relay_shortcuts.rb +28 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/member/validates_input.rb +1 -1
- data/lib/graphql/schema/member.rb +0 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +1 -7
- data/lib/graphql/schema/object.rb +15 -52
- data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
- data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
- data/lib/graphql/schema/resolver.rb +41 -42
- data/lib/graphql/schema/scalar.rb +7 -22
- data/lib/graphql/schema/subscription.rb +0 -7
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/type_membership.rb +3 -0
- data/lib/graphql/schema/union.rb +10 -17
- data/lib/graphql/schema/warden.rb +23 -6
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +240 -968
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
- data/lib/graphql/static_validation/error.rb +2 -2
- data/lib/graphql/static_validation/literal_validator.rb +19 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -25
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +3 -8
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +32 -20
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appsignal_trace.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +41 -0
- data/lib/graphql/tracing/platform_trace.rb +107 -0
- data/lib/graphql/tracing/platform_tracing.rb +26 -41
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing.rb +136 -40
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/iso_8601_date.rb +4 -1
- data/lib/graphql/types/iso_8601_date_time.rb +4 -0
- data/lib/graphql/types/relay/base_connection.rb +16 -6
- data/lib/graphql/types/relay/connection_behaviors.rb +5 -25
- data/lib/graphql/types/relay/default_relay.rb +5 -9
- data/lib/graphql/types/relay/edge_behaviors.rb +1 -4
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay.rb +0 -2
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +11 -72
- metadata +31 -132
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -232
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -255
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -55
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -133
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -226
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -260
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -54
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -39
- data/lib/graphql/relay/global_id_resolve.rb +0 -17
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -17
- data/lib/graphql/schema/member/accepts_definition.rb +0 -164
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/node_field.rb +0 -24
- data/lib/graphql/types/relay/nodes_field.rb +0 -43
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -20,6 +20,15 @@ module GraphQL
|
|
20
20
|
@graphql_metadata = nil
|
21
21
|
end
|
22
22
|
|
23
|
+
def path
|
24
|
+
@path ||= build_path([])
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_path(path_array)
|
28
|
+
graphql_result_name && path_array.unshift(graphql_result_name)
|
29
|
+
@graphql_parent ? @graphql_parent.build_path(path_array) : path_array
|
30
|
+
end
|
31
|
+
|
23
32
|
attr_accessor :graphql_dead
|
24
33
|
attr_reader :graphql_parent, :graphql_result_name
|
25
34
|
|
@@ -148,13 +157,24 @@ module GraphQL
|
|
148
157
|
# @return [GraphQL::Query::Context]
|
149
158
|
attr_reader :context
|
150
159
|
|
151
|
-
def
|
160
|
+
def thread_info
|
161
|
+
info = Thread.current[:__graphql_runtime_info]
|
162
|
+
if !info
|
163
|
+
new_ti = {}
|
164
|
+
info = Thread.current[:__graphql_runtime_info] = new_ti
|
165
|
+
end
|
166
|
+
info
|
167
|
+
end
|
168
|
+
|
169
|
+
def initialize(query:, lazies_at_depth:)
|
152
170
|
@query = query
|
153
171
|
@dataloader = query.multiplex.dataloader
|
172
|
+
@lazies_at_depth = lazies_at_depth
|
154
173
|
@schema = query.schema
|
155
174
|
@context = query.context
|
156
175
|
@multiplex_context = query.multiplex.context
|
157
|
-
|
176
|
+
# Start this off empty:
|
177
|
+
Thread.current[:__graphql_runtime_info] = nil
|
158
178
|
@response = GraphQLResultHash.new(nil, nil)
|
159
179
|
# Identify runtime directives by checking which of this schema's directives have overridden `def self.resolve`
|
160
180
|
@runtime_directive_names = []
|
@@ -198,8 +218,7 @@ module GraphQL
|
|
198
218
|
root_operation = query.selected_operation
|
199
219
|
root_op_type = root_operation.operation_type || "query"
|
200
220
|
root_type = schema.root_type_for_operation(root_op_type)
|
201
|
-
|
202
|
-
set_all_interpreter_context(query.root_value, nil, nil, path)
|
221
|
+
set_all_interpreter_context(query.root_value, nil, nil, nil, @response)
|
203
222
|
object_proxy = authorized_new(root_type, query.root_value, context)
|
204
223
|
object_proxy = schema.sync_lazy(object_proxy)
|
205
224
|
|
@@ -226,11 +245,9 @@ module GraphQL
|
|
226
245
|
end
|
227
246
|
|
228
247
|
@dataloader.append_job {
|
229
|
-
set_all_interpreter_context(query.root_value, nil, nil,
|
248
|
+
set_all_interpreter_context(query.root_value, nil, nil, nil, selection_response)
|
230
249
|
call_method_on_directives(:resolve, object_proxy, selections.graphql_directives) do
|
231
250
|
evaluate_selections(
|
232
|
-
path,
|
233
|
-
context.scoped_context,
|
234
251
|
object_proxy,
|
235
252
|
root_type,
|
236
253
|
root_op_type == "mutation",
|
@@ -244,10 +261,7 @@ module GraphQL
|
|
244
261
|
end
|
245
262
|
end
|
246
263
|
end
|
247
|
-
|
248
|
-
delete_interpreter_context(:current_field)
|
249
|
-
delete_interpreter_context(:current_object)
|
250
|
-
delete_interpreter_context(:current_arguments)
|
264
|
+
delete_all_interpreter_context
|
251
265
|
nil
|
252
266
|
end
|
253
267
|
|
@@ -349,15 +363,15 @@ module GraphQL
|
|
349
363
|
NO_ARGS = {}.freeze
|
350
364
|
|
351
365
|
# @return [void]
|
352
|
-
def evaluate_selections(
|
353
|
-
set_all_interpreter_context(owner_object, nil, nil,
|
366
|
+
def evaluate_selections(owner_object, owner_type, is_eager_selection, gathered_selections, selections_result, target_result, parent_object) # rubocop:disable Metrics/ParameterLists
|
367
|
+
set_all_interpreter_context(owner_object, nil, nil, nil, selections_result)
|
354
368
|
|
355
369
|
finished_jobs = 0
|
356
370
|
enqueued_jobs = gathered_selections.size
|
357
371
|
gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
|
358
372
|
@dataloader.append_job {
|
359
373
|
evaluate_selection(
|
360
|
-
|
374
|
+
result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_selection, selections_result, parent_object
|
361
375
|
)
|
362
376
|
finished_jobs += 1
|
363
377
|
if target_result && finished_jobs == enqueued_jobs
|
@@ -369,10 +383,8 @@ module GraphQL
|
|
369
383
|
selections_result
|
370
384
|
end
|
371
385
|
|
372
|
-
attr_reader :progress_path
|
373
|
-
|
374
386
|
# @return [void]
|
375
|
-
def evaluate_selection(
|
387
|
+
def evaluate_selection(result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_field, selections_result, parent_object) # rubocop:disable Metrics/ParameterLists
|
376
388
|
return if dead_result?(selections_result)
|
377
389
|
# As a performance optimization, the hash key will be a `Node` if
|
378
390
|
# there's only one selection of the field. But if there are multiple
|
@@ -403,10 +415,6 @@ module GraphQL
|
|
403
415
|
|
404
416
|
return_type = field_defn.type
|
405
417
|
|
406
|
-
next_path = path.dup
|
407
|
-
next_path << result_name
|
408
|
-
next_path.freeze
|
409
|
-
|
410
418
|
# This seems janky, but we need to know
|
411
419
|
# the field's return type at this path in order
|
412
420
|
# to propagate `null`
|
@@ -414,9 +422,7 @@ module GraphQL
|
|
414
422
|
(selections_result.graphql_non_null_field_names ||= []).push(result_name)
|
415
423
|
end
|
416
424
|
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
417
|
-
set_all_interpreter_context(nil, field_defn, nil,
|
418
|
-
|
419
|
-
context.scoped_context = scoped_context
|
425
|
+
set_all_interpreter_context(nil, field_defn, nil, result_name, selections_result)
|
420
426
|
object = owner_object
|
421
427
|
|
422
428
|
if is_introspection
|
@@ -426,20 +432,19 @@ module GraphQL
|
|
426
432
|
total_args_count = field_defn.arguments(context).size
|
427
433
|
if total_args_count == 0
|
428
434
|
resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
429
|
-
evaluate_selection_with_args(resolved_arguments, field_defn,
|
435
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object, return_type)
|
430
436
|
else
|
431
437
|
# TODO remove all arguments(...) usages?
|
432
438
|
@query.arguments_cache.dataload_for(ast_node, field_defn, object) do |resolved_arguments|
|
433
|
-
evaluate_selection_with_args(resolved_arguments, field_defn,
|
439
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object, return_type)
|
434
440
|
end
|
435
441
|
end
|
436
442
|
end
|
437
443
|
|
438
|
-
def evaluate_selection_with_args(arguments, field_defn,
|
439
|
-
|
440
|
-
after_lazy(arguments, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, scoped_context: context.scoped_context, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result) do |resolved_arguments|
|
444
|
+
def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type) # rubocop:disable Metrics/ParameterLists
|
445
|
+
after_lazy(arguments, owner: owner_type, field: field_defn, ast_node: ast_node, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result) do |resolved_arguments|
|
441
446
|
if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
|
442
|
-
continue_value(
|
447
|
+
continue_value(resolved_arguments, owner_type, field_defn, return_type.non_null?, ast_node, result_name, selection_result)
|
443
448
|
next
|
444
449
|
end
|
445
450
|
|
@@ -455,9 +460,9 @@ module GraphQL
|
|
455
460
|
when :ast_node
|
456
461
|
extra_args[:ast_node] = ast_node
|
457
462
|
when :execution_errors
|
458
|
-
extra_args[:execution_errors] = ExecutionErrors.new(context, ast_node,
|
463
|
+
extra_args[:execution_errors] = ExecutionErrors.new(context, ast_node, current_path)
|
459
464
|
when :path
|
460
|
-
extra_args[:path] =
|
465
|
+
extra_args[:path] = current_path
|
461
466
|
when :lookahead
|
462
467
|
if !field_ast_nodes
|
463
468
|
field_ast_nodes = [ast_node]
|
@@ -472,10 +477,6 @@ module GraphQL
|
|
472
477
|
# Use this flag to tell Interpreter::Arguments to add itself
|
473
478
|
# to the keyword args hash _before_ freezing everything.
|
474
479
|
extra_args[:argument_details] = :__arguments_add_self
|
475
|
-
when :irep_node
|
476
|
-
# This is used by `__typename` in order to support the legacy runtime,
|
477
|
-
# but it has no use here (and it's always `nil`).
|
478
|
-
# Stop adding it here to avoid the overhead of `.merge_extras` below.
|
479
480
|
when :parent
|
480
481
|
extra_args[:parent] = parent_object
|
481
482
|
else
|
@@ -488,7 +489,7 @@ module GraphQL
|
|
488
489
|
resolved_arguments.keyword_arguments
|
489
490
|
end
|
490
491
|
|
491
|
-
set_all_interpreter_context(nil, nil, resolved_arguments,
|
492
|
+
set_all_interpreter_context(nil, nil, resolved_arguments, result_name, selection_result)
|
492
493
|
|
493
494
|
# Optimize for the case that field is selected only once
|
494
495
|
if field_ast_nodes.nil? || field_ast_nodes.size == 1
|
@@ -506,18 +507,22 @@ module GraphQL
|
|
506
507
|
field_result = call_method_on_directives(:resolve, object, directives) do
|
507
508
|
# Actually call the field resolver and capture the result
|
508
509
|
app_result = begin
|
509
|
-
query.
|
510
|
-
|
511
|
-
field_defn.resolve(object, kwarg_arguments, context)
|
512
|
-
end
|
510
|
+
query.current_trace.execute_field(field: field_defn, ast_node: ast_node, query: query, object: object, arguments: kwarg_arguments) do
|
511
|
+
field_defn.resolve(object, kwarg_arguments, context)
|
513
512
|
end
|
514
513
|
rescue GraphQL::ExecutionError => err
|
515
514
|
err
|
515
|
+
rescue StandardError => err
|
516
|
+
begin
|
517
|
+
query.handle_or_reraise(err)
|
518
|
+
rescue GraphQL::ExecutionError => ex_err
|
519
|
+
ex_err
|
520
|
+
end
|
516
521
|
end
|
517
|
-
after_lazy(app_result, owner: owner_type, field: field_defn,
|
518
|
-
continue_value = continue_value(
|
522
|
+
after_lazy(app_result, owner: owner_type, field: field_defn, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result) do |inner_result|
|
523
|
+
continue_value = continue_value(inner_result, owner_type, field_defn, return_type.non_null?, ast_node, result_name, selection_result)
|
519
524
|
if HALT != continue_value
|
520
|
-
continue_field(
|
525
|
+
continue_field(continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result)
|
521
526
|
end
|
522
527
|
end
|
523
528
|
end
|
@@ -582,8 +587,30 @@ module GraphQL
|
|
582
587
|
end
|
583
588
|
end
|
584
589
|
|
590
|
+
def current_path
|
591
|
+
ti = thread_info
|
592
|
+
path = ti &&
|
593
|
+
(result = ti[:current_result]) &&
|
594
|
+
(result.path)
|
595
|
+
if path && (rn = ti[:current_result_name])
|
596
|
+
path = path.dup
|
597
|
+
path.push(rn)
|
598
|
+
end
|
599
|
+
path
|
600
|
+
end
|
601
|
+
|
602
|
+
def current_depth
|
603
|
+
ti = thread_info
|
604
|
+
depth = 1
|
605
|
+
result = ti[:current_result]
|
606
|
+
while (result = result.graphql_parent)
|
607
|
+
depth += 1
|
608
|
+
end
|
609
|
+
depth
|
610
|
+
end
|
611
|
+
|
585
612
|
HALT = Object.new
|
586
|
-
def continue_value(
|
613
|
+
def continue_value(value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
|
587
614
|
case value
|
588
615
|
when nil
|
589
616
|
if is_non_null
|
@@ -602,7 +629,7 @@ module GraphQL
|
|
602
629
|
# every time.
|
603
630
|
if value.is_a?(GraphQL::ExecutionError)
|
604
631
|
if selection_result.nil? || !dead_result?(selection_result)
|
605
|
-
value.path ||=
|
632
|
+
value.path ||= current_path
|
606
633
|
value.ast_node ||= ast_node
|
607
634
|
context.errors << value
|
608
635
|
if selection_result
|
@@ -610,6 +637,16 @@ module GraphQL
|
|
610
637
|
end
|
611
638
|
end
|
612
639
|
HALT
|
640
|
+
elsif value.is_a?(GraphQL::UnauthorizedFieldError)
|
641
|
+
value.field ||= field
|
642
|
+
# this hook might raise & crash, or it might return
|
643
|
+
# a replacement value
|
644
|
+
next_value = begin
|
645
|
+
schema.unauthorized_field(value)
|
646
|
+
rescue GraphQL::ExecutionError => err
|
647
|
+
err
|
648
|
+
end
|
649
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
613
650
|
elsif value.is_a?(GraphQL::UnauthorizedError)
|
614
651
|
# this hook might raise & crash, or it might return
|
615
652
|
# a replacement value
|
@@ -618,8 +655,8 @@ module GraphQL
|
|
618
655
|
rescue GraphQL::ExecutionError => err
|
619
656
|
err
|
620
657
|
end
|
621
|
-
continue_value(
|
622
|
-
elsif GraphQL::Execution::
|
658
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
659
|
+
elsif GraphQL::Execution::SKIP == value
|
623
660
|
# It's possible a lazy was already written here
|
624
661
|
case selection_result
|
625
662
|
when GraphQLResultHash
|
@@ -644,7 +681,7 @@ module GraphQL
|
|
644
681
|
if selection_result.nil? || !dead_result?(selection_result)
|
645
682
|
value.each_with_index do |error, index|
|
646
683
|
error.ast_node ||= ast_node
|
647
|
-
error.path ||=
|
684
|
+
error.path ||= current_path + (list_type_at_all ? [index] : [])
|
648
685
|
context.errors << error
|
649
686
|
end
|
650
687
|
if selection_result
|
@@ -677,7 +714,7 @@ module GraphQL
|
|
677
714
|
# Location information from `path` and `ast_node`.
|
678
715
|
#
|
679
716
|
# @return [Lazy, Array, Hash, Object] Lazy, Array, and Hash are all traversed to resolve lazy values later
|
680
|
-
def continue_field(
|
717
|
+
def continue_field(value, owner_type, field, current_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
|
681
718
|
if current_type.non_null?
|
682
719
|
current_type = current_type.of_type
|
683
720
|
is_non_null = true
|
@@ -685,16 +722,24 @@ module GraphQL
|
|
685
722
|
|
686
723
|
case current_type.kind.name
|
687
724
|
when "SCALAR", "ENUM"
|
688
|
-
r =
|
725
|
+
r = begin
|
726
|
+
current_type.coerce_result(value, context)
|
727
|
+
rescue StandardError => err
|
728
|
+
schema.handle_or_reraise(context, err)
|
729
|
+
end
|
689
730
|
set_result(selection_result, result_name, r)
|
690
731
|
r
|
691
732
|
when "UNION", "INTERFACE"
|
692
|
-
resolved_type_or_lazy
|
693
|
-
|
733
|
+
resolved_type_or_lazy = resolve_type(current_type, value)
|
734
|
+
after_lazy(resolved_type_or_lazy, owner: current_type, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result) do |resolved_type_result|
|
735
|
+
if resolved_type_result.is_a?(Array) && resolved_type_result.length == 2
|
736
|
+
resolved_type, resolved_value = resolved_type_result
|
737
|
+
else
|
738
|
+
resolved_type = resolved_type_result
|
739
|
+
resolved_value = value
|
740
|
+
end
|
694
741
|
|
695
|
-
after_lazy(resolved_type_or_lazy, owner: current_type, path: path, ast_node: ast_node, scoped_context: context.scoped_context, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result) do |resolved_type|
|
696
742
|
possible_types = query.possible_types(current_type)
|
697
|
-
|
698
743
|
if !possible_types.include?(resolved_type)
|
699
744
|
parent_type = field.owner_type
|
700
745
|
err_class = current_type::UnresolvedTypeError
|
@@ -703,7 +748,7 @@ module GraphQL
|
|
703
748
|
set_result(selection_result, result_name, nil)
|
704
749
|
nil
|
705
750
|
else
|
706
|
-
continue_field(
|
751
|
+
continue_field(resolved_value, owner_type, field, resolved_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result)
|
707
752
|
end
|
708
753
|
end
|
709
754
|
when "OBJECT"
|
@@ -712,8 +757,8 @@ module GraphQL
|
|
712
757
|
rescue GraphQL::ExecutionError => err
|
713
758
|
err
|
714
759
|
end
|
715
|
-
after_lazy(object_proxy, owner: current_type,
|
716
|
-
continue_value = continue_value(
|
760
|
+
after_lazy(object_proxy, owner: current_type, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result) do |inner_object|
|
761
|
+
continue_value = continue_value(inner_object, owner_type, field, is_non_null, ast_node, result_name, selection_result)
|
717
762
|
if HALT != continue_value
|
718
763
|
response_hash = GraphQLResultHash.new(result_name, selection_result)
|
719
764
|
set_result(selection_result, result_name, response_hash)
|
@@ -734,11 +779,10 @@ module GraphQL
|
|
734
779
|
this_result = response_hash
|
735
780
|
final_result = nil
|
736
781
|
end
|
737
|
-
|
782
|
+
# Don't pass `result_name` here because it's already included in the new response hash
|
783
|
+
set_all_interpreter_context(continue_value, nil, nil, nil, this_result) # reset this mutable state
|
738
784
|
call_method_on_directives(:resolve, continue_value, selections.graphql_directives) do
|
739
785
|
evaluate_selections(
|
740
|
-
path,
|
741
|
-
context.scoped_context,
|
742
786
|
continue_value,
|
743
787
|
current_type,
|
744
788
|
false,
|
@@ -759,50 +803,55 @@ module GraphQL
|
|
759
803
|
response_list = GraphQLResultArray.new(result_name, selection_result)
|
760
804
|
response_list.graphql_non_null_list_items = inner_type.non_null?
|
761
805
|
set_result(selection_result, result_name, response_list)
|
762
|
-
|
763
806
|
idx = 0
|
764
|
-
|
765
|
-
begin
|
807
|
+
list_value = begin
|
766
808
|
value.each do |inner_value|
|
767
809
|
break if dead_result?(response_list)
|
768
|
-
next_path = path.dup
|
769
|
-
next_path << idx
|
770
810
|
this_idx = idx
|
771
|
-
next_path.freeze
|
772
811
|
idx += 1
|
773
812
|
if use_dataloader_job
|
774
813
|
@dataloader.append_job do
|
775
|
-
resolve_list_item(inner_value, inner_type,
|
814
|
+
resolve_list_item(inner_value, inner_type, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
|
776
815
|
end
|
777
816
|
else
|
778
|
-
resolve_list_item(inner_value, inner_type,
|
817
|
+
resolve_list_item(inner_value, inner_type, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
|
779
818
|
end
|
780
819
|
end
|
820
|
+
|
821
|
+
response_list
|
781
822
|
rescue NoMethodError => err
|
782
823
|
# Ruby 2.2 doesn't have NoMethodError#receiver, can't check that one in this case. (It's been EOL since 2017.)
|
783
824
|
if err.name == :each && (err.respond_to?(:receiver) ? err.receiver == value : true)
|
784
825
|
# This happens when the GraphQL schema doesn't match the implementation. Help the dev debug.
|
785
|
-
raise ListResultFailedError.new(value: value, field: field, path:
|
826
|
+
raise ListResultFailedError.new(value: value, field: field, path: current_path)
|
786
827
|
else
|
787
828
|
# This was some other NoMethodError -- let it bubble to reveal the real error.
|
788
829
|
raise
|
789
830
|
end
|
831
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
832
|
+
ex_err
|
833
|
+
rescue StandardError => err
|
834
|
+
begin
|
835
|
+
query.handle_or_reraise(err)
|
836
|
+
rescue GraphQL::ExecutionError => ex_err
|
837
|
+
ex_err
|
838
|
+
end
|
790
839
|
end
|
791
840
|
|
792
|
-
|
841
|
+
continue_value(list_value, owner_type, field, inner_type.non_null?, ast_node, result_name, selection_result)
|
793
842
|
else
|
794
843
|
raise "Invariant: Unhandled type kind #{current_type.kind} (#{current_type})"
|
795
844
|
end
|
796
845
|
end
|
797
846
|
|
798
|
-
def resolve_list_item(inner_value, inner_type,
|
799
|
-
set_all_interpreter_context(nil, nil, nil,
|
847
|
+
def resolve_list_item(inner_value, inner_type, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type) # rubocop:disable Metrics/ParameterLists
|
848
|
+
set_all_interpreter_context(nil, nil, nil, this_idx, response_list)
|
800
849
|
call_method_on_directives(:resolve_each, owner_object, ast_node.directives) do
|
801
850
|
# This will update `response_list` with the lazy
|
802
|
-
after_lazy(inner_value, owner: inner_type,
|
803
|
-
continue_value = continue_value(
|
851
|
+
after_lazy(inner_value, owner: inner_type, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list) do |inner_inner_value|
|
852
|
+
continue_value = continue_value(inner_inner_value, owner_type, field, inner_type.non_null?, ast_node, this_idx, response_list)
|
804
853
|
if HALT != continue_value
|
805
|
-
continue_field(
|
854
|
+
continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list)
|
806
855
|
end
|
807
856
|
end
|
808
857
|
end
|
@@ -819,12 +868,8 @@ module GraphQL
|
|
819
868
|
yield
|
820
869
|
else
|
821
870
|
dir_defn = @schema_directives.fetch(dir_node.name)
|
822
|
-
if !dir_defn.is_a?(Class)
|
823
|
-
dir_defn = dir_defn.type_class || raise("Only class-based directives are supported (not `@#{dir_node.name}`)")
|
824
|
-
end
|
825
871
|
raw_dir_args = arguments(nil, dir_defn, dir_node)
|
826
872
|
dir_args = continue_value(
|
827
|
-
@context[:current_path], # path
|
828
873
|
raw_dir_args, # value
|
829
874
|
dir_defn, # parent_type
|
830
875
|
nil, # field
|
@@ -847,7 +892,7 @@ module GraphQL
|
|
847
892
|
# Check {Schema::Directive.include?} for each directive that's present
|
848
893
|
def directives_include?(node, graphql_object, parent_type)
|
849
894
|
node.directives.each do |dir_node|
|
850
|
-
dir_defn = @schema_directives.fetch(dir_node.name)
|
895
|
+
dir_defn = @schema_directives.fetch(dir_node.name)
|
851
896
|
args = arguments(graphql_object, dir_defn, dir_node)
|
852
897
|
if !dir_defn.include?(graphql_object, args, context)
|
853
898
|
return false
|
@@ -856,50 +901,50 @@ module GraphQL
|
|
856
901
|
true
|
857
902
|
end
|
858
903
|
|
859
|
-
def set_all_interpreter_context(object, field, arguments,
|
904
|
+
def set_all_interpreter_context(object, field, arguments, result_name, result)
|
905
|
+
ti = thread_info
|
860
906
|
if object
|
861
|
-
|
907
|
+
ti[:current_object] = object
|
862
908
|
end
|
863
909
|
if field
|
864
|
-
|
910
|
+
ti[:current_field] = field
|
865
911
|
end
|
866
912
|
if arguments
|
867
|
-
|
913
|
+
ti[:current_arguments] = arguments
|
868
914
|
end
|
869
|
-
|
870
|
-
|
915
|
+
ti[:current_result_name] = result_name
|
916
|
+
if result
|
917
|
+
ti[:current_result] = result
|
871
918
|
end
|
872
919
|
end
|
873
920
|
|
874
921
|
# @param obj [Object] Some user-returned value that may want to be batched
|
875
|
-
# @param path [Array<String>]
|
876
922
|
# @param field [GraphQL::Schema::Field]
|
877
923
|
# @param eager [Boolean] Set to `true` for mutation root fields only
|
878
924
|
# @param trace [Boolean] If `false`, don't wrap this with field tracing
|
879
925
|
# @return [GraphQL::Execution::Lazy, Object] If loading `object` will be deferred, it's a wrapper over it.
|
880
|
-
def after_lazy(lazy_obj, owner:, field:,
|
926
|
+
def after_lazy(lazy_obj, owner:, field:, owner_object:, arguments:, ast_node:, result:, result_name:, eager: false, trace: true, &block)
|
881
927
|
if lazy?(lazy_obj)
|
882
|
-
lazy = GraphQL::Execution::Lazy.new(
|
883
|
-
set_all_interpreter_context(owner_object, field, arguments,
|
884
|
-
context.scoped_context = scoped_context
|
928
|
+
lazy = GraphQL::Execution::Lazy.new(field: field) do
|
929
|
+
set_all_interpreter_context(owner_object, field, arguments, result_name, result)
|
885
930
|
# Wrap the execution of _this_ method with tracing,
|
886
931
|
# but don't wrap the continuation below
|
887
932
|
inner_obj = begin
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
query.trace("execute_field_lazy", {owner: owner, field: field, path: path, query: query, object: owner_object, arguments: arguments, ast_node: ast_node}) do
|
892
|
-
schema.sync_lazy(lazy_obj)
|
893
|
-
end
|
894
|
-
else
|
895
|
-
schema.sync_lazy(lazy_obj)
|
896
|
-
end
|
897
|
-
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => err
|
898
|
-
err
|
933
|
+
if trace
|
934
|
+
query.current_trace.execute_field_lazy(field: field, query: query, object: owner_object, arguments: arguments, ast_node: ast_node) do
|
935
|
+
schema.sync_lazy(lazy_obj)
|
899
936
|
end
|
937
|
+
else
|
938
|
+
schema.sync_lazy(lazy_obj)
|
900
939
|
end
|
901
|
-
rescue GraphQL::ExecutionError => ex_err
|
940
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
902
941
|
ex_err
|
942
|
+
rescue StandardError => err
|
943
|
+
begin
|
944
|
+
query.handle_or_reraise(err)
|
945
|
+
rescue GraphQL::ExecutionError => ex_err
|
946
|
+
ex_err
|
947
|
+
end
|
903
948
|
end
|
904
949
|
yield(inner_obj)
|
905
950
|
end
|
@@ -908,10 +953,11 @@ module GraphQL
|
|
908
953
|
lazy.value
|
909
954
|
else
|
910
955
|
set_result(result, result_name, lazy)
|
956
|
+
@lazies_at_depth[current_depth] << lazy
|
911
957
|
lazy
|
912
958
|
end
|
913
959
|
else
|
914
|
-
set_all_interpreter_context(owner_object, field, arguments,
|
960
|
+
set_all_interpreter_context(owner_object, field, arguments, result_name, result)
|
915
961
|
yield(lazy_obj)
|
916
962
|
end
|
917
963
|
end
|
@@ -925,27 +971,24 @@ module GraphQL
|
|
925
971
|
end
|
926
972
|
end
|
927
973
|
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
@interpreter_context.delete(key)
|
937
|
-
@context.delete(key)
|
974
|
+
def delete_all_interpreter_context
|
975
|
+
if (ti = thread_info)
|
976
|
+
ti.delete(:current_result)
|
977
|
+
ti.delete(:current_result_name)
|
978
|
+
ti.delete(:current_field)
|
979
|
+
ti.delete(:current_object)
|
980
|
+
ti.delete(:current_arguments)
|
981
|
+
end
|
938
982
|
end
|
939
983
|
|
940
|
-
def resolve_type(type, value
|
941
|
-
|
942
|
-
resolved_type, resolved_value = query.trace("resolve_type", trace_payload) do
|
984
|
+
def resolve_type(type, value)
|
985
|
+
resolved_type, resolved_value = query.current_trace.resolve_type(query: query, type: type, object: value) do
|
943
986
|
query.resolve_type(type, value)
|
944
987
|
end
|
945
988
|
|
946
989
|
if lazy?(resolved_type)
|
947
990
|
GraphQL::Execution::Lazy.new do
|
948
|
-
query.
|
991
|
+
query.current_trace.resolve_type_lazy(query: query, type: type, object: value) do
|
949
992
|
schema.sync_lazy(resolved_type)
|
950
993
|
end
|
951
994
|
end
|