graphql 1.9.21 → 2.0.16
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 +25 -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/field_usage.rb +31 -2
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +17 -8
- data/lib/graphql/analysis/ast.rb +14 -14
- 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/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +39 -9
- data/lib/graphql/backtrace.rb +20 -17
- 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/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +77 -45
- 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 +44 -25
- data/lib/graphql/execution/interpreter/runtime.rb +755 -395
- data/lib/graphql/execution/interpreter.rb +201 -74
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +5 -9
- data/lib/graphql/execution/lookahead.rb +65 -136
- data/lib/graphql/execution/multiplex.rb +5 -152
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -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 +11 -5
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +5 -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 -11
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +10 -10
- 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 +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +104 -68
- data/lib/graphql/language/lexer.rb +83 -40
- data/lib/graphql/language/lexer.rl +31 -9
- data/lib/graphql/language/nodes.rb +64 -93
- data/lib/graphql/language/parser.rb +940 -896
- data/lib/graphql/language/parser.y +130 -103
- 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 +2 -2
- data/lib/graphql/language.rb +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
- data/lib/graphql/pagination/array_connection.rb +79 -0
- data/lib/graphql/pagination/connection.rb +253 -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.rb +172 -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 +21 -8
- 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 +39 -12
- data/lib/graphql/query.rb +74 -38
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +4 -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 +286 -31
- 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 +334 -220
- 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 +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +2 -2
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/skip.rb +2 -2
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +117 -14
- data/lib/graphql/schema/enum.rb +113 -22
- data/lib/graphql/schema/enum_value.rb +16 -21
- data/lib/graphql/schema/field/connection_extension.rb +50 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +491 -329
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +17 -1
- data/lib/graphql/schema/finder.rb +16 -14
- data/lib/graphql/schema/input_object.rb +182 -60
- data/lib/graphql/schema/interface.rb +28 -43
- data/lib/graphql/schema/introspection_system.rb +101 -38
- data/lib/graphql/schema/late_bound_type.rb +7 -2
- data/lib/graphql/schema/list.rb +61 -3
- data/lib/graphql/schema/loader.rb +144 -102
- data/lib/graphql/schema/member/base_dsl_methods.rb +33 -32
- data/lib/graphql/schema/member/build_type.rb +24 -15
- data/lib/graphql/schema/member/has_arguments.rb +261 -24
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +113 -0
- data/lib/graphql/schema/member/has_fields.rb +99 -34
- data/lib/graphql/schema/member/has_interfaces.rb +88 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/member/has_validators.rb +31 -0
- data/lib/graphql/schema/member/relay_shortcuts.rb +28 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
- data/lib/graphql/schema/member/validates_input.rb +33 -0
- data/lib/graphql/schema/member.rb +11 -6
- data/lib/graphql/schema/mutation.rb +4 -9
- data/lib/graphql/schema/non_null.rb +34 -4
- data/lib/graphql/schema/object.rb +38 -60
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
- data/lib/graphql/schema/resolver/has_payload_type.rb +46 -6
- data/lib/graphql/schema/resolver.rb +146 -93
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +55 -26
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +22 -5
- data/lib/graphql/schema/union.rb +48 -14
- 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 +187 -33
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +773 -892
- data/lib/graphql/static_validation/all_rules.rb +3 -0
- data/lib/graphql/static_validation/base_visitor.rb +21 -31
- 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 +55 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +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 +5 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/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 +9 -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/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +31 -19
- 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 +129 -22
- 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 +85 -31
- data/lib/graphql/subscriptions/instrumentation.rb +0 -47
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions.rb +137 -57
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +34 -2
- data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/tracing/platform_tracing.rb +67 -38
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
- data/lib/graphql/tracing/scout_tracing.rb +19 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +15 -36
- 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 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +158 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +65 -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 +19 -0
- data/lib/graphql/types/relay/page_info.rb +2 -14
- data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
- data/lib/graphql/types/relay.rb +11 -5
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +41 -58
- data/readme.md +3 -6
- metadata +103 -237
- 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 -159
- 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 -53
- data/lib/graphql/define/instance_definable.rb +0 -311
- 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 -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 -330
- 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 -154
- 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/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 -187
- 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 -116
- 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 -190
- data/lib/graphql/relay/type_extensions.rb +0 -30
- data/lib/graphql/scalar_type.rb +0 -133
- 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 -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 -74
- data/lib/graphql/tracing/skylight_tracing.rb +0 -62
- 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 -135
- data/lib/graphql/upgrader/member.rb +0 -936
- data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,97 +1,224 @@
|
|
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 = {}.freeze
|
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
|
-
|
26
|
-
[schema_class, schema_defn].each do |schema_config|
|
27
|
-
schema_config.query_execution_strategy(GraphQL::Execution::Interpreter)
|
28
|
-
schema_config.mutation_execution_strategy(GraphQL::Execution::Interpreter)
|
29
|
-
schema_config.subscription_execution_strategy(GraphQL::Execution::Interpreter)
|
30
|
-
end
|
31
|
-
end
|
36
|
+
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
37
|
+
multiplex.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]
|
32
42
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
43
|
+
# First, run multiplex instrumentation, then query instrumentation for each query
|
44
|
+
call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
|
45
|
+
each_query_call_hooks(query_instrumenters, queries) do
|
46
|
+
schema = multiplex.schema
|
47
|
+
multiplex_analyzers = schema.multiplex_analyzers
|
48
|
+
queries = multiplex.queries
|
49
|
+
if multiplex.max_complexity
|
50
|
+
multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
|
51
|
+
end
|
38
52
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
53
|
+
schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
|
54
|
+
begin
|
55
|
+
# Since this is basically the batching context,
|
56
|
+
# share it for a whole multiplex
|
57
|
+
multiplex.context[:interpreter_instance] ||= multiplex.schema.query_execution_strategy.new
|
58
|
+
# Do as much eager evaluation of the query as possible
|
59
|
+
results = []
|
60
|
+
queries.each_with_index do |query, idx|
|
61
|
+
multiplex.dataloader.append_job {
|
62
|
+
operation = query.selected_operation
|
63
|
+
result = if operation.nil? || !query.valid? || query.context.errors.any?
|
64
|
+
NO_OPERATION
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
# Although queries in a multiplex _share_ an Interpreter instance,
|
68
|
+
# they also have another item of state, which is private to that query
|
69
|
+
# in particular, assign it here:
|
70
|
+
runtime = Runtime.new(query: query)
|
71
|
+
query.context.namespace(:interpreter_runtime)[:runtime] = runtime
|
48
72
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
73
|
+
query.trace("execute_query", {query: query}) do
|
74
|
+
runtime.run_eager
|
75
|
+
end
|
76
|
+
rescue GraphQL::ExecutionError => err
|
77
|
+
query.context.errors << err
|
78
|
+
NO_OPERATION
|
79
|
+
end
|
80
|
+
end
|
81
|
+
results[idx] = result
|
82
|
+
}
|
83
|
+
end
|
53
84
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
85
|
+
multiplex.dataloader.run
|
86
|
+
|
87
|
+
# Then, work through lazy results in a breadth-first way
|
88
|
+
multiplex.dataloader.append_job {
|
89
|
+
tracer = multiplex
|
90
|
+
query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
|
91
|
+
queries = multiplex ? multiplex.queries : [query]
|
92
|
+
final_values = queries.map do |query|
|
93
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
94
|
+
# it might not be present if the query has an error
|
95
|
+
runtime ? runtime.final_result : nil
|
96
|
+
end
|
97
|
+
final_values.compact!
|
98
|
+
tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
|
99
|
+
Interpreter::Resolve.resolve_all(final_values, multiplex.dataloader)
|
100
|
+
end
|
101
|
+
queries.each do |query|
|
102
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
103
|
+
if runtime
|
104
|
+
runtime.delete_interpreter_context(:current_path)
|
105
|
+
runtime.delete_interpreter_context(:current_field)
|
106
|
+
runtime.delete_interpreter_context(:current_object)
|
107
|
+
runtime.delete_interpreter_context(:current_arguments)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
}
|
111
|
+
multiplex.dataloader.run
|
112
|
+
|
113
|
+
# Then, find all errors and assign the result to the query object
|
114
|
+
results.each_with_index do |data_result, idx|
|
115
|
+
query = queries[idx]
|
116
|
+
# Assign the result so that it can be accessed in instrumentation
|
117
|
+
query.result_values = if data_result.equal?(NO_OPERATION)
|
118
|
+
if !query.valid? || query.context.errors.any?
|
119
|
+
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
120
|
+
{ "errors" => query.static_errors.map(&:to_h) }
|
121
|
+
else
|
122
|
+
data_result
|
123
|
+
end
|
124
|
+
else
|
125
|
+
result = {
|
126
|
+
"data" => query.context.namespace(:interpreter_runtime)[:runtime].final_result
|
127
|
+
}
|
128
|
+
|
129
|
+
if query.context.errors.any?
|
130
|
+
error_result = query.context.errors.map(&:to_h)
|
131
|
+
result["errors"] = error_result
|
132
|
+
end
|
59
133
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
134
|
+
result
|
135
|
+
end
|
136
|
+
if query.context.namespace?(:__query_result_extensions__)
|
137
|
+
query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
|
138
|
+
end
|
139
|
+
# Get the Query::Result, not the Hash
|
140
|
+
results[idx] = query.result
|
141
|
+
end
|
142
|
+
|
143
|
+
results
|
144
|
+
rescue Exception
|
145
|
+
# TODO rescue at a higher level so it will catch errors in analysis, too
|
146
|
+
# Assign values here so that the query's `@executed` becomes true
|
147
|
+
queries.map { |q| q.result_values ||= {} }
|
148
|
+
raise
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
74
153
|
end
|
75
154
|
|
76
|
-
|
77
|
-
end
|
155
|
+
private
|
78
156
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
157
|
+
# Call the before_ hooks of each query,
|
158
|
+
# Then yield if no errors.
|
159
|
+
# `call_hooks` takes care of appropriate cleanup.
|
160
|
+
def each_query_call_hooks(instrumenters, queries, i = 0)
|
161
|
+
if i >= queries.length
|
162
|
+
yield
|
163
|
+
else
|
164
|
+
query = queries[i]
|
165
|
+
call_hooks(instrumenters, query, :before_query, :after_query) {
|
166
|
+
each_query_call_hooks(instrumenters, queries, i + 1) {
|
167
|
+
yield
|
168
|
+
}
|
169
|
+
}
|
170
|
+
end
|
85
171
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
172
|
+
|
173
|
+
# Call each before hook, and if they all succeed, yield.
|
174
|
+
# If they don't all succeed, call after_ for each one that succeeded.
|
175
|
+
def call_hooks(instrumenters, object, before_hook_name, after_hook_name)
|
176
|
+
begin
|
177
|
+
successful = []
|
178
|
+
instrumenters.each do |instrumenter|
|
179
|
+
instrumenter.public_send(before_hook_name, object)
|
180
|
+
successful << instrumenter
|
181
|
+
end
|
182
|
+
|
183
|
+
# if any before hooks raise an exception, quit calling before hooks,
|
184
|
+
# but call the after hooks on anything that succeeded but also
|
185
|
+
# raise the exception that came from the before hook.
|
186
|
+
rescue GraphQL::ExecutionError => err
|
187
|
+
object.context.errors << err
|
188
|
+
rescue => e
|
189
|
+
raise call_after_hooks(successful, object, after_hook_name, e)
|
190
|
+
end
|
191
|
+
|
192
|
+
begin
|
193
|
+
yield # Call the user code
|
194
|
+
ensure
|
195
|
+
ex = call_after_hooks(successful, object, after_hook_name, nil)
|
196
|
+
raise ex if ex
|
197
|
+
end
|
91
198
|
end
|
92
|
-
|
93
|
-
|
94
|
-
|
199
|
+
|
200
|
+
def call_after_hooks(instrumenters, object, after_hook_name, ex)
|
201
|
+
instrumenters.reverse_each do |instrumenter|
|
202
|
+
begin
|
203
|
+
instrumenter.public_send(after_hook_name, object)
|
204
|
+
rescue => e
|
205
|
+
ex = e
|
206
|
+
end
|
207
|
+
end
|
208
|
+
ex
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class ListResultFailedError < GraphQL::Error
|
213
|
+
def initialize(value:, path:, field:)
|
214
|
+
message = "Failed to build a GraphQL list result for field `#{field.path}` at path `#{path.join(".")}`.\n".dup
|
215
|
+
|
216
|
+
message << "Expected `#{value.inspect}` (#{value.class}) to implement `.each` to satisfy the GraphQL return type `#{field.type.to_type_signature}`.\n"
|
217
|
+
|
218
|
+
if field.connection?
|
219
|
+
message << "\nThis field was treated as a Relay-style connection; add `connection: false` to the `field(...)` to disable this behavior."
|
220
|
+
end
|
221
|
+
super(message)
|
95
222
|
end
|
96
223
|
end
|
97
224
|
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,13 +12,6 @@ module GraphQL
|
|
13
12
|
# - It has no error-catching functionality
|
14
13
|
# @api private
|
15
14
|
class Lazy
|
16
|
-
# Traverse `val`, lazily resolving any values along the way
|
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
15
|
attr_reader :path, :field
|
24
16
|
|
25
17
|
# Create a {Lazy} which will get its inner value by calling the block
|
@@ -48,7 +40,11 @@ module GraphQL
|
|
48
40
|
end
|
49
41
|
end
|
50
42
|
|
51
|
-
|
43
|
+
# `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
|
44
|
+
# (fewer clauses in a hot `case` block), but now it requires special handling here.
|
45
|
+
# I think it's still worth it for the performance win, but if the number of special
|
46
|
+
# cases grows, then maybe it's worth rethinking somehow.
|
47
|
+
if @value.is_a?(StandardError) && @value != GraphQL::Execution::SKIP
|
52
48
|
raise @value
|
53
49
|
else
|
54
50
|
@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,25 +219,22 @@ module GraphQL
|
|
186
219
|
|
187
220
|
private
|
188
221
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
def normalize_keyword(keyword)
|
199
|
-
if keyword.is_a?(String)
|
200
|
-
Schema::Member::BuildType.underscore(keyword).to_sym
|
201
|
-
else
|
202
|
-
keyword
|
222
|
+
def skipped_by_directive?(ast_selection)
|
223
|
+
ast_selection.directives.each do |directive|
|
224
|
+
dir_defn = @query.schema.directives.fetch(directive.name)
|
225
|
+
directive_class = dir_defn
|
226
|
+
if directive_class
|
227
|
+
dir_args = @query.arguments_for(directive, dir_defn)
|
228
|
+
return true unless directive_class.static_include?(dir_args, @query.context)
|
229
|
+
end
|
203
230
|
end
|
231
|
+
false
|
204
232
|
end
|
205
233
|
|
206
234
|
def find_selections(subselections_by_type, selections_on_type, selected_type, ast_selections, arguments)
|
207
235
|
ast_selections.each do |ast_selection|
|
236
|
+
next if skipped_by_directive?(ast_selection)
|
237
|
+
|
208
238
|
case ast_selection
|
209
239
|
when GraphQL::Language::Nodes::Field
|
210
240
|
response_key = ast_selection.alias || ast_selection.name
|
@@ -213,7 +243,7 @@ module GraphQL
|
|
213
243
|
elsif arguments.nil? || arguments.empty?
|
214
244
|
selections_on_type[response_key] = [ast_selection]
|
215
245
|
else
|
216
|
-
field_defn =
|
246
|
+
field_defn = @query.get_field(selected_type, ast_selection.name)
|
217
247
|
if arguments_match?(arguments, field_defn, ast_selection)
|
218
248
|
selections_on_type[response_key] = [ast_selection]
|
219
249
|
end
|
@@ -223,14 +253,14 @@ module GraphQL
|
|
223
253
|
subselections_on_type = selections_on_type
|
224
254
|
if (t = ast_selection.type)
|
225
255
|
# Assuming this is valid, that `t` will be found.
|
226
|
-
on_type = @query.
|
256
|
+
on_type = @query.get_type(t.name)
|
227
257
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
228
258
|
end
|
229
259
|
find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
|
230
260
|
when GraphQL::Language::Nodes::FragmentSpread
|
231
261
|
frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
|
232
262
|
# Again, assuming a valid AST
|
233
|
-
on_type = @query.
|
263
|
+
on_type = @query.get_type(frag_defn.type.name)
|
234
264
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
235
265
|
find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
|
236
266
|
else
|
@@ -241,10 +271,11 @@ module GraphQL
|
|
241
271
|
|
242
272
|
# If a selection on `node` matches `field_name` (which is backed by `field_defn`)
|
243
273
|
# and matches the `arguments:` constraints, then add that node to `matches`
|
244
|
-
def find_selected_nodes(node,
|
274
|
+
def find_selected_nodes(node, field_defn, arguments:, matches:)
|
275
|
+
return if skipped_by_directive?(node)
|
245
276
|
case node
|
246
277
|
when GraphQL::Language::Nodes::Field
|
247
|
-
if node.name ==
|
278
|
+
if node.name == field_defn.graphql_name
|
248
279
|
if arguments.nil? || arguments.empty?
|
249
280
|
# No constraint applied
|
250
281
|
matches << node
|
@@ -253,128 +284,26 @@ module GraphQL
|
|
253
284
|
end
|
254
285
|
end
|
255
286
|
when GraphQL::Language::Nodes::InlineFragment
|
256
|
-
node.selections.each { |s| find_selected_nodes(s,
|
287
|
+
node.selections.each { |s| find_selected_nodes(s, field_defn, arguments: arguments, matches: matches) }
|
257
288
|
when GraphQL::Language::Nodes::FragmentSpread
|
258
289
|
frag_defn = @query.fragments[node.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})")
|
259
|
-
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) }
|
260
291
|
else
|
261
292
|
raise "Unexpected selection comparison on #{node.class.name} (#{node})"
|
262
293
|
end
|
263
294
|
end
|
264
295
|
|
265
296
|
def arguments_match?(arguments, field_defn, field_node)
|
266
|
-
query_kwargs =
|
297
|
+
query_kwargs = @query.arguments_for(field_node, field_defn)
|
267
298
|
arguments.all? do |arg_name, arg_value|
|
268
|
-
|
269
|
-
|
270
|
-
query_kwargs.key?(arg_name) && query_kwargs[arg_name] == arg_value
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
# TODO Dedup with interpreter
|
275
|
-
module ArgumentHelpers
|
276
|
-
module_function
|
277
|
-
|
278
|
-
def arguments(query, graphql_object, arg_owner, ast_node)
|
279
|
-
kwarg_arguments = {}
|
280
|
-
arg_defns = arg_owner.arguments
|
281
|
-
ast_node.arguments.each do |arg|
|
282
|
-
arg_defn = arg_defns[arg.name] || raise("Invariant: missing argument definition for #{arg.name.inspect} in #{arg_defns.keys} from #{arg_owner}")
|
283
|
-
# Need to distinguish between client-provided `nil`
|
284
|
-
# and nothing-at-all
|
285
|
-
is_present, value = arg_to_value(query, graphql_object, arg_defn.type, arg.value)
|
286
|
-
if is_present
|
287
|
-
# This doesn't apply to directives, which are legacy
|
288
|
-
# Can remove this when Skip and Include use classes or something.
|
289
|
-
if graphql_object
|
290
|
-
value = arg_defn.prepare_value(graphql_object, value)
|
291
|
-
end
|
292
|
-
kwarg_arguments[arg_defn.keyword] = value
|
293
|
-
end
|
294
|
-
end
|
295
|
-
arg_defns.each do |name, arg_defn|
|
296
|
-
if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
|
297
|
-
kwarg_arguments[arg_defn.keyword] = arg_defn.default_value
|
298
|
-
end
|
299
|
-
end
|
300
|
-
kwarg_arguments
|
301
|
-
end
|
302
|
-
|
303
|
-
# Get a Ruby-ready value from a client query.
|
304
|
-
# @param graphql_object [Object] The owner of the field whose argument this is
|
305
|
-
# @param arg_type [Class, GraphQL::Schema::NonNull, GraphQL::Schema::List]
|
306
|
-
# @param ast_value [GraphQL::Language::Nodes::VariableIdentifier, String, Integer, Float, Boolean]
|
307
|
-
# @return [Array(is_present, value)]
|
308
|
-
def arg_to_value(query, graphql_object, arg_type, ast_value)
|
309
|
-
if ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
310
|
-
# If it's not here, it will get added later
|
311
|
-
if query.variables.key?(ast_value.name)
|
312
|
-
return true, query.variables[ast_value.name]
|
313
|
-
else
|
314
|
-
return false, nil
|
315
|
-
end
|
316
|
-
elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
|
317
|
-
return true, nil
|
318
|
-
elsif arg_type.is_a?(GraphQL::Schema::NonNull)
|
319
|
-
arg_to_value(query, graphql_object, arg_type.of_type, ast_value)
|
320
|
-
elsif arg_type.is_a?(GraphQL::Schema::List)
|
321
|
-
# Treat a single value like a list
|
322
|
-
arg_value = Array(ast_value)
|
323
|
-
list = []
|
324
|
-
arg_value.map do |inner_v|
|
325
|
-
_present, value = arg_to_value(query, graphql_object, arg_type.of_type, inner_v)
|
326
|
-
list << value
|
327
|
-
end
|
328
|
-
return true, list
|
329
|
-
elsif arg_type.is_a?(Class) && arg_type < GraphQL::Schema::InputObject
|
330
|
-
# For these, `prepare` is applied during `#initialize`.
|
331
|
-
# Pass `nil` so it will be skipped in `#arguments`.
|
332
|
-
# What a mess.
|
333
|
-
args = arguments(query, nil, arg_type, ast_value)
|
334
|
-
# We're not tracking defaults_used, but for our purposes
|
335
|
-
# we compare the value to the default value.
|
336
|
-
return true, arg_type.new(ruby_kwargs: args, context: query.context, defaults_used: nil)
|
337
|
-
else
|
338
|
-
flat_value = flatten_ast_value(query, ast_value)
|
339
|
-
return true, arg_type.coerce_input(flat_value, query.context)
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
def flatten_ast_value(query, v)
|
344
|
-
case v
|
345
|
-
when GraphQL::Language::Nodes::Enum
|
346
|
-
v.name
|
347
|
-
when GraphQL::Language::Nodes::InputObject
|
348
|
-
h = {}
|
349
|
-
v.arguments.each do |arg|
|
350
|
-
h[arg.name] = flatten_ast_value(query, arg.value)
|
351
|
-
end
|
352
|
-
h
|
353
|
-
when Array
|
354
|
-
v.map { |v2| flatten_ast_value(query, v2) }
|
355
|
-
when GraphQL::Language::Nodes::VariableIdentifier
|
356
|
-
flatten_ast_value(query.variables[v.name])
|
357
|
-
else
|
358
|
-
v
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
# TODO dedup with interpreter
|
364
|
-
module FieldHelpers
|
365
|
-
module_function
|
366
|
-
|
367
|
-
def get_field(schema, owner_type, field_name)
|
368
|
-
field_defn = owner_type.get_field(field_name)
|
369
|
-
field_defn ||= if owner_type == schema.query.metadata[:type_class] && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
|
370
|
-
entry_point_field.metadata[:type_class]
|
371
|
-
elsif (dynamic_field = schema.introspection_system.dynamic_field(name: field_name))
|
372
|
-
dynamic_field.metadata[:type_class]
|
299
|
+
arg_name_sym = if arg_name.is_a?(String)
|
300
|
+
Schema::Member::BuildType.underscore(arg_name).to_sym
|
373
301
|
else
|
374
|
-
|
302
|
+
arg_name
|
375
303
|
end
|
376
304
|
|
377
|
-
|
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
|
378
307
|
end
|
379
308
|
end
|
380
309
|
end
|