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,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
# Lookahead creates a uniform interface to inspect the forthcoming selections.
|
|
@@ -9,28 +10,38 @@ module GraphQL
|
|
|
9
10
|
# A field may get access to its lookahead by adding `extras: [:lookahead]`
|
|
10
11
|
# to its configuration.
|
|
11
12
|
#
|
|
12
|
-
#
|
|
13
|
-
# field :articles, [Types::Article], null: false,
|
|
14
|
-
# extras: [:lookahead]
|
|
13
|
+
# **Examples**
|
|
15
14
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
15
|
+
# **Example: looking ahead in a field**
|
|
16
|
+
#
|
|
17
|
+
# ```ruby
|
|
18
|
+
# field :articles, [Types::Article], null: false,
|
|
19
|
+
# extras: [:lookahead]
|
|
20
|
+
#
|
|
21
|
+
# # For example, imagine a faster database call
|
|
22
|
+
# # may be issued when only some fields are requested.
|
|
23
|
+
# #
|
|
24
|
+
# # Imagine that _full_ fetch must be made to satisfy `fullContent`,
|
|
25
|
+
# # we can look ahead to see if we need that field. If we do,
|
|
26
|
+
# # we make the expensive database call instead of the cheap one.
|
|
27
|
+
# def articles(lookahead:)
|
|
28
|
+
# if lookahead.selects?(:full_content)
|
|
29
|
+
# fetch_full_articles(object)
|
|
30
|
+
# else
|
|
31
|
+
# fetch_preview_articles(object)
|
|
28
32
|
# end
|
|
33
|
+
# end
|
|
34
|
+
# ```
|
|
29
35
|
class Lookahead
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
36
|
+
# **Parameters**
|
|
37
|
+
#
|
|
38
|
+
# - `query` (`GraphQL::Query`)
|
|
39
|
+
# - `ast_nodes` (`Array<GraphQL::Language::Nodes::Field>, Array<GraphQL::Language::Nodes::OperationDefinition>`)
|
|
40
|
+
# - `field` (`GraphQL::Schema::Field`) — if `ast_nodes` are fields, this is the field definition matching those nodes
|
|
41
|
+
# - `root_type` (`Class`) — if `ast_nodes` are operation definition, this is the root type for that operation
|
|
42
|
+
#
|
|
43
|
+
# :call-seq:
|
|
44
|
+
# initialize(GraphQL::Query query:, Array[GraphQL::Language::Nodes::Field] | Array[GraphQL::Language::Nodes::OperationDefinition] ast_nodes:, GraphQL::Schema::Field field:, Class root_type:, owner_type:)
|
|
34
45
|
def initialize(query:, ast_nodes:, field: nil, root_type: nil, owner_type: nil)
|
|
35
46
|
@ast_nodes = ast_nodes.freeze
|
|
36
47
|
@field = field
|
|
@@ -40,16 +51,27 @@ module GraphQL
|
|
|
40
51
|
@owner_type = owner_type
|
|
41
52
|
end
|
|
42
53
|
|
|
43
|
-
#
|
|
54
|
+
# **Returns**
|
|
55
|
+
#
|
|
56
|
+
# - `Array<GraphQL::Language::Nodes::Field>`
|
|
44
57
|
attr_reader :ast_nodes
|
|
45
58
|
|
|
46
|
-
#
|
|
59
|
+
# **Returns**
|
|
60
|
+
#
|
|
61
|
+
# - `GraphQL::Schema::Field`
|
|
47
62
|
attr_reader :field
|
|
48
63
|
|
|
49
|
-
#
|
|
64
|
+
# **Returns**
|
|
65
|
+
#
|
|
66
|
+
# - `GraphQL::Schema::Object, GraphQL::Schema::Union, GraphQL::Schema::Interface`
|
|
50
67
|
attr_reader :owner_type
|
|
51
68
|
|
|
52
|
-
#
|
|
69
|
+
# **Returns**
|
|
70
|
+
#
|
|
71
|
+
# - `Hash<Symbol, Object>`
|
|
72
|
+
#
|
|
73
|
+
# :call-seq:
|
|
74
|
+
# arguments() -> Hash[Symbol, Object]
|
|
53
75
|
def arguments
|
|
54
76
|
if defined?(@arguments)
|
|
55
77
|
@arguments
|
|
@@ -80,9 +102,18 @@ module GraphQL
|
|
|
80
102
|
# against the arguments in the next selection. This method will return false
|
|
81
103
|
# if any of the given `arguments:` are not present and matching in the next selection.
|
|
82
104
|
# (But, the next selection may contain _more_ than the given arguments.)
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
105
|
+
#
|
|
106
|
+
# **Parameters**
|
|
107
|
+
#
|
|
108
|
+
# - `field_name` (`String, Symbol`)
|
|
109
|
+
# - `arguments` (`Hash`) — Arguments which must match in the selection
|
|
110
|
+
#
|
|
111
|
+
# **Returns**
|
|
112
|
+
#
|
|
113
|
+
# - `Boolean`
|
|
114
|
+
#
|
|
115
|
+
# :call-seq:
|
|
116
|
+
# selects?(String | Symbol field_name, selected_type:, Hash arguments:) -> bool
|
|
86
117
|
def selects?(field_name, selected_type: @selected_type, arguments: nil)
|
|
87
118
|
selection(field_name, selected_type: selected_type, arguments: arguments).selected?
|
|
88
119
|
end
|
|
@@ -96,22 +127,45 @@ module GraphQL
|
|
|
96
127
|
# against the arguments in the next selection. This method will return false
|
|
97
128
|
# if any of the given `arguments:` are not present and matching in the next selection.
|
|
98
129
|
# (But, the next selection may contain _more_ than the given arguments.)
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
130
|
+
#
|
|
131
|
+
# **Parameters**
|
|
132
|
+
#
|
|
133
|
+
# - `alias_name` (`String, Symbol`)
|
|
134
|
+
# - `arguments` (`Hash`) — Arguments which must match in the selection
|
|
135
|
+
#
|
|
136
|
+
# **Returns**
|
|
137
|
+
#
|
|
138
|
+
# - `Boolean`
|
|
139
|
+
#
|
|
140
|
+
# :call-seq:
|
|
141
|
+
# selects_alias?(String | Symbol alias_name, Hash arguments:) -> bool
|
|
102
142
|
def selects_alias?(alias_name, arguments: nil)
|
|
103
143
|
alias_selection(alias_name, arguments: arguments).selected?
|
|
104
144
|
end
|
|
105
145
|
|
|
106
|
-
#
|
|
146
|
+
# **Returns**
|
|
147
|
+
#
|
|
148
|
+
# - `Boolean` — True if this lookahead represents a field that was requested
|
|
149
|
+
#
|
|
150
|
+
# :call-seq:
|
|
151
|
+
# selected?() -> bool
|
|
107
152
|
def selected?
|
|
108
153
|
true
|
|
109
154
|
end
|
|
110
155
|
|
|
111
|
-
# Like
|
|
112
|
-
# It returns a null object (check with
|
|
113
|
-
#
|
|
114
|
-
#
|
|
156
|
+
# Like [selects?](rdoc-ref:#selects?), but can be used for chaining.
|
|
157
|
+
# It returns a null object (check with [selected?](rdoc-ref:#selected?))
|
|
158
|
+
#
|
|
159
|
+
# **Parameters**
|
|
160
|
+
#
|
|
161
|
+
# - `field_name` (`String, Symbol`)
|
|
162
|
+
#
|
|
163
|
+
# **Returns**
|
|
164
|
+
#
|
|
165
|
+
# - `GraphQL::Execution::Lookahead`
|
|
166
|
+
#
|
|
167
|
+
# :call-seq:
|
|
168
|
+
# selection(String | Symbol field_name, selected_type:, arguments:) -> GraphQL::Execution::Lookahead
|
|
115
169
|
def selection(field_name, selected_type: @selected_type, arguments: nil)
|
|
116
170
|
next_field_defn = case field_name
|
|
117
171
|
when String
|
|
@@ -141,12 +195,18 @@ module GraphQL
|
|
|
141
195
|
lookahead_for_selection(next_field_defn, selected_type, arguments)
|
|
142
196
|
end
|
|
143
197
|
|
|
144
|
-
# Like
|
|
145
|
-
# It returns a null object (check with
|
|
146
|
-
#
|
|
198
|
+
# Like [selection](rdoc-ref:#selection), but for aliases.
|
|
199
|
+
# It returns a null object (check with [selected?](rdoc-ref:#selected?))
|
|
200
|
+
#
|
|
201
|
+
# **Returns**
|
|
202
|
+
#
|
|
203
|
+
# - `GraphQL::Execution::Lookahead`
|
|
204
|
+
#
|
|
205
|
+
# :call-seq:
|
|
206
|
+
# alias_selection(alias_name, selected_type:, arguments:) -> GraphQL::Execution::Lookahead
|
|
147
207
|
def alias_selection(alias_name, selected_type: @selected_type, arguments: nil)
|
|
148
|
-
alias_cache_key = [alias_name, arguments]
|
|
149
|
-
return alias_selections[
|
|
208
|
+
alias_cache_key = [alias_name, selected_type, arguments]
|
|
209
|
+
return alias_selections[alias_cache_key] if alias_selections.key?(alias_cache_key)
|
|
150
210
|
|
|
151
211
|
alias_node = lookup_alias_node(ast_nodes, alias_name)
|
|
152
212
|
return NULL_LOOKAHEAD unless alias_node
|
|
@@ -163,21 +223,34 @@ module GraphQL
|
|
|
163
223
|
alias_selections[alias_cache_key] = lookahead_for_selection(next_field_defn, selected_type, alias_arguments, alias_name)
|
|
164
224
|
end
|
|
165
225
|
|
|
166
|
-
# Like
|
|
226
|
+
# Like [selection](rdoc-ref:#selection), but for all nodes.
|
|
167
227
|
# It returns a list of Lookaheads for all Selections
|
|
168
228
|
#
|
|
169
229
|
# If `arguments:` is provided, each provided key/value will be matched
|
|
170
230
|
# against the arguments in each selection. This method will filter the selections
|
|
171
231
|
# if any of the given `arguments:` do not match the given selection.
|
|
172
232
|
#
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
# next_lookaheads.map(&:name) #=> [:full_content, :title]
|
|
177
|
-
# end
|
|
233
|
+
# **Examples**
|
|
234
|
+
#
|
|
235
|
+
# **Example: getting the name of a selection**
|
|
178
236
|
#
|
|
179
|
-
#
|
|
180
|
-
#
|
|
237
|
+
# ```ruby
|
|
238
|
+
# def articles(lookahead:)
|
|
239
|
+
# next_lookaheads = lookahead.selections # => [#<GraphQL::Execution::Lookahead ...>, ...]
|
|
240
|
+
# next_lookaheads.map(&:name) #=> [:full_content, :title]
|
|
241
|
+
# end
|
|
242
|
+
# ```
|
|
243
|
+
#
|
|
244
|
+
# **Parameters**
|
|
245
|
+
#
|
|
246
|
+
# - `arguments` (`Hash`) — Arguments which must match in the selection
|
|
247
|
+
#
|
|
248
|
+
# **Returns**
|
|
249
|
+
#
|
|
250
|
+
# - `Array<GraphQL::Execution::Lookahead>`
|
|
251
|
+
#
|
|
252
|
+
# :call-seq:
|
|
253
|
+
# selections(Hash arguments:) -> Array[GraphQL::Execution::Lookahead]
|
|
181
254
|
def selections(arguments: nil)
|
|
182
255
|
subselections_by_type = {}
|
|
183
256
|
subselections_on_type = subselections_by_type[@selected_type] = {}
|
|
@@ -202,13 +275,23 @@ module GraphQL
|
|
|
202
275
|
# The method name of the field.
|
|
203
276
|
# It returns the method_sym of the Lookahead's field.
|
|
204
277
|
#
|
|
205
|
-
#
|
|
206
|
-
#
|
|
207
|
-
#
|
|
208
|
-
#
|
|
209
|
-
#
|
|
278
|
+
# **Examples**
|
|
279
|
+
#
|
|
280
|
+
# **Example: getting the name of a selection**
|
|
281
|
+
#
|
|
282
|
+
# ```ruby
|
|
283
|
+
# def articles(lookahead:)
|
|
284
|
+
# article.selection(:full_content).name # => :full_content
|
|
285
|
+
# # ...
|
|
286
|
+
# end
|
|
287
|
+
# ```
|
|
288
|
+
#
|
|
289
|
+
# **Returns**
|
|
290
|
+
#
|
|
291
|
+
# - `Symbol`
|
|
210
292
|
#
|
|
211
|
-
#
|
|
293
|
+
# :call-seq:
|
|
294
|
+
# name() -> Symbol
|
|
212
295
|
def name
|
|
213
296
|
@field && @field.original_name
|
|
214
297
|
end
|
|
@@ -217,7 +300,7 @@ module GraphQL
|
|
|
217
300
|
"#<GraphQL::Execution::Lookahead #{@field ? "@field=#{@field.path.inspect}": "@root_type=#{@root_type}"} @ast_nodes.size=#{@ast_nodes.size}>"
|
|
218
301
|
end
|
|
219
302
|
|
|
220
|
-
# This is returned for
|
|
303
|
+
# This is returned for [Lookahead#selection](rdoc-ref:Lookahead#selection) when a non-existent field is passed
|
|
221
304
|
class NullLookahead < Lookahead
|
|
222
305
|
# No inputs required here.
|
|
223
306
|
def initialize
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
# Execute multiple queries under the same multiplex "umbrella".
|
|
@@ -17,12 +18,11 @@ module GraphQL
|
|
|
17
18
|
#
|
|
18
19
|
# If one query raises an application error, all queries will be in undefined states.
|
|
19
20
|
#
|
|
20
|
-
# Validation errors and
|
|
21
|
+
# Validation errors and [GraphQL::ExecutionError](rdoc-ref:GraphQL::ExecutionError)s are handled in isolation:
|
|
21
22
|
# one of these errors in one query will not affect the other queries.
|
|
22
23
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
class Multiplex
|
|
24
|
+
# See [Schema.multiplex](rdoc-ref:GraphQL::Schema::multiplex) for the public API
|
|
25
|
+
class Multiplex # :nodoc:
|
|
26
26
|
include Tracing::Traceable
|
|
27
27
|
|
|
28
28
|
attr_reader :context, :queries, :schema, :max_complexity, :dataloader, :current_trace
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
require "graphql/execution/prepare_object_step"
|
|
3
4
|
require "graphql/execution/input_values"
|
|
4
5
|
require "graphql/execution/field_resolve_step"
|
|
@@ -9,6 +10,8 @@ require "graphql/execution/runner"
|
|
|
9
10
|
require "graphql/execution/selections_step"
|
|
10
11
|
module GraphQL
|
|
11
12
|
module Execution
|
|
13
|
+
#--
|
|
14
|
+
# @requires_ancestor: Kernel
|
|
12
15
|
module Finalizer
|
|
13
16
|
attr_accessor :path
|
|
14
17
|
|
|
@@ -30,6 +33,8 @@ module GraphQL
|
|
|
30
33
|
module HaltExecution
|
|
31
34
|
end
|
|
32
35
|
|
|
36
|
+
#--
|
|
37
|
+
# @requires_ancestor: Kernel
|
|
33
38
|
module PostProcessor
|
|
34
39
|
def after_resolve(field_results)
|
|
35
40
|
raise RequiredImplementationMissingError, "#{self.class}#after_resolve should handle `field_results` and return a new value to use"
|
|
@@ -37,6 +42,8 @@ module GraphQL
|
|
|
37
42
|
end
|
|
38
43
|
|
|
39
44
|
module Next
|
|
45
|
+
#--
|
|
46
|
+
# @requires_ancestor: singleton(GraphQL::Schema)
|
|
40
47
|
module SchemaExtension
|
|
41
48
|
def execute_next(query_str = nil, query: nil, subscription_topic: nil, context: nil, document: nil, operation_name: nil, variables: nil, warden: nil, root_value: nil, validate: true, visibility_profile: nil)
|
|
42
49
|
multiplex_context = if context
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
class PrepareObjectStep
|
|
@@ -13,6 +14,7 @@ module GraphQL
|
|
|
13
14
|
@resolved_type = nil
|
|
14
15
|
@authorized_value = nil
|
|
15
16
|
@authorization_error = nil
|
|
17
|
+
@execution_error = nil
|
|
16
18
|
@key = key
|
|
17
19
|
@next_step = :resolve_type
|
|
18
20
|
@is_from_array = is_from_array
|
|
@@ -23,7 +25,12 @@ module GraphQL
|
|
|
23
25
|
if @authorized_value
|
|
24
26
|
query = @field_resolve_step.selections_step.query
|
|
25
27
|
query.current_trace.begin_authorized(@resolved_type, @object, query.context)
|
|
26
|
-
|
|
28
|
+
begin
|
|
29
|
+
@authorized_value = @runner.schema.sync_lazy(@authorized_value)
|
|
30
|
+
rescue StandardError => err
|
|
31
|
+
@authorized_value = nil
|
|
32
|
+
handle_authorization_error(err, query)
|
|
33
|
+
end
|
|
27
34
|
query.current_trace.end_authorized(@resolved_type, @object, query.context, @authorized_value)
|
|
28
35
|
elsif @resolved_type
|
|
29
36
|
ctx = @field_resolve_step.selections_step.query.context
|
|
@@ -89,8 +96,9 @@ module GraphQL
|
|
|
89
96
|
query.current_trace.begin_authorized(@resolved_type, @object, query.context)
|
|
90
97
|
@authorized_value = @resolved_type.authorized?(@object, query.context)
|
|
91
98
|
query.current_trace.end_authorized(@resolved_type, @object, query.context, @authorized_value)
|
|
92
|
-
rescue
|
|
93
|
-
@
|
|
99
|
+
rescue StandardError => err
|
|
100
|
+
@authorized_value = nil
|
|
101
|
+
handle_authorization_error(err, query)
|
|
94
102
|
end
|
|
95
103
|
|
|
96
104
|
if @runner.resolves_lazies && @runner.lazy?(@authorized_value)
|
|
@@ -99,19 +107,14 @@ module GraphQL
|
|
|
99
107
|
else
|
|
100
108
|
create_result
|
|
101
109
|
end
|
|
102
|
-
rescue GraphQL::RuntimeError => err
|
|
103
|
-
@graphql_result[@key] = add_field_error(err)
|
|
104
|
-
rescue StandardError => err
|
|
105
|
-
query ||= @field_resolve_step.selections_step.query
|
|
106
|
-
begin
|
|
107
|
-
query.handle_or_reraise(err, field: @field_resolve_step.field_definition, arguments: @field_resolve_step.arguments, object: @object) # rubocop:disable Development/ContextIsPassedCop
|
|
108
|
-
rescue GraphQL::RuntimeError => err
|
|
109
|
-
@graphql_result[@key] = add_field_error(err)
|
|
110
|
-
end
|
|
111
110
|
end
|
|
112
111
|
|
|
113
112
|
def create_result
|
|
114
|
-
if
|
|
113
|
+
if @execution_error
|
|
114
|
+
# `.authorized?` raised (or its lazy value raised) an error other than UnauthorizedError:
|
|
115
|
+
# it isn't an authorization decision, so don't call `unauthorized_object`.
|
|
116
|
+
@graphql_result[@key] = add_field_error(@execution_error)
|
|
117
|
+
elsif !@authorized_value
|
|
115
118
|
@authorization_error ||= GraphQL::UnauthorizedError.new(object: @object, type: @resolved_type, context: @field_resolve_step.selections_step.query.context)
|
|
116
119
|
end
|
|
117
120
|
|
|
@@ -146,6 +149,28 @@ module GraphQL
|
|
|
146
149
|
|
|
147
150
|
@field_resolve_step.authorized_finished(self)
|
|
148
151
|
end
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
# Errors raised by `.authorized?` (or by syncing its lazy return value):
|
|
156
|
+
#
|
|
157
|
+
# - `UnauthorizedError` is equivalent to returning `false`, so it goes to `unauthorized_object`
|
|
158
|
+
# - Other `GraphQL::RuntimeError`s are added to the response for this field
|
|
159
|
+
# - Other errors go to `rescue_from` handlers, which might return a `GraphQL::RuntimeError`, or else re-raise
|
|
160
|
+
def handle_authorization_error(err, query)
|
|
161
|
+
case err
|
|
162
|
+
when GraphQL::UnauthorizedError
|
|
163
|
+
@authorization_error = err
|
|
164
|
+
when GraphQL::RuntimeError
|
|
165
|
+
@execution_error = err
|
|
166
|
+
else
|
|
167
|
+
begin
|
|
168
|
+
@authorized_value = query.handle_or_reraise(err, field: @field_resolve_step.field_definition, arguments: @field_resolve_step.arguments, object: @object) # rubocop:disable Development/ContextIsPassedCop
|
|
169
|
+
rescue GraphQL::RuntimeError => runtime_err
|
|
170
|
+
handle_authorization_error(runtime_err, query)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
149
174
|
end
|
|
150
175
|
end
|
|
151
176
|
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 ResolveTypeStep
|
|
@@ -17,7 +18,7 @@ module GraphQL
|
|
|
17
18
|
def self.assert_valid_resolved_type(abstract_type, resolved_type, object, field_resolution_step, query: field_resolution_step.selections_step.query)
|
|
18
19
|
possible_types = query.types.possible_types(abstract_type)
|
|
19
20
|
if !possible_types.include?(resolved_type)
|
|
20
|
-
err_class = abstract_type
|
|
21
|
+
err_class = abstract_type.const_get(:UnresolvedTypeError)
|
|
21
22
|
type_error = err_class.new(object, field_resolution_step.field_definition, abstract_type, resolved_type, possible_types)
|
|
22
23
|
query.schema.type_error(type_error, query.context)
|
|
23
24
|
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 Runner
|
|
@@ -15,7 +16,7 @@ module GraphQL
|
|
|
15
16
|
h[query] = InputValues.new(query, self)
|
|
16
17
|
end.compare_by_identity
|
|
17
18
|
|
|
18
|
-
@runtime_directives = nil
|
|
19
|
+
@runtime_directives = nil #: Hash[String, singleton(GraphQL::Schema::Directive)]?
|
|
19
20
|
@schema.directives.each do |name, dir_class|
|
|
20
21
|
if dir_class.runtime? && name != "include" && name != "skip"
|
|
21
22
|
@runtime_directives ||= {}
|
|
@@ -54,7 +55,12 @@ module GraphQL
|
|
|
54
55
|
|
|
55
56
|
attr_reader :schema, :variables, :dataloader, :resolves_lazies, :authorizes, :static_type_at, :runtime_type_at, :finalizers, :input_values
|
|
56
57
|
|
|
57
|
-
#
|
|
58
|
+
# **Returns**
|
|
59
|
+
#
|
|
60
|
+
# - `void`
|
|
61
|
+
#
|
|
62
|
+
# :call-seq:
|
|
63
|
+
# add_finalizer(query, result_value, key, finalizer) -> void
|
|
58
64
|
def add_finalizer(query, result_value, key, finalizer)
|
|
59
65
|
@finalizers ||= {}.compare_by_identity
|
|
60
66
|
f_for_query = @finalizers[query] ||= {}.compare_by_identity
|
|
@@ -72,6 +78,7 @@ module GraphQL
|
|
|
72
78
|
end
|
|
73
79
|
|
|
74
80
|
def execute
|
|
81
|
+
previous_multiplex = Fiber[:__graphql_current_multiplex]
|
|
75
82
|
Fiber[:__graphql_current_multiplex] = @multiplex
|
|
76
83
|
isolated_steps = [[]]
|
|
77
84
|
trace = @multiplex.current_trace
|
|
@@ -86,10 +93,10 @@ module GraphQL
|
|
|
86
93
|
@schema.analysis_engine.analyze_multiplex(@multiplex, multiplex_analyzers)
|
|
87
94
|
trace.end_analyze_multiplex(@multiplex, multiplex_analyzers)
|
|
88
95
|
|
|
89
|
-
results =
|
|
96
|
+
results = {}.compare_by_identity
|
|
90
97
|
queries.each do |query|
|
|
91
98
|
if query.validate && !query.valid?
|
|
92
|
-
results
|
|
99
|
+
results[query] = {
|
|
93
100
|
"errors" => query.static_errors.map(&:to_h)
|
|
94
101
|
}
|
|
95
102
|
next
|
|
@@ -124,8 +131,8 @@ module GraphQL
|
|
|
124
131
|
end
|
|
125
132
|
end
|
|
126
133
|
|
|
127
|
-
queries.
|
|
128
|
-
result = results[
|
|
134
|
+
queries.map do |query|
|
|
135
|
+
result = results[query]
|
|
129
136
|
|
|
130
137
|
fin_result = if (!@finalizers&.key?(query) && query.context.errors.empty?) || !query.valid?
|
|
131
138
|
result
|
|
@@ -154,9 +161,19 @@ module GraphQL
|
|
|
154
161
|
end
|
|
155
162
|
query.result
|
|
156
163
|
end
|
|
164
|
+
rescue SystemStackError => err
|
|
165
|
+
queries.map do |query|
|
|
166
|
+
@schema.query_stack_error(query, err)
|
|
167
|
+
query.result_values ||= { "errors" => query.context.errors.map(&:to_h) }
|
|
168
|
+
query.result
|
|
169
|
+
end
|
|
170
|
+
rescue Exception
|
|
171
|
+
# Assign values here so that the query's `@executed` becomes true
|
|
172
|
+
queries.map { |q| q.result_values ||= {} }
|
|
173
|
+
raise
|
|
157
174
|
end
|
|
158
175
|
ensure
|
|
159
|
-
Fiber[:__graphql_current_multiplex] =
|
|
176
|
+
Fiber[:__graphql_current_multiplex] = previous_multiplex
|
|
160
177
|
end
|
|
161
178
|
|
|
162
179
|
def gather_selections(type_defn, ast_selections, selections_step, query, all_selections, prototype_result, into:)
|
|
@@ -255,17 +272,17 @@ module GraphQL
|
|
|
255
272
|
end
|
|
256
273
|
|
|
257
274
|
if !auth_check
|
|
258
|
-
results
|
|
275
|
+
results[query] = {}
|
|
259
276
|
return
|
|
260
277
|
end
|
|
261
278
|
end
|
|
262
279
|
|
|
263
|
-
results
|
|
280
|
+
results[query] = { "data" => data }
|
|
264
281
|
objects = [root_value]
|
|
265
282
|
query.current_trace.objects(root_type, objects, query.context)
|
|
266
283
|
|
|
267
284
|
if query.is_a?(GraphQL::Query) && uses_runtime_directives && (query_dirs = selected_operation.directives).any? # rubocop:disable Development/NoneWithoutBlockCop
|
|
268
|
-
continue_execution = true
|
|
285
|
+
continue_execution = true #: bool
|
|
269
286
|
query_dirs.each do |dir_node|
|
|
270
287
|
dir_defn = runtime_directives[dir_node.name] || raise(GraphQL::Error, "No directive definition found for: #{dir_node.name.inspect}")
|
|
271
288
|
dir_args, errors = input_values[query].argument_values(dir_defn, dir_node.arguments, nil) # rubocop:disable Development/ContextIsPassedCop
|
|
@@ -354,7 +371,7 @@ module GraphQL
|
|
|
354
371
|
objects = [root_value]
|
|
355
372
|
query.current_trace.objects(resolved_type, objects, query.context)
|
|
356
373
|
runtime_type_at[data] = resolved_type
|
|
357
|
-
results
|
|
374
|
+
results[query] = { "data" => data }
|
|
358
375
|
isolated_steps[0] << SelectionsStep.new(
|
|
359
376
|
parent_type: resolved_type,
|
|
360
377
|
field_resolve_step: nil,
|
|
@@ -369,10 +386,10 @@ module GraphQL
|
|
|
369
386
|
inner_type = root_type.unwrap
|
|
370
387
|
case inner_type.kind.name
|
|
371
388
|
when "SCALAR", "ENUM"
|
|
372
|
-
results
|
|
389
|
+
results[query] = run_isolated_scalar(root_type, query)
|
|
373
390
|
else
|
|
374
391
|
list_result = Array.new(root_value.size) { Hash.new.compare_by_identity }
|
|
375
|
-
results
|
|
392
|
+
results[query] = { "data" => list_result }
|
|
376
393
|
isolated_steps[0] << SelectionsStep.new(
|
|
377
394
|
parent_type: inner_type,
|
|
378
395
|
field_resolve_step: nil,
|
|
@@ -385,7 +402,7 @@ module GraphQL
|
|
|
385
402
|
)
|
|
386
403
|
end
|
|
387
404
|
when "SCALAR", "ENUM"
|
|
388
|
-
results
|
|
405
|
+
results[query] = run_isolated_scalar(root_type, query)
|
|
389
406
|
else
|
|
390
407
|
raise "Unhandled root type kind: #{root_type.kind.name.inspect}"
|
|
391
408
|
end
|
|
@@ -418,7 +435,7 @@ module GraphQL
|
|
|
418
435
|
key = dummy_path.pop
|
|
419
436
|
is_from_array = key.is_a?(Integer)
|
|
420
437
|
|
|
421
|
-
if lazy?(value)
|
|
438
|
+
if resolves_lazies && lazy?(value)
|
|
422
439
|
value = @schema.sync_lazy(value)
|
|
423
440
|
end
|
|
424
441
|
selections = partial.ast_nodes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
4
|
module Execution
|
|
4
5
|
class SelectionsStep
|
|
@@ -35,10 +36,10 @@ module GraphQL
|
|
|
35
36
|
l = @all_selections.length
|
|
36
37
|
while i < l
|
|
37
38
|
grouped_selections = @all_selections[i]
|
|
38
|
-
selections_prototype_result = @all_selections[i + 1]
|
|
39
|
+
selections_prototype_result = @all_selections[i + 1] #: as !nil
|
|
39
40
|
if (directives_owner = grouped_selections.delete(:__node))
|
|
40
41
|
directives = directives_owner.directives
|
|
41
|
-
continue_execution = true
|
|
42
|
+
continue_execution = true #: bool
|
|
42
43
|
directives.each do |dir_node|
|
|
43
44
|
dir_defn = @runner.runtime_directives[dir_node.name]
|
|
44
45
|
if dir_defn # not present for `skip` or `include`
|
data/lib/graphql/execution.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
require "graphql/execution/directive_checks"
|
|
3
4
|
require "graphql/execution/next"
|
|
4
5
|
require "graphql/execution/interpreter"
|
|
@@ -9,8 +10,7 @@ require "graphql/execution/errors"
|
|
|
9
10
|
|
|
10
11
|
module GraphQL
|
|
11
12
|
module Execution
|
|
12
|
-
#
|
|
13
|
-
class Skip < GraphQL::RuntimeError
|
|
13
|
+
class Skip < GraphQL::RuntimeError # :nodoc:
|
|
14
14
|
attr_accessor :path
|
|
15
15
|
def ast_nodes=(_ignored); end
|
|
16
16
|
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
# typed: true
|
|
2
3
|
module GraphQL
|
|
3
|
-
# If a field's resolve function returns
|
|
4
|
+
# If a field's resolve function returns an [ExecutionError](rdoc-ref:GraphQL::ExecutionError),
|
|
4
5
|
# the error will be inserted into the response's `"errors"` key
|
|
5
6
|
# and the field will resolve to `nil`.
|
|
6
7
|
class ExecutionError < GraphQL::RuntimeError
|
|
7
|
-
#
|
|
8
|
-
#
|
|
8
|
+
# **Returns**
|
|
9
|
+
#
|
|
10
|
+
# - `String` — an array describing the JSON-path into the execution response which corresponds to this error.
|
|
9
11
|
attr_accessor :path
|
|
10
12
|
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
13
|
+
# **Deprecated:** Use `extensions` instead of `options`. The GraphQL spec recommends that any custom entries in an error be under the `extensions` key.
|
|
14
|
+
#
|
|
15
|
+
# **Returns**
|
|
16
|
+
#
|
|
17
|
+
# - `Hash` — Optional data for error objects
|
|
15
18
|
attr_accessor :options
|
|
16
19
|
|
|
17
|
-
#
|
|
18
|
-
#
|
|
20
|
+
# **Returns**
|
|
21
|
+
#
|
|
22
|
+
# - `Hash` — Optional custom data for error objects which will be added under the `extensions` key.
|
|
19
23
|
attr_accessor :extensions
|
|
20
24
|
|
|
21
25
|
def initialize(message, ast_node: nil, ast_nodes: nil, options: nil, extensions: nil)
|
|
@@ -38,7 +42,12 @@ module GraphQL
|
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
|
-
#
|
|
45
|
+
# **Returns**
|
|
46
|
+
#
|
|
47
|
+
# - `Hash` — An entry for the response's "errors" key
|
|
48
|
+
#
|
|
49
|
+
# :call-seq:
|
|
50
|
+
# to_h() -> Hash
|
|
42
51
|
def to_h
|
|
43
52
|
hash = {
|
|
44
53
|
"message" => message,
|