graphql 1.9.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/lib/generators/graphql/core.rb +21 -9
- 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/install/templates/base_mutation.erb +12 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +4 -0
- data/lib/generators/graphql/install_generator.rb +49 -9
- 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 +66 -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 +8 -0
- data/lib/generators/graphql/templates/base_connection.erb +10 -0
- data/lib/generators/graphql/templates/base_edge.erb +10 -0
- data/lib/generators/graphql/templates/base_enum.erb +4 -0
- data/lib/generators/graphql/templates/base_field.erb +9 -0
- data/lib/generators/graphql/templates/base_input_object.erb +5 -0
- data/lib/generators/graphql/templates/base_interface.erb +6 -0
- data/lib/generators/graphql/templates/base_object.erb +5 -0
- data/lib/generators/graphql/templates/base_scalar.erb +4 -0
- data/lib/generators/graphql/templates/base_union.erb +4 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +23 -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 +4 -0
- data/lib/generators/graphql/templates/mutation.erb +5 -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 +11 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +5 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +27 -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/ast/analyzer.rb +41 -12
- data/lib/graphql/analysis/ast/field_usage.rb +32 -3
- data/lib/graphql/analysis/ast/max_query_complexity.rb +4 -5
- data/lib/graphql/analysis/ast/max_query_depth.rb +7 -3
- data/lib/graphql/analysis/ast/query_complexity.rb +182 -66
- data/lib/graphql/analysis/ast/query_depth.rb +15 -26
- data/lib/graphql/analysis/ast/visitor.rb +83 -62
- data/lib/graphql/analysis/ast.rb +23 -20
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +37 -16
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +22 -18
- data/lib/graphql/coercion_error.rb +8 -0
- data/lib/graphql/dataloader/null_dataloader.rb +24 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +195 -0
- data/lib/graphql/dataloader.rb +320 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +93 -0
- 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 +62 -24
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
- data/lib/graphql/execution/interpreter/runtime.rb +695 -392
- data/lib/graphql/execution/interpreter.rb +199 -74
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +110 -150
- data/lib/graphql/execution/multiplex.rb +6 -148
- data/lib/graphql/execution.rb +12 -4
- data/lib/graphql/execution_error.rb +3 -2
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +26 -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/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +6 -18
- 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 -7
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +13 -12
- data/lib/graphql/introspection/type_type.rb +34 -17
- data/lib/graphql/introspection.rb +100 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +50 -23
- 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 +153 -87
- data/lib/graphql/language/lexer.rb +249 -1450
- data/lib/graphql/language/nodes.rb +152 -142
- data/lib/graphql/language/parser.rb +1036 -953
- data/lib/graphql/language/parser.y +159 -120
- data/lib/graphql/language/printer.rb +342 -154
- data/lib/graphql/language/sanitized_printer.rb +220 -0
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/token.rb +2 -2
- data/lib/graphql/language/visitor.rb +196 -140
- data/lib/graphql/language.rb +4 -1
- data/lib/graphql/load_application_object_failed_error.rb +22 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +77 -0
- data/lib/graphql/pagination/array_connection.rb +79 -0
- data/lib/graphql/pagination/connection.rb +275 -0
- data/lib/graphql/pagination/connections.rb +135 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +228 -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/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +157 -187
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +33 -7
- data/lib/graphql/query/null_context.rb +21 -14
- data/lib/graphql/query/validation_pipeline.rb +17 -38
- data/lib/graphql/query/variable_validation_error.rb +17 -3
- data/lib/graphql/query/variables.rb +49 -14
- data/lib/graphql/query.rb +142 -61
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +5 -2
- data/lib/graphql/rake_task.rb +42 -20
- data/lib/graphql/relay/range_add.rb +17 -10
- data/lib/graphql/relay.rb +0 -15
- 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/schema/addition.rb +271 -0
- data/lib/graphql/schema/always_visible.rb +10 -0
- data/lib/graphql/schema/argument.rb +301 -32
- data/lib/graphql/schema/base_64_bp.rb +3 -2
- 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 +349 -203
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/directive/deprecated.rb +18 -0
- data/lib/graphql/schema/directive/feature.rb +2 -2
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +2 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +134 -15
- data/lib/graphql/schema/enum.rb +137 -39
- data/lib/graphql/schema/enum_value.rb +17 -23
- data/lib/graphql/schema/field/connection_extension.rb +36 -20
- data/lib/graphql/schema/field/scope_extension.rb +15 -5
- data/lib/graphql/schema/field.rb +570 -334
- data/lib/graphql/schema/field_extension.rb +88 -4
- data/lib/graphql/schema/find_inherited_value.rb +31 -0
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/has_single_input_argument.rb +156 -0
- data/lib/graphql/schema/input_object.rb +190 -48
- data/lib/graphql/schema/interface.rb +24 -49
- data/lib/graphql/schema/introspection_system.rb +109 -36
- data/lib/graphql/schema/late_bound_type.rb +9 -2
- data/lib/graphql/schema/list.rb +61 -3
- data/lib/graphql/schema/loader.rb +146 -97
- data/lib/graphql/schema/member/base_dsl_methods.rb +45 -51
- data/lib/graphql/schema/member/build_type.rb +34 -17
- data/lib/graphql/schema/member/has_arguments.rb +385 -10
- data/lib/graphql/schema/member/has_ast_node.rb +32 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
- data/lib/graphql/schema/member/has_directives.rb +118 -0
- data/lib/graphql/schema/member/has_fields.rb +180 -35
- data/lib/graphql/schema/member/has_interfaces.rb +143 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +57 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +11 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +34 -4
- data/lib/graphql/schema/object.rb +55 -64
- data/lib/graphql/schema/printer.rb +26 -40
- data/lib/graphql/schema/relay_classic_mutation.rb +13 -80
- data/lib/graphql/schema/resolver/has_payload_type.rb +53 -12
- data/lib/graphql/schema/resolver.rb +182 -162
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +85 -27
- data/lib/graphql/schema/timeout.rb +119 -0
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +51 -0
- data/lib/graphql/schema/union.rb +69 -15
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- 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 +330 -59
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +985 -858
- data/lib/graphql/static_validation/all_rules.rb +4 -1
- data/lib/graphql/static_validation/base_visitor.rb +33 -32
- data/lib/graphql/static_validation/definition_dependencies.rb +28 -14
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +71 -28
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +46 -79
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +23 -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 +12 -6
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
- 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 +15 -7
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +107 -57
- 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/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/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 +6 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +22 -10
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
- 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/validation_context.rb +17 -7
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -3
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +134 -24
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
- data/lib/graphql/subscriptions/event.rb +90 -27
- data/lib/graphql/subscriptions/instrumentation.rb +0 -47
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +147 -62
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- data/lib/graphql/tracing/appoptics_trace.rb +251 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
- data/lib/graphql/tracing/data_dog_trace.rb +196 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +53 -2
- data/lib/graphql/tracing/legacy_trace.rb +69 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/notifications_trace.rb +45 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +118 -0
- data/lib/graphql/tracing/platform_tracing.rb +77 -31
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
- data/lib/graphql/tracing/prometheus_tracing.rb +11 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +24 -67
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +23 -0
- data/lib/graphql/types/int.rb +11 -3
- data/lib/graphql/types/iso_8601_date.rb +45 -0
- data/lib/graphql/types/iso_8601_date_time.rb +36 -8
- data/lib/graphql/types/json.rb +25 -0
- data/lib/graphql/types/relay/base_connection.rb +18 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -36
- data/lib/graphql/types/relay/connection_behaviors.rb +193 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +82 -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 +25 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
- data/lib/graphql/types/relay.rb +10 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/types.rb +3 -0
- data/lib/graphql/unauthorized_error.rb +3 -3
- data/lib/graphql/unauthorized_field_error.rb +1 -1
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +68 -54
- data/readme.md +4 -7
- metadata +150 -822
- data/lib/graphql/analysis/analyze_query.rb +0 -91
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -56
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -153
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -226
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -435
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -50
- data/lib/graphql/define/instance_definable.rb +0 -300
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -42
- data/lib/graphql/directive/deprecated_directive.rb +0 -13
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -104
- data/lib/graphql/enum_type.rb +0 -193
- data/lib/graphql/execution/execute.rb +0 -319
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -330
- data/lib/graphql/filter.rb +0 -53
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -153
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -153
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -86
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -236
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/literal_validation_error.rb +0 -6
- data/lib/graphql/non_null_type.rb +0 -81
- data/lib/graphql/object_type.rb +0 -141
- data/lib/graphql/query/arguments.rb +0 -179
- data/lib/graphql/query/arguments_cache.rb +0 -25
- data/lib/graphql/query/executor.rb +0 -53
- data/lib/graphql/query/literal_input.rb +0 -115
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -39
- data/lib/graphql/relay/array_connection.rb +0 -85
- data/lib/graphql/relay/base_connection.rb +0 -172
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -40
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -18
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -190
- data/lib/graphql/relay/node.rb +0 -36
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -186
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -135
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -15
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
- data/lib/graphql/schema/member/instrumentation.rb +0 -121
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -39
- data/lib/graphql/schema/rescue_middleware.rb +0 -55
- data/lib/graphql/schema/timeout_middleware.rb +0 -85
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -286
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -66
- data/lib/graphql/tracing/skylight_tracing.rb +0 -61
- 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
- data/lib/graphql/types/relay/node_field.rb +0 -43
- data/lib/graphql/types/relay/nodes_field.rb +0 -45
- data/lib/graphql/union_type.rb +0 -100
- data/lib/graphql/upgrader/member.rb +0 -899
- data/lib/graphql/upgrader/schema.rb +0 -37
- data/spec/dummy/Gemfile +0 -12
- data/spec/dummy/Gemfile.lock +0 -157
- data/spec/dummy/README.md +0 -24
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/assets/config/manifest.js +0 -1
- data/spec/dummy/app/assets/javascripts/application.js +0 -66
- data/spec/dummy/app/channels/application_cable/channel.rb +0 -5
- data/spec/dummy/app/channels/application_cable/connection.rb +0 -5
- data/spec/dummy/app/channels/graphql_channel.rb +0 -116
- data/spec/dummy/app/controllers/application_controller.rb +0 -4
- data/spec/dummy/app/controllers/pages_controller.rb +0 -5
- data/spec/dummy/app/helpers/application_helper.rb +0 -3
- data/spec/dummy/app/jobs/application_job.rb +0 -3
- data/spec/dummy/app/views/layouts/application.html.erb +0 -12
- data/spec/dummy/app/views/pages/show.html +0 -16
- data/spec/dummy/bin/bundle +0 -4
- data/spec/dummy/bin/rails +0 -5
- data/spec/dummy/bin/rake +0 -5
- data/spec/dummy/bin/setup +0 -31
- data/spec/dummy/bin/update +0 -27
- data/spec/dummy/bin/yarn +0 -12
- data/spec/dummy/config/application.rb +0 -30
- data/spec/dummy/config/boot.rb +0 -4
- data/spec/dummy/config/cable.yml +0 -10
- data/spec/dummy/config/environment.rb +0 -6
- data/spec/dummy/config/environments/development.rb +0 -40
- data/spec/dummy/config/environments/production.rb +0 -76
- data/spec/dummy/config/environments/test.rb +0 -37
- data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
- data/spec/dummy/config/initializers/cookies_serializer.rb +0 -6
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -5
- data/spec/dummy/config/initializers/inflections.rb +0 -17
- data/spec/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -10
- data/spec/dummy/config/locales/en.yml +0 -33
- data/spec/dummy/config/puma.rb +0 -57
- data/spec/dummy/config/routes.rb +0 -4
- data/spec/dummy/config/secrets.yml +0 -32
- data/spec/dummy/config.ru +0 -6
- data/spec/dummy/log/test.log +0 -199
- data/spec/dummy/package.json +0 -5
- data/spec/dummy/public/404.html +0 -67
- data/spec/dummy/public/422.html +0 -67
- data/spec/dummy/public/500.html +0 -66
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +0 -1
- data/spec/dummy/test/application_system_test_case.rb +0 -6
- data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -45
- data/spec/dummy/test/test_helper.rb +0 -4
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
- data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
- data/spec/fixtures/upgrader/account.original.rb +0 -19
- data/spec/fixtures/upgrader/account.transformed.rb +0 -20
- data/spec/fixtures/upgrader/blame_range.original.rb +0 -43
- data/spec/fixtures/upgrader/blame_range.transformed.rb +0 -30
- data/spec/fixtures/upgrader/date_time.original.rb +0 -24
- data/spec/fixtures/upgrader/date_time.transformed.rb +0 -23
- data/spec/fixtures/upgrader/delete_project.original.rb +0 -28
- data/spec/fixtures/upgrader/delete_project.transformed.rb +0 -27
- data/spec/fixtures/upgrader/gist_order_field.original.rb +0 -14
- data/spec/fixtures/upgrader/gist_order_field.transformed.rb +0 -13
- data/spec/fixtures/upgrader/increment_count.original.rb +0 -59
- data/spec/fixtures/upgrader/increment_count.transformed.rb +0 -50
- data/spec/fixtures/upgrader/photo.original.rb +0 -10
- data/spec/fixtures/upgrader/photo.transformed.rb +0 -12
- data/spec/fixtures/upgrader/release_order.original.rb +0 -15
- data/spec/fixtures/upgrader/release_order.transformed.rb +0 -14
- data/spec/fixtures/upgrader/starrable.original.rb +0 -49
- data/spec/fixtures/upgrader/starrable.transformed.rb +0 -46
- data/spec/fixtures/upgrader/subscribable.original.rb +0 -55
- data/spec/fixtures/upgrader/subscribable.transformed.rb +0 -51
- data/spec/fixtures/upgrader/type_x.original.rb +0 -65
- data/spec/fixtures/upgrader/type_x.transformed.rb +0 -56
- data/spec/graphql/analysis/analyze_query_spec.rb +0 -272
- data/spec/graphql/analysis/ast/field_usage_spec.rb +0 -51
- data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +0 -120
- data/spec/graphql/analysis/ast/max_query_depth_spec.rb +0 -114
- data/spec/graphql/analysis/ast/query_complexity_spec.rb +0 -299
- data/spec/graphql/analysis/ast/query_depth_spec.rb +0 -108
- data/spec/graphql/analysis/ast_spec.rb +0 -269
- data/spec/graphql/analysis/field_usage_spec.rb +0 -62
- data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -102
- data/spec/graphql/analysis/max_query_depth_spec.rb +0 -101
- data/spec/graphql/analysis/query_complexity_spec.rb +0 -301
- data/spec/graphql/analysis/query_depth_spec.rb +0 -81
- data/spec/graphql/argument_spec.rb +0 -159
- data/spec/graphql/authorization_spec.rb +0 -901
- data/spec/graphql/backtrace_spec.rb +0 -206
- data/spec/graphql/base_type_spec.rb +0 -171
- data/spec/graphql/boolean_type_spec.rb +0 -21
- data/spec/graphql/compatibility/execution_specification_spec.rb +0 -4
- data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +0 -4
- data/spec/graphql/compatibility/query_parser_specification_spec.rb +0 -6
- data/spec/graphql/compatibility/schema_parser_specification_spec.rb +0 -6
- data/spec/graphql/define/assign_argument_spec.rb +0 -61
- data/spec/graphql/define/instance_definable_spec.rb +0 -203
- data/spec/graphql/directive/skip_directive_spec.rb +0 -9
- data/spec/graphql/directive_spec.rb +0 -295
- data/spec/graphql/enum_type_spec.rb +0 -158
- data/spec/graphql/execution/execute_spec.rb +0 -303
- data/spec/graphql/execution/instrumentation_spec.rb +0 -184
- data/spec/graphql/execution/interpreter_spec.rb +0 -485
- data/spec/graphql/execution/lazy/lazy_method_map_spec.rb +0 -57
- data/spec/graphql/execution/lazy_spec.rb +0 -240
- data/spec/graphql/execution/lookahead_spec.rb +0 -363
- data/spec/graphql/execution/multiplex_spec.rb +0 -211
- data/spec/graphql/execution/typecast_spec.rb +0 -47
- data/spec/graphql/execution_error_spec.rb +0 -325
- data/spec/graphql/field_spec.rb +0 -246
- data/spec/graphql/float_type_spec.rb +0 -16
- data/spec/graphql/function_spec.rb +0 -129
- data/spec/graphql/id_type_spec.rb +0 -33
- data/spec/graphql/input_object_type_spec.rb +0 -25
- data/spec/graphql/int_type_spec.rb +0 -35
- data/spec/graphql/interface_type_spec.rb +0 -196
- data/spec/graphql/internal_representation/print_spec.rb +0 -41
- data/spec/graphql/internal_representation/rewrite_spec.rb +0 -376
- data/spec/graphql/introspection/directive_type_spec.rb +0 -61
- data/spec/graphql/introspection/input_value_type_spec.rb +0 -105
- data/spec/graphql/introspection/introspection_query_spec.rb +0 -59
- data/spec/graphql/introspection/schema_type_spec.rb +0 -56
- data/spec/graphql/introspection/type_type_spec.rb +0 -155
- data/spec/graphql/language/block_string_spec.rb +0 -70
- data/spec/graphql/language/definition_slice_spec.rb +0 -226
- data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
- data/spec/graphql/language/equality_spec.rb +0 -84
- data/spec/graphql/language/generation_spec.rb +0 -38
- data/spec/graphql/language/lexer_spec.rb +0 -135
- data/spec/graphql/language/nodes_spec.rb +0 -67
- data/spec/graphql/language/parser_spec.rb +0 -175
- data/spec/graphql/language/printer_spec.rb +0 -215
- data/spec/graphql/language/visitor_spec.rb +0 -400
- data/spec/graphql/list_type_spec.rb +0 -57
- data/spec/graphql/non_null_type_spec.rb +0 -48
- data/spec/graphql/object_type_spec.rb +0 -197
- data/spec/graphql/query/arguments_spec.rb +0 -346
- data/spec/graphql/query/context_spec.rb +0 -292
- data/spec/graphql/query/executor_spec.rb +0 -314
- data/spec/graphql/query/literal_input_spec.rb +0 -91
- data/spec/graphql/query/result_spec.rb +0 -29
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -109
- data/spec/graphql/query_spec.rb +0 -800
- data/spec/graphql/rake_task_spec.rb +0 -59
- data/spec/graphql/scalar_type_spec.rb +0 -66
- data/spec/graphql/schema/argument_spec.rb +0 -127
- data/spec/graphql/schema/build_from_definition_spec.rb +0 -1187
- data/spec/graphql/schema/catchall_middleware_spec.rb +0 -35
- data/spec/graphql/schema/directive/feature_spec.rb +0 -81
- data/spec/graphql/schema/directive/transform_spec.rb +0 -39
- data/spec/graphql/schema/enum_spec.rb +0 -83
- data/spec/graphql/schema/enum_value_spec.rb +0 -24
- data/spec/graphql/schema/field_extension_spec.rb +0 -115
- data/spec/graphql/schema/field_spec.rb +0 -301
- data/spec/graphql/schema/finder_spec.rb +0 -135
- data/spec/graphql/schema/input_object_spec.rb +0 -238
- data/spec/graphql/schema/instrumentation_spec.rb +0 -43
- data/spec/graphql/schema/interface_spec.rb +0 -215
- data/spec/graphql/schema/introspection_system_spec.rb +0 -47
- data/spec/graphql/schema/list_spec.rb +0 -46
- data/spec/graphql/schema/loader_spec.rb +0 -286
- data/spec/graphql/schema/member/accepts_definition_spec.rb +0 -115
- data/spec/graphql/schema/member/build_type_spec.rb +0 -63
- data/spec/graphql/schema/member/scoped_spec.rb +0 -177
- data/spec/graphql/schema/member/type_system_helpers_spec.rb +0 -63
- data/spec/graphql/schema/middleware_chain_spec.rb +0 -57
- data/spec/graphql/schema/mutation_spec.rb +0 -150
- data/spec/graphql/schema/non_null_spec.rb +0 -46
- data/spec/graphql/schema/object_spec.rb +0 -244
- data/spec/graphql/schema/printer_spec.rb +0 -869
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +0 -234
- data/spec/graphql/schema/rescue_middleware_spec.rb +0 -74
- data/spec/graphql/schema/resolver_spec.rb +0 -640
- data/spec/graphql/schema/scalar_spec.rb +0 -101
- data/spec/graphql/schema/subscription_spec.rb +0 -416
- data/spec/graphql/schema/timeout_middleware_spec.rb +0 -188
- data/spec/graphql/schema/traversal_spec.rb +0 -222
- data/spec/graphql/schema/type_expression_spec.rb +0 -39
- data/spec/graphql/schema/union_spec.rb +0 -72
- data/spec/graphql/schema/unique_within_type_spec.rb +0 -44
- data/spec/graphql/schema/validation_spec.rb +0 -355
- data/spec/graphql/schema/warden_spec.rb +0 -926
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -413
- data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +0 -44
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -112
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -35
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -42
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -167
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -66
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -740
- data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +0 -28
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -52
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -42
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -123
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +0 -24
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -56
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -61
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +0 -39
- data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +0 -62
- data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +0 -82
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -73
- data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +0 -58
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +0 -34
- data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +0 -188
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -196
- data/spec/graphql/static_validation/rules/variable_names_are_unique_spec.rb +0 -23
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -236
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -78
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -81
- data/spec/graphql/static_validation/type_stack_spec.rb +0 -29
- data/spec/graphql/static_validation/validator_spec.rb +0 -204
- data/spec/graphql/string_type_spec.rb +0 -80
- data/spec/graphql/subscriptions/serialize_spec.rb +0 -49
- data/spec/graphql/subscriptions_spec.rb +0 -502
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +0 -63
- data/spec/graphql/tracing/platform_tracing_spec.rb +0 -137
- data/spec/graphql/tracing/prometheus_tracing_spec.rb +0 -42
- data/spec/graphql/tracing/scout_tracing_spec.rb +0 -17
- data/spec/graphql/tracing/skylight_tracing_spec.rb +0 -63
- data/spec/graphql/tracing_spec.rb +0 -52
- data/spec/graphql/types/iso_8601_date_time_spec.rb +0 -137
- data/spec/graphql/union_type_spec.rb +0 -211
- data/spec/graphql/upgrader/member_spec.rb +0 -583
- data/spec/graphql/upgrader/schema_spec.rb +0 -82
- data/spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb +0 -528
- data/spec/integration/mongoid/spec_helper.rb +0 -2
- data/spec/integration/mongoid/star_trek/data.rb +0 -126
- data/spec/integration/mongoid/star_trek/schema.rb +0 -425
- data/spec/integration/rails/data.rb +0 -110
- data/spec/integration/rails/generators/base_generator_test.rb +0 -7
- data/spec/integration/rails/generators/graphql/enum_generator_spec.rb +0 -30
- data/spec/integration/rails/generators/graphql/install_generator_spec.rb +0 -218
- data/spec/integration/rails/generators/graphql/interface_generator_spec.rb +0 -34
- data/spec/integration/rails/generators/graphql/loader_generator_spec.rb +0 -59
- data/spec/integration/rails/generators/graphql/mutation_generator_spec.rb +0 -71
- data/spec/integration/rails/generators/graphql/object_generator_spec.rb +0 -54
- data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +0 -28
- data/spec/integration/rails/generators/graphql/union_generator_spec.rb +0 -67
- data/spec/integration/rails/graphql/input_object_type_spec.rb +0 -364
- data/spec/integration/rails/graphql/query/variables_spec.rb +0 -375
- data/spec/integration/rails/graphql/relay/array_connection_spec.rb +0 -290
- data/spec/integration/rails/graphql/relay/base_connection_spec.rb +0 -101
- data/spec/integration/rails/graphql/relay/connection_instrumentation_spec.rb +0 -80
- data/spec/integration/rails/graphql/relay/connection_resolve_spec.rb +0 -79
- data/spec/integration/rails/graphql/relay/connection_type_spec.rb +0 -106
- data/spec/integration/rails/graphql/relay/edge_spec.rb +0 -10
- data/spec/integration/rails/graphql/relay/mutation_spec.rb +0 -387
- data/spec/integration/rails/graphql/relay/node_spec.rb +0 -263
- data/spec/integration/rails/graphql/relay/page_info_spec.rb +0 -111
- data/spec/integration/rails/graphql/relay/range_add_spec.rb +0 -117
- data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +0 -837
- data/spec/integration/rails/graphql/schema_spec.rb +0 -476
- data/spec/integration/rails/graphql/tracing/active_support_notifications_tracing_spec.rb +0 -62
- data/spec/integration/rails/spec_helper.rb +0 -25
- data/spec/integration/tmp/app/graphql/types/family_type.rb +0 -9
- data/spec/spec_helper.rb +0 -116
- data/spec/support/dummy/data.rb +0 -45
- data/spec/support/dummy/schema.rb +0 -492
- data/spec/support/error_bubbling_helpers.rb +0 -23
- data/spec/support/global_id.rb +0 -23
- data/spec/support/jazz.rb +0 -759
- data/spec/support/lazy_helpers.rb +0 -192
- data/spec/support/magic_cards/schema.graphql +0 -33
- data/spec/support/minimum_input_object.rb +0 -21
- data/spec/support/new_relic.rb +0 -27
- data/spec/support/parser/filename_example.graphql +0 -5
- data/spec/support/parser/filename_example_error_1.graphql +0 -4
- data/spec/support/parser/filename_example_error_2.graphql +0 -5
- data/spec/support/skylight.rb +0 -39
- data/spec/support/star_wars/schema.rb +0 -465
- data/spec/support/static_validation_helpers.rb +0 -32
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "graphql/execution/interpreter/runtime/graphql_result"
|
2
3
|
|
3
4
|
module GraphQL
|
4
5
|
module Execution
|
@@ -8,61 +9,156 @@ module GraphQL
|
|
8
9
|
#
|
9
10
|
# @api private
|
10
11
|
class Runtime
|
12
|
+
class CurrentState
|
13
|
+
def initialize
|
14
|
+
@current_object = nil
|
15
|
+
@current_field = nil
|
16
|
+
@current_arguments = nil
|
17
|
+
@current_result_name = nil
|
18
|
+
@current_result = nil
|
19
|
+
@was_authorized_by_scope_items = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor :current_result, :current_result_name,
|
23
|
+
:current_arguments, :current_field, :current_object, :was_authorized_by_scope_items
|
24
|
+
end
|
25
|
+
|
11
26
|
# @return [GraphQL::Query]
|
12
27
|
attr_reader :query
|
13
28
|
|
14
|
-
# @return [Class]
|
29
|
+
# @return [Class<GraphQL::Schema>]
|
15
30
|
attr_reader :schema
|
16
31
|
|
17
32
|
# @return [GraphQL::Query::Context]
|
18
33
|
attr_reader :context
|
19
34
|
|
20
|
-
def initialize(query:,
|
35
|
+
def initialize(query:, lazies_at_depth:)
|
21
36
|
@query = query
|
37
|
+
@current_trace = query.current_trace
|
38
|
+
@dataloader = query.multiplex.dataloader
|
39
|
+
@lazies_at_depth = lazies_at_depth
|
22
40
|
@schema = query.schema
|
23
41
|
@context = query.context
|
24
|
-
@
|
25
|
-
|
26
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
42
|
+
@response = GraphQLResultHash.new(nil, nil, false)
|
43
|
+
# Identify runtime directives by checking which of this schema's directives have overridden `def self.resolve`
|
44
|
+
@runtime_directive_names = []
|
45
|
+
noop_resolve_owner = GraphQL::Schema::Directive.singleton_class
|
46
|
+
@schema_directives = schema.directives
|
47
|
+
@schema_directives.each do |name, dir_defn|
|
48
|
+
if dir_defn.method(:resolve).owner != noop_resolve_owner
|
49
|
+
@runtime_directive_names << name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
# { Class => Boolean }
|
53
|
+
@lazy_cache = {}
|
54
|
+
@lazy_cache.compare_by_identity
|
55
|
+
|
56
|
+
@gathered_selections_cache = Hash.new { |h, k|
|
57
|
+
cache = {}
|
58
|
+
cache.compare_by_identity
|
59
|
+
h[k] = cache
|
60
|
+
}
|
61
|
+
@gathered_selections_cache.compare_by_identity
|
32
62
|
end
|
33
63
|
|
34
|
-
def
|
35
|
-
@response.
|
64
|
+
def final_result
|
65
|
+
@response && @response.graphql_result_data
|
36
66
|
end
|
37
67
|
|
38
68
|
def inspect
|
39
69
|
"#<#{self.class.name} response=#{@response.inspect}>"
|
40
70
|
end
|
41
71
|
|
72
|
+
def tap_or_each(obj_or_array)
|
73
|
+
if obj_or_array.is_a?(Array)
|
74
|
+
obj_or_array.each do |item|
|
75
|
+
yield(item, true)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
yield(obj_or_array, false)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
42
82
|
# This _begins_ the execution. Some deferred work
|
43
83
|
# might be stored up in lazies.
|
44
84
|
# @return [void]
|
45
85
|
def run_eager
|
46
86
|
root_operation = query.selected_operation
|
47
87
|
root_op_type = root_operation.operation_type || "query"
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
88
|
+
root_type = schema.root_type_for_operation(root_op_type)
|
89
|
+
|
90
|
+
st = get_current_runtime_state
|
91
|
+
st.current_object = query.root_value
|
92
|
+
st.current_result = @response
|
93
|
+
runtime_object = root_type.wrap(query.root_value, context)
|
94
|
+
runtime_object = schema.sync_lazy(runtime_object)
|
95
|
+
|
96
|
+
if runtime_object.nil?
|
97
|
+
# Root .authorized? returned false.
|
98
|
+
@response = nil
|
99
|
+
else
|
100
|
+
call_method_on_directives(:resolve, runtime_object, root_operation.directives) do # execute query level directives
|
101
|
+
gathered_selections = gather_selections(runtime_object, root_type, nil, root_operation.selections)
|
102
|
+
# This is kind of a hack -- `gathered_selections` is an Array if any of the selections
|
103
|
+
# require isolation during execution (because of runtime directives). In that case,
|
104
|
+
# make a new, isolated result hash for writing the result into. (That isolated response
|
105
|
+
# is eventually merged back into the main response)
|
106
|
+
#
|
107
|
+
# Otherwise, `gathered_selections` is a hash of selections which can be
|
108
|
+
# directly evaluated and the results can be written right into the main response hash.
|
109
|
+
tap_or_each(gathered_selections) do |selections, is_selection_array|
|
110
|
+
if is_selection_array
|
111
|
+
selection_response = GraphQLResultHash.new(nil, nil, false)
|
112
|
+
final_response = @response
|
113
|
+
else
|
114
|
+
selection_response = @response
|
115
|
+
final_response = nil
|
116
|
+
end
|
117
|
+
|
118
|
+
@dataloader.append_job {
|
119
|
+
st = get_current_runtime_state
|
120
|
+
st.current_object = query.root_value
|
121
|
+
st.current_result_name = nil
|
122
|
+
st.current_result = selection_response
|
123
|
+
# This is a less-frequent case; use a fast check since it's often not there.
|
124
|
+
if (directives = selections[:graphql_directives])
|
125
|
+
selections.delete(:graphql_directives)
|
126
|
+
end
|
127
|
+
call_method_on_directives(:resolve, runtime_object, directives) do
|
128
|
+
evaluate_selections(
|
129
|
+
runtime_object,
|
130
|
+
root_type,
|
131
|
+
root_op_type == "mutation",
|
132
|
+
selections,
|
133
|
+
selection_response,
|
134
|
+
final_response,
|
135
|
+
nil,
|
136
|
+
st,
|
137
|
+
)
|
138
|
+
end
|
139
|
+
}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
54
143
|
nil
|
55
144
|
end
|
56
145
|
|
57
|
-
def gather_selections(owner_object, owner_type, selections, selections_by_name)
|
146
|
+
def gather_selections(owner_object, owner_type, ast_node_for_caching, selections, selections_to_run = nil, selections_by_name = nil)
|
147
|
+
if ast_node_for_caching && (cached_selections = @gathered_selections_cache[ast_node_for_caching][owner_type])
|
148
|
+
return cached_selections
|
149
|
+
end
|
150
|
+
selections_by_name ||= {} # allocate this default here so we check the cache first
|
151
|
+
|
152
|
+
should_cache = true
|
153
|
+
|
58
154
|
selections.each do |node|
|
59
155
|
# Skip gathering this if the directive says so
|
60
156
|
if !directives_include?(node, owner_object, owner_type)
|
157
|
+
should_cache = false
|
61
158
|
next
|
62
159
|
end
|
63
160
|
|
64
|
-
|
65
|
-
when GraphQL::Language::Nodes::Field
|
161
|
+
if node.is_a?(GraphQL::Language::Nodes::Field)
|
66
162
|
response_key = node.alias || node.name
|
67
163
|
selections = selections_by_name[response_key]
|
68
164
|
# if there was already a selection of this field,
|
@@ -78,177 +174,388 @@ module GraphQL
|
|
78
174
|
# No selection was found for this field yet
|
79
175
|
selections_by_name[response_key] = node
|
80
176
|
end
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
177
|
+
else
|
178
|
+
# This is an InlineFragment or a FragmentSpread
|
179
|
+
if @runtime_directive_names.any? && node.directives.any? { |d| @runtime_directive_names.include?(d.name) }
|
180
|
+
next_selections = {}
|
181
|
+
next_selections[:graphql_directives] = node.directives
|
182
|
+
should_cache = false
|
183
|
+
if selections_to_run
|
184
|
+
selections_to_run << next_selections
|
185
|
+
else
|
186
|
+
selections_to_run = []
|
187
|
+
selections_to_run << selections_by_name
|
188
|
+
selections_to_run << next_selections
|
91
189
|
end
|
92
190
|
else
|
93
|
-
|
94
|
-
gather_selections(owner_object, owner_type, node.selections, selections_by_name)
|
191
|
+
next_selections = selections_by_name
|
95
192
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
193
|
+
|
194
|
+
case node
|
195
|
+
when GraphQL::Language::Nodes::InlineFragment
|
196
|
+
if node.type
|
197
|
+
type_defn = schema.get_type(node.type.name, context)
|
198
|
+
|
199
|
+
if query.warden.possible_types(type_defn).include?(owner_type)
|
200
|
+
gather_selections(owner_object, owner_type, nil, node.selections, selections_to_run, next_selections)
|
201
|
+
end
|
202
|
+
else
|
203
|
+
# it's an untyped fragment, definitely continue
|
204
|
+
gather_selections(owner_object, owner_type, nil, node.selections, selections_to_run, next_selections)
|
104
205
|
end
|
206
|
+
when GraphQL::Language::Nodes::FragmentSpread
|
207
|
+
fragment_def = query.fragments[node.name]
|
208
|
+
type_defn = query.get_type(fragment_def.type.name)
|
209
|
+
if query.warden.possible_types(type_defn).include?(owner_type)
|
210
|
+
gather_selections(owner_object, owner_type, nil, fragment_def.selections, selections_to_run, next_selections)
|
211
|
+
end
|
212
|
+
else
|
213
|
+
raise "Invariant: unexpected selection class: #{node.class}"
|
105
214
|
end
|
106
|
-
else
|
107
|
-
raise "Invariant: unexpected selection class: #{node.class}"
|
108
215
|
end
|
109
216
|
end
|
217
|
+
result = selections_to_run || selections_by_name
|
218
|
+
if should_cache
|
219
|
+
@gathered_selections_cache[ast_node_for_caching][owner_type] = result
|
220
|
+
end
|
221
|
+
result
|
110
222
|
end
|
111
223
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
field_defn = @fields_cache[owner_type][field_name] ||= owner_type.get_field(field_name)
|
128
|
-
is_introspection = false
|
129
|
-
if field_defn.nil?
|
130
|
-
field_defn = if owner_type == schema.query.metadata[:type_class] && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
|
131
|
-
is_introspection = true
|
132
|
-
entry_point_field.metadata[:type_class]
|
133
|
-
elsif (dynamic_field = schema.introspection_system.dynamic_field(name: field_name))
|
134
|
-
is_introspection = true
|
135
|
-
dynamic_field.metadata[:type_class]
|
136
|
-
else
|
137
|
-
raise "Invariant: no field for #{owner_type}.#{field_name}"
|
224
|
+
NO_ARGS = GraphQL::EmptyObjects::EMPTY_HASH
|
225
|
+
|
226
|
+
# @return [void]
|
227
|
+
def evaluate_selections(owner_object, owner_type, is_eager_selection, gathered_selections, selections_result, target_result, parent_object, runtime_state) # rubocop:disable Metrics/ParameterLists
|
228
|
+
finished_jobs = 0
|
229
|
+
enqueued_jobs = gathered_selections.size
|
230
|
+
gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
|
231
|
+
@dataloader.append_job {
|
232
|
+
runtime_state = get_current_runtime_state
|
233
|
+
evaluate_selection(
|
234
|
+
result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_selection, selections_result, parent_object, runtime_state
|
235
|
+
)
|
236
|
+
finished_jobs += 1
|
237
|
+
if target_result && finished_jobs == enqueued_jobs
|
238
|
+
selections_result.merge_into(target_result)
|
138
239
|
end
|
240
|
+
}
|
241
|
+
# Field resolution may pause the fiber,
|
242
|
+
# so it wouldn't get to the `Resolve` call that happens below.
|
243
|
+
# So instead trigger a run from this outer context.
|
244
|
+
if is_eager_selection
|
245
|
+
@dataloader.clear_cache
|
246
|
+
@dataloader.run
|
247
|
+
@dataloader.clear_cache
|
139
248
|
end
|
249
|
+
end
|
140
250
|
|
141
|
-
|
251
|
+
selections_result
|
252
|
+
end
|
142
253
|
|
143
|
-
|
144
|
-
|
145
|
-
|
254
|
+
# @return [void]
|
255
|
+
def evaluate_selection(result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_field, selections_result, parent_object, runtime_state) # rubocop:disable Metrics/ParameterLists
|
256
|
+
return if dead_result?(selections_result)
|
257
|
+
# As a performance optimization, the hash key will be a `Node` if
|
258
|
+
# there's only one selection of the field. But if there are multiple
|
259
|
+
# selections of the field, it will be an Array of nodes
|
260
|
+
if field_ast_nodes_or_ast_node.is_a?(Array)
|
261
|
+
field_ast_nodes = field_ast_nodes_or_ast_node
|
262
|
+
ast_node = field_ast_nodes.first
|
263
|
+
else
|
264
|
+
field_ast_nodes = nil
|
265
|
+
ast_node = field_ast_nodes_or_ast_node
|
266
|
+
end
|
267
|
+
field_name = ast_node.name
|
268
|
+
field_defn = query.warden.get_field(owner_type, field_name)
|
146
269
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
152
|
-
@interpreter_context[:current_path] = next_path
|
153
|
-
@interpreter_context[:current_field] = field_defn
|
270
|
+
# Set this before calling `run_with_directives`, so that the directive can have the latest path
|
271
|
+
runtime_state.current_field = field_defn
|
272
|
+
runtime_state.current_result = selections_result
|
273
|
+
runtime_state.current_result_name = result_name
|
154
274
|
|
155
|
-
|
275
|
+
if field_defn.dynamic_introspection
|
276
|
+
owner_object = field_defn.owner.wrap(owner_object, context)
|
277
|
+
end
|
156
278
|
|
157
|
-
|
158
|
-
|
279
|
+
return_type = field_defn.type
|
280
|
+
if !field_defn.any_arguments?
|
281
|
+
resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
282
|
+
if field_defn.extras.size == 0
|
283
|
+
evaluate_selection_with_resolved_keyword_args(
|
284
|
+
NO_ARGS, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type.non_null?, runtime_state
|
285
|
+
)
|
286
|
+
else
|
287
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
|
159
288
|
end
|
289
|
+
else
|
290
|
+
@query.arguments_cache.dataload_for(ast_node, field_defn, owner_object) do |resolved_arguments|
|
291
|
+
runtime_state = get_current_runtime_state # This might be in a different fiber
|
292
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
160
296
|
|
297
|
+
def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, runtime_state) # rubocop:disable Metrics/ParameterLists
|
298
|
+
after_lazy(arguments, field: field_defn, ast_node: ast_node, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |resolved_arguments, runtime_state|
|
299
|
+
return_type_non_null = return_type.non_null?
|
300
|
+
if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
|
301
|
+
continue_value(resolved_arguments, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
|
302
|
+
next
|
303
|
+
end
|
161
304
|
|
162
|
-
kwarg_arguments =
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
case extra
|
167
|
-
when :ast_node
|
168
|
-
kwarg_arguments[:ast_node] = ast_node
|
169
|
-
when :execution_errors
|
170
|
-
kwarg_arguments[:execution_errors] = ExecutionErrors.new(context, ast_node, next_path)
|
171
|
-
when :path
|
172
|
-
kwarg_arguments[:path] = next_path
|
173
|
-
when :lookahead
|
174
|
-
if !field_ast_nodes
|
175
|
-
field_ast_nodes = [ast_node]
|
176
|
-
end
|
177
|
-
kwarg_arguments[:lookahead] = Execution::Lookahead.new(
|
178
|
-
query: query,
|
179
|
-
ast_nodes: field_ast_nodes,
|
180
|
-
field: field_defn,
|
181
|
-
)
|
305
|
+
kwarg_arguments = if field_defn.extras.empty?
|
306
|
+
if resolved_arguments.empty?
|
307
|
+
# We can avoid allocating the `{ Symbol => Object }` hash in this case
|
308
|
+
NO_ARGS
|
182
309
|
else
|
183
|
-
|
310
|
+
resolved_arguments.keyword_arguments
|
184
311
|
end
|
185
|
-
end
|
186
|
-
|
187
|
-
# Optimize for the case that field is selected only once
|
188
|
-
if field_ast_nodes.nil? || field_ast_nodes.size == 1
|
189
|
-
next_selections = ast_node.selections
|
190
312
|
else
|
191
|
-
|
192
|
-
|
313
|
+
# Bundle up the extras, then make a new arguments instance
|
314
|
+
# that includes the extras, too.
|
315
|
+
extra_args = {}
|
316
|
+
field_defn.extras.each do |extra|
|
317
|
+
case extra
|
318
|
+
when :ast_node
|
319
|
+
extra_args[:ast_node] = ast_node
|
320
|
+
when :execution_errors
|
321
|
+
extra_args[:execution_errors] = ExecutionErrors.new(context, ast_node, current_path)
|
322
|
+
when :path
|
323
|
+
extra_args[:path] = current_path
|
324
|
+
when :lookahead
|
325
|
+
if !field_ast_nodes
|
326
|
+
field_ast_nodes = [ast_node]
|
327
|
+
end
|
328
|
+
|
329
|
+
extra_args[:lookahead] = Execution::Lookahead.new(
|
330
|
+
query: query,
|
331
|
+
ast_nodes: field_ast_nodes,
|
332
|
+
field: field_defn,
|
333
|
+
)
|
334
|
+
when :argument_details
|
335
|
+
# Use this flag to tell Interpreter::Arguments to add itself
|
336
|
+
# to the keyword args hash _before_ freezing everything.
|
337
|
+
extra_args[:argument_details] = :__arguments_add_self
|
338
|
+
when :parent
|
339
|
+
extra_args[:parent] = parent_object
|
340
|
+
else
|
341
|
+
extra_args[extra] = field_defn.fetch_extra(extra, context)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
if extra_args.any?
|
345
|
+
resolved_arguments = resolved_arguments.merge_extras(extra_args)
|
346
|
+
end
|
347
|
+
resolved_arguments.keyword_arguments
|
193
348
|
end
|
194
349
|
|
195
|
-
|
196
|
-
|
197
|
-
|
350
|
+
evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state) # rubocop:disable Metrics/ParameterLists
|
355
|
+
runtime_state.current_field = field_defn
|
356
|
+
runtime_state.current_object = object
|
357
|
+
runtime_state.current_arguments = resolved_arguments
|
358
|
+
runtime_state.current_result_name = result_name
|
359
|
+
runtime_state.current_result = selection_result
|
360
|
+
# Optimize for the case that field is selected only once
|
361
|
+
if field_ast_nodes.nil? || field_ast_nodes.size == 1
|
362
|
+
next_selections = ast_node.selections
|
363
|
+
directives = ast_node.directives
|
364
|
+
else
|
365
|
+
next_selections = []
|
366
|
+
directives = []
|
367
|
+
field_ast_nodes.each { |f|
|
368
|
+
next_selections.concat(f.selections)
|
369
|
+
directives.concat(f.directives)
|
370
|
+
}
|
371
|
+
end
|
372
|
+
|
373
|
+
field_result = call_method_on_directives(:resolve, object, directives) do
|
374
|
+
# Actually call the field resolver and capture the result
|
375
|
+
app_result = begin
|
376
|
+
@current_trace.execute_field(field: field_defn, ast_node: ast_node, query: query, object: object, arguments: kwarg_arguments) do
|
198
377
|
field_defn.resolve(object, kwarg_arguments, context)
|
199
378
|
end
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
379
|
+
rescue GraphQL::ExecutionError => err
|
380
|
+
err
|
381
|
+
rescue StandardError => err
|
382
|
+
begin
|
383
|
+
query.handle_or_reraise(err)
|
384
|
+
rescue GraphQL::ExecutionError => ex_err
|
385
|
+
ex_err
|
386
|
+
end
|
387
|
+
end
|
388
|
+
after_lazy(app_result, field: field_defn, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_result, runtime_state|
|
389
|
+
continue_value = continue_value(inner_result, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
|
390
|
+
if HALT != continue_value
|
391
|
+
was_scoped = runtime_state.was_authorized_by_scope_items
|
392
|
+
runtime_state.was_authorized_by_scope_items = nil
|
393
|
+
continue_field(continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result, was_scoped, runtime_state)
|
205
394
|
end
|
206
395
|
end
|
396
|
+
end
|
397
|
+
|
398
|
+
# If this field is a root mutation field, immediately resolve
|
399
|
+
# all of its child fields before moving on to the next root mutation field.
|
400
|
+
# (Subselections of this mutation will still be resolved level-by-level.)
|
401
|
+
if is_eager_field
|
402
|
+
Interpreter::Resolve.resolve_all([field_result], @dataloader)
|
403
|
+
else
|
404
|
+
# Return this from `after_lazy` because it might be another lazy that needs to be resolved
|
405
|
+
field_result
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
|
410
|
+
def dead_result?(selection_result)
|
411
|
+
selection_result.graphql_dead # || ((parent = selection_result.graphql_parent) && parent.graphql_dead)
|
412
|
+
end
|
207
413
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
414
|
+
def set_result(selection_result, result_name, value, is_child_result, is_non_null)
|
415
|
+
if !dead_result?(selection_result)
|
416
|
+
if value.nil? && is_non_null
|
417
|
+
# This is an invalid nil that should be propagated
|
418
|
+
# One caller of this method passes a block,
|
419
|
+
# namely when application code returns a `nil` to GraphQL and it doesn't belong there.
|
420
|
+
# The other possibility for reaching here is when a field returns an ExecutionError, so we write
|
421
|
+
# `nil` to the response, not knowing whether it's an invalid `nil` or not.
|
422
|
+
# (And in that case, we don't have to call the schema's handler, since it's not a bug in the application.)
|
423
|
+
# TODO the code is trying to tell me something.
|
424
|
+
yield if block_given?
|
425
|
+
parent = selection_result.graphql_parent
|
426
|
+
if parent.nil? # This is a top-level result hash
|
427
|
+
@response = nil
|
428
|
+
else
|
429
|
+
name_in_parent = selection_result.graphql_result_name
|
430
|
+
is_non_null_in_parent = selection_result.graphql_is_non_null_in_parent
|
431
|
+
set_result(parent, name_in_parent, nil, false, is_non_null_in_parent)
|
432
|
+
set_graphql_dead(selection_result)
|
433
|
+
end
|
434
|
+
elsif is_child_result
|
435
|
+
selection_result.set_child_result(result_name, value)
|
213
436
|
else
|
214
|
-
|
437
|
+
selection_result.set_leaf(result_name, value)
|
215
438
|
end
|
216
439
|
end
|
217
440
|
end
|
218
441
|
|
442
|
+
# Mark this node and any already-registered children as dead,
|
443
|
+
# so that it accepts no more writes.
|
444
|
+
def set_graphql_dead(selection_result)
|
445
|
+
case selection_result
|
446
|
+
when GraphQLResultArray
|
447
|
+
selection_result.graphql_dead = true
|
448
|
+
selection_result.values.each { |v| set_graphql_dead(v) }
|
449
|
+
when GraphQLResultHash
|
450
|
+
selection_result.graphql_dead = true
|
451
|
+
selection_result.each { |k, v| set_graphql_dead(v) }
|
452
|
+
else
|
453
|
+
# It's a scalar, no way to mark it dead.
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
def current_path
|
458
|
+
st = get_current_runtime_state
|
459
|
+
result = st.current_result
|
460
|
+
path = result && result.path
|
461
|
+
if path && (rn = st.current_result_name)
|
462
|
+
path = path.dup
|
463
|
+
path.push(rn)
|
464
|
+
end
|
465
|
+
path
|
466
|
+
end
|
467
|
+
|
219
468
|
HALT = Object.new
|
220
|
-
def continue_value(
|
221
|
-
|
469
|
+
def continue_value(value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
|
470
|
+
case value
|
471
|
+
when nil
|
222
472
|
if is_non_null
|
223
|
-
|
224
|
-
|
473
|
+
set_result(selection_result, result_name, nil, false, is_non_null) do
|
474
|
+
# This block is called if `result_name` is not dead. (Maybe a previous invalid nil caused it be marked dead.)
|
475
|
+
err = parent_type::InvalidNullError.new(parent_type, field, value)
|
476
|
+
schema.type_error(err, context)
|
477
|
+
end
|
225
478
|
else
|
226
|
-
|
479
|
+
set_result(selection_result, result_name, nil, false, is_non_null)
|
227
480
|
end
|
228
481
|
HALT
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
482
|
+
when GraphQL::Error
|
483
|
+
# Handle these cases inside a single `when`
|
484
|
+
# to avoid the overhead of checking three different classes
|
485
|
+
# every time.
|
486
|
+
if value.is_a?(GraphQL::ExecutionError)
|
487
|
+
if selection_result.nil? || !dead_result?(selection_result)
|
488
|
+
value.path ||= current_path
|
489
|
+
value.ast_node ||= ast_node
|
490
|
+
context.errors << value
|
491
|
+
if selection_result
|
492
|
+
set_result(selection_result, result_name, nil, false, is_non_null)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
HALT
|
496
|
+
elsif value.is_a?(GraphQL::UnauthorizedFieldError)
|
497
|
+
value.field ||= field
|
498
|
+
# this hook might raise & crash, or it might return
|
499
|
+
# a replacement value
|
500
|
+
next_value = begin
|
501
|
+
schema.unauthorized_field(value)
|
502
|
+
rescue GraphQL::ExecutionError => err
|
503
|
+
err
|
504
|
+
end
|
505
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
506
|
+
elsif value.is_a?(GraphQL::UnauthorizedError)
|
507
|
+
# this hook might raise & crash, or it might return
|
508
|
+
# a replacement value
|
509
|
+
next_value = begin
|
510
|
+
schema.unauthorized_object(value)
|
511
|
+
rescue GraphQL::ExecutionError => err
|
512
|
+
err
|
513
|
+
end
|
514
|
+
continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
515
|
+
elsif GraphQL::Execution::SKIP == value
|
516
|
+
# It's possible a lazy was already written here
|
517
|
+
case selection_result
|
518
|
+
when GraphQLResultHash
|
519
|
+
selection_result.delete(result_name)
|
520
|
+
when GraphQLResultArray
|
521
|
+
selection_result.graphql_skip_at(result_name)
|
522
|
+
when nil
|
523
|
+
# this can happen with directives
|
524
|
+
else
|
525
|
+
raise "Invariant: unexpected result class #{selection_result.class} (#{selection_result.inspect})"
|
526
|
+
end
|
527
|
+
HALT
|
528
|
+
else
|
529
|
+
# What could this actually _be_? Anyhow,
|
530
|
+
# preserve the default behavior of doing nothing with it.
|
531
|
+
value
|
238
532
|
end
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
533
|
+
when Array
|
534
|
+
# It's an array full of execution errors; add them all.
|
535
|
+
if value.any? && value.all? { |v| v.is_a?(GraphQL::ExecutionError) }
|
536
|
+
list_type_at_all = (field && (field.type.list?))
|
537
|
+
if selection_result.nil? || !dead_result?(selection_result)
|
538
|
+
value.each_with_index do |error, index|
|
539
|
+
error.ast_node ||= ast_node
|
540
|
+
error.path ||= current_path + (list_type_at_all ? [index] : [])
|
541
|
+
context.errors << error
|
542
|
+
end
|
543
|
+
if selection_result
|
544
|
+
if list_type_at_all
|
545
|
+
result_without_errors = value.map { |v| v.is_a?(GraphQL::ExecutionError) ? nil : v }
|
546
|
+
set_result(selection_result, result_name, result_without_errors, false, is_non_null)
|
547
|
+
else
|
548
|
+
set_result(selection_result, result_name, nil, false, is_non_null)
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
HALT
|
553
|
+
else
|
554
|
+
value
|
248
555
|
end
|
249
|
-
|
250
|
-
|
251
|
-
|
556
|
+
when GraphQL::Execution::Interpreter::RawValue
|
557
|
+
# Write raw value directly to the response without resolving nested objects
|
558
|
+
set_result(selection_result, result_name, value.resolve, false, is_non_null)
|
252
559
|
HALT
|
253
560
|
else
|
254
561
|
value
|
@@ -263,92 +570,188 @@ module GraphQL
|
|
263
570
|
# Location information from `path` and `ast_node`.
|
264
571
|
#
|
265
572
|
# @return [Lazy, Array, Hash, Object] Lazy, Array, and Hash are all traversed to resolve lazy values later
|
266
|
-
def continue_field(
|
267
|
-
|
573
|
+
def continue_field(value, owner_type, field, current_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result, was_scoped, runtime_state) # rubocop:disable Metrics/ParameterLists
|
574
|
+
if current_type.non_null?
|
575
|
+
current_type = current_type.of_type
|
576
|
+
is_non_null = true
|
577
|
+
end
|
578
|
+
|
579
|
+
case current_type.kind.name
|
268
580
|
when "SCALAR", "ENUM"
|
269
|
-
r =
|
270
|
-
|
581
|
+
r = begin
|
582
|
+
current_type.coerce_result(value, context)
|
583
|
+
rescue StandardError => err
|
584
|
+
schema.handle_or_reraise(context, err)
|
585
|
+
end
|
586
|
+
set_result(selection_result, result_name, r, false, is_non_null)
|
271
587
|
r
|
272
588
|
when "UNION", "INTERFACE"
|
273
|
-
resolved_type_or_lazy =
|
274
|
-
after_lazy(resolved_type_or_lazy,
|
275
|
-
|
589
|
+
resolved_type_or_lazy = resolve_type(current_type, value)
|
590
|
+
after_lazy(resolved_type_or_lazy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |resolved_type_result, runtime_state|
|
591
|
+
if resolved_type_result.is_a?(Array) && resolved_type_result.length == 2
|
592
|
+
resolved_type, resolved_value = resolved_type_result
|
593
|
+
else
|
594
|
+
resolved_type = resolved_type_result
|
595
|
+
resolved_value = value
|
596
|
+
end
|
276
597
|
|
598
|
+
possible_types = query.possible_types(current_type)
|
277
599
|
if !possible_types.include?(resolved_type)
|
278
|
-
parent_type = field.
|
279
|
-
|
600
|
+
parent_type = field.owner_type
|
601
|
+
err_class = current_type::UnresolvedTypeError
|
602
|
+
type_error = err_class.new(resolved_value, field, parent_type, resolved_type, possible_types)
|
280
603
|
schema.type_error(type_error, context)
|
281
|
-
|
604
|
+
set_result(selection_result, result_name, nil, false, is_non_null)
|
282
605
|
nil
|
283
606
|
else
|
284
|
-
resolved_type
|
285
|
-
continue_field(path, value, field, resolved_type, ast_node, next_selections, is_non_null)
|
607
|
+
continue_field(resolved_value, owner_type, field, resolved_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result, was_scoped, runtime_state)
|
286
608
|
end
|
287
609
|
end
|
288
610
|
when "OBJECT"
|
289
611
|
object_proxy = begin
|
290
|
-
|
612
|
+
was_scoped ? current_type.wrap_scoped(value, context) : current_type.wrap(value, context)
|
291
613
|
rescue GraphQL::ExecutionError => err
|
292
614
|
err
|
293
615
|
end
|
294
|
-
after_lazy(object_proxy,
|
295
|
-
continue_value = continue_value(
|
616
|
+
after_lazy(object_proxy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_object, runtime_state|
|
617
|
+
continue_value = continue_value(inner_object, owner_type, field, is_non_null, ast_node, result_name, selection_result)
|
296
618
|
if HALT != continue_value
|
297
|
-
response_hash =
|
298
|
-
|
299
|
-
|
300
|
-
|
619
|
+
response_hash = GraphQLResultHash.new(result_name, selection_result, is_non_null)
|
620
|
+
set_result(selection_result, result_name, response_hash, true, is_non_null)
|
621
|
+
|
622
|
+
gathered_selections = gather_selections(continue_value, current_type, ast_node, next_selections)
|
623
|
+
# There are two possibilities for `gathered_selections`:
|
624
|
+
# 1. All selections of this object should be evaluated together (there are no runtime directives modifying execution).
|
625
|
+
# This case is handled below, and the result can be written right into the main `response_hash` above.
|
626
|
+
# In this case, `gathered_selections` is a hash of selections.
|
627
|
+
# 2. Some selections of this object have runtime directives that may or may not modify execution.
|
628
|
+
# That part of the selection is evaluated in an isolated way, writing into a sub-response object which is
|
629
|
+
# eventually merged into the final response. In this case, `gathered_selections` is an array of things to run in isolation.
|
630
|
+
# (Technically, it's possible that one of those entries _doesn't_ require isolation.)
|
631
|
+
tap_or_each(gathered_selections) do |selections, is_selection_array|
|
632
|
+
if is_selection_array
|
633
|
+
this_result = GraphQLResultHash.new(result_name, selection_result, is_non_null)
|
634
|
+
final_result = response_hash
|
635
|
+
else
|
636
|
+
this_result = response_hash
|
637
|
+
final_result = nil
|
638
|
+
end
|
639
|
+
# reset this mutable state
|
640
|
+
# Unset `result_name` here because it's already included in the new response hash
|
641
|
+
runtime_state.current_object = continue_value
|
642
|
+
runtime_state.current_result_name = nil
|
643
|
+
runtime_state.current_result = this_result
|
644
|
+
# This is a less-frequent case; use a fast check since it's often not there.
|
645
|
+
if (directives = selections[:graphql_directives])
|
646
|
+
selections.delete(:graphql_directives)
|
647
|
+
end
|
648
|
+
call_method_on_directives(:resolve, continue_value, directives) do
|
649
|
+
evaluate_selections(
|
650
|
+
continue_value,
|
651
|
+
current_type,
|
652
|
+
false,
|
653
|
+
selections,
|
654
|
+
this_result,
|
655
|
+
final_result,
|
656
|
+
owner_object.object,
|
657
|
+
runtime_state,
|
658
|
+
)
|
659
|
+
this_result
|
660
|
+
end
|
661
|
+
end
|
301
662
|
end
|
302
663
|
end
|
303
664
|
when "LIST"
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
665
|
+
inner_type = current_type.of_type
|
666
|
+
# This is true for objects, unions, and interfaces
|
667
|
+
use_dataloader_job = !inner_type.unwrap.kind.input?
|
668
|
+
inner_type_non_null = inner_type.non_null?
|
669
|
+
response_list = GraphQLResultArray.new(result_name, selection_result, is_non_null)
|
670
|
+
set_result(selection_result, result_name, response_list, true, is_non_null)
|
671
|
+
idx = nil
|
672
|
+
list_value = begin
|
673
|
+
value.each do |inner_value|
|
674
|
+
idx ||= 0
|
675
|
+
this_idx = idx
|
676
|
+
idx += 1
|
677
|
+
if use_dataloader_job
|
678
|
+
@dataloader.append_job do
|
679
|
+
resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped, runtime_state)
|
680
|
+
end
|
681
|
+
else
|
682
|
+
resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped, runtime_state)
|
320
683
|
end
|
321
684
|
end
|
685
|
+
|
686
|
+
response_list
|
687
|
+
rescue NoMethodError => err
|
688
|
+
# Ruby 2.2 doesn't have NoMethodError#receiver, can't check that one in this case. (It's been EOL since 2017.)
|
689
|
+
if err.name == :each && (err.respond_to?(:receiver) ? err.receiver == value : true)
|
690
|
+
# This happens when the GraphQL schema doesn't match the implementation. Help the dev debug.
|
691
|
+
raise ListResultFailedError.new(value: value, field: field, path: current_path)
|
692
|
+
else
|
693
|
+
# This was some other NoMethodError -- let it bubble to reveal the real error.
|
694
|
+
raise
|
695
|
+
end
|
696
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
697
|
+
ex_err
|
698
|
+
rescue StandardError => err
|
699
|
+
begin
|
700
|
+
query.handle_or_reraise(err)
|
701
|
+
rescue GraphQL::ExecutionError => ex_err
|
702
|
+
ex_err
|
703
|
+
end
|
322
704
|
end
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
# For fields like `__schema: __Schema!`
|
327
|
-
inner_type = resolve_if_late_bound_type(inner_type)
|
328
|
-
# Don't `set_type_at_path` because we want the static type,
|
329
|
-
# we're going to use that to determine whether a `nil` should be propagated or not.
|
330
|
-
continue_field(path, value, field, inner_type, ast_node, next_selections, true)
|
705
|
+
# Detect whether this error came while calling `.each` (before `idx` is set) or while running list *items* (after `idx` is set)
|
706
|
+
error_is_non_null = idx.nil? ? is_non_null : inner_type.non_null?
|
707
|
+
continue_value(list_value, owner_type, field, error_is_non_null, ast_node, result_name, selection_result)
|
331
708
|
else
|
332
|
-
raise "Invariant: Unhandled type kind #{
|
709
|
+
raise "Invariant: Unhandled type kind #{current_type.kind} (#{current_type})"
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
def resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped, runtime_state) # rubocop:disable Metrics/ParameterLists
|
714
|
+
runtime_state.current_result_name = this_idx
|
715
|
+
runtime_state.current_result = response_list
|
716
|
+
call_method_on_directives(:resolve_each, owner_object, ast_node.directives) do
|
717
|
+
# This will update `response_list` with the lazy
|
718
|
+
after_lazy(inner_value, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list, runtime_state: runtime_state) do |inner_inner_value, runtime_state|
|
719
|
+
continue_value = continue_value(inner_inner_value, owner_type, field, inner_type_non_null, ast_node, this_idx, response_list)
|
720
|
+
if HALT != continue_value
|
721
|
+
continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list, was_scoped, runtime_state)
|
722
|
+
end
|
723
|
+
end
|
333
724
|
end
|
334
725
|
end
|
335
726
|
|
336
|
-
def
|
337
|
-
|
727
|
+
def call_method_on_directives(method_name, object, directives, &block)
|
728
|
+
return yield if directives.nil? || directives.empty?
|
729
|
+
run_directive(method_name, object, directives, 0, &block)
|
338
730
|
end
|
339
731
|
|
340
|
-
def run_directive(object,
|
341
|
-
dir_node =
|
732
|
+
def run_directive(method_name, object, directives, idx, &block)
|
733
|
+
dir_node = directives[idx]
|
342
734
|
if !dir_node
|
343
735
|
yield
|
344
736
|
else
|
345
|
-
dir_defn =
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
737
|
+
dir_defn = @schema_directives.fetch(dir_node.name)
|
738
|
+
raw_dir_args = arguments(nil, dir_defn, dir_node)
|
739
|
+
dir_args = continue_value(
|
740
|
+
raw_dir_args, # value
|
741
|
+
dir_defn, # parent_type
|
742
|
+
nil, # field
|
743
|
+
false, # is_non_null
|
744
|
+
dir_node, # ast_node
|
745
|
+
nil, # result_name
|
746
|
+
nil, # selection_result
|
747
|
+
)
|
748
|
+
|
749
|
+
if dir_args == HALT
|
750
|
+
nil
|
751
|
+
else
|
752
|
+
dir_defn.public_send(method_name, object, dir_args, context) do
|
753
|
+
run_directive(method_name, object, directives, idx + 1, &block)
|
754
|
+
end
|
352
755
|
end
|
353
756
|
end
|
354
757
|
end
|
@@ -356,7 +759,7 @@ module GraphQL
|
|
356
759
|
# Check {Schema::Directive.include?} for each directive that's present
|
357
760
|
def directives_include?(node, graphql_object, parent_type)
|
358
761
|
node.directives.each do |dir_node|
|
359
|
-
dir_defn =
|
762
|
+
dir_defn = @schema_directives.fetch(dir_node.name)
|
360
763
|
args = arguments(graphql_object, dir_defn, dir_node)
|
361
764
|
if !dir_defn.include?(graphql_object, args, context)
|
362
765
|
return false
|
@@ -365,231 +768,131 @@ module GraphQL
|
|
365
768
|
true
|
366
769
|
end
|
367
770
|
|
368
|
-
def
|
369
|
-
|
370
|
-
|
771
|
+
def get_current_runtime_state
|
772
|
+
current_state = Thread.current[:__graphql_runtime_info] ||= begin
|
773
|
+
per_query_state = {}
|
774
|
+
per_query_state.compare_by_identity
|
775
|
+
per_query_state
|
776
|
+
end
|
777
|
+
|
778
|
+
current_state[@query] ||= CurrentState.new
|
779
|
+
end
|
780
|
+
|
781
|
+
def minimal_after_lazy(value, &block)
|
782
|
+
if lazy?(value)
|
783
|
+
GraphQL::Execution::Lazy.new do
|
784
|
+
result = @schema.sync_lazy(value)
|
785
|
+
# The returned result might also be lazy, so check it, too
|
786
|
+
minimal_after_lazy(result, &block)
|
787
|
+
end
|
371
788
|
else
|
372
|
-
|
789
|
+
yield(value)
|
373
790
|
end
|
374
791
|
end
|
375
792
|
|
376
793
|
# @param obj [Object] Some user-returned value that may want to be batched
|
377
|
-
# @param path [Array<String>]
|
378
794
|
# @param field [GraphQL::Schema::Field]
|
379
795
|
# @param eager [Boolean] Set to `true` for mutation root fields only
|
796
|
+
# @param trace [Boolean] If `false`, don't wrap this with field tracing
|
380
797
|
# @return [GraphQL::Execution::Lazy, Object] If loading `object` will be deferred, it's a wrapper over it.
|
381
|
-
def after_lazy(
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
lazy = GraphQL::Execution::Lazy.new(
|
386
|
-
|
387
|
-
|
798
|
+
def after_lazy(lazy_obj, field:, owner_object:, arguments:, ast_node:, result:, result_name:, eager: false, runtime_state:, trace: true, &block)
|
799
|
+
if lazy?(lazy_obj)
|
800
|
+
orig_result = result
|
801
|
+
was_authorized_by_scope_items = runtime_state.was_authorized_by_scope_items
|
802
|
+
lazy = GraphQL::Execution::Lazy.new(field: field) do
|
803
|
+
# This block might be called in a new fiber;
|
804
|
+
# In that case, this will initialize a new state
|
805
|
+
# to avoid conflicting with the parent fiber.
|
806
|
+
runtime_state = get_current_runtime_state
|
807
|
+
runtime_state.current_object = owner_object
|
808
|
+
runtime_state.current_field = field
|
809
|
+
runtime_state.current_arguments = arguments
|
810
|
+
runtime_state.current_result_name = result_name
|
811
|
+
runtime_state.current_result = orig_result
|
812
|
+
runtime_state.was_authorized_by_scope_items = was_authorized_by_scope_items
|
388
813
|
# Wrap the execution of _this_ method with tracing,
|
389
814
|
# but don't wrap the continuation below
|
390
|
-
inner_obj =
|
815
|
+
inner_obj = begin
|
816
|
+
if trace
|
817
|
+
@current_trace.execute_field_lazy(field: field, query: query, object: owner_object, arguments: arguments, ast_node: ast_node) do
|
818
|
+
schema.sync_lazy(lazy_obj)
|
819
|
+
end
|
820
|
+
else
|
821
|
+
schema.sync_lazy(lazy_obj)
|
822
|
+
end
|
823
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
824
|
+
ex_err
|
825
|
+
rescue StandardError => err
|
391
826
|
begin
|
392
|
-
|
393
|
-
rescue GraphQL::ExecutionError
|
394
|
-
|
827
|
+
query.handle_or_reraise(err)
|
828
|
+
rescue GraphQL::ExecutionError => ex_err
|
829
|
+
ex_err
|
395
830
|
end
|
396
831
|
end
|
397
|
-
|
398
|
-
yield(really_inner_obj)
|
399
|
-
end
|
832
|
+
yield(inner_obj, runtime_state)
|
400
833
|
end
|
401
834
|
|
402
835
|
if eager
|
403
836
|
lazy.value
|
404
837
|
else
|
405
|
-
|
838
|
+
set_result(result, result_name, lazy, false, false) # is_non_null is irrelevant here
|
839
|
+
current_depth = 0
|
840
|
+
while result
|
841
|
+
current_depth += 1
|
842
|
+
result = result.graphql_parent
|
843
|
+
end
|
844
|
+
@lazies_at_depth[current_depth] << lazy
|
406
845
|
lazy
|
407
846
|
end
|
408
847
|
else
|
409
|
-
|
410
|
-
|
411
|
-
end
|
412
|
-
|
413
|
-
def each_argument_pair(ast_args_or_hash)
|
414
|
-
case ast_args_or_hash
|
415
|
-
when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
|
416
|
-
ast_args_or_hash.arguments.each do |arg|
|
417
|
-
yield(arg.name, arg.value)
|
418
|
-
end
|
419
|
-
when Hash
|
420
|
-
ast_args_or_hash.each do |key, value|
|
421
|
-
normalized_name = GraphQL::Schema::Member::BuildType.camelize(key.to_s)
|
422
|
-
yield(normalized_name, value)
|
423
|
-
end
|
424
|
-
else
|
425
|
-
raise "Invariant, unexpected #{ast_args_or_hash.inspect}"
|
848
|
+
# Don't need to reset state here because it _wasn't_ lazy.
|
849
|
+
yield(lazy_obj, runtime_state)
|
426
850
|
end
|
427
851
|
end
|
428
852
|
|
429
|
-
def arguments(graphql_object, arg_owner,
|
430
|
-
|
431
|
-
|
432
|
-
each_argument_pair(ast_node_or_hash) do |arg_name, arg_value|
|
433
|
-
arg_defn = arg_defns[arg_name]
|
434
|
-
# Need to distinguish between client-provided `nil`
|
435
|
-
# and nothing-at-all
|
436
|
-
is_present, value = arg_to_value(graphql_object, arg_defn.type, arg_value)
|
437
|
-
if is_present
|
438
|
-
# This doesn't apply to directives, which are legacy
|
439
|
-
# Can remove this when Skip and Include use classes or something.
|
440
|
-
if graphql_object
|
441
|
-
value = arg_defn.prepare_value(graphql_object, value)
|
442
|
-
end
|
443
|
-
kwarg_arguments[arg_defn.keyword] = value
|
444
|
-
end
|
445
|
-
end
|
446
|
-
arg_defns.each do |name, arg_defn|
|
447
|
-
if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
|
448
|
-
_is_present, value = arg_to_value(graphql_object, arg_defn.type, arg_defn.default_value)
|
449
|
-
kwarg_arguments[arg_defn.keyword] = value
|
450
|
-
end
|
451
|
-
end
|
452
|
-
kwarg_arguments
|
453
|
-
end
|
454
|
-
|
455
|
-
# Get a Ruby-ready value from a client query.
|
456
|
-
# @param graphql_object [Object] The owner of the field whose argument this is
|
457
|
-
# @param arg_type [Class, GraphQL::Schema::NonNull, GraphQL::Schema::List]
|
458
|
-
# @param ast_value [GraphQL::Language::Nodes::VariableIdentifier, String, Integer, Float, Boolean]
|
459
|
-
# @return [Array(is_present, value)]
|
460
|
-
def arg_to_value(graphql_object, arg_type, ast_value)
|
461
|
-
if ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
462
|
-
# If it's not here, it will get added later
|
463
|
-
if query.variables.key?(ast_value.name)
|
464
|
-
return true, query.variables[ast_value.name]
|
465
|
-
else
|
466
|
-
return false, nil
|
467
|
-
end
|
468
|
-
elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
|
469
|
-
return true, nil
|
470
|
-
elsif arg_type.is_a?(GraphQL::Schema::NonNull)
|
471
|
-
arg_to_value(graphql_object, arg_type.of_type, ast_value)
|
472
|
-
elsif arg_type.is_a?(GraphQL::Schema::List)
|
473
|
-
# Treat a single value like a list
|
474
|
-
arg_value = Array(ast_value)
|
475
|
-
list = []
|
476
|
-
arg_value.map do |inner_v|
|
477
|
-
_present, value = arg_to_value(graphql_object, arg_type.of_type, inner_v)
|
478
|
-
list << value
|
479
|
-
end
|
480
|
-
return true, list
|
481
|
-
elsif arg_type.is_a?(Class) && arg_type < GraphQL::Schema::InputObject
|
482
|
-
# For these, `prepare` is applied during `#initialize`.
|
483
|
-
# Pass `nil` so it will be skipped in `#arguments`.
|
484
|
-
# What a mess.
|
485
|
-
args = arguments(nil, arg_type, ast_value)
|
486
|
-
# We're not tracking defaults_used, but for our purposes
|
487
|
-
# we compare the value to the default value.
|
488
|
-
return true, arg_type.new(ruby_kwargs: args, context: context, defaults_used: nil)
|
853
|
+
def arguments(graphql_object, arg_owner, ast_node)
|
854
|
+
if arg_owner.arguments_statically_coercible?
|
855
|
+
query.arguments_for(ast_node, arg_owner)
|
489
856
|
else
|
490
|
-
|
491
|
-
|
857
|
+
# The arguments must be prepared in the context of the given object
|
858
|
+
query.arguments_for(ast_node, arg_owner, parent_object: graphql_object)
|
492
859
|
end
|
493
860
|
end
|
494
861
|
|
495
|
-
def
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
v.arguments.each do |arg|
|
502
|
-
h[arg.name] = flatten_ast_value(arg.value)
|
862
|
+
def delete_all_interpreter_context
|
863
|
+
per_query_state = Thread.current[:__graphql_runtime_info]
|
864
|
+
if per_query_state
|
865
|
+
per_query_state.delete(@query)
|
866
|
+
if per_query_state.size == 0
|
867
|
+
Thread.current[:__graphql_runtime_info] = nil
|
503
868
|
end
|
504
|
-
h
|
505
|
-
when Array
|
506
|
-
v.map { |v2| flatten_ast_value(v2) }
|
507
|
-
when GraphQL::Language::Nodes::VariableIdentifier
|
508
|
-
flatten_ast_value(query.variables[v.name])
|
509
|
-
else
|
510
|
-
v
|
511
869
|
end
|
870
|
+
nil
|
512
871
|
end
|
513
872
|
|
514
|
-
def
|
515
|
-
|
516
|
-
|
517
|
-
write_in_response(path, nil)
|
518
|
-
add_dead_path(path)
|
873
|
+
def resolve_type(type, value)
|
874
|
+
resolved_type, resolved_value = @current_trace.resolve_type(query: query, type: type, object: value) do
|
875
|
+
query.resolve_type(type, value)
|
519
876
|
end
|
520
|
-
end
|
521
877
|
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
878
|
+
if lazy?(resolved_type)
|
879
|
+
GraphQL::Execution::Lazy.new do
|
880
|
+
@current_trace.resolve_type_lazy(query: query, type: type, object: value) do
|
881
|
+
schema.sync_lazy(resolved_type)
|
882
|
+
end
|
526
883
|
end
|
527
|
-
write_in_response(path, nil)
|
528
|
-
add_dead_path(path)
|
529
|
-
end
|
530
|
-
end
|
531
|
-
|
532
|
-
def write_in_response(path, value)
|
533
|
-
if dead_path?(path)
|
534
|
-
return
|
535
884
|
else
|
536
|
-
|
537
|
-
# This nil is invalid, try writing it at the previous spot
|
538
|
-
propagate_path = path[0..-2]
|
539
|
-
write_in_response(propagate_path, value)
|
540
|
-
add_dead_path(propagate_path)
|
541
|
-
else
|
542
|
-
@response.write(path, value)
|
543
|
-
end
|
544
|
-
end
|
545
|
-
end
|
546
|
-
|
547
|
-
# To propagate nulls, we have to know what the field type was
|
548
|
-
# at previous parts of the response.
|
549
|
-
# This hash matches the response
|
550
|
-
def type_at(path)
|
551
|
-
t = @types_at_paths
|
552
|
-
path.each do |part|
|
553
|
-
t = t[part] || (raise("Invariant: #{part.inspect} not found in #{t}"))
|
554
|
-
end
|
555
|
-
t = t[:__type]
|
556
|
-
t
|
557
|
-
end
|
558
|
-
|
559
|
-
def set_type_at_path(path, type)
|
560
|
-
types = @types_at_paths
|
561
|
-
path.each do |part|
|
562
|
-
types = types[part] ||= {}
|
885
|
+
[resolved_type, resolved_value]
|
563
886
|
end
|
564
|
-
# Use this magic key so that the hash contains:
|
565
|
-
# - string keys for nested fields
|
566
|
-
# - :__type for the object type of a selection
|
567
|
-
types[:__type] ||= type
|
568
|
-
nil
|
569
887
|
end
|
570
888
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
dead = dead[part] ||= {}
|
577
|
-
end
|
578
|
-
dead[:__dead] = true
|
579
|
-
end
|
580
|
-
|
581
|
-
def dead_path?(path)
|
582
|
-
res = @dead_paths
|
583
|
-
path.each do |part|
|
584
|
-
if res
|
585
|
-
if res[:__dead]
|
586
|
-
break
|
587
|
-
else
|
588
|
-
res = res[part]
|
589
|
-
end
|
590
|
-
end
|
889
|
+
def lazy?(object)
|
890
|
+
obj_class = object.class
|
891
|
+
is_lazy = @lazy_cache[obj_class]
|
892
|
+
if is_lazy.nil?
|
893
|
+
is_lazy = @lazy_cache[obj_class] = @schema.lazy?(object)
|
591
894
|
end
|
592
|
-
|
895
|
+
is_lazy
|
593
896
|
end
|
594
897
|
end
|
595
898
|
end
|