graphql 1.12.12 → 2.4.8
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 +3 -8
- 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 +60 -4
- data/lib/generators/graphql/interface_generator.rb +7 -7
- 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 +5 -30
- data/lib/generators/graphql/mutation_update_generator.rb +22 -0
- data/lib/generators/graphql/object_generator.rb +10 -38
- data/lib/generators/graphql/orm_mutations_base.rb +40 -0
- data/lib/generators/graphql/relay.rb +23 -12
- 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 +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -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_resolver.erb +8 -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 +5 -1
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
- data/lib/generators/graphql/templates/input.erb +9 -0
- data/lib/generators/graphql/templates/interface.erb +4 -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 +2 -0
- data/lib/generators/graphql/templates/object.erb +4 -2
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/scalar.erb +3 -1
- data/lib/generators/graphql/templates/schema.erb +22 -2
- data/lib/generators/graphql/templates/union.erb +4 -2
- data/lib/generators/graphql/type_generator.rb +46 -10
- data/lib/generators/graphql/union_generator.rb +5 -5
- data/lib/graphql/analysis/analyzer.rb +89 -0
- data/lib/graphql/analysis/field_usage.rb +65 -28
- data/lib/graphql/analysis/max_query_complexity.rb +11 -17
- data/lib/graphql/analysis/max_query_depth.rb +13 -19
- data/lib/graphql/analysis/query_complexity.rb +156 -61
- data/lib/graphql/analysis/query_depth.rb +38 -23
- data/lib/graphql/analysis/visitor.rb +283 -0
- data/lib/graphql/analysis.rb +90 -6
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/backtrace/table.rb +4 -22
- data/lib/graphql/backtrace/trace.rb +93 -0
- data/lib/graphql/backtrace/tracer.rb +8 -6
- data/lib/graphql/backtrace.rb +3 -8
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/current.rb +52 -0
- data/lib/graphql/dataloader/async_dataloader.rb +89 -0
- data/lib/graphql/dataloader/null_dataloader.rb +4 -2
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/dataloader/source.rb +125 -33
- data/lib/graphql/dataloader.rb +193 -143
- data/lib/graphql/date_encoding_error.rb +16 -0
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/errors.rb +12 -81
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments.rb +2 -2
- data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -36
- data/lib/graphql/execution/interpreter/resolve.rb +38 -4
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
- data/lib/graphql/execution/interpreter/runtime.rb +447 -403
- data/lib/graphql/execution/interpreter.rb +126 -80
- data/lib/graphql/execution/lazy.rb +11 -21
- data/lib/graphql/execution/lookahead.rb +133 -55
- data/lib/graphql/execution/multiplex.rb +4 -172
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/introspection/directive_location_enum.rb +2 -2
- data/lib/graphql/introspection/directive_type.rb +6 -4
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +11 -18
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +4 -4
- data/lib/graphql/introspection/input_value_type.rb +10 -4
- data/lib/graphql/introspection/schema_type.rb +17 -15
- data/lib/graphql/introspection/type_type.rb +29 -16
- data/lib/graphql/introspection.rb +6 -2
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/block_string.rb +37 -25
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +122 -81
- data/lib/graphql/language/lexer.rb +364 -1467
- data/lib/graphql/language/nodes.rb +197 -106
- data/lib/graphql/language/parser.rb +799 -1920
- data/lib/graphql/language/printer.rb +372 -160
- data/lib/graphql/language/sanitized_printer.rb +25 -27
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/visitor.rb +188 -141
- data/lib/graphql/language.rb +62 -1
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
- data/lib/graphql/pagination/array_connection.rb +8 -6
- data/lib/graphql/pagination/connection.rb +61 -7
- data/lib/graphql/pagination/connections.rb +22 -23
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
- data/lib/graphql/pagination/relation_connection.rb +60 -28
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +146 -222
- data/lib/graphql/query/input_validation_result.rb +10 -1
- data/lib/graphql/query/null_context.rb +15 -32
- data/lib/graphql/query/validation_pipeline.rb +15 -39
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +35 -17
- data/lib/graphql/query.rb +149 -82
- data/lib/graphql/railtie.rb +15 -109
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +30 -11
- data/lib/graphql/relay/range_add.rb +9 -16
- 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/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +6 -0
- data/lib/graphql/schema/addition.rb +98 -54
- data/lib/graphql/schema/always_visible.rb +14 -0
- data/lib/graphql/schema/argument.rb +179 -82
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +77 -39
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +4 -4
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/one_of.rb +24 -0
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive/transform.rb +2 -2
- data/lib/graphql/schema/directive.rb +36 -22
- data/lib/graphql/schema/enum.rb +158 -63
- data/lib/graphql/schema/enum_value.rb +12 -21
- data/lib/graphql/schema/field/connection_extension.rb +7 -17
- data/lib/graphql/schema/field/scope_extension.rb +8 -1
- data/lib/graphql/schema/field.rb +521 -359
- data/lib/graphql/schema/field_extension.rb +86 -2
- data/lib/graphql/schema/find_inherited_value.rb +3 -7
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/has_single_input_argument.rb +160 -0
- data/lib/graphql/schema/input_object.rb +148 -99
- data/lib/graphql/schema/interface.rb +41 -64
- data/lib/graphql/schema/introspection_system.rb +12 -26
- data/lib/graphql/schema/late_bound_type.rb +12 -2
- data/lib/graphql/schema/list.rb +18 -7
- data/lib/graphql/schema/loader.rb +6 -5
- data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
- data/lib/graphql/schema/member/build_type.rb +16 -13
- data/lib/graphql/schema/member/has_arguments.rb +270 -86
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -61
- data/lib/graphql/schema/member/has_fields.rb +169 -31
- data/lib/graphql/schema/member/has_interfaces.rb +143 -0
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
- data/lib/graphql/schema/member/validates_input.rb +6 -6
- data/lib/graphql/schema/member.rb +1 -6
- data/lib/graphql/schema/mutation.rb +7 -9
- data/lib/graphql/schema/non_null.rb +7 -7
- data/lib/graphql/schema/object.rb +38 -119
- data/lib/graphql/schema/printer.rb +24 -25
- data/lib/graphql/schema/relay_classic_mutation.rb +13 -91
- data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
- data/lib/graphql/schema/resolver.rb +118 -115
- data/lib/graphql/schema/scalar.rb +20 -21
- data/lib/graphql/schema/subscription.rb +95 -21
- data/lib/graphql/schema/timeout.rb +25 -29
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/type_membership.rb +21 -4
- data/lib/graphql/schema/union.rb +16 -16
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- 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 +3 -1
- data/lib/graphql/schema/validator/format_validator.rb +4 -5
- data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
- data/lib/graphql/schema/validator/length_validator.rb +5 -3
- data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
- data/lib/graphql/schema/validator/required_validator.rb +56 -18
- data/lib/graphql/schema/validator.rb +38 -28
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +359 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +294 -0
- data/lib/graphql/schema/warden.rb +423 -134
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +1015 -1057
- data/lib/graphql/static_validation/all_rules.rb +3 -1
- data/lib/graphql/static_validation/base_visitor.rb +15 -28
- 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 +24 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +4 -3
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +15 -13
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +13 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +62 -35
- 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/fragment_types_exist.rb +12 -2
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- 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 +7 -5
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +14 -8
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
- data/lib/graphql/static_validation/validation_context.rb +32 -6
- data/lib/graphql/static_validation/validator.rb +11 -27
- data/lib/graphql/static_validation.rb +0 -3
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +49 -11
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
- data/lib/graphql/subscriptions/event.rb +87 -38
- data/lib/graphql/subscriptions/serialize.rb +27 -3
- data/lib/graphql/subscriptions.rb +63 -49
- data/lib/graphql/testing/helpers.rb +155 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
- data/lib/graphql/tracing/appoptics_trace.rb +253 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +4 -2
- data/lib/graphql/tracing/appsignal_trace.rb +79 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +17 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +185 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +27 -15
- data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
- data/lib/graphql/tracing/legacy_trace.rb +12 -0
- data/lib/graphql/tracing/new_relic_trace.rb +77 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +45 -0
- data/lib/graphql/tracing/notifications_tracing.rb +61 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/platform_trace.rb +118 -0
- data/lib/graphql/tracing/platform_tracing.rb +46 -49
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
- data/lib/graphql/tracing/prometheus_trace.rb +94 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
- data/lib/graphql/tracing/scout_trace.rb +74 -0
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +114 -0
- data/lib/graphql/tracing/statsd_trace.rb +58 -0
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +79 -0
- data/lib/graphql/tracing.rb +29 -52
- data/lib/graphql/type_kinds.rb +7 -4
- data/lib/graphql/types/big_int.rb +5 -1
- data/lib/graphql/types/int.rb +1 -1
- data/lib/graphql/types/iso_8601_date.rb +17 -6
- data/lib/graphql/types/iso_8601_date_time.rb +12 -1
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/base_connection.rb +16 -6
- data/lib/graphql/types/relay/connection_behaviors.rb +92 -32
- data/lib/graphql/types/relay/edge_behaviors.rb +46 -7
- data/lib/graphql/types/relay/has_node_field.rb +2 -2
- data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
- data/lib/graphql/types/relay/node_behaviors.rb +12 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
- data/lib/graphql/types/relay.rb +0 -3
- data/lib/graphql/types/string.rb +2 -2
- data/lib/graphql/types.rb +18 -10
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +82 -137
- data/readme.md +13 -6
- metadata +127 -186
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/ast/analyzer.rb +0 -84
- data/lib/graphql/analysis/ast/field_usage.rb +0 -28
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -234
- data/lib/graphql/analysis/ast/query_depth.rb +0 -56
- data/lib/graphql/analysis/ast/visitor.rb +0 -268
- data/lib/graphql/analysis/ast.rb +0 -91
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -230
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- 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 -240
- 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 -47
- data/lib/graphql/deprecation.rb +0 -13
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -111
- data/lib/graphql/enum_type.rb +0 -129
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- 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 -226
- data/lib/graphql/filter.rb +0 -53
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -262
- data/lib/graphql/language/parser.y +0 -543
- data/lib/graphql/language/token.rb +0 -38
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -41
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -40
- data/lib/graphql/relay/global_id_resolve.rb +0 -18
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- 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 -17
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/schema/member/accepts_definition.rb +0 -152
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/instrumentation.rb +0 -79
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/default_relay.rb +0 -27
- data/lib/graphql/types/relay/node_field.rb +0 -25
- data/lib/graphql/types/relay/nodes_field.rb +0 -27
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -8,6 +8,7 @@ module GraphQL
|
|
8
8
|
# - Arguments, via `.argument(...)` helper, which will be applied to the field.
|
9
9
|
# - Return type, via `.type(..., null: ...)`, which will be applied to the field.
|
10
10
|
# - Description, via `.description(...)`, which will be applied to the field
|
11
|
+
# - Comment, via `.comment(...)`, which will be applied to the field
|
11
12
|
# - Resolution, via `#resolve(**args)` method, which will be called to resolve the field.
|
12
13
|
# - `#object` and `#context` accessors for use during `#resolve`.
|
13
14
|
#
|
@@ -15,20 +16,19 @@ module GraphQL
|
|
15
16
|
#
|
16
17
|
# A resolver's configuration may be overridden with other keywords in the `field(...)` call.
|
17
18
|
#
|
18
|
-
# See the {.field_options} to see how a Resolver becomes a set of field configuration options.
|
19
|
-
#
|
20
19
|
# @see {GraphQL::Schema::Mutation} for a concrete subclass of `Resolver`.
|
21
20
|
# @see {GraphQL::Function} `Resolver` is a replacement for `GraphQL::Function`
|
22
21
|
class Resolver
|
23
22
|
include Schema::Member::GraphQLTypeNames
|
24
|
-
# Really we only need description from here, but:
|
23
|
+
# Really we only need description & comment from here, but:
|
25
24
|
extend Schema::Member::BaseDSLMethods
|
26
25
|
extend GraphQL::Schema::Member::HasArguments
|
27
26
|
extend GraphQL::Schema::Member::HasValidators
|
28
27
|
include Schema::Member::HasPath
|
29
28
|
extend Schema::Member::HasPath
|
29
|
+
extend Schema::Member::HasDirectives
|
30
30
|
|
31
|
-
# @param object [Object]
|
31
|
+
# @param object [Object] The application object that this field is being resolved on
|
32
32
|
# @param context [GraphQL::Query::Context]
|
33
33
|
# @param field [GraphQL::Schema::Field]
|
34
34
|
def initialize(object:, context:, field:)
|
@@ -37,10 +37,9 @@ module GraphQL
|
|
37
37
|
@field = field
|
38
38
|
# Since this hash is constantly rebuilt, cache it for this call
|
39
39
|
@arguments_by_keyword = {}
|
40
|
-
self.class.
|
40
|
+
context.types.arguments(self.class).each do |arg|
|
41
41
|
@arguments_by_keyword[arg.keyword] = arg
|
42
42
|
end
|
43
|
-
@arguments_loads_as_type = self.class.arguments_loads_as_type
|
44
43
|
@prepared_arguments = nil
|
45
44
|
end
|
46
45
|
|
@@ -68,49 +67,47 @@ module GraphQL
|
|
68
67
|
# @api private
|
69
68
|
def resolve_with_support(**args)
|
70
69
|
# First call the ready? hook which may raise
|
71
|
-
|
70
|
+
raw_ready_val = if !args.empty?
|
72
71
|
ready?(**args)
|
73
72
|
else
|
74
73
|
ready?
|
75
74
|
end
|
76
|
-
context.
|
77
|
-
if
|
75
|
+
context.query.after_lazy(raw_ready_val) do |ready_val|
|
76
|
+
if ready_val.is_a?(Array)
|
77
|
+
is_ready, ready_early_return = ready_val
|
78
78
|
if is_ready != false
|
79
|
-
raise "Unexpected result from #ready? (expected `true`, `false` or `[false, {...}]`): [#{
|
79
|
+
raise "Unexpected result from #ready? (expected `true`, `false` or `[false, {...}]`): [#{is_ready.inspect}, #{ready_early_return.inspect}]"
|
80
80
|
else
|
81
81
|
ready_early_return
|
82
82
|
end
|
83
|
-
elsif
|
83
|
+
elsif ready_val
|
84
84
|
# Then call each prepare hook, which may return a different value
|
85
85
|
# for that argument, or may return a lazy object
|
86
86
|
load_arguments_val = load_arguments(args)
|
87
|
-
context.
|
87
|
+
context.query.after_lazy(load_arguments_val) do |loaded_args|
|
88
88
|
@prepared_arguments = loaded_args
|
89
89
|
Schema::Validator.validate!(self.class.validators, object, context, loaded_args, as: @field)
|
90
90
|
# Then call `authorized?`, which may raise or may return a lazy object
|
91
|
-
|
91
|
+
raw_authorized_val = if !loaded_args.empty?
|
92
92
|
authorized?(**loaded_args)
|
93
93
|
else
|
94
94
|
authorized?
|
95
95
|
end
|
96
|
-
context.
|
96
|
+
context.query.after_lazy(raw_authorized_val) do |authorized_val|
|
97
97
|
# If the `authorized?` returned two values, `false, early_return`,
|
98
98
|
# then use the early return value instead of continuing
|
99
|
-
if
|
99
|
+
if authorized_val.is_a?(Array)
|
100
|
+
authorized_result, early_return = authorized_val
|
100
101
|
if authorized_result == false
|
101
102
|
early_return
|
102
103
|
else
|
103
104
|
raise "Unexpected result from #authorized? (expected `true`, `false` or `[false, {...}]`): [#{authorized_result.inspect}, #{early_return.inspect}]"
|
104
105
|
end
|
105
|
-
elsif
|
106
|
+
elsif authorized_val
|
106
107
|
# Finally, all the hooks have passed, so resolve it
|
107
|
-
|
108
|
-
public_send(self.class.resolve_method, **loaded_args)
|
109
|
-
else
|
110
|
-
public_send(self.class.resolve_method)
|
111
|
-
end
|
108
|
+
call_resolve(loaded_args)
|
112
109
|
else
|
113
|
-
|
110
|
+
raise GraphQL::UnauthorizedFieldError.new(context: context, object: object, type: field.owner, field: field)
|
114
111
|
end
|
115
112
|
end
|
116
113
|
end
|
@@ -118,6 +115,15 @@ module GraphQL
|
|
118
115
|
end
|
119
116
|
end
|
120
117
|
|
118
|
+
# @api private {GraphQL::Schema::Mutation} uses this to clear the dataloader cache
|
119
|
+
def call_resolve(args_hash)
|
120
|
+
if !args_hash.empty?
|
121
|
+
public_send(self.class.resolve_method, **args_hash)
|
122
|
+
else
|
123
|
+
public_send(self.class.resolve_method)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
121
127
|
# Do the work. Everything happens here.
|
122
128
|
# @return [Object] An object corresponding to the return type
|
123
129
|
def resolve(**args)
|
@@ -146,23 +152,42 @@ module GraphQL
|
|
146
152
|
# @raise [GraphQL::UnauthorizedError] To signal an authorization failure
|
147
153
|
# @return [Boolean, early_return_data] If `false`, execution will stop (and `early_return_data` will be returned instead, if present.)
|
148
154
|
def authorized?(**inputs)
|
149
|
-
self.class
|
155
|
+
arg_owner = @field # || self.class
|
156
|
+
args = context.types.arguments(arg_owner)
|
157
|
+
authorize_arguments(args, inputs)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Called when an object loaded by `loads:` fails the `.authorized?` check for its resolved GraphQL object type.
|
161
|
+
#
|
162
|
+
# By default, the error is re-raised and passed along to {{Schema.unauthorized_object}}.
|
163
|
+
#
|
164
|
+
# Any value returned here will be used _instead of_ of the loaded object.
|
165
|
+
# @param err [GraphQL::UnauthorizedError]
|
166
|
+
def unauthorized_object(err)
|
167
|
+
raise err
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
|
172
|
+
def authorize_arguments(args, inputs)
|
173
|
+
args.each do |argument|
|
150
174
|
arg_keyword = argument.keyword
|
151
175
|
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
152
|
-
|
153
|
-
if
|
154
|
-
return
|
155
|
-
|
156
|
-
|
176
|
+
auth_result = argument.authorized?(self, arg_value, context)
|
177
|
+
if auth_result.is_a?(Array)
|
178
|
+
# only return this second value if the application returned a second value
|
179
|
+
arg_auth, err = auth_result
|
180
|
+
if !arg_auth
|
181
|
+
return arg_auth, err
|
182
|
+
end
|
183
|
+
elsif auth_result == false
|
184
|
+
return auth_result
|
157
185
|
end
|
158
|
-
else
|
159
|
-
true
|
160
186
|
end
|
161
187
|
end
|
188
|
+
true
|
162
189
|
end
|
163
190
|
|
164
|
-
private
|
165
|
-
|
166
191
|
def load_arguments(args)
|
167
192
|
prepared_args = {}
|
168
193
|
prepare_lazies = []
|
@@ -170,35 +195,47 @@ module GraphQL
|
|
170
195
|
args.each do |key, value|
|
171
196
|
arg_defn = @arguments_by_keyword[key]
|
172
197
|
if arg_defn
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
if context.schema.lazy?(prepped_value)
|
178
|
-
prepare_lazies << context.schema.after_lazy(prepped_value) do |finished_prepped_value|
|
179
|
-
prepared_args[key] = finished_prepped_value
|
180
|
-
end
|
198
|
+
prepped_value = prepared_args[key] = arg_defn.load_and_authorize_value(self, value, context)
|
199
|
+
if context.schema.lazy?(prepped_value)
|
200
|
+
prepare_lazies << context.query.after_lazy(prepped_value) do |finished_prepped_value|
|
201
|
+
prepared_args[key] = finished_prepped_value
|
181
202
|
end
|
182
203
|
end
|
183
204
|
else
|
184
|
-
#
|
205
|
+
# these are `extras:`
|
185
206
|
prepared_args[key] = value
|
186
207
|
end
|
187
208
|
end
|
188
209
|
|
189
210
|
# Avoid returning a lazy if none are needed
|
190
|
-
if prepare_lazies.
|
211
|
+
if !prepare_lazies.empty?
|
191
212
|
GraphQL::Execution::Lazy.all(prepare_lazies).then { prepared_args }
|
192
213
|
else
|
193
214
|
prepared_args
|
194
215
|
end
|
195
216
|
end
|
196
217
|
|
197
|
-
def
|
198
|
-
|
218
|
+
def get_argument(name, context = GraphQL::Query::NullContext.instance)
|
219
|
+
self.class.get_argument(name, context)
|
199
220
|
end
|
200
221
|
|
201
222
|
class << self
|
223
|
+
def field_arguments(context = GraphQL::Query::NullContext.instance)
|
224
|
+
arguments(context)
|
225
|
+
end
|
226
|
+
|
227
|
+
def any_field_arguments?
|
228
|
+
any_arguments?
|
229
|
+
end
|
230
|
+
|
231
|
+
def get_field_argument(name, context = GraphQL::Query::NullContext.instance)
|
232
|
+
get_argument(name, context)
|
233
|
+
end
|
234
|
+
|
235
|
+
def all_field_argument_definitions
|
236
|
+
all_argument_definitions
|
237
|
+
end
|
238
|
+
|
202
239
|
# Default `:resolve` set below.
|
203
240
|
# @return [Symbol] The method to call on instances of this object to resolve the field
|
204
241
|
def resolve_method(new_method = nil)
|
@@ -218,8 +255,10 @@ module GraphQL
|
|
218
255
|
own_extras + (superclass.respond_to?(:extras) ? superclass.extras : [])
|
219
256
|
end
|
220
257
|
|
221
|
-
#
|
222
|
-
#
|
258
|
+
# If `true` (default), then the return type for this resolver will be nullable.
|
259
|
+
# If `false`, then the return type is non-null.
|
260
|
+
#
|
261
|
+
# @see #type which sets the return type of this field and accepts a `null:` option
|
223
262
|
# @param allow_null [Boolean] Whether or not the response can be null
|
224
263
|
def null(allow_null = nil)
|
225
264
|
if !allow_null.nil?
|
@@ -229,6 +268,14 @@ module GraphQL
|
|
229
268
|
@null.nil? ? (superclass.respond_to?(:null) ? superclass.null : true) : @null
|
230
269
|
end
|
231
270
|
|
271
|
+
def resolver_method(new_method_name = nil)
|
272
|
+
if new_method_name
|
273
|
+
@resolver_method = new_method_name
|
274
|
+
else
|
275
|
+
@resolver_method || :resolve_with_support
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
232
279
|
# Call this method to get the return type of the field,
|
233
280
|
# or use it as a configuration method to assign a return type
|
234
281
|
# instead of generating one.
|
@@ -244,8 +291,8 @@ module GraphQL
|
|
244
291
|
@type_expr = new_type
|
245
292
|
@null = null
|
246
293
|
else
|
247
|
-
if
|
248
|
-
GraphQL::Schema::Member::BuildType.parse_type(
|
294
|
+
if type_expr
|
295
|
+
GraphQL::Schema::Member::BuildType.parse_type(type_expr, null: self.null)
|
249
296
|
elsif superclass.respond_to?(:type)
|
250
297
|
superclass.type
|
251
298
|
else
|
@@ -280,8 +327,8 @@ module GraphQL
|
|
280
327
|
# (`nil` means "unlimited max page size".)
|
281
328
|
# @param max_page_size [Integer, nil] Set a new value
|
282
329
|
# @return [Integer, nil] The `max_page_size` assigned to fields that use this resolver
|
283
|
-
def max_page_size(new_max_page_size =
|
284
|
-
if new_max_page_size !=
|
330
|
+
def max_page_size(new_max_page_size = NOT_CONFIGURED)
|
331
|
+
if new_max_page_size != NOT_CONFIGURED
|
285
332
|
@max_page_size = new_max_page_size
|
286
333
|
elsif defined?(@max_page_size)
|
287
334
|
@max_page_size
|
@@ -294,28 +341,28 @@ module GraphQL
|
|
294
341
|
|
295
342
|
# @return [Boolean] `true` if this resolver or a superclass has an assigned `max_page_size`
|
296
343
|
def has_max_page_size?
|
297
|
-
defined?(@max_page_size) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?)
|
344
|
+
(!!defined?(@max_page_size)) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?)
|
298
345
|
end
|
299
346
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
if has_max_page_size?
|
315
|
-
field_opts[:max_page_size] = max_page_size
|
347
|
+
# Get or set the `default_page_size:` which will be configured for fields using this resolver
|
348
|
+
# (`nil` means "unlimited default page size".)
|
349
|
+
# @param default_page_size [Integer, nil] Set a new value
|
350
|
+
# @return [Integer, nil] The `default_page_size` assigned to fields that use this resolver
|
351
|
+
def default_page_size(new_default_page_size = NOT_CONFIGURED)
|
352
|
+
if new_default_page_size != NOT_CONFIGURED
|
353
|
+
@default_page_size = new_default_page_size
|
354
|
+
elsif defined?(@default_page_size)
|
355
|
+
@default_page_size
|
356
|
+
elsif superclass.respond_to?(:default_page_size)
|
357
|
+
superclass.default_page_size
|
358
|
+
else
|
359
|
+
nil
|
316
360
|
end
|
361
|
+
end
|
317
362
|
|
318
|
-
|
363
|
+
# @return [Boolean] `true` if this resolver or a superclass has an assigned `default_page_size`
|
364
|
+
def has_default_page_size?
|
365
|
+
(!!defined?(@default_page_size)) || (superclass.respond_to?(:has_default_page_size?) && superclass.has_default_page_size?)
|
319
366
|
end
|
320
367
|
|
321
368
|
# A non-normalized type configuration, without `null` applied
|
@@ -327,47 +374,9 @@ module GraphQL
|
|
327
374
|
# also add some preparation hook methods which will be used for this argument
|
328
375
|
# @see {GraphQL::Schema::Argument#initialize} for the signature
|
329
376
|
def argument(*args, **kwargs, &block)
|
330
|
-
loads = kwargs[:loads]
|
331
377
|
# Use `from_resolver: true` to short-circuit the InputObject's own `loads:` implementation
|
332
378
|
# so that we can support `#load_{x}` methods below.
|
333
|
-
|
334
|
-
own_arguments_loads_as_type[arg_defn.keyword] = loads if loads
|
335
|
-
|
336
|
-
if !method_defined?(:"load_#{arg_defn.keyword}")
|
337
|
-
if loads && arg_defn.type.list?
|
338
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
339
|
-
def load_#{arg_defn.keyword}(values)
|
340
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
341
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
342
|
-
context.schema.after_lazy(values) do |values2|
|
343
|
-
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, lookup_as_type, value, context) })
|
344
|
-
end
|
345
|
-
end
|
346
|
-
RUBY
|
347
|
-
elsif loads
|
348
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
349
|
-
def load_#{arg_defn.keyword}(value)
|
350
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
351
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
352
|
-
load_application_object(argument, lookup_as_type, value, context)
|
353
|
-
end
|
354
|
-
RUBY
|
355
|
-
else
|
356
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
357
|
-
def load_#{arg_defn.keyword}(value)
|
358
|
-
value
|
359
|
-
end
|
360
|
-
RUBY
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
arg_defn
|
365
|
-
end
|
366
|
-
|
367
|
-
# @api private
|
368
|
-
def arguments_loads_as_type
|
369
|
-
inherited_lookups = superclass.respond_to?(:arguments_loads_as_type) ? superclass.arguments_loads_as_type : {}
|
370
|
-
inherited_lookups.merge(own_arguments_loads_as_type)
|
379
|
+
super(*args, from_resolver: true, **kwargs)
|
371
380
|
end
|
372
381
|
|
373
382
|
# Registers new extension
|
@@ -385,7 +394,7 @@ module GraphQL
|
|
385
394
|
if superclass.respond_to?(:extensions)
|
386
395
|
s_exts = superclass.extensions
|
387
396
|
if own_exts
|
388
|
-
if s_exts.
|
397
|
+
if !s_exts.empty?
|
389
398
|
own_exts + s_exts
|
390
399
|
else
|
391
400
|
own_exts
|
@@ -400,13 +409,7 @@ module GraphQL
|
|
400
409
|
|
401
410
|
private
|
402
411
|
|
403
|
-
|
404
|
-
@own_extensions
|
405
|
-
end
|
406
|
-
|
407
|
-
def own_arguments_loads_as_type
|
408
|
-
@own_arguments_loads_as_type ||= {}
|
409
|
-
end
|
412
|
+
attr_reader :own_extensions
|
410
413
|
end
|
411
414
|
end
|
412
415
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
class Scalar < GraphQL::Schema::Member
|
5
|
-
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
5
|
extend GraphQL::Schema::Member::ValidatesInput
|
7
6
|
|
8
7
|
class << self
|
@@ -14,22 +13,22 @@ module GraphQL
|
|
14
13
|
val
|
15
14
|
end
|
16
15
|
|
17
|
-
def to_graphql
|
18
|
-
type_defn = GraphQL::ScalarType.new
|
19
|
-
type_defn.name = graphql_name
|
20
|
-
type_defn.description = description
|
21
|
-
type_defn.coerce_result = method(:coerce_result)
|
22
|
-
type_defn.coerce_input = method(:coerce_input)
|
23
|
-
type_defn.metadata[:type_class] = self
|
24
|
-
type_defn.default_scalar = default_scalar
|
25
|
-
type_defn.ast_node = ast_node
|
26
|
-
type_defn
|
27
|
-
end
|
28
|
-
|
29
16
|
def kind
|
30
17
|
GraphQL::TypeKinds::SCALAR
|
31
18
|
end
|
32
19
|
|
20
|
+
def specified_by_url(new_url = nil)
|
21
|
+
if new_url
|
22
|
+
directive(GraphQL::Schema::Directive::SpecifiedBy, url: new_url)
|
23
|
+
elsif (directive = directives.find { |dir| dir.graphql_name == "specifiedBy" })
|
24
|
+
directive.arguments[:url] # rubocop:disable Development/ContextIsPassedCop
|
25
|
+
elsif superclass.respond_to?(:specified_by_url)
|
26
|
+
superclass.specified_by_url
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
33
32
|
def default_scalar(is_default = nil)
|
34
33
|
if !is_default.nil?
|
35
34
|
@default_scalar = is_default
|
@@ -41,14 +40,13 @@ module GraphQL
|
|
41
40
|
@default_scalar ||= false
|
42
41
|
end
|
43
42
|
|
44
|
-
def validate_non_null_input(value, ctx)
|
45
|
-
result = Query::InputValidationResult.new
|
43
|
+
def validate_non_null_input(value, ctx, max_errors: nil)
|
46
44
|
coerced_result = begin
|
47
|
-
ctx
|
48
|
-
coerce_input(value, ctx)
|
49
|
-
end
|
45
|
+
coerce_input(value, ctx)
|
50
46
|
rescue GraphQL::CoercionError => err
|
51
47
|
err
|
48
|
+
rescue StandardError => err
|
49
|
+
ctx.query.handle_or_reraise(err)
|
52
50
|
end
|
53
51
|
|
54
52
|
if coerced_result.nil?
|
@@ -57,11 +55,12 @@ module GraphQL
|
|
57
55
|
else
|
58
56
|
" #{GraphQL::Language.serialize(value)}"
|
59
57
|
end
|
60
|
-
|
58
|
+
Query::InputValidationResult.from_problem("Could not coerce value#{str_value} to #{graphql_name}")
|
61
59
|
elsif coerced_result.is_a?(GraphQL::CoercionError)
|
62
|
-
|
60
|
+
Query::InputValidationResult.from_problem(coerced_result.message, message: coerced_result.message, extensions: coerced_result.extensions)
|
61
|
+
else
|
62
|
+
nil
|
63
63
|
end
|
64
|
-
result
|
65
64
|
end
|
66
65
|
end
|
67
66
|
end
|
@@ -14,34 +14,50 @@ module GraphQL
|
|
14
14
|
class Subscription < GraphQL::Schema::Resolver
|
15
15
|
extend GraphQL::Schema::Resolver::HasPayloadType
|
16
16
|
extend GraphQL::Schema::Member::HasFields
|
17
|
-
|
17
|
+
NO_UPDATE = :no_update
|
18
18
|
# The generated payload type is required; If there's no payload,
|
19
19
|
# propagate null.
|
20
20
|
null false
|
21
21
|
|
22
|
+
# @api private
|
22
23
|
def initialize(object:, context:, field:)
|
23
24
|
super
|
24
25
|
# Figure out whether this is an update or an initial subscription
|
25
26
|
@mode = context.query.subscription_update? ? :update : :subscribe
|
27
|
+
@subscription_written = false
|
28
|
+
@original_arguments = nil
|
29
|
+
if (subs_ns = context.namespace(:subscriptions)) &&
|
30
|
+
(sub_insts = subs_ns[:subscriptions])
|
31
|
+
sub_insts[context.current_path] = self
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
35
|
+
# @api private
|
28
36
|
def resolve_with_support(**args)
|
37
|
+
@original_arguments = args # before `loads:` have been run
|
29
38
|
result = nil
|
30
39
|
unsubscribed = true
|
31
|
-
catch :graphql_subscription_unsubscribed do
|
40
|
+
unsubscribed_result = catch :graphql_subscription_unsubscribed do
|
32
41
|
result = super
|
33
42
|
unsubscribed = false
|
34
43
|
end
|
35
44
|
|
36
45
|
|
37
46
|
if unsubscribed
|
38
|
-
|
47
|
+
if unsubscribed_result
|
48
|
+
context.namespace(:subscriptions)[:final_update] = true
|
49
|
+
unsubscribed_result
|
50
|
+
else
|
51
|
+
context.skip
|
52
|
+
end
|
39
53
|
else
|
40
54
|
result
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
44
|
-
# Implement the {Resolve} API
|
58
|
+
# Implement the {Resolve} API.
|
59
|
+
# You can implement this if you want code to run for _both_ the initial subscription
|
60
|
+
# and for later updates. Or, implement {#subscribe} and {#update}
|
45
61
|
def resolve(**args)
|
46
62
|
# Dispatch based on `@mode`, which will raise a `NoMethodError` if we ever
|
47
63
|
# have an unexpected `@mode`
|
@@ -49,8 +65,9 @@ module GraphQL
|
|
49
65
|
end
|
50
66
|
|
51
67
|
# Wrap the user-defined `#subscribe` hook
|
68
|
+
# @api private
|
52
69
|
def resolve_subscribe(**args)
|
53
|
-
ret_val = args.
|
70
|
+
ret_val = !args.empty? ? subscribe(**args) : subscribe
|
54
71
|
if ret_val == :no_response
|
55
72
|
context.skip
|
56
73
|
else
|
@@ -58,19 +75,18 @@ module GraphQL
|
|
58
75
|
end
|
59
76
|
end
|
60
77
|
|
61
|
-
#
|
78
|
+
# The default implementation returns nothing on subscribe.
|
62
79
|
# Override it to return an object or
|
63
|
-
# `:no_response` to return nothing.
|
64
|
-
#
|
65
|
-
# The default is `:no_response`.
|
80
|
+
# `:no_response` to (explicitly) return nothing.
|
66
81
|
def subscribe(args = {})
|
67
82
|
:no_response
|
68
83
|
end
|
69
84
|
|
70
85
|
# Wrap the user-provided `#update` hook
|
86
|
+
# @api private
|
71
87
|
def resolve_update(**args)
|
72
|
-
ret_val = args.
|
73
|
-
if ret_val ==
|
88
|
+
ret_val = !args.empty? ? update(**args) : update
|
89
|
+
if ret_val == NO_UPDATE
|
74
90
|
context.namespace(:subscriptions)[:no_update] = true
|
75
91
|
context.skip
|
76
92
|
else
|
@@ -79,7 +95,7 @@ module GraphQL
|
|
79
95
|
end
|
80
96
|
|
81
97
|
# The default implementation returns the root object.
|
82
|
-
# Override it to return
|
98
|
+
# Override it to return {NO_UPDATE} if you want to
|
83
99
|
# skip updates sometimes. Or override it to return a different object.
|
84
100
|
def update(args = {})
|
85
101
|
object
|
@@ -96,19 +112,22 @@ module GraphQL
|
|
96
112
|
end
|
97
113
|
|
98
114
|
# Call this to halt execution and remove this subscription from the system
|
99
|
-
|
115
|
+
# @param update_value [Object] if present, deliver this update before unsubscribing
|
116
|
+
# @return [void]
|
117
|
+
def unsubscribe(update_value = nil)
|
100
118
|
context.namespace(:subscriptions)[:unsubscribed] = true
|
101
|
-
throw :graphql_subscription_unsubscribed
|
119
|
+
throw :graphql_subscription_unsubscribed, update_value
|
102
120
|
end
|
103
121
|
|
104
|
-
READING_SCOPE = ::Object.new
|
105
122
|
# Call this method to provide a new subscription_scope; OR
|
106
123
|
# call it without an argument to get the subscription_scope
|
107
124
|
# @param new_scope [Symbol]
|
125
|
+
# @param optional [Boolean] If true, then don't require `scope:` to be provided to updates to this subscription.
|
108
126
|
# @return [Symbol]
|
109
|
-
def self.subscription_scope(new_scope =
|
110
|
-
if new_scope !=
|
127
|
+
def self.subscription_scope(new_scope = NOT_CONFIGURED, optional: false)
|
128
|
+
if new_scope != NOT_CONFIGURED
|
111
129
|
@subscription_scope = new_scope
|
130
|
+
@subscription_scope_optional = optional
|
112
131
|
elsif defined?(@subscription_scope)
|
113
132
|
@subscription_scope
|
114
133
|
else
|
@@ -116,10 +135,65 @@ module GraphQL
|
|
116
135
|
end
|
117
136
|
end
|
118
137
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
138
|
+
def self.subscription_scope_optional?
|
139
|
+
if defined?(@subscription_scope_optional)
|
140
|
+
@subscription_scope_optional
|
141
|
+
else
|
142
|
+
find_inherited_value(:subscription_scope_optional, false)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# This is called during initial subscription to get a "name" for this subscription.
|
147
|
+
# Later, when `.trigger` is called, this will be called again to build another "name".
|
148
|
+
# Any subscribers with matching topic will begin the update flow.
|
149
|
+
#
|
150
|
+
# The default implementation creates a string using the field name, subscription scope, and argument keys and values.
|
151
|
+
# In that implementation, only `.trigger` calls with _exact matches_ result in updates to subscribers.
|
152
|
+
#
|
153
|
+
# To implement a filtered stream-type subscription flow, override this method to return a string with field name and subscription scope.
|
154
|
+
# Then, implement {#update} to compare its arguments to the current `object` and return {NO_UPDATE} when an
|
155
|
+
# update should be filtered out.
|
156
|
+
#
|
157
|
+
# @see {#update} for how to skip updates when an event comes with a matching topic.
|
158
|
+
# @param arguments [Hash<String => Object>] The arguments for this topic, in GraphQL-style (camelized strings)
|
159
|
+
# @param field [GraphQL::Schema::Field]
|
160
|
+
# @param scope [Object, nil] A value corresponding to `.trigger(... scope:)` (for updates) or the `subscription_scope` found in `context` (for initial subscriptions).
|
161
|
+
# @return [String] An identifier corresponding to a stream of updates
|
162
|
+
def self.topic_for(arguments:, field:, scope:)
|
163
|
+
Subscriptions::Serialize.dump_recursive([scope, field.graphql_name, arguments])
|
164
|
+
end
|
165
|
+
|
166
|
+
# Calls through to `schema.subscriptions` to register this subscription with the backend.
|
167
|
+
# This is automatically called by GraphQL-Ruby after a query finishes successfully,
|
168
|
+
# but if you need to commit the subscription during `#subscribe`, you can call it there.
|
169
|
+
# (This method also sets a flag showing that this subscription was already written.)
|
170
|
+
#
|
171
|
+
# If you call this method yourself, you may also need to {#unsubscribe}
|
172
|
+
# or call `subscriptions.delete_subscription` to clean up the database if the query crashes with an error
|
173
|
+
# later in execution.
|
174
|
+
# @return [void]
|
175
|
+
def write_subscription
|
176
|
+
if subscription_written?
|
177
|
+
raise GraphQL::Error, "`write_subscription` was called but `#{self.class}#subscription_written?` is already true. Remove a call to `write subscription`."
|
178
|
+
else
|
179
|
+
@subscription_written = true
|
180
|
+
context.schema.subscriptions.write_subscription(context.query, [event])
|
181
|
+
end
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
|
185
|
+
# @return [Boolean] `true` if {#write_subscription} was called already
|
186
|
+
def subscription_written?
|
187
|
+
@subscription_written
|
188
|
+
end
|
189
|
+
|
190
|
+
# @return [Subscriptions::Event] This object is used as a representation of this subscription for the backend
|
191
|
+
def event
|
192
|
+
@event ||= Subscriptions::Event.new(
|
193
|
+
name: field.name,
|
194
|
+
arguments: @original_arguments,
|
195
|
+
context: context,
|
196
|
+
field: field,
|
123
197
|
)
|
124
198
|
end
|
125
199
|
end
|