graphql 1.9.21 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +44 -7
- data/lib/generators/graphql/interface_generator.rb +7 -7
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_create_generator.rb +22 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
- data/lib/generators/graphql/mutation_generator.rb +6 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +28 -12
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- data/lib/generators/graphql/scalar_generator.rb +4 -2
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +8 -0
- data/lib/generators/graphql/templates/base_edge.erb +8 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/enum.erb +7 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +6 -2
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +3 -1
- data/lib/generators/graphql/templates/mutation_create.erb +20 -0
- data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
- data/lib/generators/graphql/templates/mutation_update.erb +21 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +7 -3
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +5 -1
- data/lib/generators/graphql/templates/schema.erb +22 -27
- data/lib/generators/graphql/templates/union.erb +6 -2
- data/lib/generators/graphql/type_generator.rb +47 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/ast/field_usage.rb +29 -2
- 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 +22 -0
- data/lib/graphql/dataloader/request.rb +19 -0
- data/lib/graphql/dataloader/request_all.rb +19 -0
- data/lib/graphql/dataloader/source.rb +155 -0
- data/lib/graphql/dataloader.rb +308 -0
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/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 +108 -14
- data/lib/graphql/execution/instrumentation.rb +1 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
- data/lib/graphql/execution/interpreter/arguments.rb +88 -0
- data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
- data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
- data/lib/graphql/execution/interpreter/resolve.rb +37 -25
- data/lib/graphql/execution/interpreter/runtime.rb +715 -387
- data/lib/graphql/execution/interpreter.rb +32 -31
- data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +32 -114
- data/lib/graphql/execution/multiplex.rb +60 -92
- data/lib/graphql/execution.rb +11 -3
- 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 +27 -17
- data/lib/graphql/introspection.rb +99 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/definition_slice.rb +21 -10
- data/lib/graphql/language/document_from_schema_definition.rb +99 -63
- data/lib/graphql/language/lexer.rb +53 -27
- data/lib/graphql/language/lexer.rl +5 -3
- data/lib/graphql/language/nodes.rb +64 -93
- data/lib/graphql/language/parser.rb +929 -896
- data/lib/graphql/language/parser.y +125 -102
- data/lib/graphql/language/printer.rb +11 -2
- data/lib/graphql/language/sanitized_printer.rb +222 -0
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/language.rb +3 -1
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
- data/lib/graphql/pagination/array_connection.rb +77 -0
- data/lib/graphql/pagination/connection.rb +226 -0
- data/lib/graphql/pagination/connections.rb +134 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +226 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/context.rb +51 -190
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +23 -6
- data/lib/graphql/query/literal_input.rb +26 -11
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/validation_pipeline.rb +12 -38
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +26 -9
- data/lib/graphql/query.rb +62 -32
- data/lib/graphql/railtie.rb +6 -102
- data/lib/graphql/rake_task/validate.rb +3 -0
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/range_add.rb +23 -9
- 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 +240 -0
- data/lib/graphql/schema/argument.rb +262 -28
- 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 +319 -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/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 +115 -22
- data/lib/graphql/schema/enum_value.rb +16 -21
- data/lib/graphql/schema/field/connection_extension.rb +46 -20
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +376 -291
- 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 +147 -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 +3 -2
- data/lib/graphql/schema/list.rb +46 -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 +23 -14
- data/lib/graphql/schema/member/has_arguments.rb +212 -23
- data/lib/graphql/schema/member/has_ast_node.rb +20 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
- data/lib/graphql/schema/member/has_directives.rb +98 -0
- data/lib/graphql/schema/member/has_fields.rb +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/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 -65
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +57 -32
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +133 -79
- data/lib/graphql/schema/scalar.rb +40 -15
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +19 -5
- data/lib/graphql/schema/union.rb +39 -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 +182 -32
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +687 -891
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/base_visitor.rb +21 -31
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/error.rb +3 -1
- data/lib/graphql/static_validation/literal_validator.rb +51 -26
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +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/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +13 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +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 +123 -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 +111 -52
- 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 +14 -1
- 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 +57 -29
- 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 +16 -8
- data/lib/graphql/types/iso_8601_date_time.rb +32 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -88
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +170 -0
- data/lib/graphql/types/relay/default_relay.rb +21 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
- data/lib/graphql/types/relay/has_node_field.rb +41 -0
- data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
- data/lib/graphql/types/relay/node.rb +2 -4
- data/lib/graphql/types/relay/node_behaviors.rb +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 +97 -231
- 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/interpreter/hash_response.rb +0 -46
- 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/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
@@ -0,0 +1,240 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Addition
|
6
|
+
attr_reader :directives, :possible_types, :types, :union_memberships, :references, :arguments_with_default_values
|
7
|
+
|
8
|
+
def initialize(schema:, own_types:, new_types:)
|
9
|
+
@schema = schema
|
10
|
+
@own_types = own_types
|
11
|
+
@directives = Set.new
|
12
|
+
@possible_types = {}
|
13
|
+
@types = {}
|
14
|
+
@union_memberships = {}
|
15
|
+
@references = Hash.new { |h, k| h[k] = [] }
|
16
|
+
@arguments_with_default_values = []
|
17
|
+
add_type_and_traverse(new_types)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def references_to(thing, from:)
|
23
|
+
@references[thing] << from
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_type(name)
|
27
|
+
local_type = @types[name]
|
28
|
+
# This isn't really sophisticated, but
|
29
|
+
# I think it's good enough to support the current usage of LateBoundTypes
|
30
|
+
if local_type.is_a?(Array)
|
31
|
+
local_type = local_type.first
|
32
|
+
end
|
33
|
+
local_type || @schema.get_type(name)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Lookup using `own_types` here because it's ok to override
|
37
|
+
# inherited types by name
|
38
|
+
def get_local_type(name)
|
39
|
+
@types[name] || @own_types[name]
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_directives_from(owner)
|
43
|
+
dirs = owner.directives.map(&:class)
|
44
|
+
@directives.merge(dirs)
|
45
|
+
add_type_and_traverse(dirs)
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_type_and_traverse(new_types)
|
49
|
+
late_types = []
|
50
|
+
new_types.each { |t| add_type(t, owner: nil, late_types: late_types, path: [t.graphql_name]) }
|
51
|
+
missed_late_types = 0
|
52
|
+
while (late_type_vals = late_types.shift)
|
53
|
+
type_owner, lt = late_type_vals
|
54
|
+
if lt.is_a?(String)
|
55
|
+
type = Member::BuildType.constantize(lt)
|
56
|
+
# Reset the counter, since we might succeed next go-round
|
57
|
+
missed_late_types = 0
|
58
|
+
update_type_owner(type_owner, type)
|
59
|
+
add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name])
|
60
|
+
elsif lt.is_a?(LateBoundType)
|
61
|
+
if (type = get_type(lt.name))
|
62
|
+
# Reset the counter, since we might succeed next go-round
|
63
|
+
missed_late_types = 0
|
64
|
+
update_type_owner(type_owner, type)
|
65
|
+
add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name])
|
66
|
+
else
|
67
|
+
missed_late_types += 1
|
68
|
+
# Add it back to the list, maybe we'll be able to resolve it later.
|
69
|
+
late_types << [type_owner, lt]
|
70
|
+
if missed_late_types == late_types.size
|
71
|
+
# We've looked at all of them and haven't resolved one.
|
72
|
+
raise UnresolvedLateBoundTypeError.new(type: lt)
|
73
|
+
else
|
74
|
+
# Try the next one
|
75
|
+
end
|
76
|
+
end
|
77
|
+
else
|
78
|
+
raise ArgumentError, "Unexpected late type: #{lt.inspect}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def update_type_owner(owner, type)
|
85
|
+
case owner
|
86
|
+
when Module
|
87
|
+
if owner.kind.union?
|
88
|
+
# It's a union with possible_types
|
89
|
+
# Replace the item by class name
|
90
|
+
owner.assign_type_membership_object_type(type)
|
91
|
+
@possible_types[owner.graphql_name] = owner.possible_types
|
92
|
+
elsif type.kind.interface? && (owner.kind.object? || owner.kind.interface?)
|
93
|
+
new_interfaces = []
|
94
|
+
owner.interfaces.each do |int_t|
|
95
|
+
if int_t.is_a?(String) && int_t == type.graphql_name
|
96
|
+
new_interfaces << type
|
97
|
+
elsif int_t.is_a?(LateBoundType) && int_t.graphql_name == type.graphql_name
|
98
|
+
new_interfaces << type
|
99
|
+
else
|
100
|
+
# Don't re-add proper interface definitions,
|
101
|
+
# they were probably already added, maybe with options.
|
102
|
+
end
|
103
|
+
end
|
104
|
+
owner.implements(*new_interfaces)
|
105
|
+
new_interfaces.each do |int|
|
106
|
+
pt = @possible_types[int.graphql_name] ||= []
|
107
|
+
if !pt.include?(owner) && owner.is_a?(Class)
|
108
|
+
pt << owner
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
when nil
|
113
|
+
# It's a root type
|
114
|
+
@types[type.graphql_name] = type
|
115
|
+
when GraphQL::Schema::Field, GraphQL::Schema::Argument
|
116
|
+
orig_type = owner.type
|
117
|
+
# Apply list/non-null wrapper as needed
|
118
|
+
if orig_type.respond_to?(:of_type)
|
119
|
+
transforms = []
|
120
|
+
while (orig_type.respond_to?(:of_type))
|
121
|
+
if orig_type.kind.non_null?
|
122
|
+
transforms << :to_non_null_type
|
123
|
+
elsif orig_type.kind.list?
|
124
|
+
transforms << :to_list_type
|
125
|
+
else
|
126
|
+
raise "Invariant: :of_type isn't non-null or list"
|
127
|
+
end
|
128
|
+
orig_type = orig_type.of_type
|
129
|
+
end
|
130
|
+
transforms.reverse_each { |t| type = type.public_send(t) }
|
131
|
+
end
|
132
|
+
owner.type = type
|
133
|
+
else
|
134
|
+
raise "Unexpected update: #{owner.inspect} #{type.inspect}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_type(type, owner:, late_types:, path:)
|
139
|
+
if type.is_a?(String) || type.is_a?(GraphQL::Schema::LateBoundType)
|
140
|
+
late_types << [owner, type]
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
144
|
+
if owner.is_a?(Class) && owner < GraphQL::Schema::Union
|
145
|
+
um = @union_memberships[type.graphql_name] ||= []
|
146
|
+
um << owner
|
147
|
+
end
|
148
|
+
|
149
|
+
if (prev_type = get_local_type(type.graphql_name)) && prev_type == type
|
150
|
+
# No need to re-visit
|
151
|
+
elsif type.is_a?(Class) && type < GraphQL::Schema::Directive
|
152
|
+
@directives << type
|
153
|
+
type.all_argument_definitions.each do |arg|
|
154
|
+
arg_type = arg.type.unwrap
|
155
|
+
references_to(arg_type, from: arg)
|
156
|
+
add_type(arg_type, owner: arg, late_types: late_types, path: path + [arg.graphql_name])
|
157
|
+
if arg.default_value?
|
158
|
+
@arguments_with_default_values << arg
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
prev_type = @types[type.graphql_name]
|
163
|
+
if prev_type.nil?
|
164
|
+
@types[type.graphql_name] = type
|
165
|
+
elsif prev_type.is_a?(Array)
|
166
|
+
prev_type << type
|
167
|
+
else
|
168
|
+
@types[type.graphql_name] = [prev_type, type]
|
169
|
+
end
|
170
|
+
|
171
|
+
add_directives_from(type)
|
172
|
+
if type.kind.fields?
|
173
|
+
type.all_field_definitions.each do |field|
|
174
|
+
name = field.graphql_name
|
175
|
+
field_type = field.type.unwrap
|
176
|
+
references_to(field_type, from: field)
|
177
|
+
field_path = path + [name]
|
178
|
+
add_type(field_type, owner: field, late_types: late_types, path: field_path)
|
179
|
+
add_directives_from(field)
|
180
|
+
field.all_argument_definitions.each do |arg|
|
181
|
+
add_directives_from(arg)
|
182
|
+
arg_type = arg.type.unwrap
|
183
|
+
references_to(arg_type, from: arg)
|
184
|
+
add_type(arg_type, owner: arg, late_types: late_types, path: field_path + [arg.graphql_name])
|
185
|
+
if arg.default_value?
|
186
|
+
@arguments_with_default_values << arg
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
if type.kind.input_object?
|
192
|
+
type.all_argument_definitions.each do |arg|
|
193
|
+
add_directives_from(arg)
|
194
|
+
arg_type = arg.type.unwrap
|
195
|
+
references_to(arg_type, from: arg)
|
196
|
+
add_type(arg_type, owner: arg, late_types: late_types, path: path + [arg.graphql_name])
|
197
|
+
if arg.default_value?
|
198
|
+
@arguments_with_default_values << arg
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
if type.kind.union?
|
203
|
+
@possible_types[type.graphql_name] = type.all_possible_types
|
204
|
+
type.all_possible_types.each do |t|
|
205
|
+
add_type(t, owner: type, late_types: late_types, path: path + ["possible_types"])
|
206
|
+
end
|
207
|
+
end
|
208
|
+
if type.kind.interface?
|
209
|
+
type.orphan_types.each do |t|
|
210
|
+
add_type(t, owner: type, late_types: late_types, path: path + ["orphan_types"])
|
211
|
+
end
|
212
|
+
end
|
213
|
+
if type.kind.object?
|
214
|
+
possible_types_for_this_name = @possible_types[type.graphql_name] ||= []
|
215
|
+
possible_types_for_this_name << type
|
216
|
+
end
|
217
|
+
|
218
|
+
if type.kind.object? || type.kind.interface?
|
219
|
+
type.interface_type_memberships.each do |interface_type_membership|
|
220
|
+
case interface_type_membership
|
221
|
+
when Schema::TypeMembership
|
222
|
+
interface_type = interface_type_membership.abstract_type
|
223
|
+
# We can get these now; we'll have to get late-bound types later
|
224
|
+
if interface_type.is_a?(Module) && type.is_a?(Class)
|
225
|
+
implementers = @possible_types[interface_type.graphql_name] ||= []
|
226
|
+
implementers << type
|
227
|
+
end
|
228
|
+
when String, Schema::LateBoundType
|
229
|
+
interface_type = interface_type_membership
|
230
|
+
else
|
231
|
+
raise ArgumentError, "Invariant: unexpected type membership for #{type.graphql_name}: #{interface_type_membership.class} (#{interface_type_membership.inspect})"
|
232
|
+
end
|
233
|
+
add_type(interface_type, owner: type, late_types: late_types, path: path + ["implements"])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -2,9 +2,12 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
class Argument
|
5
|
-
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
6
|
-
include GraphQL::Schema::Member::AcceptsDefinition
|
7
5
|
include GraphQL::Schema::Member::HasPath
|
6
|
+
include GraphQL::Schema::Member::HasAstNode
|
7
|
+
include GraphQL::Schema::Member::HasDirectives
|
8
|
+
include GraphQL::Schema::Member::HasDeprecationReason
|
9
|
+
include GraphQL::Schema::Member::HasValidators
|
10
|
+
include GraphQL::Schema::FindInheritedValue::EmptyObjects
|
8
11
|
|
9
12
|
NO_DEFAULT = :__no_default__
|
10
13
|
|
@@ -32,30 +35,50 @@ module GraphQL
|
|
32
35
|
# @param arg_name [Symbol]
|
33
36
|
# @param type_expr
|
34
37
|
# @param desc [String]
|
35
|
-
# @param required [Boolean] if true, this argument is non-null; if false, this argument is nullable
|
38
|
+
# @param required [Boolean, :nullable] if true, this argument is non-null; if false, this argument is nullable. If `:nullable`, then the argument must be provided, though it may be `null`.
|
36
39
|
# @param description [String]
|
37
40
|
# @param default_value [Object]
|
38
41
|
# @param as [Symbol] Override the keyword name when passed to a method
|
39
42
|
# @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
|
40
43
|
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
41
44
|
# @param from_resolver [Boolean] if true, a Resolver class defined this argument
|
42
|
-
# @param
|
43
|
-
|
45
|
+
# @param directives [Hash{Class => Hash}]
|
46
|
+
# @param deprecation_reason [String]
|
47
|
+
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
48
|
+
# @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
|
49
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
44
50
|
arg_name ||= name
|
45
|
-
|
46
|
-
@name = name_str.freeze
|
51
|
+
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
47
52
|
@type_expr = type_expr || type
|
48
53
|
@description = desc || description
|
49
|
-
@null =
|
54
|
+
@null = required != true
|
50
55
|
@default_value = default_value
|
56
|
+
if replace_null_with_default
|
57
|
+
if !default_value?
|
58
|
+
raise ArgumentError, "`replace_null_with_default: true` requires a default value, please provide one with `default_value: ...`"
|
59
|
+
end
|
60
|
+
@replace_null_with_default = true
|
61
|
+
end
|
62
|
+
|
51
63
|
@owner = owner
|
52
64
|
@as = as
|
53
65
|
@loads = loads
|
54
|
-
@keyword = as || Schema::Member::BuildType.underscore(@name).to_sym
|
66
|
+
@keyword = as || (arg_name.is_a?(Symbol) ? arg_name : Schema::Member::BuildType.underscore(@name).to_sym)
|
55
67
|
@prepare = prepare
|
56
68
|
@ast_node = ast_node
|
57
69
|
@from_resolver = from_resolver
|
58
|
-
|
70
|
+
self.deprecation_reason = deprecation_reason
|
71
|
+
|
72
|
+
if directives
|
73
|
+
directives.each do |dir_class, dir_options|
|
74
|
+
directive(dir_class, **dir_options)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
self.validates(validates)
|
79
|
+
if required == :nullable
|
80
|
+
self.owner.validates(required: { argument: arg_name })
|
81
|
+
end
|
59
82
|
|
60
83
|
if definition_block
|
61
84
|
if definition_block.arity == 1
|
@@ -66,6 +89,10 @@ module GraphQL
|
|
66
89
|
end
|
67
90
|
end
|
68
91
|
|
92
|
+
def inspect
|
93
|
+
"#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
|
94
|
+
end
|
95
|
+
|
69
96
|
# @return [Object] the value used when the client doesn't provide a value for this argument
|
70
97
|
attr_reader :default_value
|
71
98
|
|
@@ -74,6 +101,10 @@ module GraphQL
|
|
74
101
|
@default_value != NO_DEFAULT
|
75
102
|
end
|
76
103
|
|
104
|
+
def replace_null_with_default?
|
105
|
+
@replace_null_with_default
|
106
|
+
end
|
107
|
+
|
77
108
|
attr_writer :description
|
78
109
|
|
79
110
|
# @return [String] Documentation for this argument
|
@@ -85,6 +116,20 @@ module GraphQL
|
|
85
116
|
end
|
86
117
|
end
|
87
118
|
|
119
|
+
# @return [String] Deprecation reason for this argument
|
120
|
+
def deprecation_reason(text = nil)
|
121
|
+
if text
|
122
|
+
self.deprecation_reason = text
|
123
|
+
else
|
124
|
+
super()
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def deprecation_reason=(new_reason)
|
129
|
+
validate_deprecated_or_optional(null: @null, deprecation_reason: new_reason)
|
130
|
+
super
|
131
|
+
end
|
132
|
+
|
88
133
|
def visible?(context)
|
89
134
|
true
|
90
135
|
end
|
@@ -93,48 +138,237 @@ module GraphQL
|
|
93
138
|
true
|
94
139
|
end
|
95
140
|
|
96
|
-
def authorized?(obj, ctx)
|
141
|
+
def authorized?(obj, value, ctx)
|
142
|
+
authorized_as_type?(obj, value, ctx, as_type: type)
|
143
|
+
end
|
144
|
+
|
145
|
+
def authorized_as_type?(obj, value, ctx, as_type:)
|
146
|
+
if value.nil?
|
147
|
+
return true
|
148
|
+
end
|
149
|
+
|
150
|
+
if as_type.kind.non_null?
|
151
|
+
as_type = as_type.of_type
|
152
|
+
end
|
153
|
+
|
154
|
+
if as_type.kind.list?
|
155
|
+
value.each do |v|
|
156
|
+
if !authorized_as_type?(obj, v, ctx, as_type: as_type.of_type)
|
157
|
+
return false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
elsif as_type.kind.input_object?
|
161
|
+
return as_type.authorized?(obj, value, ctx)
|
162
|
+
end
|
163
|
+
# None of the early-return conditions were activated,
|
164
|
+
# so this is authorized.
|
97
165
|
true
|
98
166
|
end
|
99
167
|
|
100
|
-
def
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
argument.as = @as
|
107
|
-
argument.method_access = @method_access
|
108
|
-
if NO_DEFAULT != @default_value
|
109
|
-
argument.default_value = @default_value
|
168
|
+
def type=(new_type)
|
169
|
+
validate_input_type(new_type)
|
170
|
+
# This isn't true for LateBoundTypes, but we can assume those will
|
171
|
+
# be updated via this codepath later in schema setup.
|
172
|
+
if new_type.respond_to?(:non_null?)
|
173
|
+
validate_deprecated_or_optional(null: !new_type.non_null?, deprecation_reason: deprecation_reason)
|
110
174
|
end
|
111
|
-
|
175
|
+
@type = new_type
|
112
176
|
end
|
113
177
|
|
114
178
|
def type
|
115
|
-
@type ||=
|
116
|
-
|
117
|
-
|
179
|
+
@type ||= begin
|
180
|
+
parsed_type = begin
|
181
|
+
Member::BuildType.parse_type(@type_expr, null: @null)
|
182
|
+
rescue StandardError => err
|
183
|
+
raise ArgumentError, "Couldn't build type for Argument #{@owner.name}.#{name}: #{err.class.name}: #{err.message}", err.backtrace
|
184
|
+
end
|
185
|
+
# Use the setter method to get validations
|
186
|
+
self.type = parsed_type
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def statically_coercible?
|
191
|
+
return @statically_coercible if defined?(@statically_coercible)
|
192
|
+
|
193
|
+
@statically_coercible = !@prepare.is_a?(String) && !@prepare.is_a?(Symbol)
|
118
194
|
end
|
119
195
|
|
120
196
|
# Apply the {prepare} configuration to `value`, using methods from `obj`.
|
121
197
|
# Used by the runtime.
|
122
198
|
# @api private
|
123
|
-
def prepare_value(obj, value)
|
199
|
+
def prepare_value(obj, value, context: nil)
|
124
200
|
if value.is_a?(GraphQL::Schema::InputObject)
|
125
201
|
value = value.prepare
|
126
202
|
end
|
127
203
|
|
204
|
+
Schema::Validator.validate!(validators, obj, context, value)
|
205
|
+
|
128
206
|
if @prepare.nil?
|
129
207
|
value
|
130
208
|
elsif @prepare.is_a?(String) || @prepare.is_a?(Symbol)
|
131
|
-
obj.
|
209
|
+
if obj.nil?
|
210
|
+
# The problem here is, we _used to_ prepare while building variables.
|
211
|
+
# But now we don't have the runtime object there.
|
212
|
+
#
|
213
|
+
# This will have to be called later, when the runtime object _is_ available.
|
214
|
+
value
|
215
|
+
else
|
216
|
+
obj.public_send(@prepare, value)
|
217
|
+
end
|
132
218
|
elsif @prepare.respond_to?(:call)
|
133
|
-
@prepare.call(value, obj.context)
|
219
|
+
@prepare.call(value, context || obj.context)
|
134
220
|
else
|
135
221
|
raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}"
|
136
222
|
end
|
137
223
|
end
|
224
|
+
|
225
|
+
# @api private
|
226
|
+
def coerce_into_values(parent_object, values, context, argument_values)
|
227
|
+
arg_name = graphql_name
|
228
|
+
arg_key = keyword
|
229
|
+
default_used = false
|
230
|
+
|
231
|
+
if values.key?(arg_name)
|
232
|
+
value = values[arg_name]
|
233
|
+
elsif values.key?(arg_key)
|
234
|
+
value = values[arg_key]
|
235
|
+
elsif default_value?
|
236
|
+
value = default_value
|
237
|
+
default_used = true
|
238
|
+
else
|
239
|
+
# no value at all
|
240
|
+
owner.validate_directive_argument(self, nil)
|
241
|
+
return
|
242
|
+
end
|
243
|
+
|
244
|
+
if value.nil? && replace_null_with_default?
|
245
|
+
value = default_value
|
246
|
+
default_used = true
|
247
|
+
end
|
248
|
+
|
249
|
+
loaded_value = nil
|
250
|
+
coerced_value = context.schema.error_handler.with_error_handling(context) do
|
251
|
+
type.coerce_input(value, context)
|
252
|
+
end
|
253
|
+
|
254
|
+
# If this isn't lazy, then the block returns eagerly and assigns the result here
|
255
|
+
# If it _is_ lazy, then we write the lazy to the hash, then update it later
|
256
|
+
argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
|
257
|
+
if loads && !from_resolver?
|
258
|
+
loaded_value = context.query.with_error_handling do
|
259
|
+
load_and_authorize_value(owner, coerced_value, context)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
maybe_loaded_value = loaded_value || resolved_coerced_value
|
264
|
+
context.schema.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
|
265
|
+
owner.validate_directive_argument(self, resolved_loaded_value)
|
266
|
+
prepared_value = context.schema.error_handler.with_error_handling(context) do
|
267
|
+
prepare_value(parent_object, resolved_loaded_value, context: context)
|
268
|
+
end
|
269
|
+
|
270
|
+
# TODO code smell to access such a deeply-nested constant in a distant module
|
271
|
+
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
272
|
+
value: prepared_value,
|
273
|
+
definition: self,
|
274
|
+
default_used: default_used,
|
275
|
+
)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def load_and_authorize_value(load_method_owner, coerced_value, context)
|
281
|
+
if coerced_value.nil?
|
282
|
+
return nil
|
283
|
+
end
|
284
|
+
arg_load_method = "load_#{keyword}"
|
285
|
+
if load_method_owner.respond_to?(arg_load_method)
|
286
|
+
custom_loaded_value = if load_method_owner.is_a?(Class)
|
287
|
+
load_method_owner.public_send(arg_load_method, coerced_value, context)
|
288
|
+
else
|
289
|
+
load_method_owner.public_send(arg_load_method, coerced_value)
|
290
|
+
end
|
291
|
+
context.schema.after_lazy(custom_loaded_value) do |custom_value|
|
292
|
+
if loads
|
293
|
+
if type.list?
|
294
|
+
loaded_values = custom_value.each_with_index.map { |custom_val, idx|
|
295
|
+
id = coerced_value[idx]
|
296
|
+
load_method_owner.authorize_application_object(self, id, context, custom_val)
|
297
|
+
}
|
298
|
+
context.schema.after_any_lazies(loaded_values, &:itself)
|
299
|
+
else
|
300
|
+
load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
|
301
|
+
end
|
302
|
+
else
|
303
|
+
custom_value
|
304
|
+
end
|
305
|
+
end
|
306
|
+
elsif loads
|
307
|
+
if type.list?
|
308
|
+
loaded_values = coerced_value.map { |val| load_method_owner.load_and_authorize_application_object(self, val, context) }
|
309
|
+
context.schema.after_any_lazies(loaded_values, &:itself)
|
310
|
+
else
|
311
|
+
load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
|
312
|
+
end
|
313
|
+
else
|
314
|
+
coerced_value
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# @api private
|
319
|
+
def validate_default_value
|
320
|
+
coerced_default_value = begin
|
321
|
+
# This is weird, but we should accept single-item default values for list-type arguments.
|
322
|
+
# If we used `coerce_isolated_input` below, it would do this for us, but it's not really
|
323
|
+
# the right thing here because we expect default values in application format (Ruby values)
|
324
|
+
# not GraphQL format (scalar values).
|
325
|
+
#
|
326
|
+
# But I don't think Schema::List#coerce_result should apply wrapping to single-item lists.
|
327
|
+
prepped_default_value = if default_value.nil?
|
328
|
+
nil
|
329
|
+
elsif (type.kind.list? || (type.kind.non_null? && type.of_type.list?)) && !default_value.respond_to?(:map)
|
330
|
+
[default_value]
|
331
|
+
else
|
332
|
+
default_value
|
333
|
+
end
|
334
|
+
|
335
|
+
type.coerce_isolated_result(prepped_default_value) unless prepped_default_value.nil?
|
336
|
+
rescue GraphQL::Schema::Enum::UnresolvedValueError
|
337
|
+
# It raises this, which is helpful at runtime, but not here...
|
338
|
+
default_value
|
339
|
+
end
|
340
|
+
res = type.valid_isolated_input?(coerced_default_value)
|
341
|
+
if !res
|
342
|
+
raise InvalidDefaultValueError.new(self)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
class InvalidDefaultValueError < GraphQL::Error
|
347
|
+
def initialize(argument)
|
348
|
+
message = "`#{argument.path}` has an invalid default value: `#{argument.default_value.inspect}` isn't accepted by `#{argument.type.to_type_signature}`; update the default value or the argument type."
|
349
|
+
super(message)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
private
|
354
|
+
|
355
|
+
def validate_input_type(input_type)
|
356
|
+
if input_type.is_a?(String) || input_type.is_a?(GraphQL::Schema::LateBoundType)
|
357
|
+
# Do nothing; assume this will be validated later
|
358
|
+
elsif input_type.kind.non_null? || input_type.kind.list?
|
359
|
+
validate_input_type(input_type.unwrap)
|
360
|
+
elsif !input_type.kind.input?
|
361
|
+
raise ArgumentError, "Invalid input type for #{path}: #{input_type.graphql_name}. Must be scalar, enum, or input object, not #{input_type.kind.name}."
|
362
|
+
else
|
363
|
+
# It's an input type, we're OK
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def validate_deprecated_or_optional(null:, deprecation_reason:)
|
368
|
+
if deprecation_reason && !null
|
369
|
+
raise ArgumentError, "Required arguments cannot be deprecated: #{path}."
|
370
|
+
end
|
371
|
+
end
|
138
372
|
end
|
139
373
|
end
|
140
374
|
end
|
@@ -13,6 +13,8 @@ module GraphQL
|
|
13
13
|
def self.decode(encoded_text, nonce: false)
|
14
14
|
# urlsafe_decode64 is for forward compatibility
|
15
15
|
Base64Bp.urlsafe_decode64(encoded_text)
|
16
|
+
rescue ArgumentError
|
17
|
+
raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -20,7 +20,7 @@ module GraphQL
|
|
20
20
|
def call(obj, args, ctx)
|
21
21
|
method_name = @field_name
|
22
22
|
if !obj.respond_to?(method_name)
|
23
|
-
raise KeyError, "Can't resolve field #{method_name} on #{obj}"
|
23
|
+
raise KeyError, "Can't resolve field #{method_name} on #{obj.inspect}"
|
24
24
|
else
|
25
25
|
method_arity = obj.method(method_name).arity
|
26
26
|
resolver = case method_arity
|
@@ -14,6 +14,12 @@ module GraphQL
|
|
14
14
|
#
|
15
15
|
# @api private
|
16
16
|
class ResolveMap
|
17
|
+
module NullScalarCoerce
|
18
|
+
def self.call(val, _ctx)
|
19
|
+
val
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
17
23
|
def initialize(user_resolve_hash)
|
18
24
|
@resolve_hash = Hash.new do |h, k|
|
19
25
|
# For each type name, provide a new hash if one wasn't given:
|
@@ -21,7 +27,7 @@ module GraphQL
|
|
21
27
|
if k2 == "coerce_input" || k2 == "coerce_result"
|
22
28
|
# This isn't an object field, it's a scalar coerce function.
|
23
29
|
# Use a passthrough
|
24
|
-
|
30
|
+
NullScalarCoerce
|
25
31
|
else
|
26
32
|
# For each field, provide a resolver that will
|
27
33
|
# make runtime checks & replace itself
|
@@ -39,8 +45,10 @@ module GraphQL
|
|
39
45
|
@resolve_hash[type_name_s][field_name.to_s] = resolve_fn
|
40
46
|
end
|
41
47
|
when Proc
|
42
|
-
# for example,
|
48
|
+
# for example, "resolve_type"
|
43
49
|
@resolve_hash[type_name_s] = fields
|
50
|
+
else
|
51
|
+
raise ArgumentError, "Unexpected resolve hash value for #{type_name.inspect}: #{fields.inspect} (#{fields.class})"
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
@@ -53,16 +61,16 @@ module GraphQL
|
|
53
61
|
end
|
54
62
|
|
55
63
|
def call(type, field, obj, args, ctx)
|
56
|
-
resolver = @resolve_hash[type.
|
64
|
+
resolver = @resolve_hash[type.graphql_name][field.graphql_name]
|
57
65
|
resolver.call(obj, args, ctx)
|
58
66
|
end
|
59
67
|
|
60
68
|
def coerce_input(type, value, ctx)
|
61
|
-
@resolve_hash[type.
|
69
|
+
@resolve_hash[type.graphql_name]["coerce_input"].call(value, ctx)
|
62
70
|
end
|
63
71
|
|
64
72
|
def coerce_result(type, value, ctx)
|
65
|
-
@resolve_hash[type.
|
73
|
+
@resolve_hash[type.graphql_name]["coerce_result"].call(value, ctx)
|
66
74
|
end
|
67
75
|
end
|
68
76
|
end
|