graphql 1.9.18 → 1.13.24
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/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +44 -7
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +22 -27
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +29 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +174 -67
- data/lib/graphql/analysis/ast/visitor.rb +16 -7
- data/lib/graphql/analysis/ast.rb +21 -11
- data/lib/graphql/argument.rb +8 -36
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +44 -5
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +10 -4
- data/lib/graphql/boolean_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- data/lib/graphql/dataloader/null_dataloader.rb +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/define/assign_enum_value.rb +1 -1
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/assign_object_field.rb +1 -1
- data/lib/graphql/define/defined_object_proxy.rb +5 -8
- data/lib/graphql/define/instance_definable.rb +60 -110
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -12
- data/lib/graphql/directive/include_directive.rb +1 -1
- data/lib/graphql/directive/skip_directive.rb +1 -1
- data/lib/graphql/directive.rb +9 -6
- data/lib/graphql/enum_type.rb +14 -74
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +110 -8
- data/lib/graphql/execution/execute.rb +8 -1
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +721 -386
- data/lib/graphql/execution/interpreter.rb +42 -19
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +39 -114
- data/lib/graphql/execution/multiplex.rb +50 -25
- data/lib/graphql/field.rb +15 -119
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/float_type.rb +1 -1
- data/lib/graphql/function.rb +5 -30
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +9 -25
- data/lib/graphql/int_type.rb +1 -1
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +10 -24
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -2
- data/lib/graphql/introspection/base_object.rb +2 -5
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +12 -6
- data/lib/graphql/introspection/entry_points.rb +9 -9
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +41 -11
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +12 -12
- data/lib/graphql/introspection/type_type.rb +27 -17
- data/lib/graphql/introspection.rb +99 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +116 -63
- data/lib/graphql/language/lexer.rb +53 -27
- data/lib/graphql/language/lexer.rl +5 -3
- data/lib/graphql/language/nodes.rb +67 -93
- data/lib/graphql/language/parser.rb +929 -896
- data/lib/graphql/language/parser.y +125 -102
- data/lib/graphql/language/printer.rb +11 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/non_null_type.rb +0 -10
- data/lib/graphql/object_type.rb +47 -58
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
- data/lib/graphql/pagination/array_connection.rb +77 -0
- data/lib/graphql/pagination/connection.rb +226 -0
- data/lib/graphql/pagination/connections.rb +160 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +226 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +6 -4
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +52 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +32 -6
- data/lib/graphql/query/literal_input.rb +31 -11
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +6 -4
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +50 -10
- data/lib/graphql/query.rb +77 -18
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task/validate.rb +3 -0
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +30 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +18 -4
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/edges_instrumentation.rb +1 -2
- data/lib/graphql/relay/global_id_resolve.rb +1 -2
- data/lib/graphql/relay/mutation.rb +3 -87
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/page_info.rb +1 -1
- data/lib/graphql/relay/range_add.rb +27 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/relay/type_extensions.rb +2 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/scalar_type.rb +18 -60
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +274 -18
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
- data/lib/graphql/schema/build_from_definition.rb +320 -219
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +2 -2
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +130 -6
- data/lib/graphql/schema/enum.rb +121 -12
- data/lib/graphql/schema/enum_value.rb +24 -7
- data/lib/graphql/schema/field/connection_extension.rb +46 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +465 -181
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +17 -1
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/input_object.rb +172 -37
- data/lib/graphql/schema/interface.rb +39 -25
- data/lib/graphql/schema/introspection_system.rb +106 -38
- data/lib/graphql/schema/late_bound_type.rb +3 -2
- data/lib/graphql/schema/list.rb +65 -1
- data/lib/graphql/schema/loader.rb +145 -102
- data/lib/graphql/schema/member/accepts_definition.rb +15 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +34 -28
- data/lib/graphql/schema/member/build_type.rb +19 -8
- data/lib/graphql/schema/member/cached_graphql_definition.rb +34 -2
- data/lib/graphql/schema/member/has_arguments.rb +206 -13
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +97 -32
- data/lib/graphql/schema/member/has_interfaces.rb +100 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +11 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +37 -1
- data/lib/graphql/schema/object.rb +51 -38
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +40 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +133 -79
- data/lib/graphql/schema/scalar.rb +43 -3
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/traversal.rb +2 -2
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +19 -5
- data/lib/graphql/schema/union.rb +44 -3
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +14 -4
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +82 -0
- data/lib/graphql/schema/validator.rb +171 -0
- data/lib/graphql/schema/warden.rb +193 -34
- data/lib/graphql/schema.rb +882 -247
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/base_visitor.rb +17 -10
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +43 -9
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/string_type.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +84 -30
- data/lib/graphql/subscriptions/instrumentation.rb +10 -6
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -5
- data/lib/graphql/subscriptions.rb +117 -49
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +32 -15
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +66 -10
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/skylight_tracing.rb +9 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +15 -35
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +16 -8
- data/lib/graphql/types/iso_8601_date_time.rb +32 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -88
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
- data/lib/graphql/types/relay/default_relay.rb +31 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +15 -0
- data/lib/graphql/types/relay/node_field.rb +3 -22
- data/lib/graphql/types/relay/nodes_field.rb +16 -18
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/union_type.rb +5 -25
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +87 -31
- data/readme.md +3 -6
- metadata +126 -124
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/types/relay/base_field.rb +0 -22
- data/lib/graphql/types/relay/base_interface.rb +0 -29
- data/lib/graphql/types/relay/base_object.rb +0 -26
|
@@ -4,13 +4,13 @@ module GraphQL
|
|
|
4
4
|
#
|
|
5
5
|
# 1. Scoped by file (CRuby only), add to the top of the file:
|
|
6
6
|
#
|
|
7
|
-
# using GraphQL::
|
|
7
|
+
# using GraphQL::DeprecationDSL
|
|
8
8
|
#
|
|
9
9
|
# (This is a "refinement", there are also other ways to scope it.)
|
|
10
10
|
#
|
|
11
11
|
# 2. Global application, add before schema definition:
|
|
12
12
|
#
|
|
13
|
-
# GraphQL::
|
|
13
|
+
# GraphQL::DeprecationDSL.activate
|
|
14
14
|
#
|
|
15
15
|
module DeprecatedDSL
|
|
16
16
|
TYPE_CLASSES = [
|
|
@@ -23,19 +23,32 @@ module GraphQL
|
|
|
23
23
|
]
|
|
24
24
|
|
|
25
25
|
def self.activate
|
|
26
|
+
deprecated_caller = caller(1, 1).first
|
|
27
|
+
GraphQL::Deprecation.warn "DeprecatedDSL will be removed from GraphQL-Ruby 2.0, use `.to_non_null_type` instead of `!` and remove `.activate` from #{deprecated_caller}"
|
|
26
28
|
TYPE_CLASSES.each { |c| c.extend(Methods) }
|
|
27
29
|
GraphQL::Schema::List.include(Methods)
|
|
28
30
|
GraphQL::Schema::NonNull.include(Methods)
|
|
29
31
|
end
|
|
32
|
+
|
|
30
33
|
module Methods
|
|
31
34
|
def !
|
|
35
|
+
deprecated_caller = caller(1, 1).first
|
|
36
|
+
GraphQL::Deprecation.warn "DeprecatedDSL will be removed from GraphQL-Ruby 2.0, use `.to_non_null_type` instead of `!` at #{deprecated_caller}"
|
|
32
37
|
to_non_null_type
|
|
33
38
|
end
|
|
34
39
|
end
|
|
35
40
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
if defined?(::Refinement) && Refinement.private_method_defined?(:import_methods)
|
|
42
|
+
TYPE_CLASSES.each do |type_class|
|
|
43
|
+
refine type_class.singleton_class do
|
|
44
|
+
import_methods Methods
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
TYPE_CLASSES.each do |type_class|
|
|
49
|
+
refine type_class.singleton_class do
|
|
50
|
+
include Methods
|
|
51
|
+
end
|
|
39
52
|
end
|
|
40
53
|
end
|
|
41
54
|
end
|
|
@@ -1,13 +1,2 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
GraphQL::Directive::DeprecatedDirective = GraphQL::Directive.
|
|
3
|
-
name "deprecated"
|
|
4
|
-
description "Marks an element of a GraphQL schema as no longer supported."
|
|
5
|
-
locations([GraphQL::Directive::FIELD_DEFINITION, GraphQL::Directive::ENUM_VALUE])
|
|
6
|
-
|
|
7
|
-
reason_description = "Explains why this element was deprecated, usually also including a "\
|
|
8
|
-
"suggestion for how to access supported similar data. Formatted "\
|
|
9
|
-
"in [Markdown](https://daringfireball.net/projects/markdown/)."
|
|
10
|
-
|
|
11
|
-
argument :reason, GraphQL::STRING_TYPE, reason_description, default_value: GraphQL::Directive::DEFAULT_DEPRECATION_REASON
|
|
12
|
-
default_directive true
|
|
13
|
-
end
|
|
2
|
+
GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition(silence_deprecation_warning: true)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition
|
|
2
|
+
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition(silence_deprecation_warning: true)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition
|
|
2
|
+
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/directive.rb
CHANGED
|
@@ -8,7 +8,7 @@ module GraphQL
|
|
|
8
8
|
#
|
|
9
9
|
class Directive
|
|
10
10
|
include GraphQL::Define::InstanceDefinable
|
|
11
|
-
|
|
11
|
+
deprecated_accepts_definitions :locations, :name, :description, :arguments, :default_directive, argument: GraphQL::Define::AssignArgument
|
|
12
12
|
|
|
13
13
|
attr_accessor :locations, :arguments, :name, :description, :arguments_class
|
|
14
14
|
attr_accessor :ast_node
|
|
@@ -45,7 +45,6 @@ module GraphQL
|
|
|
45
45
|
INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
|
|
46
46
|
]
|
|
47
47
|
|
|
48
|
-
DEFAULT_DEPRECATION_REASON = 'No longer supported'
|
|
49
48
|
LOCATION_DESCRIPTIONS = {
|
|
50
49
|
QUERY: 'Location adjacent to a query operation.',
|
|
51
50
|
MUTATION: 'Location adjacent to a mutation operation.',
|
|
@@ -96,9 +95,13 @@ module GraphQL
|
|
|
96
95
|
def inspect
|
|
97
96
|
"#<GraphQL::Directive #{name}>"
|
|
98
97
|
end
|
|
98
|
+
|
|
99
|
+
def type_class
|
|
100
|
+
metadata[:type_class]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def get_argument(argument_name)
|
|
104
|
+
arguments[argument_name]
|
|
105
|
+
end
|
|
99
106
|
end
|
|
100
107
|
end
|
|
101
|
-
|
|
102
|
-
require "graphql/directive/include_directive"
|
|
103
|
-
require "graphql/directive/skip_directive"
|
|
104
|
-
require "graphql/directive/deprecated_directive"
|
data/lib/graphql/enum_type.rb
CHANGED
|
@@ -1,78 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
module GraphQL
|
|
3
|
-
#
|
|
4
|
-
# By convention, enum names are `SCREAMING_CASE_NAMES`,
|
|
5
|
-
# but other identifiers are supported too.
|
|
6
|
-
#
|
|
7
|
-
# You can use as return types _or_ as inputs.
|
|
8
|
-
#
|
|
9
|
-
# By default, enums are passed to `resolve` functions as
|
|
10
|
-
# the strings that identify them, but you can provide a
|
|
11
|
-
# custom Ruby value with the `value:` keyword.
|
|
12
|
-
#
|
|
13
|
-
# @example An enum of programming languages
|
|
14
|
-
# LanguageEnum = GraphQL::EnumType.define do
|
|
15
|
-
# name "Language"
|
|
16
|
-
# description "Programming language for Web projects"
|
|
17
|
-
# value("PYTHON", "A dynamic, function-oriented language")
|
|
18
|
-
# value("RUBY", "A very dynamic language aimed at programmer happiness")
|
|
19
|
-
# value("JAVASCRIPT", "Accidental lingua franca of the web")
|
|
20
|
-
# end
|
|
21
|
-
#
|
|
22
|
-
# @example Using an enum as a return type
|
|
23
|
-
# field :favoriteLanguage, LanguageEnum, "This person's favorite coding language"
|
|
24
|
-
# # ...
|
|
25
|
-
# # In a query:
|
|
26
|
-
# Schema.execute("{ coder(id: 1) { favoriteLanguage } }")
|
|
27
|
-
# # { "data" => { "coder" => { "favoriteLanguage" => "RUBY" } } }
|
|
28
|
-
#
|
|
29
|
-
# @example Defining an enum input
|
|
30
|
-
# field :coders, types[CoderType] do
|
|
31
|
-
# argument :knowing, types[LanguageEnum]
|
|
32
|
-
# resolve ->(obj, args, ctx) {
|
|
33
|
-
# Coder.where(language: args[:knowing])
|
|
34
|
-
# }
|
|
35
|
-
# end
|
|
36
|
-
#
|
|
37
|
-
# @example Using an enum as input
|
|
38
|
-
# {
|
|
39
|
-
# # find coders who know Python and Ruby
|
|
40
|
-
# coders(knowing: [PYTHON, RUBY]) {
|
|
41
|
-
# name
|
|
42
|
-
# hourlyRate
|
|
43
|
-
# }
|
|
44
|
-
# }
|
|
45
|
-
#
|
|
46
|
-
# @example Enum whose values are different in Ruby-land
|
|
47
|
-
# GraphQL::EnumType.define do
|
|
48
|
-
# # ...
|
|
49
|
-
# # use the `value:` keyword:
|
|
50
|
-
# value("RUBY", "Lisp? Smalltalk?", value: :rb)
|
|
51
|
-
# end
|
|
52
|
-
#
|
|
53
|
-
# # Now, resolve functions will receive `:rb` instead of `"RUBY"`
|
|
54
|
-
# field :favoriteLanguage, LanguageEnum
|
|
55
|
-
# resolve ->(obj, args, ctx) {
|
|
56
|
-
# args[:favoriteLanguage] # => :rb
|
|
57
|
-
# }
|
|
58
|
-
#
|
|
59
|
-
# @example Enum whose values are different in ActiveRecord-land
|
|
60
|
-
# class Language < ActiveRecord::Base
|
|
61
|
-
# enum language: {
|
|
62
|
-
# rb: 0
|
|
63
|
-
# }
|
|
64
|
-
# end
|
|
65
|
-
#
|
|
66
|
-
# # Now enum type should be defined as
|
|
67
|
-
# GraphQL::EnumType.define do
|
|
68
|
-
# # ...
|
|
69
|
-
# # use the `value:` keyword:
|
|
70
|
-
# value("RUBY", "Lisp? Smalltalk?", value: 'rb')
|
|
71
|
-
# end
|
|
72
|
-
#
|
|
73
|
-
|
|
3
|
+
# @api deprecated
|
|
74
4
|
class EnumType < GraphQL::BaseType
|
|
75
|
-
|
|
5
|
+
extend Define::InstanceDefinable::DeprecatedDefine
|
|
6
|
+
|
|
7
|
+
deprecated_accepts_definitions :values, value: GraphQL::Define::AssignEnumValue
|
|
76
8
|
ensure_defined(:values, :validate_non_null_input, :coerce_non_null_input, :coerce_result)
|
|
77
9
|
attr_accessor :ast_node
|
|
78
10
|
|
|
@@ -102,10 +34,14 @@ module GraphQL
|
|
|
102
34
|
end
|
|
103
35
|
|
|
104
36
|
# @return [Hash<String => EnumValue>] `{name => value}` pairs contained in this type
|
|
105
|
-
def values
|
|
37
|
+
def values(_context = nil)
|
|
106
38
|
@values_by_name
|
|
107
39
|
end
|
|
108
40
|
|
|
41
|
+
def enum_values(_context = nil)
|
|
42
|
+
values.values
|
|
43
|
+
end
|
|
44
|
+
|
|
109
45
|
def kind
|
|
110
46
|
GraphQL::TypeKinds::ENUM
|
|
111
47
|
end
|
|
@@ -136,7 +72,7 @@ module GraphQL
|
|
|
136
72
|
class EnumValue
|
|
137
73
|
include GraphQL::Define::InstanceDefinable
|
|
138
74
|
ATTRIBUTES = [:name, :description, :deprecation_reason, :value]
|
|
139
|
-
|
|
75
|
+
deprecated_accepts_definitions(*ATTRIBUTES)
|
|
140
76
|
attr_accessor(*ATTRIBUTES)
|
|
141
77
|
attr_accessor :ast_node
|
|
142
78
|
ensure_defined(*ATTRIBUTES)
|
|
@@ -151,6 +87,10 @@ module GraphQL
|
|
|
151
87
|
def graphql_name
|
|
152
88
|
name
|
|
153
89
|
end
|
|
90
|
+
|
|
91
|
+
def type_class
|
|
92
|
+
metadata[:type_class]
|
|
93
|
+
end
|
|
154
94
|
end
|
|
155
95
|
|
|
156
96
|
class UnresolvedValueError < GraphQL::Error
|
|
@@ -18,12 +18,12 @@ module GraphQL
|
|
|
18
18
|
case name
|
|
19
19
|
when SKIP
|
|
20
20
|
args = query.arguments_for(directive_ast_node, directive_defn)
|
|
21
|
-
if args[
|
|
21
|
+
if args[:if] == true
|
|
22
22
|
return false
|
|
23
23
|
end
|
|
24
24
|
when INCLUDE
|
|
25
25
|
args = query.arguments_for(directive_ast_node, directive_defn)
|
|
26
|
-
if args[
|
|
26
|
+
if args[:if] == false
|
|
27
27
|
return false
|
|
28
28
|
end
|
|
29
29
|
else
|
|
@@ -18,18 +18,83 @@ module GraphQL
|
|
|
18
18
|
#
|
|
19
19
|
class Errors
|
|
20
20
|
def self.use(schema)
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
definition_line = caller(2, 1).first
|
|
22
|
+
GraphQL::Deprecation.warn("GraphQL::Execution::Errors is now installed by default, remove `use GraphQL::Execution::Errors` from #{definition_line}")
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
NEW_HANDLER_HASH = ->(h, k) {
|
|
26
|
+
h[k] = {
|
|
27
|
+
class: k,
|
|
28
|
+
handler: nil,
|
|
29
|
+
subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
def initialize(schema)
|
|
26
34
|
@schema = schema
|
|
35
|
+
@handlers = {
|
|
36
|
+
class: nil,
|
|
37
|
+
handler: nil,
|
|
38
|
+
subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
|
|
39
|
+
}
|
|
27
40
|
end
|
|
28
41
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
# @api private
|
|
43
|
+
def each_rescue
|
|
44
|
+
handlers = @handlers.values
|
|
45
|
+
while (handler = handlers.shift) do
|
|
46
|
+
yield(handler[:class], handler[:handler])
|
|
47
|
+
handlers.concat(handler[:subclass_handlers].values)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Register this handler, updating the
|
|
52
|
+
# internal handler index to maintain least-to-most specific.
|
|
53
|
+
#
|
|
54
|
+
# @param error_class [Class<Exception>]
|
|
55
|
+
# @param error_handler [Proc]
|
|
56
|
+
# @return [void]
|
|
57
|
+
def rescue_from(error_class, error_handler)
|
|
58
|
+
subclasses_handlers = {}
|
|
59
|
+
this_level_subclasses = []
|
|
60
|
+
# During this traversal, do two things:
|
|
61
|
+
# - Identify any already-registered subclasses of this error class
|
|
62
|
+
# and gather them up to be inserted _under_ this class
|
|
63
|
+
# - Find the point in the index where this handler should be inserted
|
|
64
|
+
# (That is, _under_ any superclasses, or at top-level, if there are no superclasses registered)
|
|
65
|
+
handlers = @handlers[:subclass_handlers]
|
|
66
|
+
while (handlers) do
|
|
67
|
+
this_level_subclasses.clear
|
|
68
|
+
# First, identify already-loaded handlers that belong
|
|
69
|
+
# _under_ this one. (That is, they're handlers
|
|
70
|
+
# for subclasses of `error_class`.)
|
|
71
|
+
handlers.each do |err_class, handler|
|
|
72
|
+
if err_class < error_class
|
|
73
|
+
subclasses_handlers[err_class] = handler
|
|
74
|
+
this_level_subclasses << err_class
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
# Any handlers that we'll be moving, delete them from this point in the index
|
|
78
|
+
this_level_subclasses.each do |err_class|
|
|
79
|
+
handlers.delete(err_class)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# See if any keys in this hash are superclasses of this new class:
|
|
83
|
+
next_index_point = handlers.find { |err_class, handler| error_class < err_class }
|
|
84
|
+
if next_index_point
|
|
85
|
+
handlers = next_index_point[1][:subclass_handlers]
|
|
86
|
+
else
|
|
87
|
+
# this new handler doesn't belong to any sub-handlers,
|
|
88
|
+
# so insert it in the current set of `handlers`
|
|
89
|
+
break
|
|
90
|
+
end
|
|
32
91
|
end
|
|
92
|
+
# Having found the point at which to insert this handler,
|
|
93
|
+
# register it and merge any subclass handlers back in at this point.
|
|
94
|
+
this_class_handlers = handlers[error_class]
|
|
95
|
+
this_class_handlers[:handler] = error_handler
|
|
96
|
+
this_class_handlers[:subclass_handlers].merge!(subclasses_handlers)
|
|
97
|
+
nil
|
|
33
98
|
end
|
|
34
99
|
|
|
35
100
|
# Call the given block with the schema's configured error handlers.
|
|
@@ -41,21 +106,58 @@ module GraphQL
|
|
|
41
106
|
def with_error_handling(ctx)
|
|
42
107
|
yield
|
|
43
108
|
rescue StandardError => err
|
|
44
|
-
|
|
45
|
-
_err_class, handler = rescues.find { |err_class, handler| err.is_a?(err_class) }
|
|
109
|
+
handler = find_handler_for(err.class)
|
|
46
110
|
if handler
|
|
47
111
|
runtime_info = ctx.namespace(:interpreter) || {}
|
|
48
112
|
obj = runtime_info[:current_object]
|
|
49
113
|
args = runtime_info[:current_arguments]
|
|
114
|
+
args = args && args.keyword_arguments
|
|
50
115
|
field = runtime_info[:current_field]
|
|
51
116
|
if obj.is_a?(GraphQL::Schema::Object)
|
|
52
117
|
obj = obj.object
|
|
53
118
|
end
|
|
54
|
-
handler.call(err, obj, args, ctx, field)
|
|
119
|
+
handler[:handler].call(err, obj, args, ctx, field)
|
|
55
120
|
else
|
|
56
121
|
raise err
|
|
57
122
|
end
|
|
58
123
|
end
|
|
124
|
+
|
|
125
|
+
# @return [Proc, nil] The handler for `error_class`, if one was registered on this schema or inherited
|
|
126
|
+
def find_handler_for(error_class)
|
|
127
|
+
handlers = @handlers[:subclass_handlers]
|
|
128
|
+
handler = nil
|
|
129
|
+
while (handlers) do
|
|
130
|
+
_err_class, next_handler = handlers.find { |err_class, handler| error_class <= err_class }
|
|
131
|
+
if next_handler
|
|
132
|
+
handlers = next_handler[:subclass_handlers]
|
|
133
|
+
handler = next_handler
|
|
134
|
+
else
|
|
135
|
+
# Don't reassign `handler` --
|
|
136
|
+
# let the previous assignment carry over outside this block.
|
|
137
|
+
break
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# check for a handler from a parent class:
|
|
142
|
+
if @schema.superclass.respond_to?(:error_handler) && (parent_errors = @schema.superclass.error_handler)
|
|
143
|
+
parent_handler = parent_errors.find_handler_for(error_class)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# If the inherited handler is more specific than the one defined here,
|
|
147
|
+
# use it.
|
|
148
|
+
# If it's a tie (or there is no parent handler), use the one defined here.
|
|
149
|
+
# If there's an inherited one, but not one defined here, use the inherited one.
|
|
150
|
+
# Otherwise, there's no handler for this error, return `nil`.
|
|
151
|
+
if parent_handler && handler && parent_handler[:class] < handler[:class]
|
|
152
|
+
parent_handler
|
|
153
|
+
elsif handler
|
|
154
|
+
handler
|
|
155
|
+
elsif parent_handler
|
|
156
|
+
parent_handler
|
|
157
|
+
else
|
|
158
|
+
nil
|
|
159
|
+
end
|
|
160
|
+
end
|
|
59
161
|
end
|
|
60
162
|
end
|
|
61
163
|
end
|
|
@@ -6,7 +6,7 @@ module GraphQL
|
|
|
6
6
|
class Execute
|
|
7
7
|
|
|
8
8
|
# @api private
|
|
9
|
-
class Skip; end
|
|
9
|
+
class Skip < GraphQL::Error; end
|
|
10
10
|
|
|
11
11
|
# Just a singleton for implementing {Query::Context#skip}
|
|
12
12
|
# @api private
|
|
@@ -18,7 +18,14 @@ module GraphQL
|
|
|
18
18
|
# @api private
|
|
19
19
|
PROPAGATE_NULL = PropagateNull.new
|
|
20
20
|
|
|
21
|
+
def self.use(schema_class)
|
|
22
|
+
schema_class.query_execution_strategy(self)
|
|
23
|
+
schema_class.mutation_execution_strategy(self)
|
|
24
|
+
schema_class.subscription_execution_strategy(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
21
27
|
def execute(ast_operation, root_type, query)
|
|
28
|
+
GraphQL::Deprecation.warn "#{self.class} will be removed in GraphQL-Ruby 2.0, please upgrade to the Interpreter: https://graphql-ruby.org/queries/interpreter.html"
|
|
22
29
|
result = resolve_root_selection(query)
|
|
23
30
|
lazy_resolve_root_selection(result, **{query: query})
|
|
24
31
|
GraphQL::Execution::Flatten.call(query.context)
|
|
@@ -77,7 +77,7 @@ module GraphQL
|
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
def call_after_hooks(instrumenters, object, after_hook_name, ex)
|
|
80
|
-
instrumenters.
|
|
80
|
+
instrumenters.reverse_each do |instrumenter|
|
|
81
81
|
begin
|
|
82
82
|
instrumenter.public_send(after_hook_name, object)
|
|
83
83
|
rescue => e
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
module Execution
|
|
5
|
+
class Interpreter
|
|
6
|
+
# A container for metadata regarding arguments present in a GraphQL query.
|
|
7
|
+
# @see Interpreter::Arguments#argument_values for a hash of these objects.
|
|
8
|
+
class ArgumentValue
|
|
9
|
+
def initialize(definition:, value:, default_used:)
|
|
10
|
+
@definition = definition
|
|
11
|
+
@value = value
|
|
12
|
+
@default_used = default_used
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [Object] The Ruby-ready value for this Argument
|
|
16
|
+
attr_reader :value
|
|
17
|
+
|
|
18
|
+
# @return [GraphQL::Schema::Argument] The definition instance for this argument
|
|
19
|
+
attr_reader :definition
|
|
20
|
+
|
|
21
|
+
# @return [Boolean] `true` if the schema-defined `default_value:` was applied in this case. (No client-provided value was present.)
|
|
22
|
+
def default_used?
|
|
23
|
+
@default_used
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
module Execution
|
|
5
|
+
class Interpreter
|
|
6
|
+
# A wrapper for argument hashes in GraphQL queries.
|
|
7
|
+
#
|
|
8
|
+
# This object is immutable so that the runtime code can be sure that
|
|
9
|
+
# modifications don't leak from one use to another
|
|
10
|
+
#
|
|
11
|
+
# @see GraphQL::Query#arguments_for to get access to these objects.
|
|
12
|
+
class Arguments
|
|
13
|
+
extend Forwardable
|
|
14
|
+
include GraphQL::Dig
|
|
15
|
+
|
|
16
|
+
# The Ruby-style arguments hash, ready for a resolver.
|
|
17
|
+
# This hash is the one used at runtime.
|
|
18
|
+
#
|
|
19
|
+
# @return [Hash<Symbol, Object>]
|
|
20
|
+
attr_reader :keyword_arguments
|
|
21
|
+
|
|
22
|
+
# @param argument_values [nil, Hash{Symbol => ArgumentValue}]
|
|
23
|
+
# @param keyword_arguments [nil, Hash{Symbol => Object}]
|
|
24
|
+
def initialize(keyword_arguments: nil, argument_values:)
|
|
25
|
+
@empty = argument_values.nil? || argument_values.empty?
|
|
26
|
+
# This is only present when `extras` have been merged in:
|
|
27
|
+
if keyword_arguments
|
|
28
|
+
# This is a little crazy. We expect the `:argument_details` extra to _include extras_,
|
|
29
|
+
# but the object isn't created until _after_ extras are put together.
|
|
30
|
+
# So, we have to use a special flag here to say, "at the last minute, add yourself to the keyword args."
|
|
31
|
+
#
|
|
32
|
+
# Otherwise:
|
|
33
|
+
# - We can't access the final Arguments instance _while_ we're preparing extras
|
|
34
|
+
# - After we _can_ access it, it's frozen, so we can't add anything.
|
|
35
|
+
#
|
|
36
|
+
# So, this flag gives us a chance to sneak it in before freezing, _and_ while we have access
|
|
37
|
+
# to the new Arguments instance itself.
|
|
38
|
+
if keyword_arguments[:argument_details] == :__arguments_add_self
|
|
39
|
+
keyword_arguments[:argument_details] = self
|
|
40
|
+
end
|
|
41
|
+
@keyword_arguments = keyword_arguments.freeze
|
|
42
|
+
elsif !@empty
|
|
43
|
+
@keyword_arguments = {}
|
|
44
|
+
argument_values.each do |name, arg_val|
|
|
45
|
+
@keyword_arguments[name] = arg_val.value
|
|
46
|
+
end
|
|
47
|
+
@keyword_arguments.freeze
|
|
48
|
+
else
|
|
49
|
+
@keyword_arguments = NO_ARGS
|
|
50
|
+
end
|
|
51
|
+
@argument_values = argument_values ? argument_values.freeze : NO_ARGS
|
|
52
|
+
freeze
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Hash{Symbol => ArgumentValue}]
|
|
56
|
+
attr_reader :argument_values
|
|
57
|
+
|
|
58
|
+
def empty?
|
|
59
|
+
@empty
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values, :size, :to_h
|
|
63
|
+
def_delegators :argument_values, :each_value
|
|
64
|
+
|
|
65
|
+
def inspect
|
|
66
|
+
"#<#{self.class} @keyword_arguments=#{keyword_arguments.inspect}>"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Create a new arguments instance which includes these extras.
|
|
70
|
+
#
|
|
71
|
+
# This is called by the runtime to implement field `extras: [...]`
|
|
72
|
+
#
|
|
73
|
+
# @param extra_args [Hash<Symbol => Object>]
|
|
74
|
+
# @return [Interpreter::Arguments]
|
|
75
|
+
# @api private
|
|
76
|
+
def merge_extras(extra_args)
|
|
77
|
+
self.class.new(
|
|
78
|
+
argument_values: argument_values,
|
|
79
|
+
keyword_arguments: keyword_arguments.merge(extra_args)
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
NO_ARGS = {}.freeze
|
|
84
|
+
EMPTY = self.new(argument_values: nil, keyword_arguments: NO_ARGS).freeze
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
module Execution
|
|
5
|
+
class Interpreter
|
|
6
|
+
class ArgumentsCache
|
|
7
|
+
def initialize(query)
|
|
8
|
+
@query = query
|
|
9
|
+
@dataloader = query.context.dataloader
|
|
10
|
+
@storage = Hash.new do |h, ast_node|
|
|
11
|
+
h[ast_node] = Hash.new do |h2, arg_owner|
|
|
12
|
+
h2[arg_owner] = Hash.new do |h3, parent_object|
|
|
13
|
+
dataload_for(ast_node, arg_owner, parent_object) do |kwarg_arguments|
|
|
14
|
+
h3[parent_object] = @query.schema.after_lazy(kwarg_arguments) do |resolved_args|
|
|
15
|
+
h3[parent_object] = resolved_args
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if !h3.key?(parent_object)
|
|
20
|
+
# TODO should i bother putting anything here?
|
|
21
|
+
h3[parent_object] = NO_ARGUMENTS
|
|
22
|
+
else
|
|
23
|
+
h3[parent_object]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def fetch(ast_node, argument_owner, parent_object)
|
|
31
|
+
# If any jobs were enqueued, run them now,
|
|
32
|
+
# since this might have been called outside of execution.
|
|
33
|
+
# (The jobs are responsible for updating `result` in-place.)
|
|
34
|
+
if !@storage.key?(ast_node) || !@storage[ast_node].key?(argument_owner)
|
|
35
|
+
@dataloader.run_isolated do
|
|
36
|
+
@storage[ast_node][argument_owner][parent_object]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
# Ack, the _hash_ is updated, but the key is eventually
|
|
40
|
+
# overridden with an immutable arguments instance.
|
|
41
|
+
# The first call queues up the job,
|
|
42
|
+
# then this call fetches the result.
|
|
43
|
+
# TODO this should be better, find a solution
|
|
44
|
+
# that works with merging the runtime.rb code
|
|
45
|
+
@storage[ast_node][argument_owner][parent_object]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @yield [Interpreter::Arguments, Lazy<Interpreter::Arguments>] The finally-loaded arguments
|
|
49
|
+
def dataload_for(ast_node, argument_owner, parent_object, &block)
|
|
50
|
+
# First, normalize all AST or Ruby values to a plain Ruby hash
|
|
51
|
+
args_hash = self.class.prepare_args_hash(@query, ast_node)
|
|
52
|
+
argument_owner.coerce_arguments(parent_object, args_hash, @query.context, &block)
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
NO_ARGUMENTS = {}.freeze
|
|
59
|
+
|
|
60
|
+
NO_VALUE_GIVEN = Object.new
|
|
61
|
+
|
|
62
|
+
def self.prepare_args_hash(query, ast_arg_or_hash_or_value)
|
|
63
|
+
case ast_arg_or_hash_or_value
|
|
64
|
+
when Hash
|
|
65
|
+
if ast_arg_or_hash_or_value.empty?
|
|
66
|
+
return NO_ARGUMENTS
|
|
67
|
+
end
|
|
68
|
+
args_hash = {}
|
|
69
|
+
ast_arg_or_hash_or_value.each do |k, v|
|
|
70
|
+
args_hash[k] = prepare_args_hash(query, v)
|
|
71
|
+
end
|
|
72
|
+
args_hash
|
|
73
|
+
when Array
|
|
74
|
+
ast_arg_or_hash_or_value.map { |v| prepare_args_hash(query, v) }
|
|
75
|
+
when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
|
|
76
|
+
if ast_arg_or_hash_or_value.arguments.empty? # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
|
77
|
+
return NO_ARGUMENTS
|
|
78
|
+
end
|
|
79
|
+
args_hash = {}
|
|
80
|
+
ast_arg_or_hash_or_value.arguments.each do |arg| # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
|
81
|
+
v = prepare_args_hash(query, arg.value)
|
|
82
|
+
if v != NO_VALUE_GIVEN
|
|
83
|
+
args_hash[arg.name] = v
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
args_hash
|
|
87
|
+
when GraphQL::Language::Nodes::VariableIdentifier
|
|
88
|
+
if query.variables.key?(ast_arg_or_hash_or_value.name)
|
|
89
|
+
variable_value = query.variables[ast_arg_or_hash_or_value.name]
|
|
90
|
+
prepare_args_hash(query, variable_value)
|
|
91
|
+
else
|
|
92
|
+
NO_VALUE_GIVEN
|
|
93
|
+
end
|
|
94
|
+
when GraphQL::Language::Nodes::Enum
|
|
95
|
+
ast_arg_or_hash_or_value.name
|
|
96
|
+
when GraphQL::Language::Nodes::NullValue
|
|
97
|
+
nil
|
|
98
|
+
else
|
|
99
|
+
ast_arg_or_hash_or_value
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
module Execution
|
|
5
|
+
class Interpreter
|
|
6
|
+
# Wrapper for raw values
|
|
7
|
+
class RawValue
|
|
8
|
+
def initialize(obj = nil)
|
|
9
|
+
@object = obj
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resolve
|
|
13
|
+
@object
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|