graphql 1.10.2 → 2.0.21
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 +4 -4
- data/lib/generators/graphql/core.rb +21 -10
- data/lib/generators/graphql/enum_generator.rb +4 -10
- data/lib/generators/graphql/field_extractor.rb +31 -0
- data/lib/generators/graphql/input_generator.rb +50 -0
- data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
- data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
- data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +45 -8
- 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 +49 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +24 -33
- 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/field_usage.rb +30 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +52 -36
- data/lib/graphql/analysis/ast.rb +7 -8
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +31 -18
- 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 +26 -18
- 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 +164 -0
- data/lib/graphql/dataloader.rb +311 -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/errors.rb +77 -44
- 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 +104 -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.rb +826 -464
- data/lib/graphql/execution/interpreter.rb +206 -68
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +55 -136
- data/lib/graphql/execution/multiplex.rb +6 -162
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +4 -17
- 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 +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +11 -6
- data/lib/graphql/introspection/type_type.rb +31 -14
- data/lib/graphql/introspection.rb +100 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +96 -44
- data/lib/graphql/language/lexer.rb +216 -1462
- data/lib/graphql/language/nodes.rb +126 -129
- data/lib/graphql/language/parser.rb +997 -933
- data/lib/graphql/language/parser.y +148 -118
- data/lib/graphql/language/printer.rb +48 -23
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +192 -84
- data/lib/graphql/language.rb +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
- data/lib/graphql/pagination/array_connection.rb +6 -4
- data/lib/graphql/pagination/connection.rb +105 -23
- data/lib/graphql/pagination/connections.rb +62 -35
- data/lib/graphql/pagination/relation_connection.rb +88 -36
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +203 -198
- 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 +22 -9
- data/lib/graphql/query/validation_pipeline.rb +16 -38
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +36 -12
- data/lib/graphql/query.rb +92 -44
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +41 -10
- 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 +245 -0
- data/lib/graphql/schema/argument.rb +250 -46
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +243 -89
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +108 -20
- data/lib/graphql/schema/enum.rb +105 -44
- data/lib/graphql/schema/enum_value.rb +15 -25
- data/lib/graphql/schema/field/connection_extension.rb +50 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +476 -331
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +6 -8
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +133 -121
- data/lib/graphql/schema/interface.rb +17 -45
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +25 -8
- data/lib/graphql/schema/loader.rb +139 -103
- data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
- data/lib/graphql/schema/member/build_type.rb +19 -14
- data/lib/graphql/schema/member/has_arguments.rb +310 -26
- data/lib/graphql/schema/member/has_ast_node.rb +16 -1
- 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 +164 -42
- data/lib/graphql/schema/member/has_interfaces.rb +129 -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/type_system_helpers.rb +20 -3
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/member.rb +6 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +12 -7
- data/lib/graphql/schema/object.rb +35 -69
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
- data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
- data/lib/graphql/schema/resolver.rb +144 -79
- data/lib/graphql/schema/scalar.rb +27 -18
- data/lib/graphql/schema/subscription.rb +55 -26
- data/lib/graphql/schema/timeout.rb +45 -35
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +48 -13
- 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 +185 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +471 -1116
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +13 -27
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +69 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- 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 +13 -13
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- 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 +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- 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 +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +32 -20
- data/lib/graphql/static_validation.rb +1 -2
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
- 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 +81 -35
- data/lib/graphql/subscriptions/instrumentation.rb +0 -52
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +113 -58
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
- data/lib/graphql/tracing/appoptics_trace.rb +231 -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 +15 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +64 -43
- 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 +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/scout_tracing.rb +11 -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 +23 -71
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +10 -3
- data/lib/graphql/types/iso_8601_date.rb +20 -9
- data/lib/graphql/types/iso_8601_date_time.rb +36 -10
- data/lib/graphql/types/relay/base_connection.rb +18 -92
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +75 -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/unauthorized_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +54 -65
- data/readme.md +3 -6
- metadata +116 -236
- 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 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backwards_compatibility.rb +0 -60
- data/lib/graphql/base_type.rb +0 -230
- 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 -87
- 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 -53
- data/lib/graphql/define/instance_definable.rb +0 -210
- 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 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -127
- data/lib/graphql/execution/execute.rb +0 -326
- 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 -222
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -124
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -132
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -65
- 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 -258
- 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 -71
- data/lib/graphql/object_type.rb +0 -121
- data/lib/graphql/query/arguments.rb +0 -188
- 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 -136
- 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 -176
- 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 -41
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- 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 -105
- 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 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -76
- 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 -31
- data/lib/graphql/schema/member/instrumentation.rb +0 -132
- 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 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -86
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -303
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -65
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- 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 -113
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,91 +1,229 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "fiber"
|
3
|
+
require "graphql/execution/interpreter/argument_value"
|
4
|
+
require "graphql/execution/interpreter/arguments"
|
5
|
+
require "graphql/execution/interpreter/arguments_cache"
|
2
6
|
require "graphql/execution/interpreter/execution_errors"
|
3
|
-
require "graphql/execution/interpreter/hash_response"
|
4
7
|
require "graphql/execution/interpreter/runtime"
|
5
8
|
require "graphql/execution/interpreter/resolve"
|
9
|
+
require "graphql/execution/interpreter/handles_raw_value"
|
6
10
|
|
7
11
|
module GraphQL
|
8
12
|
module Execution
|
9
13
|
class Interpreter
|
10
|
-
|
11
|
-
|
14
|
+
class << self
|
15
|
+
# Used internally to signal that the query shouldn't be executed
|
16
|
+
# @api private
|
17
|
+
NO_OPERATION = GraphQL::EmptyObjects::EMPTY_HASH
|
12
18
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
# @param schema [GraphQL::Schema]
|
20
|
+
# @param queries [Array<GraphQL::Query, Hash>]
|
21
|
+
# @param context [Hash]
|
22
|
+
# @param max_complexity [Integer, nil]
|
23
|
+
# @return [Array<Hash>] One result per query
|
24
|
+
def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
|
25
|
+
queries = query_options.map do |opts|
|
26
|
+
case opts
|
27
|
+
when Hash
|
28
|
+
GraphQL::Query.new(schema, nil, **opts)
|
29
|
+
when GraphQL::Query
|
30
|
+
opts
|
31
|
+
else
|
32
|
+
raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
|
33
|
+
end
|
34
|
+
end
|
19
35
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
36
|
+
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
37
|
+
multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
|
38
|
+
schema = multiplex.schema
|
39
|
+
queries = multiplex.queries
|
40
|
+
query_instrumenters = schema.instrumenters[:query]
|
41
|
+
multiplex_instrumenters = schema.instrumenters[:multiplex]
|
42
|
+
lazies_at_depth = Hash.new { |h, k| h[k] = [] }
|
26
43
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
44
|
+
# First, run multiplex instrumentation, then query instrumentation for each query
|
45
|
+
call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
|
46
|
+
each_query_call_hooks(query_instrumenters, queries) do
|
47
|
+
schema = multiplex.schema
|
48
|
+
multiplex_analyzers = schema.multiplex_analyzers
|
49
|
+
queries = multiplex.queries
|
50
|
+
if multiplex.max_complexity
|
51
|
+
multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
|
52
|
+
end
|
32
53
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
54
|
+
schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
|
55
|
+
begin
|
56
|
+
# Since this is basically the batching context,
|
57
|
+
# share it for a whole multiplex
|
58
|
+
multiplex.context[:interpreter_instance] ||= multiplex.schema.query_execution_strategy.new
|
59
|
+
# Do as much eager evaluation of the query as possible
|
60
|
+
results = []
|
61
|
+
queries.each_with_index do |query, idx|
|
62
|
+
multiplex.dataloader.append_job {
|
63
|
+
operation = query.selected_operation
|
64
|
+
result = if operation.nil? || !query.valid? || query.context.errors.any?
|
65
|
+
NO_OPERATION
|
66
|
+
else
|
67
|
+
begin
|
68
|
+
# Although queries in a multiplex _share_ an Interpreter instance,
|
69
|
+
# they also have another item of state, which is private to that query
|
70
|
+
# in particular, assign it here:
|
71
|
+
runtime = Runtime.new(query: query, lazies_at_depth: lazies_at_depth)
|
72
|
+
query.context.namespace(:interpreter_runtime)[:runtime] = runtime
|
42
73
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
74
|
+
query.current_trace.execute_query(query: query) do
|
75
|
+
runtime.run_eager
|
76
|
+
end
|
77
|
+
rescue GraphQL::ExecutionError => err
|
78
|
+
query.context.errors << err
|
79
|
+
NO_OPERATION
|
80
|
+
end
|
81
|
+
end
|
82
|
+
results[idx] = result
|
83
|
+
}
|
84
|
+
end
|
47
85
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
86
|
+
multiplex.dataloader.run
|
87
|
+
|
88
|
+
# Then, work through lazy results in a breadth-first way
|
89
|
+
multiplex.dataloader.append_job {
|
90
|
+
tracer = multiplex
|
91
|
+
query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
|
92
|
+
queries = multiplex ? multiplex.queries : [query]
|
93
|
+
final_values = queries.map do |query|
|
94
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
95
|
+
# it might not be present if the query has an error
|
96
|
+
runtime ? runtime.final_result : nil
|
97
|
+
end
|
98
|
+
final_values.compact!
|
99
|
+
tracer.current_trace.execute_query_lazy(multiplex: multiplex, query: query) do
|
100
|
+
Interpreter::Resolve.resolve_each_depth(lazies_at_depth, multiplex.dataloader)
|
101
|
+
end
|
102
|
+
queries.each do |query|
|
103
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
104
|
+
if runtime
|
105
|
+
runtime.delete_all_interpreter_context
|
106
|
+
end
|
107
|
+
end
|
108
|
+
}
|
109
|
+
multiplex.dataloader.run
|
110
|
+
|
111
|
+
# Then, find all errors and assign the result to the query object
|
112
|
+
results.each_with_index do |data_result, idx|
|
113
|
+
query = queries[idx]
|
114
|
+
# Assign the result so that it can be accessed in instrumentation
|
115
|
+
query.result_values = if data_result.equal?(NO_OPERATION)
|
116
|
+
if !query.valid? || query.context.errors.any?
|
117
|
+
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
118
|
+
{ "errors" => query.static_errors.map(&:to_h) }
|
119
|
+
else
|
120
|
+
data_result
|
121
|
+
end
|
122
|
+
else
|
123
|
+
result = {
|
124
|
+
"data" => query.context.namespace(:interpreter_runtime)[:runtime].final_result
|
125
|
+
}
|
126
|
+
|
127
|
+
if query.context.errors.any?
|
128
|
+
error_result = query.context.errors.map(&:to_h)
|
129
|
+
result["errors"] = error_result
|
130
|
+
end
|
131
|
+
|
132
|
+
result
|
133
|
+
end
|
134
|
+
if query.context.namespace?(:__query_result_extensions__)
|
135
|
+
query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
|
136
|
+
end
|
137
|
+
# Get the Query::Result, not the Hash
|
138
|
+
results[idx] = query.result
|
139
|
+
end
|
53
140
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
141
|
+
results
|
142
|
+
rescue Exception
|
143
|
+
# TODO rescue at a higher level so it will catch errors in analysis, too
|
144
|
+
# Assign values here so that the query's `@executed` becomes true
|
145
|
+
queries.map { |q| q.result_values ||= {} }
|
146
|
+
raise
|
147
|
+
ensure
|
148
|
+
queries.map { |query|
|
149
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
150
|
+
if runtime
|
151
|
+
runtime.delete_all_interpreter_context
|
152
|
+
end
|
153
|
+
}
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
68
158
|
end
|
69
159
|
|
70
|
-
|
71
|
-
|
160
|
+
private
|
161
|
+
|
162
|
+
# Call the before_ hooks of each query,
|
163
|
+
# Then yield if no errors.
|
164
|
+
# `call_hooks` takes care of appropriate cleanup.
|
165
|
+
def each_query_call_hooks(instrumenters, queries, i = 0)
|
166
|
+
if i >= queries.length
|
167
|
+
yield
|
168
|
+
else
|
169
|
+
query = queries[i]
|
170
|
+
call_hooks(instrumenters, query, :before_query, :after_query) {
|
171
|
+
each_query_call_hooks(instrumenters, queries, i + 1) {
|
172
|
+
yield
|
173
|
+
}
|
174
|
+
}
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Call each before hook, and if they all succeed, yield.
|
179
|
+
# If they don't all succeed, call after_ for each one that succeeded.
|
180
|
+
def call_hooks(instrumenters, object, before_hook_name, after_hook_name)
|
181
|
+
begin
|
182
|
+
successful = []
|
183
|
+
instrumenters.each do |instrumenter|
|
184
|
+
instrumenter.public_send(before_hook_name, object)
|
185
|
+
successful << instrumenter
|
186
|
+
end
|
187
|
+
|
188
|
+
# if any before hooks raise an exception, quit calling before hooks,
|
189
|
+
# but call the after hooks on anything that succeeded but also
|
190
|
+
# raise the exception that came from the before hook.
|
191
|
+
rescue GraphQL::ExecutionError => err
|
192
|
+
object.context.errors << err
|
193
|
+
rescue => e
|
194
|
+
raise call_after_hooks(successful, object, after_hook_name, e)
|
195
|
+
end
|
72
196
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
197
|
+
begin
|
198
|
+
yield # Call the user code
|
199
|
+
ensure
|
200
|
+
ex = call_after_hooks(successful, object, after_hook_name, nil)
|
201
|
+
raise ex if ex
|
202
|
+
end
|
79
203
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
204
|
+
|
205
|
+
def call_after_hooks(instrumenters, object, after_hook_name, ex)
|
206
|
+
instrumenters.reverse_each do |instrumenter|
|
207
|
+
begin
|
208
|
+
instrumenter.public_send(after_hook_name, object)
|
209
|
+
rescue => e
|
210
|
+
ex = e
|
211
|
+
end
|
212
|
+
end
|
213
|
+
ex
|
85
214
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
215
|
+
end
|
216
|
+
|
217
|
+
class ListResultFailedError < GraphQL::Error
|
218
|
+
def initialize(value:, path:, field:)
|
219
|
+
message = "Failed to build a GraphQL list result for field `#{field.path}` at path `#{path.join(".")}`.\n".dup
|
220
|
+
|
221
|
+
message << "Expected `#{value.inspect}` (#{value.class}) to implement `.each` to satisfy the GraphQL return type `#{field.type.to_type_signature}`.\n"
|
222
|
+
|
223
|
+
if field.connection?
|
224
|
+
message << "\nThis field was treated as a Relay-style connection; add `connection: false` to the `field(...)` to disable this behavior."
|
225
|
+
end
|
226
|
+
super(message)
|
89
227
|
end
|
90
228
|
end
|
91
229
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/execution/lazy/lazy_method_map"
|
3
|
-
require "graphql/execution/lazy/resolve"
|
4
3
|
|
5
4
|
module GraphQL
|
6
5
|
module Execution
|
@@ -13,23 +12,14 @@ module GraphQL
|
|
13
12
|
# - It has no error-catching functionality
|
14
13
|
# @api private
|
15
14
|
class Lazy
|
16
|
-
|
17
|
-
# @param val [Object] A data structure containing mixed plain values and `Lazy` instances
|
18
|
-
# @return void
|
19
|
-
def self.resolve(val)
|
20
|
-
Resolve.resolve(val)
|
21
|
-
end
|
22
|
-
|
23
|
-
attr_reader :path, :field
|
15
|
+
attr_reader :field
|
24
16
|
|
25
17
|
# Create a {Lazy} which will get its inner value by calling the block
|
26
|
-
# @param path [Array<String, Integer>]
|
27
18
|
# @param field [GraphQL::Schema::Field]
|
28
19
|
# @param get_value_func [Proc] a block to get the inner value (later)
|
29
|
-
def initialize(
|
20
|
+
def initialize(field: nil, &get_value_func)
|
30
21
|
@get_value_func = get_value_func
|
31
22
|
@resolved = false
|
32
|
-
@path = path
|
33
23
|
@field = field
|
34
24
|
end
|
35
25
|
|
@@ -37,18 +27,18 @@ module GraphQL
|
|
37
27
|
def value
|
38
28
|
if !@resolved
|
39
29
|
@resolved = true
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
v = v.value
|
44
|
-
end
|
45
|
-
v
|
46
|
-
rescue GraphQL::ExecutionError => err
|
47
|
-
err
|
30
|
+
v = @get_value_func.call
|
31
|
+
if v.is_a?(Lazy)
|
32
|
+
v = v.value
|
48
33
|
end
|
34
|
+
@value = v
|
49
35
|
end
|
50
36
|
|
51
|
-
|
37
|
+
# `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
|
38
|
+
# (fewer clauses in a hot `case` block), but now it requires special handling here.
|
39
|
+
# I think it's still worth it for the performance win, but if the number of special
|
40
|
+
# cases grows, then maybe it's worth rethinking somehow.
|
41
|
+
if @value.is_a?(StandardError) && @value != GraphQL::Execution::SKIP
|
52
42
|
raise @value
|
53
43
|
else
|
54
44
|
@value
|
@@ -51,7 +51,17 @@ module GraphQL
|
|
51
51
|
|
52
52
|
# @return [Hash<Symbol, Object>]
|
53
53
|
def arguments
|
54
|
-
|
54
|
+
if defined?(@arguments)
|
55
|
+
@arguments
|
56
|
+
else
|
57
|
+
@arguments = if @field
|
58
|
+
@query.schema.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
|
59
|
+
args.is_a?(Execution::Interpreter::Arguments) ? args.keyword_arguments : args
|
60
|
+
end
|
61
|
+
else
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
# True if this node has a selection on `field_name`.
|
@@ -66,8 +76,8 @@ module GraphQL
|
|
66
76
|
# @param field_name [String, Symbol]
|
67
77
|
# @param arguments [Hash] Arguments which must match in the selection
|
68
78
|
# @return [Boolean]
|
69
|
-
def selects?(field_name, arguments: nil)
|
70
|
-
selection(field_name, arguments: arguments).selected?
|
79
|
+
def selects?(field_name, selected_type: @selected_type, arguments: nil)
|
80
|
+
selection(field_name, selected_type: selected_type, arguments: arguments).selected?
|
71
81
|
end
|
72
82
|
|
73
83
|
# @return [Boolean] True if this lookahead represents a field that was requested
|
@@ -77,16 +87,39 @@ module GraphQL
|
|
77
87
|
|
78
88
|
# Like {#selects?}, but can be used for chaining.
|
79
89
|
# It returns a null object (check with {#selected?})
|
90
|
+
# @param field_name [String, Symbol]
|
80
91
|
# @return [GraphQL::Execution::Lookahead]
|
81
92
|
def selection(field_name, selected_type: @selected_type, arguments: nil)
|
82
|
-
|
93
|
+
next_field_defn = case field_name
|
94
|
+
when String
|
95
|
+
@query.get_field(selected_type, field_name)
|
96
|
+
when Symbol
|
97
|
+
# Try to avoid the `.to_s` below, if possible
|
98
|
+
all_fields = if selected_type.kind.fields?
|
99
|
+
@query.warden.fields(selected_type)
|
100
|
+
else
|
101
|
+
# Handle unions by checking possible
|
102
|
+
@query.warden
|
103
|
+
.possible_types(selected_type)
|
104
|
+
.map { |t| @query.warden.fields(t) }
|
105
|
+
.flatten
|
106
|
+
end
|
107
|
+
|
108
|
+
if (match_by_orig_name = all_fields.find { |f| f.original_name == field_name })
|
109
|
+
match_by_orig_name
|
110
|
+
else
|
111
|
+
# Symbol#name is only present on 3.0+
|
112
|
+
sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
|
113
|
+
guessed_name = Schema::Member::BuildType.camelize(sym_s)
|
114
|
+
@query.get_field(selected_type, guessed_name)
|
115
|
+
end
|
116
|
+
end
|
83
117
|
|
84
|
-
next_field_defn = FieldHelpers.get_field(@query.schema, selected_type, next_field_name)
|
85
118
|
if next_field_defn
|
86
119
|
next_nodes = []
|
87
120
|
@ast_nodes.each do |ast_node|
|
88
121
|
ast_node.selections.each do |selection|
|
89
|
-
find_selected_nodes(selection,
|
122
|
+
find_selected_nodes(selection, next_field_defn, arguments: arguments, matches: next_nodes)
|
90
123
|
end
|
91
124
|
end
|
92
125
|
|
@@ -127,7 +160,7 @@ module GraphQL
|
|
127
160
|
|
128
161
|
subselections_by_type.each do |type, ast_nodes_by_response_key|
|
129
162
|
ast_nodes_by_response_key.each do |response_key, ast_nodes|
|
130
|
-
field_defn =
|
163
|
+
field_defn = @query.get_field(type, ast_nodes.first.name)
|
131
164
|
lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
|
132
165
|
subselections.push(lookahead)
|
133
166
|
end
|
@@ -186,29 +219,12 @@ module GraphQL
|
|
186
219
|
|
187
220
|
private
|
188
221
|
|
189
|
-
# If it's a symbol, stringify and camelize it
|
190
|
-
def normalize_name(name)
|
191
|
-
if name.is_a?(Symbol)
|
192
|
-
Schema::Member::BuildType.camelize(name.to_s)
|
193
|
-
else
|
194
|
-
name
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
def normalize_keyword(keyword)
|
199
|
-
if keyword.is_a?(String)
|
200
|
-
Schema::Member::BuildType.underscore(keyword).to_sym
|
201
|
-
else
|
202
|
-
keyword
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
222
|
def skipped_by_directive?(ast_selection)
|
207
223
|
ast_selection.directives.each do |directive|
|
208
224
|
dir_defn = @query.schema.directives.fetch(directive.name)
|
209
|
-
directive_class = dir_defn
|
225
|
+
directive_class = dir_defn
|
210
226
|
if directive_class
|
211
|
-
dir_args =
|
227
|
+
dir_args = @query.arguments_for(directive, dir_defn)
|
212
228
|
return true unless directive_class.static_include?(dir_args, @query.context)
|
213
229
|
end
|
214
230
|
end
|
@@ -227,7 +243,7 @@ module GraphQL
|
|
227
243
|
elsif arguments.nil? || arguments.empty?
|
228
244
|
selections_on_type[response_key] = [ast_selection]
|
229
245
|
else
|
230
|
-
field_defn =
|
246
|
+
field_defn = @query.get_field(selected_type, ast_selection.name)
|
231
247
|
if arguments_match?(arguments, field_defn, ast_selection)
|
232
248
|
selections_on_type[response_key] = [ast_selection]
|
233
249
|
end
|
@@ -237,14 +253,14 @@ module GraphQL
|
|
237
253
|
subselections_on_type = selections_on_type
|
238
254
|
if (t = ast_selection.type)
|
239
255
|
# Assuming this is valid, that `t` will be found.
|
240
|
-
on_type = @query.
|
256
|
+
on_type = @query.get_type(t.name)
|
241
257
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
242
258
|
end
|
243
259
|
find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
|
244
260
|
when GraphQL::Language::Nodes::FragmentSpread
|
245
261
|
frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
|
246
262
|
# Again, assuming a valid AST
|
247
|
-
on_type = @query.
|
263
|
+
on_type = @query.get_type(frag_defn.type.name)
|
248
264
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
249
265
|
find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
|
250
266
|
else
|
@@ -255,11 +271,11 @@ module GraphQL
|
|
255
271
|
|
256
272
|
# If a selection on `node` matches `field_name` (which is backed by `field_defn`)
|
257
273
|
# and matches the `arguments:` constraints, then add that node to `matches`
|
258
|
-
def find_selected_nodes(node,
|
274
|
+
def find_selected_nodes(node, field_defn, arguments:, matches:)
|
259
275
|
return if skipped_by_directive?(node)
|
260
276
|
case node
|
261
277
|
when GraphQL::Language::Nodes::Field
|
262
|
-
if node.name ==
|
278
|
+
if node.name == field_defn.graphql_name
|
263
279
|
if arguments.nil? || arguments.empty?
|
264
280
|
# No constraint applied
|
265
281
|
matches << node
|
@@ -268,123 +284,26 @@ module GraphQL
|
|
268
284
|
end
|
269
285
|
end
|
270
286
|
when GraphQL::Language::Nodes::InlineFragment
|
271
|
-
node.selections.each { |s| find_selected_nodes(s,
|
287
|
+
node.selections.each { |s| find_selected_nodes(s, field_defn, arguments: arguments, matches: matches) }
|
272
288
|
when GraphQL::Language::Nodes::FragmentSpread
|
273
289
|
frag_defn = @query.fragments[node.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})")
|
274
|
-
frag_defn.selections.each { |s| find_selected_nodes(s,
|
290
|
+
frag_defn.selections.each { |s| find_selected_nodes(s, field_defn, arguments: arguments, matches: matches) }
|
275
291
|
else
|
276
292
|
raise "Unexpected selection comparison on #{node.class.name} (#{node})"
|
277
293
|
end
|
278
294
|
end
|
279
295
|
|
280
296
|
def arguments_match?(arguments, field_defn, field_node)
|
281
|
-
query_kwargs =
|
297
|
+
query_kwargs = @query.arguments_for(field_node, field_defn)
|
282
298
|
arguments.all? do |arg_name, arg_value|
|
283
|
-
|
284
|
-
|
285
|
-
query_kwargs.key?(arg_name) && query_kwargs[arg_name] == arg_value
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
|
-
# TODO Dedup with interpreter
|
290
|
-
module ArgumentHelpers
|
291
|
-
module_function
|
292
|
-
|
293
|
-
def arguments(query, arg_owner, ast_node)
|
294
|
-
kwarg_arguments = {}
|
295
|
-
arg_defns = arg_owner.arguments
|
296
|
-
ast_node.arguments.each do |arg|
|
297
|
-
arg_defn = arg_defns[arg.name] || raise("Invariant: missing argument definition for #{arg.name.inspect} in #{arg_defns.keys} from #{arg_owner}")
|
298
|
-
# Need to distinguish between client-provided `nil`
|
299
|
-
# and nothing-at-all
|
300
|
-
is_present, value = arg_to_value(query, arg_defn.type, arg.value)
|
301
|
-
if is_present
|
302
|
-
kwarg_arguments[arg_defn.keyword] = value
|
303
|
-
end
|
304
|
-
end
|
305
|
-
arg_defns.each do |name, arg_defn|
|
306
|
-
if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
|
307
|
-
kwarg_arguments[arg_defn.keyword] = arg_defn.default_value
|
308
|
-
end
|
309
|
-
end
|
310
|
-
kwarg_arguments
|
311
|
-
end
|
312
|
-
|
313
|
-
# Get a Ruby-ready value from a client query.
|
314
|
-
# @param graphql_object [Object] The owner of the field whose argument this is
|
315
|
-
# @param arg_type [Class, GraphQL::Schema::NonNull, GraphQL::Schema::List]
|
316
|
-
# @param ast_value [GraphQL::Language::Nodes::VariableIdentifier, String, Integer, Float, Boolean]
|
317
|
-
# @return [Array(is_present, value)]
|
318
|
-
def arg_to_value(query, arg_type, ast_value)
|
319
|
-
if ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
320
|
-
# If it's not here, it will get added later
|
321
|
-
if query.variables.key?(ast_value.name)
|
322
|
-
return true, query.variables[ast_value.name]
|
323
|
-
else
|
324
|
-
return false, nil
|
325
|
-
end
|
326
|
-
elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
|
327
|
-
return true, nil
|
328
|
-
elsif arg_type.is_a?(GraphQL::Schema::NonNull)
|
329
|
-
arg_to_value(query, arg_type.of_type, ast_value)
|
330
|
-
elsif arg_type.is_a?(GraphQL::Schema::List)
|
331
|
-
# Treat a single value like a list
|
332
|
-
arg_value = Array(ast_value)
|
333
|
-
list = []
|
334
|
-
arg_value.map do |inner_v|
|
335
|
-
_present, value = arg_to_value(query, arg_type.of_type, inner_v)
|
336
|
-
list << value
|
337
|
-
end
|
338
|
-
return true, list
|
339
|
-
elsif arg_type.is_a?(Class) && arg_type < GraphQL::Schema::InputObject
|
340
|
-
# For these, `prepare` is applied during `#initialize`.
|
341
|
-
# Pass `nil` so it will be skipped in `#arguments`.
|
342
|
-
# What a mess.
|
343
|
-
args = arguments(query, nil, arg_type, ast_value)
|
344
|
-
# We're not tracking defaults_used, but for our purposes
|
345
|
-
# we compare the value to the default value.
|
346
|
-
return true, arg_type.new(ruby_kwargs: args, context: query.context, defaults_used: nil)
|
347
|
-
else
|
348
|
-
flat_value = flatten_ast_value(query, ast_value)
|
349
|
-
return true, arg_type.coerce_input(flat_value, query.context)
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
def flatten_ast_value(query, v)
|
354
|
-
case v
|
355
|
-
when GraphQL::Language::Nodes::Enum
|
356
|
-
v.name
|
357
|
-
when GraphQL::Language::Nodes::InputObject
|
358
|
-
h = {}
|
359
|
-
v.arguments.each do |arg|
|
360
|
-
h[arg.name] = flatten_ast_value(query, arg.value)
|
361
|
-
end
|
362
|
-
h
|
363
|
-
when Array
|
364
|
-
v.map { |v2| flatten_ast_value(query, v2) }
|
365
|
-
when GraphQL::Language::Nodes::VariableIdentifier
|
366
|
-
flatten_ast_value(query.variables[v.name])
|
367
|
-
else
|
368
|
-
v
|
369
|
-
end
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
# TODO dedup with interpreter
|
374
|
-
module FieldHelpers
|
375
|
-
module_function
|
376
|
-
|
377
|
-
def get_field(schema, owner_type, field_name)
|
378
|
-
field_defn = owner_type.get_field(field_name)
|
379
|
-
field_defn ||= if owner_type == schema.query.type_class && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
|
380
|
-
entry_point_field.type_class
|
381
|
-
elsif (dynamic_field = schema.introspection_system.dynamic_field(name: field_name))
|
382
|
-
dynamic_field.type_class
|
299
|
+
arg_name_sym = if arg_name.is_a?(String)
|
300
|
+
Schema::Member::BuildType.underscore(arg_name).to_sym
|
383
301
|
else
|
384
|
-
|
302
|
+
arg_name
|
385
303
|
end
|
386
304
|
|
387
|
-
|
305
|
+
# Make sure the constraint is present with a matching value
|
306
|
+
query_kwargs.key?(arg_name_sym) && query_kwargs[arg_name_sym] == arg_value
|
388
307
|
end
|
389
308
|
end
|
390
309
|
end
|