graphql 1.13.17 → 2.0.20
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 +159 -120
- 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/directive_type.rb +2 -2
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +13 -6
- 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/nodes.rb +65 -39
- data/lib/graphql/language/parser.rb +376 -364
- data/lib/graphql/language/parser.y +49 -44
- 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 +12 -23
- 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 +237 -339
- 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 +17 -19
- data/lib/graphql/schema/member/build_type.rb +5 -7
- data/lib/graphql/schema/member/has_arguments.rb +146 -55
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -59
- data/lib/graphql/schema/member/has_fields.rb +17 -4
- data/lib/graphql/schema/member/has_interfaces.rb +49 -10
- data/lib/graphql/schema/member/has_validators.rb +31 -5
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -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 +34 -8
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +241 -973
- 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 +71 -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 -40
- 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 +29 -27
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
- data/lib/graphql/types/relay/node_behaviors.rb +12 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -3
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +13 -74
- metadata +30 -133
- 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/default_relay.rb +0 -31
- 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
|
@@ -400,11 +412,8 @@ module GraphQL
|
|
400
412
|
raise "Invariant: no field for #{owner_type}.#{field_name}"
|
401
413
|
end
|
402
414
|
end
|
403
|
-
return_type = field_defn.type
|
404
415
|
|
405
|
-
|
406
|
-
next_path << result_name
|
407
|
-
next_path.freeze
|
416
|
+
return_type = field_defn.type
|
408
417
|
|
409
418
|
# This seems janky, but we need to know
|
410
419
|
# the field's return type at this path in order
|
@@ -413,9 +422,7 @@ module GraphQL
|
|
413
422
|
(selections_result.graphql_non_null_field_names ||= []).push(result_name)
|
414
423
|
end
|
415
424
|
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
416
|
-
set_all_interpreter_context(nil, field_defn, nil,
|
417
|
-
|
418
|
-
context.scoped_context = scoped_context
|
425
|
+
set_all_interpreter_context(nil, field_defn, nil, result_name, selections_result)
|
419
426
|
object = owner_object
|
420
427
|
|
421
428
|
if is_introspection
|
@@ -425,21 +432,19 @@ module GraphQL
|
|
425
432
|
total_args_count = field_defn.arguments(context).size
|
426
433
|
if total_args_count == 0
|
427
434
|
resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
428
|
-
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)
|
429
436
|
else
|
430
437
|
# TODO remove all arguments(...) usages?
|
431
438
|
@query.arguments_cache.dataload_for(ast_node, field_defn, object) do |resolved_arguments|
|
432
|
-
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)
|
433
440
|
end
|
434
441
|
end
|
435
442
|
end
|
436
443
|
|
437
|
-
def evaluate_selection_with_args(arguments, field_defn,
|
438
|
-
|
439
|
-
return_type = field_defn.type
|
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,20 @@ 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
|
+
|
585
602
|
HALT = Object.new
|
586
|
-
def continue_value(
|
603
|
+
def continue_value(value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
|
587
604
|
case value
|
588
605
|
when nil
|
589
606
|
if is_non_null
|
@@ -602,7 +619,7 @@ module GraphQL
|
|
602
619
|
# every time.
|
603
620
|
if value.is_a?(GraphQL::ExecutionError)
|
604
621
|
if selection_result.nil? || !dead_result?(selection_result)
|
605
|
-
value.path ||=
|
622
|
+
value.path ||= current_path
|
606
623
|
value.ast_node ||= ast_node
|
607
624
|
context.errors << value
|
608
625
|
if selection_result
|
@@ -610,6 +627,16 @@ module GraphQL
|
|
610
627
|
end
|
611
628
|
end
|
612
629
|
HALT
|
630
|
+
elsif value.is_a?(GraphQL::UnauthorizedFieldError)
|
631
|
+
value.field ||= field
|
632
|
+
# this hook might raise & crash, or it might return
|
633
|
+
# a replacement value
|
634
|
+
next_value = begin
|
635
|
+
schema.unauthorized_field(value)
|
636
|
+
rescue GraphQL::ExecutionError => err
|
637
|
+
err
|
638
|
+
end
|
639
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
613
640
|
elsif value.is_a?(GraphQL::UnauthorizedError)
|
614
641
|
# this hook might raise & crash, or it might return
|
615
642
|
# a replacement value
|
@@ -618,8 +645,8 @@ module GraphQL
|
|
618
645
|
rescue GraphQL::ExecutionError => err
|
619
646
|
err
|
620
647
|
end
|
621
|
-
continue_value(
|
622
|
-
elsif GraphQL::Execution::
|
648
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
649
|
+
elsif GraphQL::Execution::SKIP == value
|
623
650
|
# It's possible a lazy was already written here
|
624
651
|
case selection_result
|
625
652
|
when GraphQLResultHash
|
@@ -644,7 +671,7 @@ module GraphQL
|
|
644
671
|
if selection_result.nil? || !dead_result?(selection_result)
|
645
672
|
value.each_with_index do |error, index|
|
646
673
|
error.ast_node ||= ast_node
|
647
|
-
error.path ||=
|
674
|
+
error.path ||= current_path + (list_type_at_all ? [index] : [])
|
648
675
|
context.errors << error
|
649
676
|
end
|
650
677
|
if selection_result
|
@@ -677,7 +704,7 @@ module GraphQL
|
|
677
704
|
# Location information from `path` and `ast_node`.
|
678
705
|
#
|
679
706
|
# @return [Lazy, Array, Hash, Object] Lazy, Array, and Hash are all traversed to resolve lazy values later
|
680
|
-
def continue_field(
|
707
|
+
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
708
|
if current_type.non_null?
|
682
709
|
current_type = current_type.of_type
|
683
710
|
is_non_null = true
|
@@ -685,16 +712,24 @@ module GraphQL
|
|
685
712
|
|
686
713
|
case current_type.kind.name
|
687
714
|
when "SCALAR", "ENUM"
|
688
|
-
r =
|
715
|
+
r = begin
|
716
|
+
current_type.coerce_result(value, context)
|
717
|
+
rescue StandardError => err
|
718
|
+
schema.handle_or_reraise(context, err)
|
719
|
+
end
|
689
720
|
set_result(selection_result, result_name, r)
|
690
721
|
r
|
691
722
|
when "UNION", "INTERFACE"
|
692
|
-
resolved_type_or_lazy
|
693
|
-
|
723
|
+
resolved_type_or_lazy = resolve_type(current_type, value)
|
724
|
+
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|
|
725
|
+
if resolved_type_result.is_a?(Array) && resolved_type_result.length == 2
|
726
|
+
resolved_type, resolved_value = resolved_type_result
|
727
|
+
else
|
728
|
+
resolved_type = resolved_type_result
|
729
|
+
resolved_value = value
|
730
|
+
end
|
694
731
|
|
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
732
|
possible_types = query.possible_types(current_type)
|
697
|
-
|
698
733
|
if !possible_types.include?(resolved_type)
|
699
734
|
parent_type = field.owner_type
|
700
735
|
err_class = current_type::UnresolvedTypeError
|
@@ -703,7 +738,7 @@ module GraphQL
|
|
703
738
|
set_result(selection_result, result_name, nil)
|
704
739
|
nil
|
705
740
|
else
|
706
|
-
continue_field(
|
741
|
+
continue_field(resolved_value, owner_type, field, resolved_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result)
|
707
742
|
end
|
708
743
|
end
|
709
744
|
when "OBJECT"
|
@@ -712,8 +747,8 @@ module GraphQL
|
|
712
747
|
rescue GraphQL::ExecutionError => err
|
713
748
|
err
|
714
749
|
end
|
715
|
-
after_lazy(object_proxy, owner: current_type,
|
716
|
-
continue_value = continue_value(
|
750
|
+
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|
|
751
|
+
continue_value = continue_value(inner_object, owner_type, field, is_non_null, ast_node, result_name, selection_result)
|
717
752
|
if HALT != continue_value
|
718
753
|
response_hash = GraphQLResultHash.new(result_name, selection_result)
|
719
754
|
set_result(selection_result, result_name, response_hash)
|
@@ -734,11 +769,10 @@ module GraphQL
|
|
734
769
|
this_result = response_hash
|
735
770
|
final_result = nil
|
736
771
|
end
|
737
|
-
|
772
|
+
# Don't pass `result_name` here because it's already included in the new response hash
|
773
|
+
set_all_interpreter_context(continue_value, nil, nil, nil, this_result) # reset this mutable state
|
738
774
|
call_method_on_directives(:resolve, continue_value, selections.graphql_directives) do
|
739
775
|
evaluate_selections(
|
740
|
-
path,
|
741
|
-
context.scoped_context,
|
742
776
|
continue_value,
|
743
777
|
current_type,
|
744
778
|
false,
|
@@ -759,50 +793,55 @@ module GraphQL
|
|
759
793
|
response_list = GraphQLResultArray.new(result_name, selection_result)
|
760
794
|
response_list.graphql_non_null_list_items = inner_type.non_null?
|
761
795
|
set_result(selection_result, result_name, response_list)
|
762
|
-
|
763
796
|
idx = 0
|
764
|
-
|
765
|
-
begin
|
797
|
+
list_value = begin
|
766
798
|
value.each do |inner_value|
|
767
799
|
break if dead_result?(response_list)
|
768
|
-
next_path = path.dup
|
769
|
-
next_path << idx
|
770
800
|
this_idx = idx
|
771
|
-
next_path.freeze
|
772
801
|
idx += 1
|
773
802
|
if use_dataloader_job
|
774
803
|
@dataloader.append_job do
|
775
|
-
resolve_list_item(inner_value, inner_type,
|
804
|
+
resolve_list_item(inner_value, inner_type, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
|
776
805
|
end
|
777
806
|
else
|
778
|
-
resolve_list_item(inner_value, inner_type,
|
807
|
+
resolve_list_item(inner_value, inner_type, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
|
779
808
|
end
|
780
809
|
end
|
810
|
+
|
811
|
+
response_list
|
781
812
|
rescue NoMethodError => err
|
782
813
|
# Ruby 2.2 doesn't have NoMethodError#receiver, can't check that one in this case. (It's been EOL since 2017.)
|
783
814
|
if err.name == :each && (err.respond_to?(:receiver) ? err.receiver == value : true)
|
784
815
|
# This happens when the GraphQL schema doesn't match the implementation. Help the dev debug.
|
785
|
-
raise ListResultFailedError.new(value: value, field: field, path:
|
816
|
+
raise ListResultFailedError.new(value: value, field: field, path: current_path)
|
786
817
|
else
|
787
818
|
# This was some other NoMethodError -- let it bubble to reveal the real error.
|
788
819
|
raise
|
789
820
|
end
|
821
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
822
|
+
ex_err
|
823
|
+
rescue StandardError => err
|
824
|
+
begin
|
825
|
+
query.handle_or_reraise(err)
|
826
|
+
rescue GraphQL::ExecutionError => ex_err
|
827
|
+
ex_err
|
828
|
+
end
|
790
829
|
end
|
791
830
|
|
792
|
-
|
831
|
+
continue_value(list_value, owner_type, field, inner_type.non_null?, ast_node, result_name, selection_result)
|
793
832
|
else
|
794
833
|
raise "Invariant: Unhandled type kind #{current_type.kind} (#{current_type})"
|
795
834
|
end
|
796
835
|
end
|
797
836
|
|
798
|
-
def resolve_list_item(inner_value, inner_type,
|
799
|
-
set_all_interpreter_context(nil, nil, nil,
|
837
|
+
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
|
838
|
+
set_all_interpreter_context(nil, nil, nil, this_idx, response_list)
|
800
839
|
call_method_on_directives(:resolve_each, owner_object, ast_node.directives) do
|
801
840
|
# This will update `response_list` with the lazy
|
802
|
-
after_lazy(inner_value, owner: inner_type,
|
803
|
-
continue_value = continue_value(
|
841
|
+
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|
|
842
|
+
continue_value = continue_value(inner_inner_value, owner_type, field, inner_type.non_null?, ast_node, this_idx, response_list)
|
804
843
|
if HALT != continue_value
|
805
|
-
continue_field(
|
844
|
+
continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list)
|
806
845
|
end
|
807
846
|
end
|
808
847
|
end
|
@@ -819,12 +858,8 @@ module GraphQL
|
|
819
858
|
yield
|
820
859
|
else
|
821
860
|
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
861
|
raw_dir_args = arguments(nil, dir_defn, dir_node)
|
826
862
|
dir_args = continue_value(
|
827
|
-
@context[:current_path], # path
|
828
863
|
raw_dir_args, # value
|
829
864
|
dir_defn, # parent_type
|
830
865
|
nil, # field
|
@@ -847,7 +882,7 @@ module GraphQL
|
|
847
882
|
# Check {Schema::Directive.include?} for each directive that's present
|
848
883
|
def directives_include?(node, graphql_object, parent_type)
|
849
884
|
node.directives.each do |dir_node|
|
850
|
-
dir_defn = @schema_directives.fetch(dir_node.name)
|
885
|
+
dir_defn = @schema_directives.fetch(dir_node.name)
|
851
886
|
args = arguments(graphql_object, dir_defn, dir_node)
|
852
887
|
if !dir_defn.include?(graphql_object, args, context)
|
853
888
|
return false
|
@@ -856,50 +891,51 @@ module GraphQL
|
|
856
891
|
true
|
857
892
|
end
|
858
893
|
|
859
|
-
def set_all_interpreter_context(object, field, arguments,
|
894
|
+
def set_all_interpreter_context(object, field, arguments, result_name, result)
|
895
|
+
ti = thread_info
|
860
896
|
if object
|
861
|
-
|
897
|
+
ti[:current_object] = object
|
862
898
|
end
|
863
899
|
if field
|
864
|
-
|
900
|
+
ti[:current_field] = field
|
865
901
|
end
|
866
902
|
if arguments
|
867
|
-
|
903
|
+
ti[:current_arguments] = arguments
|
868
904
|
end
|
869
|
-
|
870
|
-
|
905
|
+
ti[:current_result_name] = result_name
|
906
|
+
if result
|
907
|
+
ti[:current_result] = result
|
871
908
|
end
|
872
909
|
end
|
873
910
|
|
874
911
|
# @param obj [Object] Some user-returned value that may want to be batched
|
875
|
-
# @param path [Array<String>]
|
876
912
|
# @param field [GraphQL::Schema::Field]
|
877
913
|
# @param eager [Boolean] Set to `true` for mutation root fields only
|
878
914
|
# @param trace [Boolean] If `false`, don't wrap this with field tracing
|
879
915
|
# @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:,
|
916
|
+
def after_lazy(lazy_obj, owner:, field:, owner_object:, arguments:, ast_node:, result:, result_name:, eager: false, trace: true, &block)
|
881
917
|
if lazy?(lazy_obj)
|
882
|
-
|
883
|
-
|
884
|
-
|
918
|
+
orig_result = result
|
919
|
+
lazy = GraphQL::Execution::Lazy.new(field: field) do
|
920
|
+
set_all_interpreter_context(owner_object, field, arguments, result_name, orig_result)
|
885
921
|
# Wrap the execution of _this_ method with tracing,
|
886
922
|
# but don't wrap the continuation below
|
887
923
|
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
|
924
|
+
if trace
|
925
|
+
query.current_trace.execute_field_lazy(field: field, query: query, object: owner_object, arguments: arguments, ast_node: ast_node) do
|
926
|
+
schema.sync_lazy(lazy_obj)
|
899
927
|
end
|
928
|
+
else
|
929
|
+
schema.sync_lazy(lazy_obj)
|
900
930
|
end
|
901
|
-
rescue GraphQL::ExecutionError => ex_err
|
931
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
902
932
|
ex_err
|
933
|
+
rescue StandardError => err
|
934
|
+
begin
|
935
|
+
query.handle_or_reraise(err)
|
936
|
+
rescue GraphQL::ExecutionError => ex_err
|
937
|
+
ex_err
|
938
|
+
end
|
903
939
|
end
|
904
940
|
yield(inner_obj)
|
905
941
|
end
|
@@ -908,10 +944,16 @@ module GraphQL
|
|
908
944
|
lazy.value
|
909
945
|
else
|
910
946
|
set_result(result, result_name, lazy)
|
947
|
+
current_depth = 0
|
948
|
+
while result
|
949
|
+
current_depth += 1
|
950
|
+
result = result.graphql_parent
|
951
|
+
end
|
952
|
+
@lazies_at_depth[current_depth] << lazy
|
911
953
|
lazy
|
912
954
|
end
|
913
955
|
else
|
914
|
-
set_all_interpreter_context(owner_object, field, arguments,
|
956
|
+
set_all_interpreter_context(owner_object, field, arguments, result_name, result)
|
915
957
|
yield(lazy_obj)
|
916
958
|
end
|
917
959
|
end
|
@@ -925,27 +967,24 @@ module GraphQL
|
|
925
967
|
end
|
926
968
|
end
|
927
969
|
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
@interpreter_context.delete(key)
|
937
|
-
@context.delete(key)
|
970
|
+
def delete_all_interpreter_context
|
971
|
+
if (ti = thread_info)
|
972
|
+
ti.delete(:current_result)
|
973
|
+
ti.delete(:current_result_name)
|
974
|
+
ti.delete(:current_field)
|
975
|
+
ti.delete(:current_object)
|
976
|
+
ti.delete(:current_arguments)
|
977
|
+
end
|
938
978
|
end
|
939
979
|
|
940
|
-
def resolve_type(type, value
|
941
|
-
|
942
|
-
resolved_type, resolved_value = query.trace("resolve_type", trace_payload) do
|
980
|
+
def resolve_type(type, value)
|
981
|
+
resolved_type, resolved_value = query.current_trace.resolve_type(query: query, type: type, object: value) do
|
943
982
|
query.resolve_type(type, value)
|
944
983
|
end
|
945
984
|
|
946
985
|
if lazy?(resolved_type)
|
947
986
|
GraphQL::Execution::Lazy.new do
|
948
|
-
query.
|
987
|
+
query.current_trace.resolve_type_lazy(query: query, type: type, object: value) do
|
949
988
|
schema.sync_lazy(resolved_type)
|
950
989
|
end
|
951
990
|
end
|