graphql 1.8.7 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +2 -1
- data/lib/generators/graphql/scalar_generator.rb +20 -0
- data/lib/generators/graphql/templates/base_scalar.erb +4 -0
- data/lib/generators/graphql/templates/scalar.erb +13 -0
- data/lib/graphql/analysis/ast/analyzer.rb +62 -0
- data/lib/graphql/analysis/ast/field_usage.rb +28 -0
- data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -0
- data/lib/graphql/analysis/ast/max_query_depth.rb +18 -0
- data/lib/graphql/analysis/ast/query_complexity.rb +114 -0
- data/lib/graphql/analysis/ast/query_depth.rb +66 -0
- data/lib/graphql/analysis/ast/visitor.rb +255 -0
- data/lib/graphql/analysis/ast.rb +82 -0
- data/lib/graphql/analysis.rb +1 -0
- data/lib/graphql/argument.rb +5 -0
- data/lib/graphql/authorization.rb +1 -0
- data/lib/graphql/backwards_compatibility.rb +1 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -2
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -6
- data/lib/graphql/dig.rb +19 -0
- data/lib/graphql/directive/include_directive.rb +1 -7
- data/lib/graphql/directive/skip_directive.rb +1 -8
- data/lib/graphql/directive.rb +13 -1
- data/lib/graphql/enum_type.rb +8 -0
- data/lib/graphql/execution/execute.rb +36 -17
- data/lib/graphql/execution/instrumentation.rb +2 -0
- data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
- data/lib/graphql/execution/interpreter/hash_response.rb +46 -0
- data/lib/graphql/execution/interpreter/resolve.rb +58 -0
- data/lib/graphql/execution/interpreter/runtime.rb +597 -0
- data/lib/graphql/execution/interpreter.rb +99 -0
- data/lib/graphql/execution/lazy.rb +8 -1
- data/lib/graphql/execution/lookahead.rb +351 -0
- data/lib/graphql/execution/multiplex.rb +37 -29
- data/lib/graphql/execution.rb +2 -0
- data/lib/graphql/execution_error.rb +1 -1
- data/lib/graphql/field.rb +1 -7
- data/lib/graphql/integer_encoding_error.rb +12 -0
- data/lib/graphql/internal_representation/rewrite.rb +127 -142
- data/lib/graphql/introspection/dynamic_fields.rb +8 -2
- data/lib/graphql/introspection/entry_points.rb +11 -6
- data/lib/graphql/introspection/enum_value_type.rb +4 -0
- data/lib/graphql/introspection/schema_type.rb +7 -2
- data/lib/graphql/introspection/type_type.rb +9 -5
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/block_string.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +10 -7
- data/lib/graphql/language/lexer.rb +55 -36
- data/lib/graphql/language/lexer.rl +8 -3
- data/lib/graphql/language/nodes.rb +440 -362
- data/lib/graphql/language/parser.rb +56 -56
- data/lib/graphql/language/parser.y +12 -12
- data/lib/graphql/language/printer.rb +2 -2
- data/lib/graphql/language/visitor.rb +158 -15
- data/lib/graphql/language.rb +0 -1
- data/lib/graphql/literal_validation_error.rb +6 -0
- data/lib/graphql/query/arguments.rb +3 -2
- data/lib/graphql/query/arguments_cache.rb +1 -1
- data/lib/graphql/query/context.rb +14 -5
- data/lib/graphql/query/executor.rb +1 -1
- data/lib/graphql/query/result.rb +1 -1
- data/lib/graphql/query/validation_pipeline.rb +35 -11
- data/lib/graphql/query/variable_validation_error.rb +10 -1
- data/lib/graphql/query.rb +16 -2
- data/lib/graphql/relay/base_connection.rb +2 -0
- data/lib/graphql/relay/connection_instrumentation.rb +3 -1
- data/lib/graphql/relay/connection_resolve.rb +1 -1
- data/lib/graphql/relay/node.rb +2 -28
- data/lib/graphql/relay/relation_connection.rb +1 -1
- data/lib/graphql/schema/argument.rb +13 -5
- data/lib/graphql/schema/base_64_encoder.rb +4 -4
- data/lib/graphql/schema/build_from_definition.rb +2 -4
- data/lib/graphql/schema/default_type_error.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +66 -0
- data/lib/graphql/schema/directive/include.rb +25 -0
- data/lib/graphql/schema/directive/skip.rb +25 -0
- data/lib/graphql/schema/directive/transform.rb +48 -0
- data/lib/graphql/schema/directive.rb +103 -0
- data/lib/graphql/schema/enum_value.rb +3 -2
- data/lib/graphql/schema/field/connection_extension.rb +50 -0
- data/lib/graphql/schema/field/scope_extension.rb +18 -0
- data/lib/graphql/schema/field.rb +273 -64
- data/lib/graphql/schema/field_extension.rb +69 -0
- data/lib/graphql/schema/input_object.rb +16 -8
- data/lib/graphql/schema/interface.rb +1 -0
- data/lib/graphql/schema/loader.rb +22 -16
- data/lib/graphql/schema/member/base_dsl_methods.rb +8 -2
- data/lib/graphql/schema/member/build_type.rb +33 -1
- data/lib/graphql/schema/member/has_arguments.rb +6 -2
- data/lib/graphql/schema/member/has_fields.rb +18 -70
- data/lib/graphql/schema/member/has_path.rb +25 -0
- data/lib/graphql/schema/member/instrumentation.rb +10 -7
- data/lib/graphql/schema/member.rb +2 -0
- data/lib/graphql/schema/mutation.rb +6 -48
- data/lib/graphql/schema/non_null.rb +5 -1
- data/lib/graphql/schema/object.rb +18 -4
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +42 -9
- data/lib/graphql/schema/resolver/has_payload_type.rb +65 -0
- data/lib/graphql/schema/resolver.rb +45 -20
- data/lib/graphql/schema/subscription.rb +97 -0
- data/lib/graphql/schema/traversal.rb +11 -7
- data/lib/graphql/schema.rb +186 -38
- data/lib/graphql/static_validation/all_rules.rb +3 -2
- data/lib/graphql/static_validation/base_visitor.rb +199 -0
- data/lib/graphql/static_validation/default_visitor.rb +15 -0
- data/lib/graphql/static_validation/definition_dependencies.rb +62 -68
- data/lib/graphql/static_validation/{message.rb → error.rb} +11 -11
- data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
- data/lib/graphql/static_validation/literal_validator.rb +54 -11
- data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +87 -16
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +31 -0
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +11 -11
- data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +52 -8
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +35 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -15
- data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +19 -14
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +17 -19
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +30 -14
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +356 -29
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +32 -0
- data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +20 -13
- data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +37 -29
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +25 -17
- data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +12 -10
- data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +7 -11
- data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +16 -16
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +21 -14
- data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +10 -14
- data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +30 -30
- data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
- data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +25 -17
- data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +17 -18
- data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +47 -0
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +10 -14
- data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +28 -17
- data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +35 -27
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +15 -14
- data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -30
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +18 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +73 -65
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
- data/lib/graphql/static_validation/validation_context.rb +8 -51
- data/lib/graphql/static_validation/validator.rb +23 -15
- data/lib/graphql/static_validation.rb +5 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -2
- data/lib/graphql/subscriptions/event.rb +28 -5
- data/lib/graphql/subscriptions/subscription_root.rb +66 -0
- data/lib/graphql/subscriptions.rb +16 -2
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +0 -1
- data/lib/graphql/tracing/appsignal_tracing.rb +1 -1
- data/lib/graphql/tracing/data_dog_tracing.rb +1 -1
- data/lib/graphql/tracing/new_relic_tracing.rb +3 -3
- data/lib/graphql/tracing/platform_tracing.rb +17 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +1 -1
- data/lib/graphql/tracing/scout_tracing.rb +1 -1
- data/lib/graphql/tracing/skylight_tracing.rb +3 -3
- data/lib/graphql/tracing.rb +8 -8
- data/lib/graphql/types/float.rb +1 -1
- data/lib/graphql/types/int.rb +11 -2
- data/lib/graphql/types/iso_8601_date_time.rb +15 -1
- data/lib/graphql/types/relay/base_connection.rb +15 -1
- data/lib/graphql/types/relay/node.rb +0 -1
- data/lib/graphql/types/relay/node_field.rb +43 -0
- data/lib/graphql/types/relay/nodes_field.rb +45 -0
- data/lib/graphql/types/relay.rb +2 -0
- data/lib/graphql/unauthorized_error.rb +4 -0
- data/lib/graphql/unauthorized_field_error.rb +23 -0
- data/lib/graphql/upgrader/member.rb +5 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +6 -1
- data/readme.md +7 -7
- data/spec/dummy/Gemfile +1 -1
- data/spec/dummy/Gemfile.lock +157 -0
- data/spec/dummy/app/channels/graphql_channel.rb +22 -11
- data/spec/dummy/config/locales/en.yml +1 -1
- data/spec/dummy/log/test.log +199 -0
- data/spec/dummy/test/test_helper.rb +1 -0
- 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 +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +3 -0
- 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 +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +2 -0
- 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 +1 -0
- 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 +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +3 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +1 -0
- 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 +1 -0
- 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/graphql/analysis/analyze_query_spec.rb +1 -1
- data/spec/graphql/analysis/ast/field_usage_spec.rb +51 -0
- data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +120 -0
- data/spec/graphql/analysis/ast/max_query_depth_spec.rb +114 -0
- data/spec/graphql/analysis/ast/query_complexity_spec.rb +299 -0
- data/spec/graphql/analysis/ast/query_depth_spec.rb +108 -0
- data/spec/graphql/analysis/ast_spec.rb +269 -0
- data/spec/graphql/authorization_spec.rb +120 -23
- data/spec/graphql/base_type_spec.rb +6 -4
- data/spec/graphql/enum_type_spec.rb +6 -1
- data/spec/graphql/execution/execute_spec.rb +9 -9
- data/spec/graphql/execution/instrumentation_spec.rb +19 -0
- data/spec/graphql/execution/interpreter_spec.rb +485 -0
- data/spec/graphql/execution/lazy_spec.rb +67 -1
- data/spec/graphql/execution/lookahead_spec.rb +363 -0
- data/spec/graphql/execution/multiplex_spec.rb +31 -3
- data/spec/graphql/execution/typecast_spec.rb +20 -20
- data/spec/graphql/execution_error_spec.rb +110 -96
- data/spec/graphql/field_spec.rb +1 -1
- data/spec/graphql/input_object_type_spec.rb +13 -352
- data/spec/graphql/int_type_spec.rb +19 -0
- data/spec/graphql/interface_type_spec.rb +4 -4
- data/spec/graphql/internal_representation/rewrite_spec.rb +2 -0
- data/spec/graphql/introspection/input_value_type_spec.rb +1 -1
- data/spec/graphql/introspection/type_type_spec.rb +1 -2
- data/spec/graphql/language/document_from_schema_definition_spec.rb +2 -2
- data/spec/graphql/language/lexer_spec.rb +72 -3
- data/spec/graphql/language/nodes_spec.rb +20 -0
- data/spec/graphql/language/printer_spec.rb +18 -6
- data/spec/graphql/language/visitor_spec.rb +320 -14
- data/spec/graphql/non_null_type_spec.rb +1 -1
- data/spec/graphql/object_type_spec.rb +32 -27
- data/spec/graphql/query/arguments_spec.rb +21 -0
- data/spec/graphql/query/context_spec.rb +28 -0
- data/spec/graphql/query/executor_spec.rb +40 -36
- data/spec/graphql/query_spec.rb +12 -6
- data/spec/graphql/schema/argument_spec.rb +35 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +144 -29
- data/spec/graphql/schema/catchall_middleware_spec.rb +16 -15
- data/spec/graphql/schema/directive/feature_spec.rb +81 -0
- data/spec/graphql/schema/directive/transform_spec.rb +39 -0
- data/spec/graphql/schema/enum_spec.rb +12 -3
- data/spec/graphql/schema/enum_value_spec.rb +11 -0
- data/spec/graphql/schema/field_extension_spec.rb +115 -0
- data/spec/graphql/schema/field_spec.rb +47 -7
- data/spec/graphql/schema/input_object_spec.rb +95 -0
- data/spec/graphql/schema/instrumentation_spec.rb +3 -0
- data/spec/graphql/schema/interface_spec.rb +8 -2
- data/spec/graphql/schema/introspection_system_spec.rb +9 -1
- data/spec/graphql/schema/loader_spec.rb +5 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +4 -0
- data/spec/graphql/schema/member/build_type_spec.rb +46 -0
- data/spec/graphql/schema/member/scoped_spec.rb +19 -3
- data/spec/graphql/schema/mutation_spec.rb +5 -3
- data/spec/graphql/schema/object_spec.rb +9 -1
- data/spec/graphql/schema/printer_spec.rb +255 -93
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +133 -0
- data/spec/graphql/schema/resolver_spec.rb +173 -9
- data/spec/graphql/schema/scalar_spec.rb +6 -0
- data/spec/graphql/schema/subscription_spec.rb +416 -0
- data/spec/graphql/schema/traversal_spec.rb +10 -10
- data/spec/graphql/schema/type_expression_spec.rb +2 -2
- data/spec/graphql/schema/union_spec.rb +7 -0
- data/spec/graphql/schema/validation_spec.rb +1 -1
- data/spec/graphql/schema/warden_spec.rb +145 -88
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +213 -73
- data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +72 -29
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +10 -5
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -5
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +131 -5
- data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -2
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +22 -2
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +6 -3
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +13 -4
- data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +58 -0
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -1
- data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +14 -7
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +14 -7
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +8 -4
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +8 -4
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +23 -3
- data/spec/graphql/static_validation/type_stack_spec.rb +10 -19
- data/spec/graphql/static_validation/validator_spec.rb +50 -2
- data/spec/graphql/subscriptions_spec.rb +27 -16
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +16 -0
- data/spec/graphql/tracing/platform_tracing_spec.rb +59 -37
- data/spec/graphql/tracing/prometheus_tracing_spec.rb +3 -0
- data/spec/graphql/tracing/skylight_tracing_spec.rb +16 -0
- data/spec/graphql/types/iso_8601_date_time_spec.rb +29 -2
- data/spec/graphql/union_type_spec.rb +2 -2
- data/spec/graphql/upgrader/member_spec.rb +67 -0
- data/spec/{graphql → integration/mongoid/graphql}/relay/mongo_relation_connection_spec.rb +11 -22
- data/spec/integration/mongoid/spec_helper.rb +2 -0
- data/spec/{support → integration/mongoid}/star_trek/data.rb +0 -0
- data/spec/{support → integration/mongoid}/star_trek/schema.rb +56 -34
- data/spec/{support/star_wars → integration/rails}/data.rb +1 -0
- data/spec/{support → integration/rails/generators}/base_generator_test.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/enum_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/install_generator_spec.rb +1 -1
- data/spec/{generators → integration/rails/generators}/graphql/interface_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/loader_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/mutation_generator_spec.rb +0 -0
- data/spec/{generators → integration/rails/generators}/graphql/object_generator_spec.rb +0 -0
- data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +28 -0
- data/spec/{generators → integration/rails/generators}/graphql/union_generator_spec.rb +0 -0
- data/spec/integration/rails/graphql/input_object_type_spec.rb +364 -0
- data/spec/{graphql → integration/rails/graphql}/query/variables_spec.rb +7 -7
- data/spec/{graphql → integration/rails/graphql}/relay/array_connection_spec.rb +9 -9
- data/spec/{graphql → integration/rails/graphql}/relay/base_connection_spec.rb +11 -3
- data/spec/{graphql → integration/rails/graphql}/relay/connection_instrumentation_spec.rb +19 -22
- data/spec/{graphql → integration/rails/graphql}/relay/connection_resolve_spec.rb +16 -0
- data/spec/{graphql → integration/rails/graphql}/relay/connection_type_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/edge_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/mutation_spec.rb +48 -0
- data/spec/{graphql → integration/rails/graphql}/relay/node_spec.rb +0 -0
- data/spec/{graphql → integration/rails/graphql}/relay/page_info_spec.rb +22 -22
- data/spec/{graphql → integration/rails/graphql}/relay/range_add_spec.rb +4 -4
- data/spec/{graphql → integration/rails/graphql}/relay/relation_connection_spec.rb +56 -27
- data/spec/{graphql → integration/rails/graphql}/schema_spec.rb +15 -11
- data/spec/{graphql → integration/rails/graphql}/tracing/active_support_notifications_tracing_spec.rb +16 -9
- data/spec/integration/rails/spec_helper.rb +25 -0
- data/spec/integration/tmp/app/graphql/types/family_type.rb +9 -0
- data/spec/spec_helper.rb +23 -39
- data/spec/support/dummy/data.rb +20 -17
- data/spec/support/dummy/schema.rb +315 -305
- data/spec/support/error_bubbling_helpers.rb +23 -0
- data/spec/support/jazz.rb +213 -46
- data/spec/support/lazy_helpers.rb +69 -27
- data/spec/support/new_relic.rb +3 -0
- data/spec/support/skylight.rb +3 -0
- data/spec/support/star_wars/schema.rb +131 -81
- data/spec/support/static_validation_helpers.rb +9 -5
- metadata +418 -261
- data/lib/graphql/language/comments.rb +0 -45
- data/lib/graphql/static_validation/arguments_validator.rb +0 -50
- data/spec/graphql/schema/member/has_fields_spec.rb +0 -129
- data/spec/rails_dependency_sanity_spec.rb +0 -14
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "graphql/analysis/ast/visitor"
|
3
|
+
require "graphql/analysis/ast/analyzer"
|
4
|
+
require "graphql/analysis/ast/field_usage"
|
5
|
+
require "graphql/analysis/ast/query_complexity"
|
6
|
+
require "graphql/analysis/ast/max_query_complexity"
|
7
|
+
require "graphql/analysis/ast/query_depth"
|
8
|
+
require "graphql/analysis/ast/max_query_depth"
|
9
|
+
|
10
|
+
# frozen_string_literal: true
|
11
|
+
module GraphQL
|
12
|
+
module Analysis
|
13
|
+
module AST
|
14
|
+
module_function
|
15
|
+
|
16
|
+
def use(schema_defn)
|
17
|
+
schema = schema_defn.target
|
18
|
+
schema.analysis_engine = GraphQL::Analysis::AST
|
19
|
+
end
|
20
|
+
|
21
|
+
# Analyze a multiplex, and all queries within.
|
22
|
+
# Multiplex analyzers are ran for all queries, keeping state.
|
23
|
+
# Query analyzers are ran per query, without carrying state between queries.
|
24
|
+
#
|
25
|
+
# @param multiplex [GraphQL::Execution::Multiplex]
|
26
|
+
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
27
|
+
# @return [void]
|
28
|
+
def analyze_multiplex(multiplex, analyzers)
|
29
|
+
multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
|
30
|
+
|
31
|
+
multiplex.trace("analyze_multiplex", { multiplex: multiplex }) do
|
32
|
+
query_results = multiplex.queries.map do |query|
|
33
|
+
if query.valid?
|
34
|
+
analyze_query(
|
35
|
+
query,
|
36
|
+
query.analyzers,
|
37
|
+
multiplex_analyzers: multiplex_analyzers
|
38
|
+
)
|
39
|
+
else
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
multiplex_results = multiplex_analyzers.map(&:result)
|
45
|
+
multiplex_errors = analysis_errors(multiplex_results)
|
46
|
+
|
47
|
+
multiplex.queries.each_with_index do |query, idx|
|
48
|
+
query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param query [GraphQL::Query]
|
55
|
+
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
56
|
+
# @return [Array<Any>] Results from those analyzers
|
57
|
+
def analyze_query(query, analyzers, multiplex_analyzers: [])
|
58
|
+
query.trace("analyze_query", { query: query }) do
|
59
|
+
query_analyzers = analyzers
|
60
|
+
.map { |analyzer| analyzer.new(query) }
|
61
|
+
.select { |analyzer| analyzer.analyze? }
|
62
|
+
|
63
|
+
analyzers_to_run = query_analyzers + multiplex_analyzers
|
64
|
+
return [] unless analyzers_to_run.any?
|
65
|
+
|
66
|
+
visitor = GraphQL::Analysis::AST::Visitor.new(
|
67
|
+
query: query,
|
68
|
+
analyzers: analyzers_to_run
|
69
|
+
)
|
70
|
+
|
71
|
+
visitor.visit
|
72
|
+
|
73
|
+
query_analyzers.map(&:result)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def analysis_errors(results)
|
78
|
+
results.flatten.select { |r| r.is_a?(GraphQL::AnalysisError) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/graphql/analysis.rb
CHANGED
data/lib/graphql/argument.rb
CHANGED
@@ -89,6 +89,11 @@ module GraphQL
|
|
89
89
|
@expose_as ||= (@as || @name).to_s
|
90
90
|
end
|
91
91
|
|
92
|
+
# Backport this to support legacy-style directives
|
93
|
+
def keyword
|
94
|
+
@keyword ||= GraphQL::Schema::Member::BuildType.underscore(expose_as).to_sym
|
95
|
+
end
|
96
|
+
|
92
97
|
# @param value [Object] The incoming value from variables or query string literal
|
93
98
|
# @param ctx [GraphQL::Query::Context]
|
94
99
|
# @return [Object] The prepared `value` for this argument or `value` itself if no `prepare` function exists.
|
data/lib/graphql/base_type.rb
CHANGED
@@ -187,7 +187,7 @@ module GraphQL
|
|
187
187
|
resolve_related_type(type_arg.call)
|
188
188
|
when String
|
189
189
|
# Get a constant by this name
|
190
|
-
Object.const_get(type_arg)
|
190
|
+
resolve_related_type(Object.const_get(type_arg))
|
191
191
|
else
|
192
192
|
if type_arg.respond_to?(:graphql_definition)
|
193
193
|
type_arg.graphql_definition
|
@@ -49,8 +49,7 @@ module GraphQL
|
|
49
49
|
end
|
50
50
|
|
51
51
|
module TestMiddleware
|
52
|
-
|
53
|
-
def self.call(parent_type, parent_object, field_definition, field_args, query_context, next_middleware)
|
52
|
+
def self.call(parent_type, parent_object, field_definition, field_args, query_context, &next_middleware)
|
54
53
|
query_context[:middleware_log] && query_context[:middleware_log] << field_definition.name
|
55
54
|
next_middleware.call
|
56
55
|
end
|
@@ -595,31 +595,27 @@ module GraphQL
|
|
595
595
|
|
596
596
|
assert_equal 6, document.definitions.size
|
597
597
|
|
598
|
-
schema_definition = document.definitions
|
598
|
+
schema_definition, directive_definition, enum_type_definition, object_type_definition, input_object_type_definition, interface_type_definition = document.definitions
|
599
|
+
|
599
600
|
assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class
|
600
601
|
|
601
|
-
directive_definition = document.definitions.shift
|
602
602
|
assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
|
603
603
|
assert_equal 'This is a directive', directive_definition.description
|
604
604
|
|
605
|
-
enum_type_definition = document.definitions.shift
|
606
605
|
assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
|
607
606
|
assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description
|
608
607
|
|
609
608
|
assert_nil enum_type_definition.values[0].description
|
610
609
|
assert_equal 'Not a creative color', enum_type_definition.values[1].description
|
611
610
|
|
612
|
-
object_type_definition = document.definitions.shift
|
613
611
|
assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
|
614
612
|
assert_equal 'Comment without preceding space', object_type_definition.description
|
615
613
|
assert_equal 'And a field to boot', object_type_definition.fields[0].description
|
616
614
|
|
617
|
-
input_object_type_definition = document.definitions.shift
|
618
615
|
assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
|
619
616
|
assert_equal 'Comment for input object types', input_object_type_definition.description
|
620
617
|
assert_equal 'Color of the car', input_object_type_definition.fields[0].description
|
621
618
|
|
622
|
-
interface_type_definition = document.definitions.shift
|
623
619
|
assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
|
624
620
|
assert_equal 'Comment for interface definitions', interface_type_definition.description
|
625
621
|
assert_equal 'Amount of wheels', interface_type_definition.fields[0].description
|
data/lib/graphql/dig.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Dig
|
4
|
+
# implemented using the old activesupport #dig instead of the ruby built-in
|
5
|
+
# so we can use some of the magic in Schema::InputObject and Query::Arguments
|
6
|
+
# to handle stringified/symbolized keys.
|
7
|
+
#
|
8
|
+
# @param args [Array<[String, Symbol>] Retrieves the value object corresponding to the each key objects repeatedly
|
9
|
+
# @return [Object]
|
10
|
+
def dig(own_key, *rest_keys)
|
11
|
+
val = self[own_key]
|
12
|
+
if val.nil? || rest_keys.empty?
|
13
|
+
val
|
14
|
+
else
|
15
|
+
val.dig(*rest_keys)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,8 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::IncludeDirective = GraphQL::Directive.
|
3
|
-
name "include"
|
4
|
-
description "Directs the executor to include this field or fragment only when the `if` argument is true."
|
5
|
-
locations([GraphQL::Directive::FIELD, GraphQL::Directive::FRAGMENT_SPREAD, GraphQL::Directive::INLINE_FRAGMENT])
|
6
|
-
argument :if, !GraphQL::BOOLEAN_TYPE, 'Included when true.'
|
7
|
-
default_directive true
|
8
|
-
end
|
2
|
+
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition
|
@@ -1,9 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::SkipDirective = GraphQL::Directive.
|
3
|
-
name "skip"
|
4
|
-
description "Directs the executor to skip this field or fragment when the `if` argument is true."
|
5
|
-
locations([GraphQL::Directive::FIELD, GraphQL::Directive::FRAGMENT_SPREAD, GraphQL::Directive::INLINE_FRAGMENT])
|
6
|
-
|
7
|
-
argument :if, !GraphQL::BOOLEAN_TYPE, 'Skipped when true.'
|
8
|
-
default_directive true
|
9
|
-
end
|
2
|
+
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition
|
data/lib/graphql/directive.rb
CHANGED
@@ -14,7 +14,15 @@ module GraphQL
|
|
14
14
|
attr_accessor :ast_node
|
15
15
|
# @api private
|
16
16
|
attr_writer :default_directive
|
17
|
-
ensure_defined(:locations, :arguments, :name, :description, :default_directive?)
|
17
|
+
ensure_defined(:locations, :arguments, :graphql_name, :name, :description, :default_directive?)
|
18
|
+
|
19
|
+
# Future-compatible alias
|
20
|
+
# @see {GraphQL::SchemaMember}
|
21
|
+
alias :graphql_name :name
|
22
|
+
|
23
|
+
# Future-compatible alias
|
24
|
+
# @see {GraphQL::SchemaMember}
|
25
|
+
alias :graphql_definition :itself
|
18
26
|
|
19
27
|
LOCATIONS = [
|
20
28
|
QUERY = :QUERY,
|
@@ -84,6 +92,10 @@ module GraphQL
|
|
84
92
|
def default_directive?
|
85
93
|
@default_directive
|
86
94
|
end
|
95
|
+
|
96
|
+
def inspect
|
97
|
+
"#<GraphQL::Directive #{name}>"
|
98
|
+
end
|
87
99
|
end
|
88
100
|
end
|
89
101
|
|
data/lib/graphql/enum_type.rb
CHANGED
@@ -147,6 +147,10 @@ module GraphQL
|
|
147
147
|
GraphQL::NameValidator.validate!(new_name)
|
148
148
|
@name = new_name
|
149
149
|
end
|
150
|
+
|
151
|
+
def graphql_name
|
152
|
+
name
|
153
|
+
end
|
150
154
|
end
|
151
155
|
|
152
156
|
class UnresolvedValueError < GraphQL::Error
|
@@ -165,6 +169,10 @@ module GraphQL
|
|
165
169
|
def coerce_non_null_input(value_name, ctx)
|
166
170
|
if @values_by_name.key?(value_name)
|
167
171
|
@values_by_name.fetch(value_name).value
|
172
|
+
elsif match_by_value = @values_by_name.find { |k, v| v.value == value_name }
|
173
|
+
# this is for matching default values, which are "inputs", but they're
|
174
|
+
# the Ruby value, not the GraphQL string.
|
175
|
+
match_by_value[1].value
|
168
176
|
else
|
169
177
|
nil
|
170
178
|
end
|
@@ -24,6 +24,23 @@ module GraphQL
|
|
24
24
|
GraphQL::Execution::Flatten.call(query.context)
|
25
25
|
end
|
26
26
|
|
27
|
+
def self.begin_multiplex(_multiplex)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.begin_query(query, _multiplex)
|
31
|
+
ExecutionFunctions.resolve_root_selection(query)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.finish_multiplex(results, multiplex)
|
35
|
+
ExecutionFunctions.lazy_resolve_root_selection(results, multiplex: multiplex)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.finish_query(query, _multiplex)
|
39
|
+
{
|
40
|
+
"data" => Execution::Flatten.call(query.context)
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
27
44
|
# @api private
|
28
45
|
module ExecutionFunctions
|
29
46
|
module_function
|
@@ -142,11 +159,11 @@ module GraphQL
|
|
142
159
|
# If the returned object is finished, continue to coerce
|
143
160
|
# and resolve child fields
|
144
161
|
def continue_or_wait(raw_value, field_type, field_ctx)
|
145
|
-
if
|
162
|
+
if field_ctx.schema.lazy?(raw_value)
|
146
163
|
field_ctx.value = Execution::Lazy.new {
|
147
164
|
inner_value = begin
|
148
165
|
begin
|
149
|
-
|
166
|
+
field_ctx.schema.sync_lazy(raw_value)
|
150
167
|
rescue GraphQL::UnauthorizedError => err
|
151
168
|
field_ctx.schema.unauthorized_object(err)
|
152
169
|
end
|
@@ -179,7 +196,7 @@ module GraphQL
|
|
179
196
|
if list_errors.any?
|
180
197
|
list_errors.each do |error, index|
|
181
198
|
error.ast_node = field_ctx.ast_node
|
182
|
-
error.path = field_ctx.path + [index]
|
199
|
+
error.path = field_ctx.path + (field_ctx.type.list? ? [index] : [])
|
183
200
|
query.context.errors.push(error)
|
184
201
|
end
|
185
202
|
end
|
@@ -264,20 +281,22 @@ module GraphQL
|
|
264
281
|
)
|
265
282
|
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
266
283
|
query = field_ctx.query
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
284
|
+
resolved_type_or_lazy = field_type.resolve_type(value, field_ctx)
|
285
|
+
query.schema.after_lazy(resolved_type_or_lazy) do |resolved_type|
|
286
|
+
possible_types = query.possible_types(field_type)
|
287
|
+
|
288
|
+
if !possible_types.include?(resolved_type)
|
289
|
+
parent_type = field_ctx.irep_node.owner_type
|
290
|
+
type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
|
291
|
+
field_ctx.schema.type_error(type_error, field_ctx)
|
292
|
+
PROPAGATE_NULL
|
293
|
+
else
|
294
|
+
resolve_value(
|
295
|
+
value,
|
296
|
+
resolved_type,
|
297
|
+
field_ctx,
|
298
|
+
)
|
299
|
+
end
|
281
300
|
end
|
282
301
|
else
|
283
302
|
raise("Unknown type kind: #{field_type.kind}")
|
@@ -62,6 +62,8 @@ module GraphQL
|
|
62
62
|
# if any before hooks raise an exception, quit calling before hooks,
|
63
63
|
# but call the after hooks on anything that succeeded but also
|
64
64
|
# raise the exception that came from the before hook.
|
65
|
+
rescue GraphQL::ExecutionError => err
|
66
|
+
object.context.errors << err
|
65
67
|
rescue => e
|
66
68
|
raise call_after_hooks(successful, object, after_hook_name, e)
|
67
69
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Execution
|
5
|
+
class Interpreter
|
6
|
+
class ExecutionErrors
|
7
|
+
def initialize(ctx, ast_node, path)
|
8
|
+
@context = ctx
|
9
|
+
@ast_node = ast_node
|
10
|
+
@path = path
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(err_or_msg)
|
14
|
+
err = case err_or_msg
|
15
|
+
when String
|
16
|
+
GraphQL::ExecutionError.new(err_or_msg)
|
17
|
+
when GraphQL::ExecutionError
|
18
|
+
err_or_msg
|
19
|
+
else
|
20
|
+
raise ArgumentError, "expected String or GraphQL::ExecutionError, not #{err_or_msg.class} (#{err_or_msg.inspect})"
|
21
|
+
end
|
22
|
+
err.ast_node ||= @ast_node
|
23
|
+
err.path ||= @path
|
24
|
+
@context.add_error(err)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Execution
|
5
|
+
class Interpreter
|
6
|
+
# This response class handles `#write` by accumulating
|
7
|
+
# values into a Hash.
|
8
|
+
class HashResponse
|
9
|
+
def initialize
|
10
|
+
@result = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def final_value
|
14
|
+
@result
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect
|
18
|
+
"#<#{self.class.name} result=#{@result.inspect}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Add `value` at `path`.
|
22
|
+
# @return [void]
|
23
|
+
def write(path, value)
|
24
|
+
if path.empty?
|
25
|
+
@result = value
|
26
|
+
elsif (write_target = @result)
|
27
|
+
i = 0
|
28
|
+
prefinal_steps = path.size - 1
|
29
|
+
# Use `while` to avoid a closure
|
30
|
+
while i < prefinal_steps
|
31
|
+
path_part = path[i]
|
32
|
+
i += 1
|
33
|
+
write_target = write_target[path_part]
|
34
|
+
end
|
35
|
+
path_part = path[i]
|
36
|
+
write_target[path_part] = value
|
37
|
+
else
|
38
|
+
# The response is completely nulled out
|
39
|
+
end
|
40
|
+
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Execution
|
5
|
+
class Interpreter
|
6
|
+
module Resolve
|
7
|
+
# Continue field results in `results` until there's nothing else to continue.
|
8
|
+
# @return [void]
|
9
|
+
def self.resolve_all(results)
|
10
|
+
while results.any?
|
11
|
+
results = resolve(results)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# After getting `results` back from an interpreter evaluation,
|
16
|
+
# continue it until you get a response-ready Ruby value.
|
17
|
+
#
|
18
|
+
# `results` is one level of _depth_ of a query or multiplex.
|
19
|
+
#
|
20
|
+
# Resolve all lazy values in that depth before moving on
|
21
|
+
# to the next level.
|
22
|
+
#
|
23
|
+
# It's assumed that the lazies will
|
24
|
+
# return {Lazy} instances if there's more work to be done,
|
25
|
+
# or return {Hash}/{Array} if the query should be continued.
|
26
|
+
#
|
27
|
+
# @param results [Array]
|
28
|
+
# @return [Array] Same size, filled with finished values
|
29
|
+
def self.resolve(results)
|
30
|
+
next_results = []
|
31
|
+
|
32
|
+
# Work through the queue until it's empty
|
33
|
+
while results.size > 0
|
34
|
+
result_value = results.shift
|
35
|
+
|
36
|
+
if result_value.is_a?(Lazy)
|
37
|
+
result_value = result_value.value
|
38
|
+
end
|
39
|
+
|
40
|
+
if result_value.is_a?(Lazy)
|
41
|
+
# Since this field returned another lazy,
|
42
|
+
# add it to the same queue
|
43
|
+
results << result_value
|
44
|
+
elsif result_value.is_a?(Hash)
|
45
|
+
# This is part of the next level, add it
|
46
|
+
next_results.concat(result_value.values)
|
47
|
+
elsif result_value.is_a?(Array)
|
48
|
+
# This is part of the next level, add it
|
49
|
+
next_results.concat(result_value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
next_results
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|