graphql 2.6.9 → 2.6.14
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 +4 -4
- data/.rdoc_options +4 -0
- data/lib/generators/graphql/core.rb +1 -0
- data/lib/generators/graphql/detailed_trace_generator.rb +1 -0
- data/lib/generators/graphql/enum_generator.rb +1 -0
- data/lib/generators/graphql/field_extractor.rb +1 -0
- data/lib/generators/graphql/input_generator.rb +1 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +1 -0
- data/lib/generators/graphql/install_generator.rb +1 -0
- data/lib/generators/graphql/interface_generator.rb +1 -0
- data/lib/generators/graphql/loader_generator.rb +8 -2
- data/lib/generators/graphql/mutation_create_generator.rb +8 -2
- data/lib/generators/graphql/mutation_delete_generator.rb +8 -2
- data/lib/generators/graphql/mutation_generator.rb +8 -2
- data/lib/generators/graphql/mutation_update_generator.rb +8 -2
- data/lib/generators/graphql/object_generator.rb +1 -0
- data/lib/generators/graphql/orm_mutations_base.rb +8 -2
- data/lib/generators/graphql/relay.rb +1 -0
- data/lib/generators/graphql/relay_generator.rb +1 -0
- data/lib/generators/graphql/scalar_generator.rb +1 -0
- data/lib/generators/graphql/type_generator.rb +38 -8
- data/lib/generators/graphql/union_generator.rb +1 -0
- data/lib/graphql/analysis/analyzer.rb +35 -9
- data/lib/graphql/analysis/field_usage.rb +1 -0
- data/lib/graphql/analysis/max_query_complexity.rb +3 -2
- data/lib/graphql/analysis/max_query_depth.rb +1 -0
- data/lib/graphql/analysis/query_complexity.rb +57 -20
- data/lib/graphql/analysis/query_depth.rb +17 -12
- data/lib/graphql/analysis/visitor.rb +79 -16
- data/lib/graphql/analysis.rb +23 -6
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/autoload.rb +30 -7
- data/lib/graphql/backtrace/table.rb +21 -5
- data/lib/graphql/backtrace/traced_error.rb +8 -3
- data/lib/graphql/backtrace.rb +14 -9
- data/lib/graphql/coercion_error.rb +1 -0
- data/lib/graphql/current.rb +44 -19
- data/lib/graphql/dashboard/application_controller.rb +1 -0
- data/lib/graphql/dashboard/detailed_traces.rb +1 -0
- data/lib/graphql/dashboard/installable.rb +1 -0
- data/lib/graphql/dashboard/landings_controller.rb +1 -0
- data/lib/graphql/dashboard/limiters.rb +1 -0
- data/lib/graphql/dashboard/operation_store.rb +1 -0
- data/lib/graphql/dashboard/statics_controller.rb +1 -0
- data/lib/graphql/dashboard/subscriptions.rb +1 -0
- data/lib/graphql/dashboard.rb +36 -22
- data/lib/graphql/dataloader/active_record_association_source.rb +1 -0
- data/lib/graphql/dataloader/active_record_source.rb +1 -0
- data/lib/graphql/dataloader/async_dataloader.rb +45 -16
- data/lib/graphql/dataloader/null_dataloader.rb +4 -3
- data/lib/graphql/dataloader/request.rb +8 -2
- data/lib/graphql/dataloader/request_all.rb +8 -2
- data/lib/graphql/dataloader/source.rb +127 -35
- data/lib/graphql/dataloader.rb +98 -44
- data/lib/graphql/date_encoding_error.rb +2 -1
- data/lib/graphql/dig.rb +12 -3
- data/lib/graphql/duration_encoding_error.rb +2 -1
- data/lib/graphql/execution/directive_checks.rb +8 -3
- data/lib/graphql/execution/errors.rb +20 -6
- data/lib/graphql/execution/field_resolve_step.rb +288 -168
- data/lib/graphql/execution/finalize.rb +12 -6
- data/lib/graphql/execution/input_values.rb +5 -2
- data/lib/graphql/execution/interpreter/argument_value.rb +17 -5
- data/lib/graphql/execution/interpreter/arguments.rb +24 -9
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -1
- data/lib/graphql/execution/interpreter/execution_errors.rb +1 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +1 -0
- data/lib/graphql/execution/interpreter/resolve.rb +18 -8
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +4 -1
- data/lib/graphql/execution/interpreter/runtime.rb +72 -25
- data/lib/graphql/execution/interpreter.rb +18 -7
- data/lib/graphql/execution/lazy/lazy_method_map.rb +21 -8
- data/lib/graphql/execution/lazy.rb +34 -10
- data/lib/graphql/execution/load_argument_step.rb +1 -0
- data/lib/graphql/execution/lookahead.rb +137 -54
- data/lib/graphql/execution/multiplex.rb +4 -4
- data/lib/graphql/execution/next.rb +7 -0
- data/lib/graphql/execution/prepare_object_step.rb +38 -13
- data/lib/graphql/execution/resolve_type_step.rb +2 -1
- data/lib/graphql/execution/runner.rb +32 -15
- data/lib/graphql/execution/selections_step.rb +3 -2
- data/lib/graphql/execution.rb +2 -2
- data/lib/graphql/execution_error.rb +19 -10
- data/lib/graphql/float_decoding_error.rb +14 -0
- data/lib/graphql/float_encoding_error.rb +33 -0
- data/lib/graphql/integer_decoding_error.rb +2 -1
- data/lib/graphql/integer_encoding_error.rb +8 -3
- data/lib/graphql/introspection/base_object.rb +3 -1
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/dynamic_fields.rb +1 -0
- data/lib/graphql/introspection/entry_points.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/input_value_type.rb +1 -0
- data/lib/graphql/introspection/introspection_query.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +1 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/introspection.rb +1 -0
- data/lib/graphql/invalid_name_error.rb +1 -0
- data/lib/graphql/invalid_null_error.rb +19 -6
- data/lib/graphql/language/block_string.rb +2 -1
- data/lib/graphql/language/cache.rb +10 -4
- data/lib/graphql/language/comment.rb +1 -0
- data/lib/graphql/language/definition_slice.rb +1 -0
- data/lib/graphql/language/document_from_schema_definition.rb +9 -10
- data/lib/graphql/language/generation.rb +23 -9
- data/lib/graphql/language/lexer.rb +16 -8
- data/lib/graphql/language/nodes.rb +2094 -419
- data/lib/graphql/language/parser.rb +29 -18
- data/lib/graphql/language/printer.rb +31 -16
- data/lib/graphql/language/sanitized_printer.rb +16 -5
- data/lib/graphql/language/static_visitor.rb +19 -4
- data/lib/graphql/language/visitor.rb +51 -29
- data/lib/graphql/language.rb +15 -9
- data/lib/graphql/load_application_object_failed_error.rb +14 -5
- data/lib/graphql/name_validator.rb +1 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +1 -0
- data/lib/graphql/pagination/array_connection.rb +24 -6
- data/lib/graphql/pagination/connection.rb +178 -48
- data/lib/graphql/pagination/connections.rb +21 -14
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -0
- data/lib/graphql/pagination/relation_connection.rb +164 -27
- data/lib/graphql/pagination/sequel_dataset_connection.rb +1 -0
- data/lib/graphql/pagination.rb +1 -0
- data/lib/graphql/parse_error.rb +1 -0
- data/lib/graphql/query/context/scoped_context.rb +2 -1
- data/lib/graphql/query/context.rb +106 -35
- data/lib/graphql/query/fingerprint.rb +15 -7
- data/lib/graphql/query/input_validation_result.rb +1 -0
- data/lib/graphql/query/null_context.rb +1 -0
- data/lib/graphql/query/partial.rb +28 -16
- data/lib/graphql/query/result.rb +15 -5
- data/lib/graphql/query/validation_pipeline.rb +16 -6
- data/lib/graphql/query/variable_validation_error.rb +17 -1
- data/lib/graphql/query/variables.rb +9 -2
- data/lib/graphql/query.rb +195 -50
- data/lib/graphql/railtie.rb +7 -3
- data/lib/graphql/rake_task/validate.rb +72 -17
- data/lib/graphql/rake_task.rb +55 -23
- data/lib/graphql/relay/range_add.rb +32 -21
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/default_required_true.rb +9 -6
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +12 -8
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +9 -5
- data/lib/graphql/rubocop.rb +1 -0
- data/lib/graphql/runtime_error.rb +1 -0
- data/lib/graphql/runtime_type_error.rb +1 -0
- data/lib/graphql/schema/addition.rb +69 -50
- data/lib/graphql/schema/always_visible.rb +1 -0
- data/lib/graphql/schema/argument.rb +279 -45
- data/lib/graphql/schema/base_64_encoder.rb +2 -2
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/build_from_definition.rb +507 -178
- data/lib/graphql/schema/built_in_types.rb +1 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -0
- data/lib/graphql/schema/directive/feature.rb +39 -22
- data/lib/graphql/schema/directive/flagged.rb +6 -1
- data/lib/graphql/schema/directive/include.rb +1 -0
- data/lib/graphql/schema/directive/one_of.rb +1 -0
- data/lib/graphql/schema/directive/skip.rb +1 -0
- data/lib/graphql/schema/directive/specified_by.rb +1 -0
- data/lib/graphql/schema/directive/transform.rb +17 -8
- data/lib/graphql/schema/directive.rb +33 -7
- data/lib/graphql/schema/enum.rb +99 -38
- data/lib/graphql/schema/enum_value.rb +21 -13
- data/lib/graphql/schema/field/connection_extension.rb +10 -2
- data/lib/graphql/schema/field/scope_extension.rb +1 -0
- data/lib/graphql/schema/field.rb +622 -110
- data/lib/graphql/schema/field_extension.rb +89 -34
- data/lib/graphql/schema/find_inherited_value.rb +5 -3
- data/lib/graphql/schema/finder.rb +22 -8
- data/lib/graphql/schema/has_single_input_argument.rb +39 -6
- data/lib/graphql/schema/input_object.rb +40 -13
- data/lib/graphql/schema/interface.rb +33 -17
- data/lib/graphql/schema/introspection_system.rb +7 -3
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +15 -4
- data/lib/graphql/schema/loader.rb +23 -12
- data/lib/graphql/schema/member/base_dsl_methods.rb +58 -12
- data/lib/graphql/schema/member/build_type.rb +21 -7
- data/lib/graphql/schema/member/graphql_type_names.rb +10 -6
- data/lib/graphql/schema/member/has_arguments.rb +112 -49
- data/lib/graphql/schema/member/has_ast_node.rb +1 -0
- data/lib/graphql/schema/member/has_authorization.rb +5 -0
- data/lib/graphql/schema/member/has_dataloader.rb +91 -34
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -2
- data/lib/graphql/schema/member/has_directives.rb +45 -11
- data/lib/graphql/schema/member/has_fields.rb +151 -70
- data/lib/graphql/schema/member/has_interfaces.rb +8 -2
- data/lib/graphql/schema/member/has_path.rb +14 -5
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +1 -0
- data/lib/graphql/schema/member/has_validators.rb +19 -4
- data/lib/graphql/schema/member/relay_shortcuts.rb +10 -2
- data/lib/graphql/schema/member/scoped.rb +14 -3
- data/lib/graphql/schema/member/type_system_helpers.rb +36 -6
- data/lib/graphql/schema/member/validates_input.rb +1 -0
- data/lib/graphql/schema/member.rb +9 -2
- data/lib/graphql/schema/mutation.rb +50 -46
- data/lib/graphql/schema/non_null.rb +21 -5
- data/lib/graphql/schema/object.rb +44 -15
- data/lib/graphql/schema/printer.rb +52 -31
- data/lib/graphql/schema/ractor_shareable.rb +6 -2
- data/lib/graphql/schema/relay_classic_mutation.rb +3 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +29 -7
- data/lib/graphql/schema/resolver.rb +156 -45
- data/lib/graphql/schema/scalar.rb +1 -0
- data/lib/graphql/schema/subscription.rb +67 -28
- data/lib/graphql/schema/timeout.rb +65 -25
- data/lib/graphql/schema/type_expression.rb +14 -5
- data/lib/graphql/schema/type_membership.rb +29 -10
- data/lib/graphql/schema/union.rb +4 -2
- data/lib/graphql/schema/unique_within_type.rb +24 -5
- data/lib/graphql/schema/validator/all_validator.rb +17 -9
- data/lib/graphql/schema/validator/allow_blank_validator.rb +8 -2
- data/lib/graphql/schema/validator/allow_null_validator.rb +8 -2
- data/lib/graphql/schema/validator/exclusion_validator.rb +14 -5
- data/lib/graphql/schema/validator/format_validator.rb +21 -10
- data/lib/graphql/schema/validator/inclusion_validator.rb +15 -6
- data/lib/graphql/schema/validator/length_validator.rb +23 -12
- data/lib/graphql/schema/validator/numericality_validator.rb +29 -16
- data/lib/graphql/schema/validator/required_validator.rb +45 -31
- data/lib/graphql/schema/validator.rb +89 -25
- data/lib/graphql/schema/visibility/migration.rb +14 -7
- data/lib/graphql/schema/visibility/profile.rb +73 -19
- data/lib/graphql/schema/visibility/visit.rb +12 -10
- data/lib/graphql/schema/visibility.rb +24 -20
- data/lib/graphql/schema/warden.rb +117 -31
- data/lib/graphql/schema/wrapper.rb +4 -1
- data/lib/graphql/schema.rb +1052 -304
- data/lib/graphql/static_validation/all_rules.rb +2 -1
- data/lib/graphql/static_validation/base_visitor.rb +59 -9
- data/lib/graphql/static_validation/definition_dependencies.rb +27 -7
- data/lib/graphql/static_validation/error.rb +3 -0
- data/lib/graphql/static_validation/interpreter_visitor.rb +1 -0
- data/lib/graphql/static_validation/literal_validator.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +3 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +3 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +9 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +355 -157
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +14 -2
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +3 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -0
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +1 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +3 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +1 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +4 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +3 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +1 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +3 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +1 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +43 -5
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +1 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +3 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +3 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +207 -51
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +3 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -3
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +1 -0
- data/lib/graphql/static_validation/validation_context.rb +3 -2
- data/lib/graphql/static_validation/validation_timeout_error.rb +1 -0
- data/lib/graphql/static_validation/validator.rb +41 -16
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +1 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +85 -65
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +1 -0
- data/lib/graphql/subscriptions/event.rb +25 -6
- data/lib/graphql/subscriptions/serialize.rb +89 -23
- data/lib/graphql/subscriptions.rb +172 -46
- data/lib/graphql/testing/helpers.rb +17 -4
- data/lib/graphql/testing/mock_action_cable.rb +55 -33
- data/lib/graphql/testing.rb +1 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +17 -9
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_trace.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -1
- data/lib/graphql/tracing/appsignal_trace.rb +16 -7
- data/lib/graphql/tracing/appsignal_tracing.rb +7 -3
- data/lib/graphql/tracing/call_legacy_tracers.rb +1 -0
- data/lib/graphql/tracing/data_dog_trace.rb +17 -6
- data/lib/graphql/tracing/data_dog_tracing.rb +10 -3
- data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +1 -0
- data/lib/graphql/tracing/detailed_trace.rb +105 -42
- data/lib/graphql/tracing/legacy_hooks_trace.rb +5 -0
- data/lib/graphql/tracing/legacy_trace.rb +1 -0
- data/lib/graphql/tracing/monitor_trace.rb +17 -11
- data/lib/graphql/tracing/new_relic_trace.rb +17 -8
- data/lib/graphql/tracing/new_relic_tracing.rb +7 -3
- data/lib/graphql/tracing/notifications_trace.rb +11 -8
- data/lib/graphql/tracing/notifications_tracing.rb +23 -7
- data/lib/graphql/tracing/null_trace.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +1 -0
- data/lib/graphql/tracing/perfetto_trace.rb +41 -19
- data/lib/graphql/tracing/platform_trace.rb +3 -1
- data/lib/graphql/tracing/platform_tracing.rb +16 -7
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +1 -0
- data/lib/graphql/tracing/prometheus_trace.rb +22 -13
- data/lib/graphql/tracing/prometheus_tracing.rb +1 -0
- data/lib/graphql/tracing/scout_trace.rb +10 -4
- data/lib/graphql/tracing/scout_tracing.rb +7 -3
- data/lib/graphql/tracing/sentry_trace.rb +25 -6
- data/lib/graphql/tracing/statsd_trace.rb +12 -6
- data/lib/graphql/tracing/statsd_tracing.rb +7 -1
- data/lib/graphql/tracing/trace.rb +231 -58
- data/lib/graphql/tracing.rb +25 -9
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/big_int.rb +1 -0
- data/lib/graphql/types/boolean.rb +1 -0
- data/lib/graphql/types/float.rb +19 -4
- data/lib/graphql/types/id.rb +1 -0
- data/lib/graphql/types/int.rb +2 -1
- data/lib/graphql/types/iso_8601_date.rb +21 -4
- data/lib/graphql/types/iso_8601_date_time.rb +33 -6
- data/lib/graphql/types/iso_8601_duration.rb +42 -9
- data/lib/graphql/types/json.rb +1 -0
- data/lib/graphql/types/relay/base_connection.rb +38 -32
- data/lib/graphql/types/relay/base_edge.rb +15 -9
- data/lib/graphql/types/relay/connection_behaviors.rb +19 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +17 -4
- data/lib/graphql/types/relay/has_node_field.rb +6 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +6 -1
- data/lib/graphql/types/relay/node.rb +1 -0
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay/page_info.rb +1 -0
- data/lib/graphql/types/relay/page_info_behaviors.rb +1 -0
- data/lib/graphql/types/relay.rb +4 -3
- data/lib/graphql/types/string.rb +1 -0
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/unauthorized_enum_value_error.rb +4 -1
- data/lib/graphql/unauthorized_error.rb +11 -4
- data/lib/graphql/unauthorized_field_error.rb +4 -1
- data/lib/graphql/unresolved_type_error.rb +16 -5
- data/lib/graphql/version.rb +2 -1
- data/lib/graphql.rb +39 -9
- data/readme.md +1 -1
- metadata +91 -5
- data/.yardopts +0 -5
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
class FieldResolveStep
|
|
6
|
+
# Only these built-in fields on Relay connection and edge types return already-scoped items.
|
|
7
|
+
# Custom fields on those types must still be authorized normally.
|
|
8
|
+
SCOPED_RELAY_FIELD_NAMES = [:node, :nodes, :edges].freeze
|
|
9
|
+
|
|
5
10
|
def initialize(parent_type:, runner:, key:, selections_step:)
|
|
6
11
|
@selections_step = selections_step
|
|
7
12
|
@key = key
|
|
@@ -21,6 +26,8 @@ module GraphQL
|
|
|
21
26
|
@finish_extension_idx = nil
|
|
22
27
|
@was_scoped = nil
|
|
23
28
|
@pending_steps = nil
|
|
29
|
+
@field_authorization_objects = @field_authorization_results = @field_authorization_errors = nil
|
|
30
|
+
@field_authorization_next_idx = @field_authorization_pending = nil
|
|
24
31
|
@arguments_without_loads = @post_processors = @directive_finalizers = nil
|
|
25
32
|
end
|
|
26
33
|
|
|
@@ -89,6 +96,12 @@ module GraphQL
|
|
|
89
96
|
finish_extensions
|
|
90
97
|
elsif @field_results
|
|
91
98
|
build_results
|
|
99
|
+
elsif @field_authorization_results
|
|
100
|
+
if @field_authorization_next_idx < @field_authorization_objects.size
|
|
101
|
+
authorize_next_field_object
|
|
102
|
+
else
|
|
103
|
+
finish_field_authorizations
|
|
104
|
+
end
|
|
92
105
|
elsif @arguments
|
|
93
106
|
execute_field
|
|
94
107
|
else
|
|
@@ -113,7 +126,7 @@ module GraphQL
|
|
|
113
126
|
@runner.add_finalizer(@selections_step.query, result, key, err)
|
|
114
127
|
if !err.is_a?(GraphQL::Execution::Skip)
|
|
115
128
|
field_type = return_type
|
|
116
|
-
should_propagate_null = field_type.non_null?
|
|
129
|
+
should_propagate_null = field_type.non_null? #: bool
|
|
117
130
|
while (should_propagate_null == false && field_type.kind.wraps?)
|
|
118
131
|
field_type = field_type.of_type
|
|
119
132
|
should_propagate_null = field_type.non_null?
|
|
@@ -126,10 +139,10 @@ module GraphQL
|
|
|
126
139
|
end
|
|
127
140
|
|
|
128
141
|
def propagate_nulls
|
|
129
|
-
propagating_null = true
|
|
142
|
+
propagating_null = true #: bool
|
|
130
143
|
highest_nulled_depth = path.size
|
|
131
|
-
highest_list_depth = nil
|
|
132
|
-
current_field_step = self
|
|
144
|
+
highest_list_depth = nil #: Integer?
|
|
145
|
+
current_field_step = self #: FieldResolveStep?
|
|
133
146
|
while current_field_step && current_field_step.field_definition
|
|
134
147
|
return_type = current_field_step.field_definition.type
|
|
135
148
|
if propagating_null && return_type.non_null?
|
|
@@ -146,7 +159,7 @@ module GraphQL
|
|
|
146
159
|
end
|
|
147
160
|
|
|
148
161
|
if highest_list_depth.nil? || highest_nulled_depth <= highest_list_depth
|
|
149
|
-
kill_field_step = self
|
|
162
|
+
kill_field_step = self #: FieldResolveStep?
|
|
150
163
|
while kill_field_step && kill_field_step.field_definition && highest_nulled_depth <= kill_field_step.path.size
|
|
151
164
|
kill_field_step.selections_step.killed = true
|
|
152
165
|
kill_field_step = kill_field_step.selections_step.field_resolve_step
|
|
@@ -238,153 +251,30 @@ module GraphQL
|
|
|
238
251
|
end
|
|
239
252
|
|
|
240
253
|
if @runner.authorizes?(@field_definition, ctx)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
field_authed = @field_definition.authorized?(o, @arguments, ctx)
|
|
250
|
-
if @runner.resolves_lazies && @runner.lazy?(field_authed)
|
|
251
|
-
# TODO batch this properly...
|
|
252
|
-
field_authed = sync(field_authed)
|
|
253
|
-
end
|
|
254
|
-
rescue GraphQL::UnauthorizedFieldError => field_auth_err
|
|
255
|
-
err = field_auth_err
|
|
256
|
-
err.field ||= @field_definition
|
|
257
|
-
field_authed = false
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
if field_authed
|
|
261
|
-
authorized_results << @results[i]
|
|
262
|
-
authorized_objects << o
|
|
263
|
-
else
|
|
264
|
-
begin
|
|
265
|
-
err ||= GraphQL::UnauthorizedFieldError.new(object: o, type: @parent_type, context: ctx, field: @field_definition)
|
|
266
|
-
new_obj = query.schema.unauthorized_field(err)
|
|
267
|
-
if !new_obj.nil?
|
|
268
|
-
authorized_objects << new_obj
|
|
269
|
-
authorized_results << @results[i]
|
|
270
|
-
end
|
|
271
|
-
rescue GraphQL::ExecutionError => exec_err
|
|
272
|
-
add_graphql_error(@results[i], key, exec_err)
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
i += 1
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
if authorized_objects.size == 0
|
|
254
|
+
@field_authorization_objects = objects
|
|
255
|
+
@field_authorization_results = Array.new(objects.size)
|
|
256
|
+
@field_authorization_next_idx = 0
|
|
257
|
+
if objects.size > 1 && !@runner.dataloader.is_a?(GraphQL::Dataloader::NullDataloader)
|
|
258
|
+
# Enqueue this step once per object, so Dataloader sources loaded by `authorized?` batch across objects.
|
|
259
|
+
# Each call authorizes the next object; see `authorize_next_field_object`.
|
|
260
|
+
@field_authorization_pending = objects.size
|
|
261
|
+
objects.size.times { @runner.dataloader.append_job(self) }
|
|
279
262
|
return
|
|
280
263
|
end
|
|
281
|
-
|
|
264
|
+
objects.size.times { |idx| authorize_field_at(idx, ctx) }
|
|
265
|
+
authorized_objects = collect_field_authorizations
|
|
266
|
+
return if authorized_objects.nil?
|
|
282
267
|
else
|
|
283
268
|
authorized_objects = objects
|
|
284
269
|
end
|
|
285
270
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
query.current_trace.begin_execute_field(@field_definition, authorized_objects, @arguments, query)
|
|
291
|
-
|
|
292
|
-
if @runner.uses_runtime_directives
|
|
293
|
-
if @ast_nodes.nil? || @ast_nodes.size == 1
|
|
294
|
-
directives = if !@ast_node.directives.empty?
|
|
295
|
-
@ast_node.directives
|
|
296
|
-
else
|
|
297
|
-
nil
|
|
298
|
-
end
|
|
299
|
-
else
|
|
300
|
-
directives = nil
|
|
301
|
-
@ast_nodes.each do |n|
|
|
302
|
-
if (d = n.directives).any? # rubocop:disable Development/NoneWithoutBlockCop
|
|
303
|
-
directives ||= []
|
|
304
|
-
directives.concat(d)
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
if directives
|
|
310
|
-
directives.each do |dir_node|
|
|
311
|
-
if (dir_defn = @runner.runtime_directives[dir_node.name])
|
|
312
|
-
dir_args, errors = @runner.input_values[query].argument_values(dir_defn, dir_node.arguments, self) # rubocop:disable Development/ContextIsPassedCop
|
|
313
|
-
if errors
|
|
314
|
-
@results.each { |r| r.delete(@key) }
|
|
315
|
-
errors.each { |e| e.ast_node = dir_node }
|
|
316
|
-
build_errors_result(errors, nil)
|
|
317
|
-
return
|
|
318
|
-
else
|
|
319
|
-
begin
|
|
320
|
-
dir_defn.validate!(dir_args, query.context)
|
|
321
|
-
if !(result = dir_defn.resolve_field(ast_nodes, @parent_type, field_definition, authorized_objects, dir_args, ctx)).nil?
|
|
322
|
-
if result.is_a?(Finalizer)
|
|
323
|
-
result.path = path
|
|
324
|
-
@directive_finalizers ||= []
|
|
325
|
-
@directive_finalizers << result
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
if result.is_a?(PostProcessor)
|
|
329
|
-
@post_processors ||= []
|
|
330
|
-
@post_processors << result
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
if result.is_a?(HaltExecution)
|
|
334
|
-
@directive_finalizers&.each { |f|
|
|
335
|
-
@selections_step.results.each { |r| @runner.add_finalizer(query, r, key, f) }
|
|
336
|
-
}
|
|
337
|
-
return
|
|
338
|
-
end
|
|
339
|
-
end
|
|
340
|
-
rescue GraphQL::RuntimeError => err
|
|
341
|
-
err.ast_node = dir_node
|
|
342
|
-
raise
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
has_extensions = @field_definition.extensions.size > 0
|
|
351
|
-
if has_extensions
|
|
352
|
-
@extended = GraphQL::Schema::Field::ExtendedState.new(@arguments, authorized_objects)
|
|
353
|
-
@field_results = @field_definition.run_next_extensions_before_resolve(authorized_objects, @arguments, ctx, @extended) do |objs, args|
|
|
354
|
-
if (added_extras = @extended.added_extras)
|
|
355
|
-
args = args.dup
|
|
356
|
-
added_extras.each { |e| args.delete(e) }
|
|
357
|
-
end
|
|
358
|
-
resolve_batch(objs, ctx, args)
|
|
359
|
-
end
|
|
360
|
-
@finish_extension_idx = 0
|
|
361
|
-
else
|
|
362
|
-
@field_results = resolve_batch(authorized_objects, ctx, @arguments)
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
query.current_trace.end_execute_field(@field_definition, authorized_objects, @arguments, query, @field_results)
|
|
366
|
-
|
|
367
|
-
if any_lazy_results?
|
|
368
|
-
@runner.dataloader.lazy_at_depth(path.size, self)
|
|
369
|
-
elsif @pending_steps.nil? || @pending_steps.empty?
|
|
370
|
-
if has_extensions
|
|
371
|
-
finish_extensions
|
|
372
|
-
else
|
|
373
|
-
build_results
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
rescue GraphQL::ExecutionError => err
|
|
377
|
-
build_errors_result(nil, err)
|
|
378
|
-
rescue StandardError => stderr
|
|
379
|
-
begin
|
|
380
|
-
@selections_step.query.handle_or_reraise(stderr, field: @field_definition, arguments: @arguments, object: nil)
|
|
381
|
-
rescue GraphQL::ExecutionError => err
|
|
382
|
-
add_graphql_error(@results[0], key, err)
|
|
383
|
-
end
|
|
271
|
+
execute_authorized_field(authorized_objects)
|
|
272
|
+
rescue StandardError => err
|
|
273
|
+
handle_execute_field_error(err)
|
|
384
274
|
end
|
|
385
275
|
|
|
386
276
|
def any_lazy_results?
|
|
387
|
-
lazies = false
|
|
277
|
+
lazies = false #: bool
|
|
388
278
|
if @runner.resolves_lazies # TODO extract this
|
|
389
279
|
@field_results.each do |field_result|
|
|
390
280
|
if @runner.lazy?(field_result)
|
|
@@ -414,11 +304,15 @@ module GraphQL
|
|
|
414
304
|
case ext
|
|
415
305
|
when Schema::Field::ConnectionExtension
|
|
416
306
|
conns = ctx.schema.connections
|
|
307
|
+
lookahead = @arguments[:lookahead]
|
|
308
|
+
# The memo omits the extension's extras (`:lookahead`)
|
|
309
|
+
conn_arguments = memos[@finish_extension_idx] || @arguments
|
|
417
310
|
@field_results.map!.each_with_index do |value, idx|
|
|
418
311
|
object = @extended.object[idx]
|
|
419
|
-
conn = conns.populate_connection(@field_definition, object, value,
|
|
312
|
+
conn = conns.populate_connection(@field_definition, object, value, conn_arguments, ctx)
|
|
420
313
|
if conn
|
|
421
314
|
conn.was_authorized_by_scope_items = @was_scoped
|
|
315
|
+
conn.lookahead ||= lookahead
|
|
422
316
|
end
|
|
423
317
|
conn
|
|
424
318
|
rescue GraphQL::RuntimeError => err
|
|
@@ -510,7 +404,7 @@ module GraphQL
|
|
|
510
404
|
def build_leaf_result(result_h, result_key, field_result, return_type, ctx, is_from_array)
|
|
511
405
|
if field_result.nil?
|
|
512
406
|
if return_type.non_null?
|
|
513
|
-
add_non_null_error(is_from_array)
|
|
407
|
+
add_non_null_error(is_from_array, return_type: return_type)
|
|
514
408
|
else
|
|
515
409
|
nil
|
|
516
410
|
end
|
|
@@ -527,7 +421,7 @@ module GraphQL
|
|
|
527
421
|
end
|
|
528
422
|
|
|
529
423
|
inner_type = return_type.of_type
|
|
530
|
-
result_a = Array.new(field_result.size)
|
|
424
|
+
result_a = field_result.is_a?(Array) ? Array.new(field_result.size) : []
|
|
531
425
|
field_result.each_with_index do |item, idx|
|
|
532
426
|
result_a[idx] = build_leaf_result(result_a, idx, item, inner_type, ctx, true)
|
|
533
427
|
end
|
|
@@ -605,8 +499,14 @@ module GraphQL
|
|
|
605
499
|
end
|
|
606
500
|
end
|
|
607
501
|
|
|
608
|
-
def add_non_null_error(is_from_array)
|
|
609
|
-
|
|
502
|
+
def add_non_null_error(is_from_array, return_type: nil)
|
|
503
|
+
if is_from_array && return_type
|
|
504
|
+
list_type = @field_definition.type
|
|
505
|
+
list_type = list_type.of_type if list_type.non_null?
|
|
506
|
+
# Preserve existing messages for single-level lists.
|
|
507
|
+
element_type = return_type.of_type if list_type.of_type.list?
|
|
508
|
+
end
|
|
509
|
+
err = @parent_type.const_get(:InvalidNullError).new(@parent_type, @field_definition, ast_nodes, is_from_array: is_from_array, path: path, element_type: element_type)
|
|
610
510
|
nn_result = @runner.schema.type_error(err, @selections_step.query.context)
|
|
611
511
|
if nn_result.nil?
|
|
612
512
|
propagate_nulls
|
|
@@ -620,6 +520,207 @@ module GraphQL
|
|
|
620
520
|
|
|
621
521
|
private
|
|
622
522
|
|
|
523
|
+
def execute_authorized_field(authorized_objects)
|
|
524
|
+
query = @selections_step.query
|
|
525
|
+
ctx = query.context
|
|
526
|
+
|
|
527
|
+
if @parent_type.default_relay? && SCOPED_RELAY_FIELD_NAMES.include?(@field_definition.original_name) && authorized_objects.all? { |o| o.respond_to?(:was_authorized_by_scope_items?) && o.was_authorized_by_scope_items? }
|
|
528
|
+
@was_scoped = true
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
query.current_trace.begin_execute_field(@field_definition, authorized_objects, @arguments, query)
|
|
532
|
+
|
|
533
|
+
if @runner.uses_runtime_directives
|
|
534
|
+
if @ast_nodes.nil? || @ast_nodes.size == 1
|
|
535
|
+
directives = if !@ast_node.directives.empty?
|
|
536
|
+
@ast_node.directives
|
|
537
|
+
else
|
|
538
|
+
nil
|
|
539
|
+
end
|
|
540
|
+
else
|
|
541
|
+
directives = nil #: Array[untyped]?
|
|
542
|
+
@ast_nodes.each do |n|
|
|
543
|
+
if (d = n.directives).any? # rubocop:disable Development/NoneWithoutBlockCop
|
|
544
|
+
directives ||= []
|
|
545
|
+
directives.concat(d)
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
if directives
|
|
551
|
+
directives.each do |dir_node|
|
|
552
|
+
if (dir_defn = @runner.runtime_directives[dir_node.name])
|
|
553
|
+
dir_args, errors = @runner.input_values[query].argument_values(dir_defn, dir_node.arguments, self) # rubocop:disable Development/ContextIsPassedCop
|
|
554
|
+
if errors
|
|
555
|
+
@results.each { |r| r.delete(@key) }
|
|
556
|
+
errors.each { |e| e.ast_node = dir_node }
|
|
557
|
+
build_errors_result(errors, nil)
|
|
558
|
+
return
|
|
559
|
+
else
|
|
560
|
+
begin
|
|
561
|
+
dir_defn.validate!(dir_args, query.context)
|
|
562
|
+
if !(result = dir_defn.resolve_field(ast_nodes, @parent_type, field_definition, authorized_objects, dir_args, ctx)).nil?
|
|
563
|
+
if result.is_a?(Finalizer)
|
|
564
|
+
result.path = path
|
|
565
|
+
@directive_finalizers ||= []
|
|
566
|
+
@directive_finalizers << result
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
if result.is_a?(PostProcessor)
|
|
570
|
+
@post_processors ||= []
|
|
571
|
+
@post_processors << result
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
if result.is_a?(HaltExecution)
|
|
575
|
+
@directive_finalizers&.each { |f|
|
|
576
|
+
@selections_step.results.each { |r| @runner.add_finalizer(query, r, key, f) }
|
|
577
|
+
}
|
|
578
|
+
return
|
|
579
|
+
end
|
|
580
|
+
end
|
|
581
|
+
rescue GraphQL::RuntimeError => err
|
|
582
|
+
err.ast_node = dir_node
|
|
583
|
+
raise
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
end
|
|
590
|
+
|
|
591
|
+
has_extensions = @field_definition.extensions.size > 0
|
|
592
|
+
if has_extensions
|
|
593
|
+
@extended = GraphQL::Schema::Field::ExtendedState.new(@arguments, authorized_objects)
|
|
594
|
+
@field_results = @field_definition.run_next_extensions_before_resolve(authorized_objects, @arguments, ctx, @extended) do |objs, args|
|
|
595
|
+
if (added_extras = @extended.added_extras)
|
|
596
|
+
args = args.dup
|
|
597
|
+
added_extras.each { |e| args.delete(e) }
|
|
598
|
+
end
|
|
599
|
+
resolve_batch(objs, ctx, args)
|
|
600
|
+
end
|
|
601
|
+
@finish_extension_idx = 0
|
|
602
|
+
else
|
|
603
|
+
@field_results = resolve_batch(authorized_objects, ctx, @arguments)
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
query.current_trace.end_execute_field(@field_definition, authorized_objects, @arguments, query, @field_results)
|
|
607
|
+
|
|
608
|
+
if any_lazy_results?
|
|
609
|
+
@runner.dataloader.lazy_at_depth(path.size, self)
|
|
610
|
+
elsif @pending_steps.nil? || @pending_steps.empty?
|
|
611
|
+
if has_extensions
|
|
612
|
+
finish_extensions
|
|
613
|
+
else
|
|
614
|
+
build_results
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
rescue StandardError => err
|
|
618
|
+
handle_execute_field_error(err)
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
def handle_execute_field_error(err)
|
|
622
|
+
if @field_authorization_objects
|
|
623
|
+
clear_field_authorizations
|
|
624
|
+
end
|
|
625
|
+
if err.is_a?(GraphQL::ExecutionError)
|
|
626
|
+
build_errors_result(nil, err)
|
|
627
|
+
else
|
|
628
|
+
begin
|
|
629
|
+
@selections_step.query.handle_or_reraise(err, field: @field_definition, arguments: @arguments, object: nil)
|
|
630
|
+
rescue GraphQL::ExecutionError => exec_err
|
|
631
|
+
add_graphql_error(@results[0], key, exec_err)
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
# Stores the (possibly synced) +authorized?+ result for the object at +idx+.
|
|
637
|
+
# A GraphQL::UnauthorizedFieldError raised by +authorized?+ is stored in +@field_authorization_errors+.
|
|
638
|
+
def authorize_field_at(idx, ctx)
|
|
639
|
+
field_authed = @field_definition.authorized?(@field_authorization_objects[idx], @arguments, ctx)
|
|
640
|
+
if @runner.resolves_lazies && @runner.lazy?(field_authed)
|
|
641
|
+
field_authed = sync(field_authed)
|
|
642
|
+
end
|
|
643
|
+
@field_authorization_results[idx] = field_authed
|
|
644
|
+
rescue GraphQL::UnauthorizedFieldError => field_auth_err
|
|
645
|
+
field_auth_err.field ||= @field_definition
|
|
646
|
+
(@field_authorization_errors ||= {})[idx] = field_auth_err
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
# Runs once for each time this step was enqueued for field authorization.
|
|
650
|
+
# The index is taken before +authorized?+ runs, so it's still correct if this Fiber pauses.
|
|
651
|
+
# When the last object is done, the step is enqueued again to call +finish_field_authorizations+.
|
|
652
|
+
def authorize_next_field_object
|
|
653
|
+
idx = @field_authorization_next_idx
|
|
654
|
+
@field_authorization_next_idx += 1
|
|
655
|
+
begin
|
|
656
|
+
authorize_field_at(idx, @selections_step.query.context)
|
|
657
|
+
rescue StandardError => err
|
|
658
|
+
(@field_authorization_errors ||= {})[idx] = err
|
|
659
|
+
end
|
|
660
|
+
@field_authorization_pending -= 1
|
|
661
|
+
if @field_authorization_pending == 0
|
|
662
|
+
@runner.add_step(self)
|
|
663
|
+
end
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
def finish_field_authorizations
|
|
667
|
+
if (errors = @field_authorization_errors)
|
|
668
|
+
@field_authorization_objects.size.times do |idx|
|
|
669
|
+
err = errors[idx]
|
|
670
|
+
if err && !err.is_a?(GraphQL::UnauthorizedFieldError)
|
|
671
|
+
raise err
|
|
672
|
+
end
|
|
673
|
+
end
|
|
674
|
+
end
|
|
675
|
+
authorized_objects = collect_field_authorizations
|
|
676
|
+
if authorized_objects
|
|
677
|
+
execute_authorized_field(authorized_objects)
|
|
678
|
+
end
|
|
679
|
+
rescue StandardError => err
|
|
680
|
+
handle_execute_field_error(err)
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
def clear_field_authorizations
|
|
684
|
+
@field_authorization_objects = @field_authorization_results = @field_authorization_errors = nil
|
|
685
|
+
@field_authorization_next_idx = @field_authorization_pending = nil
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
# Applies +unauthorized_field+ for denied objects, in object order.
|
|
689
|
+
# Returns the objects to resolve, or +nil+ if none are left.
|
|
690
|
+
def collect_field_authorizations
|
|
691
|
+
objects = @field_authorization_objects
|
|
692
|
+
auth_results = @field_authorization_results
|
|
693
|
+
errors = @field_authorization_errors
|
|
694
|
+
clear_field_authorizations
|
|
695
|
+
ctx = @selections_step.query.context
|
|
696
|
+
authorized_objects = []
|
|
697
|
+
authorized_results = []
|
|
698
|
+
objects.each_with_index do |o, i|
|
|
699
|
+
err = errors && errors[i]
|
|
700
|
+
if !err && auth_results[i]
|
|
701
|
+
authorized_results << @results[i]
|
|
702
|
+
authorized_objects << o
|
|
703
|
+
else
|
|
704
|
+
begin
|
|
705
|
+
err ||= GraphQL::UnauthorizedFieldError.new(object: o, type: @parent_type, context: ctx, field: @field_definition)
|
|
706
|
+
new_obj = ctx.schema.unauthorized_field(err)
|
|
707
|
+
if !new_obj.nil?
|
|
708
|
+
authorized_objects << new_obj
|
|
709
|
+
authorized_results << @results[i]
|
|
710
|
+
end
|
|
711
|
+
rescue GraphQL::ExecutionError => exec_err
|
|
712
|
+
add_graphql_error(@results[i], key, exec_err)
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
if authorized_objects.size == 0
|
|
718
|
+
return nil
|
|
719
|
+
end
|
|
720
|
+
@results = authorized_results
|
|
721
|
+
authorized_objects
|
|
722
|
+
end
|
|
723
|
+
|
|
623
724
|
def build_graphql_result(graphql_result, key, field_result, return_type, is_nn, is_list, is_from_array) # rubocop:disable Metrics/ParameterLists
|
|
624
725
|
if field_result.nil?
|
|
625
726
|
if is_nn
|
|
@@ -645,11 +746,18 @@ module GraphQL
|
|
|
645
746
|
list_result = graphql_result[key] = []
|
|
646
747
|
@directive_finalizers&.each { |f| @runner.add_finalizer(@selections_step.query, list_result, nil, f) }
|
|
647
748
|
i = 0
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
749
|
+
if field_result.is_a?(Array)
|
|
750
|
+
s = field_result.size
|
|
751
|
+
while i < s
|
|
752
|
+
inner_f_r = field_result[i]
|
|
753
|
+
build_graphql_result(list_result, i, inner_f_r, inner_type, inner_type_nn, inner_type_l, true)
|
|
754
|
+
i += 1
|
|
755
|
+
end
|
|
756
|
+
else
|
|
757
|
+
field_result.each do |inner_f_r|
|
|
758
|
+
build_graphql_result(list_result, i, inner_f_r, inner_type, inner_type_nn, inner_type_l, true)
|
|
759
|
+
i += 1
|
|
760
|
+
end
|
|
653
761
|
end
|
|
654
762
|
elsif @runner.resolves_lazies || (
|
|
655
763
|
@static_type.kind.object? ?
|
|
@@ -690,25 +798,25 @@ module GraphQL
|
|
|
690
798
|
when :resolve_batch
|
|
691
799
|
begin
|
|
692
800
|
method_receiver.public_send(@field_definition.execution_mode_key, objects, context, **args_hash)
|
|
693
|
-
rescue GraphQL::ExecutionError =>
|
|
694
|
-
error_instance_array(objects.size,
|
|
695
|
-
rescue StandardError =>
|
|
801
|
+
rescue GraphQL::ExecutionError => batch_err
|
|
802
|
+
error_instance_array(objects.size, batch_err)
|
|
803
|
+
rescue StandardError => batch_stderr
|
|
696
804
|
begin
|
|
697
|
-
context.query.handle_or_reraise(
|
|
698
|
-
rescue GraphQL::ExecutionError =>
|
|
699
|
-
error_instance_array(objects.size,
|
|
805
|
+
context.query.handle_or_reraise(batch_stderr, field: @field_definition, arguments: @arguments, object: nil)
|
|
806
|
+
rescue GraphQL::ExecutionError => batch_err
|
|
807
|
+
error_instance_array(objects.size, batch_err)
|
|
700
808
|
end
|
|
701
809
|
end
|
|
702
810
|
when :resolve_static
|
|
703
811
|
result = begin
|
|
704
812
|
method_receiver.public_send(@field_definition.execution_mode_key, context, **args_hash)
|
|
705
|
-
rescue GraphQL::ExecutionError =>
|
|
706
|
-
|
|
707
|
-
rescue StandardError =>
|
|
813
|
+
rescue GraphQL::ExecutionError => static_err
|
|
814
|
+
static_err
|
|
815
|
+
rescue StandardError => static_stderr
|
|
708
816
|
begin
|
|
709
|
-
context.query.handle_or_reraise(
|
|
710
|
-
rescue GraphQL::ExecutionError =>
|
|
711
|
-
|
|
817
|
+
context.query.handle_or_reraise(static_stderr, field: @field_definition, arguments: @arguments, object: nil)
|
|
818
|
+
rescue GraphQL::ExecutionError => static_err
|
|
819
|
+
static_err
|
|
712
820
|
end
|
|
713
821
|
end
|
|
714
822
|
Array.new(objects.size, result)
|
|
@@ -744,7 +852,8 @@ module GraphQL
|
|
|
744
852
|
when :dig
|
|
745
853
|
objects.map { |o| o.dig(*@field_definition.execution_mode_key) }
|
|
746
854
|
when :dataload
|
|
747
|
-
|
|
855
|
+
k = @field_definition.execution_mode_key
|
|
856
|
+
results = if k.is_a?(Class)
|
|
748
857
|
context.dataload_all(k, objects)
|
|
749
858
|
elsif (source_class = k[:with])
|
|
750
859
|
if (batch_args = k[:by])
|
|
@@ -764,6 +873,12 @@ module GraphQL
|
|
|
764
873
|
else
|
|
765
874
|
raise ArgumentError, "Unexpected `dataload: ...` configuration: #{k.inspect}"
|
|
766
875
|
end
|
|
876
|
+
method = k.is_a?(Hash) ? k[:method] : nil
|
|
877
|
+
if method
|
|
878
|
+
results.map { |r| r&.public_send(method) }
|
|
879
|
+
else
|
|
880
|
+
results
|
|
881
|
+
end
|
|
767
882
|
when :resolver_class
|
|
768
883
|
results = Array.new(objects.size, nil)
|
|
769
884
|
ps = @pending_steps ||= []
|
|
@@ -779,8 +894,13 @@ module GraphQL
|
|
|
779
894
|
end
|
|
780
895
|
results
|
|
781
896
|
when :resolve_legacy_instance_method
|
|
782
|
-
@selections_step.
|
|
783
|
-
|
|
897
|
+
graphql_objects = if objects.equal?(@selections_step.objects)
|
|
898
|
+
@selections_step.graphql_objects
|
|
899
|
+
else
|
|
900
|
+
objects.map { |object| @parent_type.scoped_new(object, context) }
|
|
901
|
+
end
|
|
902
|
+
graphql_objects.map do |graphql_object|
|
|
903
|
+
graphql_object.public_send(@field_definition.execution_mode_key, **args_hash)
|
|
784
904
|
rescue GraphQL::ExecutionError => exec_err
|
|
785
905
|
exec_err
|
|
786
906
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
class Finalize
|
|
@@ -39,11 +40,16 @@ module GraphQL
|
|
|
39
40
|
tf[key] = err
|
|
40
41
|
@finalizers_count += 1
|
|
41
42
|
elsif value_at_key.is_a?(Array)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
pending_arrays = [value_at_key]
|
|
44
|
+
while (array = pending_arrays.pop)
|
|
45
|
+
array.each_with_index do |el, idx|
|
|
46
|
+
if el.equal?(err)
|
|
47
|
+
array_tf = @finalizers[array] ||= {}.compare_by_identity
|
|
48
|
+
array_tf[idx] = err
|
|
49
|
+
@finalizers_count += 1
|
|
50
|
+
elsif el.is_a?(Array)
|
|
51
|
+
pending_arrays << el
|
|
52
|
+
end
|
|
47
53
|
end
|
|
48
54
|
end
|
|
49
55
|
end
|
|
@@ -175,7 +181,7 @@ module GraphQL
|
|
|
175
181
|
inner_type = inner_type.of_type
|
|
176
182
|
end
|
|
177
183
|
|
|
178
|
-
new_invalid_null = false
|
|
184
|
+
new_invalid_null = false #: bool
|
|
179
185
|
|
|
180
186
|
if (f = finalizers(result_arr, nil))
|
|
181
187
|
run_finalizers(@current_result_path.dup, f, result_arr, nil)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
class InputValues
|
|
@@ -38,7 +39,7 @@ module GraphQL
|
|
|
38
39
|
def argument_values(owner_defn, argument_nodes, field_resolve_step)
|
|
39
40
|
arg_defns = @query.types.arguments(owner_defn)
|
|
40
41
|
argument_values = {}
|
|
41
|
-
errors = nil
|
|
42
|
+
errors = nil #: untyped
|
|
42
43
|
|
|
43
44
|
arg_defns.each do |argument_definition|
|
|
44
45
|
arg_ruby_key = argument_definition.keyword
|
|
@@ -182,7 +183,9 @@ module GraphQL
|
|
|
182
183
|
arg_value = begin
|
|
183
184
|
argument_definition.prepare_value(nil, arg_value, context: @query.context)
|
|
184
185
|
rescue StandardError => err
|
|
185
|
-
@runner.schema.handle_or_reraise(@query.context, err, object: nil, arguments: argument_values, field: field_resolve_step&.field_definition)
|
|
186
|
+
handled_err = @runner.schema.handle_or_reraise(@query.context, err, object: nil, arguments: argument_values, field: field_resolve_step&.field_definition)
|
|
187
|
+
raise handled_err if handled_err.is_a?(GraphQL::RuntimeError)
|
|
188
|
+
handled_err
|
|
186
189
|
end
|
|
187
190
|
end
|
|
188
191
|
|