graphql 1.9.18 → 1.13.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/graphql/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/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +29 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +174 -67
- data/lib/graphql/analysis/ast/visitor.rb +16 -7
- data/lib/graphql/analysis/ast.rb +21 -11
- data/lib/graphql/argument.rb +8 -36
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +44 -5
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +40 -9
- data/lib/graphql/backtrace.rb +28 -19
- data/lib/graphql/backwards_compatibility.rb +2 -1
- data/lib/graphql/base_type.rb +10 -4
- data/lib/graphql/boolean_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
- data/lib/graphql/compatibility/execution_specification.rb +1 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
- data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
- 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/define/assign_enum_value.rb +1 -1
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/assign_object_field.rb +1 -1
- data/lib/graphql/define/defined_object_proxy.rb +5 -8
- data/lib/graphql/define/instance_definable.rb +60 -110
- data/lib/graphql/define/type_definer.rb +5 -5
- data/lib/graphql/deprecated_dsl.rb +18 -5
- data/lib/graphql/deprecation.rb +9 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -12
- data/lib/graphql/directive/include_directive.rb +1 -1
- data/lib/graphql/directive/skip_directive.rb +1 -1
- data/lib/graphql/directive.rb +9 -6
- data/lib/graphql/enum_type.rb +14 -74
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +110 -8
- data/lib/graphql/execution/execute.rb +8 -1
- 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 +721 -386
- data/lib/graphql/execution/interpreter.rb +42 -19
- 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 +39 -114
- data/lib/graphql/execution/multiplex.rb +50 -25
- data/lib/graphql/field.rb +15 -119
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/float_type.rb +1 -1
- data/lib/graphql/function.rb +5 -30
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/input_object_type.rb +9 -25
- data/lib/graphql/int_type.rb +1 -1
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +10 -24
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/internal_representation/scope.rb +2 -2
- data/lib/graphql/internal_representation/visit.rb +2 -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 +12 -6
- data/lib/graphql/introspection/entry_points.rb +9 -9
- 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 +12 -12
- 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 +116 -63
- data/lib/graphql/language/lexer.rb +53 -27
- data/lib/graphql/language/lexer.rl +5 -3
- data/lib/graphql/language/nodes.rb +67 -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/non_null_type.rb +0 -10
- data/lib/graphql/object_type.rb +47 -58
- 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 +160 -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/arguments.rb +6 -4
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +52 -7
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/fingerprint.rb +26 -0
- data/lib/graphql/query/input_validation_result.rb +32 -6
- data/lib/graphql/query/literal_input.rb +31 -11
- data/lib/graphql/query/null_context.rb +24 -8
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/serial_execution.rb +1 -0
- data/lib/graphql/query/validation_pipeline.rb +6 -4
- data/lib/graphql/query/variable_validation_error.rb +3 -3
- data/lib/graphql/query/variables.rb +50 -10
- data/lib/graphql/query.rb +77 -18
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task/validate.rb +3 -0
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +30 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +18 -4
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/edges_instrumentation.rb +1 -2
- data/lib/graphql/relay/global_id_resolve.rb +1 -2
- data/lib/graphql/relay/mutation.rb +3 -87
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/page_info.rb +1 -1
- data/lib/graphql/relay/range_add.rb +27 -9
- data/lib/graphql/relay/relation_connection.rb +8 -10
- data/lib/graphql/relay/type_extensions.rb +2 -0
- 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/scalar_type.rb +18 -60
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +274 -18
- 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 +320 -219
- data/lib/graphql/schema/built_in_types.rb +5 -5
- data/lib/graphql/schema/default_type_error.rb +2 -0
- 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 +130 -6
- data/lib/graphql/schema/enum.rb +121 -12
- data/lib/graphql/schema/enum_value.rb +24 -7
- 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 +465 -181
- 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 +172 -37
- data/lib/graphql/schema/interface.rb +39 -25
- data/lib/graphql/schema/introspection_system.rb +106 -38
- data/lib/graphql/schema/late_bound_type.rb +3 -2
- data/lib/graphql/schema/list.rb +65 -1
- data/lib/graphql/schema/loader.rb +145 -102
- data/lib/graphql/schema/member/accepts_definition.rb +15 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +34 -28
- data/lib/graphql/schema/member/build_type.rb +19 -8
- data/lib/graphql/schema/member/cached_graphql_definition.rb +34 -2
- data/lib/graphql/schema/member/has_arguments.rb +206 -13
- 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 +97 -32
- data/lib/graphql/schema/member/has_interfaces.rb +100 -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/instrumentation.rb +0 -1
- 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 -0
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/non_null.rb +37 -1
- data/lib/graphql/schema/object.rb +51 -38
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -35
- data/lib/graphql/schema/relay_classic_mutation.rb +40 -4
- 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 +43 -3
- data/lib/graphql/schema/subscription.rb +57 -21
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/timeout_middleware.rb +3 -1
- data/lib/graphql/schema/traversal.rb +2 -2
- data/lib/graphql/schema/type_expression.rb +21 -13
- data/lib/graphql/schema/type_membership.rb +19 -5
- data/lib/graphql/schema/union.rb +44 -3
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +14 -4
- 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 +193 -34
- data/lib/graphql/schema.rb +882 -247
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/base_visitor.rb +17 -10
- 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 +2 -2
- 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 +43 -9
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/string_type.rb +1 -1
- 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 +21 -0
- data/lib/graphql/subscriptions/event.rb +84 -30
- data/lib/graphql/subscriptions/instrumentation.rb +10 -6
- data/lib/graphql/subscriptions/serialize.rb +53 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -5
- data/lib/graphql/subscriptions.rb +117 -49
- 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 +32 -15
- 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 +66 -10
- 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/skylight_tracing.rb +9 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +15 -35
- 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 +174 -0
- data/lib/graphql/types/relay/default_relay.rb +31 -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 +15 -0
- data/lib/graphql/types/relay/node_field.rb +3 -22
- data/lib/graphql/types/relay/nodes_field.rb +16 -18
- 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 -3
- data/lib/graphql/types/string.rb +8 -2
- data/lib/graphql/unauthorized_error.rb +2 -2
- data/lib/graphql/union_type.rb +5 -25
- data/lib/graphql/unresolved_type_error.rb +2 -2
- data/lib/graphql/upgrader/member.rb +1 -0
- data/lib/graphql/upgrader/schema.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +87 -31
- data/readme.md +3 -6
- metadata +126 -124
- data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
- data/lib/graphql/literal_validation_error.rb +0 -6
- 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
|
@@ -3,40 +3,51 @@
|
|
|
3
3
|
module GraphQL
|
|
4
4
|
class Schema
|
|
5
5
|
class Member
|
|
6
|
-
# Shared code for
|
|
6
|
+
# Shared code for Objects, Interfaces, Mutations, Subscriptions
|
|
7
7
|
module HasFields
|
|
8
8
|
# Add a field to this object or interface with the given definition
|
|
9
9
|
# @see {GraphQL::Schema::Field#initialize} for method signature
|
|
10
|
-
# @return [
|
|
10
|
+
# @return [GraphQL::Schema::Field]
|
|
11
11
|
def field(*args, **kwargs, &block)
|
|
12
12
|
field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
|
|
13
13
|
add_field(field_defn)
|
|
14
|
-
|
|
14
|
+
field_defn
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
|
18
|
-
def fields
|
|
18
|
+
def fields(context = GraphQL::Query::NullContext)
|
|
19
|
+
warden = Warden.from_context(context)
|
|
20
|
+
is_object = self.respond_to?(:kind) && self.kind.object?
|
|
19
21
|
# Local overrides take precedence over inherited fields
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if ancestor.respond_to?(:own_fields)
|
|
23
|
-
|
|
22
|
+
visible_fields = {}
|
|
23
|
+
for ancestor in ancestors
|
|
24
|
+
if ancestor.respond_to?(:own_fields) &&
|
|
25
|
+
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true)
|
|
26
|
+
|
|
27
|
+
ancestor.own_fields.each do |field_name, fields_entry|
|
|
28
|
+
# Choose the most local definition that passes `.visible?` --
|
|
29
|
+
# stop checking for fields by name once one has been found.
|
|
30
|
+
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
|
|
31
|
+
visible_fields[field_name] = f
|
|
32
|
+
end
|
|
33
|
+
end
|
|
24
34
|
end
|
|
25
35
|
end
|
|
26
|
-
|
|
36
|
+
visible_fields
|
|
27
37
|
end
|
|
28
38
|
|
|
29
|
-
def get_field(field_name)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
def get_field(field_name, context = GraphQL::Query::NullContext)
|
|
40
|
+
warden = Warden.from_context(context)
|
|
41
|
+
is_object = self.respond_to?(:kind) && self.kind.object?
|
|
42
|
+
for ancestor in ancestors
|
|
43
|
+
if ancestor.respond_to?(:own_fields) &&
|
|
44
|
+
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true) &&
|
|
45
|
+
(f_entry = ancestor.own_fields[field_name]) &&
|
|
46
|
+
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
|
|
47
|
+
return f
|
|
37
48
|
end
|
|
38
|
-
nil
|
|
39
49
|
end
|
|
50
|
+
nil
|
|
40
51
|
end
|
|
41
52
|
|
|
42
53
|
# A list of Ruby keywords.
|
|
@@ -47,22 +58,36 @@ module GraphQL
|
|
|
47
58
|
# A list of GraphQL-Ruby keywords.
|
|
48
59
|
#
|
|
49
60
|
# @api private
|
|
50
|
-
GRAPHQL_RUBY_KEYWORDS = [:context, :object, :
|
|
61
|
+
GRAPHQL_RUBY_KEYWORDS = [:context, :object, :raw_value]
|
|
51
62
|
|
|
52
63
|
# A list of field names that we should advise users to pick a different
|
|
53
64
|
# resolve method name.
|
|
54
65
|
#
|
|
55
66
|
# @api private
|
|
56
|
-
CONFLICT_FIELD_NAMES = Set.new(GRAPHQL_RUBY_KEYWORDS + RUBY_KEYWORDS)
|
|
67
|
+
CONFLICT_FIELD_NAMES = Set.new(GRAPHQL_RUBY_KEYWORDS + RUBY_KEYWORDS + Object.instance_methods)
|
|
57
68
|
|
|
58
69
|
# Register this field with the class, overriding a previous one if needed.
|
|
59
70
|
# @param field_defn [GraphQL::Schema::Field]
|
|
60
71
|
# @return [void]
|
|
61
|
-
def add_field(field_defn)
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
|
|
73
|
+
# Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
|
|
74
|
+
# that shows that no override value was given manually.
|
|
75
|
+
if method_conflict_warning && CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) && field_defn.original_name == field_defn.resolver_method && field_defn.original_name == field_defn.method_sym
|
|
76
|
+
warn(conflict_field_name_warning(field_defn))
|
|
77
|
+
end
|
|
78
|
+
prev_defn = own_fields[field_defn.name]
|
|
79
|
+
|
|
80
|
+
case prev_defn
|
|
81
|
+
when nil
|
|
82
|
+
own_fields[field_defn.name] = field_defn
|
|
83
|
+
when Array
|
|
84
|
+
prev_defn << field_defn
|
|
85
|
+
when GraphQL::Schema::Field
|
|
86
|
+
own_fields[field_defn.name] = [prev_defn, field_defn]
|
|
87
|
+
else
|
|
88
|
+
raise "Invariant: unexpected previous field definition for #{field_defn.name.inspect}: #{prev_defn.inspect}"
|
|
64
89
|
end
|
|
65
|
-
|
|
90
|
+
|
|
66
91
|
nil
|
|
67
92
|
end
|
|
68
93
|
|
|
@@ -70,28 +95,68 @@ module GraphQL
|
|
|
70
95
|
def field_class(new_field_class = nil)
|
|
71
96
|
if new_field_class
|
|
72
97
|
@field_class = new_field_class
|
|
73
|
-
elsif @field_class
|
|
98
|
+
elsif defined?(@field_class) && @field_class
|
|
74
99
|
@field_class
|
|
75
|
-
elsif self.is_a?(Class)
|
|
76
|
-
superclass.respond_to?(:field_class) ? superclass.field_class : GraphQL::Schema::Field
|
|
77
100
|
else
|
|
78
|
-
|
|
79
|
-
ancestor ? ancestor.field_class : GraphQL::Schema::Field
|
|
101
|
+
find_inherited_value(:field_class, GraphQL::Schema::Field)
|
|
80
102
|
end
|
|
81
103
|
end
|
|
82
104
|
|
|
83
|
-
def global_id_field(field_name)
|
|
105
|
+
def global_id_field(field_name, **kwargs)
|
|
84
106
|
id_resolver = GraphQL::Relay::GlobalIdResolve.new(type: self)
|
|
85
|
-
field field_name, "ID", null: false
|
|
107
|
+
field field_name, "ID", **kwargs, null: false
|
|
86
108
|
define_method(field_name) do
|
|
87
109
|
id_resolver.call(object, {}, context)
|
|
88
110
|
end
|
|
89
111
|
end
|
|
90
112
|
|
|
91
|
-
# @return [Array<GraphQL::Schema::Field
|
|
113
|
+
# @return [Hash<String => GraphQL::Schema::Field, Array<GraphQL::Schema::Field>>] Fields defined on this class _specifically_, not parent classes
|
|
92
114
|
def own_fields
|
|
93
115
|
@own_fields ||= {}
|
|
94
116
|
end
|
|
117
|
+
|
|
118
|
+
def all_field_definitions
|
|
119
|
+
all_fields = {}
|
|
120
|
+
ancestors.reverse_each do |ancestor|
|
|
121
|
+
if ancestor.respond_to?(:own_fields)
|
|
122
|
+
all_fields.merge!(ancestor.own_fields)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
all_fields = all_fields.values
|
|
126
|
+
all_fields.flatten!
|
|
127
|
+
all_fields
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
# If `type` is an interface, and `self` has a type membership for `type`, then make sure it's visible.
|
|
133
|
+
def visible_interface_implementation?(type, context, warden)
|
|
134
|
+
if type.respond_to?(:kind) && type.kind.interface?
|
|
135
|
+
implements_this_interface = false
|
|
136
|
+
implementation_is_visible = false
|
|
137
|
+
warden.interface_type_memberships(self, context).each do |tm|
|
|
138
|
+
if tm.abstract_type == type
|
|
139
|
+
implements_this_interface ||= true
|
|
140
|
+
if warden.visible_type_membership?(tm, context)
|
|
141
|
+
implementation_is_visible = true
|
|
142
|
+
break
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
# It's possible this interface came by way of `include` in another interface which this
|
|
147
|
+
# object type _does_ implement, and that's ok
|
|
148
|
+
implements_this_interface ? implementation_is_visible : true
|
|
149
|
+
else
|
|
150
|
+
# If there's no implementation, then we're looking at Ruby-style inheritance instead
|
|
151
|
+
true
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# @param [GraphQL::Schema::Field]
|
|
156
|
+
# @return [String] A warning to give when this field definition might conflict with a built-in method
|
|
157
|
+
def conflict_field_name_warning(field_defn)
|
|
158
|
+
"#{self.graphql_name}'s `field :#{field_defn.original_name}` conflicts with a built-in method, use `resolver_method:` to pick a different resolver method for this field (for example, `resolver_method: :resolve_#{field_defn.resolver_method}` and `def resolve_#{field_defn.resolver_method}`). Or use `method_conflict_warning: false` to suppress this warning."
|
|
159
|
+
end
|
|
95
160
|
end
|
|
96
161
|
end
|
|
97
162
|
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
class Schema
|
|
5
|
+
class Member
|
|
6
|
+
module HasInterfaces
|
|
7
|
+
def implements(*new_interfaces, **options)
|
|
8
|
+
new_memberships = []
|
|
9
|
+
new_interfaces.each do |int|
|
|
10
|
+
if int.is_a?(Module)
|
|
11
|
+
unless int.include?(GraphQL::Schema::Interface)
|
|
12
|
+
raise "#{int} cannot be implemented since it's not a GraphQL Interface. Use `include` for plain Ruby modules."
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
new_memberships << int.type_membership_class.new(int, self, **options)
|
|
16
|
+
|
|
17
|
+
# Include the methods here,
|
|
18
|
+
# `.fields` will use the inheritance chain
|
|
19
|
+
# to find inherited fields
|
|
20
|
+
include(int)
|
|
21
|
+
|
|
22
|
+
# If this interface has interfaces of its own, add those, too
|
|
23
|
+
int.interfaces.each do |next_interface|
|
|
24
|
+
implements(next_interface)
|
|
25
|
+
end
|
|
26
|
+
elsif int.is_a?(GraphQL::InterfaceType)
|
|
27
|
+
new_memberships << int.type_membership_class.new(int, self, **options)
|
|
28
|
+
elsif int.is_a?(String) || int.is_a?(GraphQL::Schema::LateBoundType)
|
|
29
|
+
if options.any?
|
|
30
|
+
raise ArgumentError, "`implements(...)` doesn't support options with late-loaded types yet. Remove #{options} and open an issue to request this feature."
|
|
31
|
+
end
|
|
32
|
+
new_memberships << int
|
|
33
|
+
else
|
|
34
|
+
raise ArgumentError, "Unexpected interface definition (expected module): #{int} (#{int.class})"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Remove any String or late-bound interfaces which are being replaced
|
|
39
|
+
own_interface_type_memberships.reject! { |old_i_m|
|
|
40
|
+
if !(old_i_m.respond_to?(:abstract_type) && old_i_m.abstract_type.is_a?(Module))
|
|
41
|
+
old_int_type = old_i_m.respond_to?(:abstract_type) ? old_i_m.abstract_type : old_i_m
|
|
42
|
+
old_name = Schema::Member::BuildType.to_type_name(old_int_type)
|
|
43
|
+
|
|
44
|
+
new_memberships.any? { |new_i_m|
|
|
45
|
+
new_int_type = new_i_m.respond_to?(:abstract_type) ? new_i_m.abstract_type : new_i_m
|
|
46
|
+
new_name = Schema::Member::BuildType.to_type_name(new_int_type)
|
|
47
|
+
|
|
48
|
+
new_name == old_name
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
}
|
|
52
|
+
own_interface_type_memberships.concat(new_memberships)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def own_interface_type_memberships
|
|
56
|
+
@own_interface_type_memberships ||= []
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def interface_type_memberships
|
|
60
|
+
own_tms = own_interface_type_memberships
|
|
61
|
+
if (self.is_a?(Class) && superclass.respond_to?(:interface_type_memberships))
|
|
62
|
+
inherited_tms = superclass.interface_type_memberships
|
|
63
|
+
if inherited_tms.size > 0
|
|
64
|
+
own_tms + inherited_tms
|
|
65
|
+
else
|
|
66
|
+
own_tms
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
own_tms
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# param context [Query::Context] If omitted, skip filtering.
|
|
74
|
+
def interfaces(context = GraphQL::Query::NullContext)
|
|
75
|
+
warden = Warden.from_context(context)
|
|
76
|
+
visible_interfaces = []
|
|
77
|
+
own_interface_type_memberships.each do |type_membership|
|
|
78
|
+
# During initialization, `type_memberships` can hold late-bound types
|
|
79
|
+
case type_membership
|
|
80
|
+
when String, Schema::LateBoundType
|
|
81
|
+
visible_interfaces << type_membership
|
|
82
|
+
when Schema::TypeMembership
|
|
83
|
+
if warden.visible_type_membership?(type_membership, context)
|
|
84
|
+
visible_interfaces << type_membership.abstract_type
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
raise "Invariant: Unexpected type_membership #{type_membership.class}: #{type_membership.inspect}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if self.is_a?(Class) && superclass <= GraphQL::Schema::Object
|
|
92
|
+
visible_interfaces.concat(superclass.interfaces(context))
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
visible_interfaces
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
class Schema
|
|
5
|
+
class Member
|
|
6
|
+
# Set up a type-specific error to make debugging & bug tracker integration better
|
|
7
|
+
module HasUnresolvedTypeError
|
|
8
|
+
private
|
|
9
|
+
def add_unresolved_type_error(child_class)
|
|
10
|
+
child_class.const_set(:UnresolvedTypeError, Class.new(GraphQL::UnresolvedTypeError))
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module GraphQL
|
|
3
|
+
class Schema
|
|
4
|
+
class Member
|
|
5
|
+
module HasValidators
|
|
6
|
+
include Schema::FindInheritedValue::EmptyObjects
|
|
7
|
+
|
|
8
|
+
# Build {GraphQL::Schema::Validator}s based on the given configuration
|
|
9
|
+
# and use them for this schema member
|
|
10
|
+
# @param validation_config [Hash{Symbol => Hash}]
|
|
11
|
+
# @return [void]
|
|
12
|
+
def validates(validation_config)
|
|
13
|
+
new_validators = GraphQL::Schema::Validator.from_config(self, validation_config)
|
|
14
|
+
@own_validators ||= []
|
|
15
|
+
@own_validators.concat(new_validators)
|
|
16
|
+
nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array<GraphQL::Schema::Validator>]
|
|
20
|
+
def validators
|
|
21
|
+
own_validators = @own_validators || EMPTY_ARRAY
|
|
22
|
+
if self.is_a?(Class) && superclass.respond_to?(:validators) && (inherited_validators = superclass.validators).any?
|
|
23
|
+
inherited_validators + own_validators
|
|
24
|
+
else
|
|
25
|
+
own_validators
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -6,12 +6,12 @@ module GraphQL
|
|
|
6
6
|
module TypeSystemHelpers
|
|
7
7
|
# @return [Schema::NonNull] Make a non-null-type representation of this type
|
|
8
8
|
def to_non_null_type
|
|
9
|
-
GraphQL::Schema::NonNull.new(self)
|
|
9
|
+
@to_non_null_type ||= GraphQL::Schema::NonNull.new(self)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# @return [Schema::List] Make a list-type representation of this type
|
|
13
13
|
def to_list_type
|
|
14
|
-
GraphQL::Schema::List.new(self)
|
|
14
|
+
@to_list_type ||= GraphQL::Schema::List.new(self)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# @return [Boolean] true if this is a non-nullable type. A nullable list of non-nullables is considered nullable.
|
|
@@ -30,7 +30,7 @@ module GraphQL
|
|
|
30
30
|
|
|
31
31
|
# @return [GraphQL::TypeKinds::TypeKind]
|
|
32
32
|
def kind
|
|
33
|
-
raise GraphQL::RequiredImplementationMissingError
|
|
33
|
+
raise GraphQL::RequiredImplementationMissingError, "No `.kind` defined for #{self}"
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GraphQL
|
|
4
|
+
class Schema
|
|
5
|
+
class Member
|
|
6
|
+
module ValidatesInput
|
|
7
|
+
def valid_input?(val, ctx)
|
|
8
|
+
validate_input(val, ctx).valid?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def validate_input(val, ctx, max_errors: nil)
|
|
12
|
+
if val.nil?
|
|
13
|
+
GraphQL::Query::InputValidationResult.new
|
|
14
|
+
else
|
|
15
|
+
validate_non_null_input(val, ctx, max_errors: max_errors) || Query::InputValidationResult::VALID
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def valid_isolated_input?(v)
|
|
20
|
+
valid_input?(v, GraphQL::Query::NullContext)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def coerce_isolated_input(v)
|
|
24
|
+
coerce_input(v, GraphQL::Query::NullContext)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def coerce_isolated_result(v)
|
|
28
|
+
coerce_result(v, GraphQL::Query::NullContext)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -3,10 +3,17 @@ require 'graphql/schema/member/accepts_definition'
|
|
|
3
3
|
require 'graphql/schema/member/base_dsl_methods'
|
|
4
4
|
require 'graphql/schema/member/cached_graphql_definition'
|
|
5
5
|
require 'graphql/schema/member/graphql_type_names'
|
|
6
|
+
require 'graphql/schema/member/has_ast_node'
|
|
7
|
+
require 'graphql/schema/member/has_directives'
|
|
8
|
+
require 'graphql/schema/member/has_deprecation_reason'
|
|
9
|
+
require 'graphql/schema/member/has_interfaces'
|
|
6
10
|
require 'graphql/schema/member/has_path'
|
|
11
|
+
require 'graphql/schema/member/has_unresolved_type_error'
|
|
12
|
+
require 'graphql/schema/member/has_validators'
|
|
7
13
|
require 'graphql/schema/member/relay_shortcuts'
|
|
8
14
|
require 'graphql/schema/member/scoped'
|
|
9
15
|
require 'graphql/schema/member/type_system_helpers'
|
|
16
|
+
require 'graphql/schema/member/validates_input'
|
|
10
17
|
require "graphql/relay/type_extensions"
|
|
11
18
|
|
|
12
19
|
module GraphQL
|
|
@@ -20,10 +27,14 @@ module GraphQL
|
|
|
20
27
|
extend CachedGraphQLDefinition
|
|
21
28
|
extend GraphQL::Relay::TypeExtensions
|
|
22
29
|
extend BaseDSLMethods
|
|
30
|
+
extend BaseDSLMethods::ConfigurationExtension
|
|
31
|
+
introspection(false)
|
|
23
32
|
extend TypeSystemHelpers
|
|
24
33
|
extend Scoped
|
|
25
34
|
extend RelayShortcuts
|
|
26
35
|
extend HasPath
|
|
36
|
+
extend HasAstNode
|
|
37
|
+
extend HasDirectives
|
|
27
38
|
end
|
|
28
39
|
end
|
|
29
40
|
end
|
|
@@ -71,7 +71,7 @@ module GraphQL
|
|
|
71
71
|
|
|
72
72
|
def wrap(callable)
|
|
73
73
|
if BackwardsCompatibility.get_arity(callable) == 6
|
|
74
|
-
warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
|
|
74
|
+
GraphQL::Deprecation.warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
|
|
75
75
|
MiddlewareWrapper.new(callable)
|
|
76
76
|
else
|
|
77
77
|
callable
|
|
@@ -78,6 +78,10 @@ module GraphQL
|
|
|
78
78
|
|
|
79
79
|
private
|
|
80
80
|
|
|
81
|
+
def conflict_field_name_warning(field_defn)
|
|
82
|
+
"#{self.graphql_name}'s `field :#{field_defn.name}` conflicts with a built-in method, use `hash_key:` or `method:` to pick a different resolve behavior for this field (for example, `hash_key: :#{field_defn.resolver_method}_value`, and modify the return hash). Or use `method_conflict_warning: false` to suppress this warning."
|
|
83
|
+
end
|
|
84
|
+
|
|
81
85
|
# Override this to attach self as `mutation`
|
|
82
86
|
def generate_payload_type
|
|
83
87
|
payload_class = super
|
|
@@ -6,8 +6,12 @@ module GraphQL
|
|
|
6
6
|
# Wraps a {Schema::Member} when it is required.
|
|
7
7
|
# @see {Schema::Member::TypeSystemHelpers#to_non_null_type}
|
|
8
8
|
class NonNull < GraphQL::Schema::Wrapper
|
|
9
|
+
include Schema::Member::ValidatesInput
|
|
10
|
+
|
|
11
|
+
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
|
12
|
+
|
|
9
13
|
def to_graphql
|
|
10
|
-
@of_type.graphql_definition.to_non_null_type
|
|
14
|
+
@of_type.graphql_definition(silence_deprecation_warning: true).to_non_null_type
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
# @return [GraphQL::TypeKinds::NON_NULL]
|
|
@@ -32,6 +36,38 @@ module GraphQL
|
|
|
32
36
|
def inspect
|
|
33
37
|
"#<#{self.class.name} @of_type=#{@of_type.inspect}>"
|
|
34
38
|
end
|
|
39
|
+
|
|
40
|
+
def validate_input(value, ctx, max_errors: nil)
|
|
41
|
+
if value.nil?
|
|
42
|
+
result = GraphQL::Query::InputValidationResult.new
|
|
43
|
+
result.add_problem("Expected value to not be null")
|
|
44
|
+
result
|
|
45
|
+
else
|
|
46
|
+
of_type.validate_input(value, ctx, max_errors: max_errors)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# This is for introspection, where it's expected the name will be `null`
|
|
51
|
+
def graphql_name
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def coerce_input(value, ctx)
|
|
56
|
+
# `.validate_input` above is used for variables, but this method is used for arguments
|
|
57
|
+
if value.nil?
|
|
58
|
+
raise GraphQL::ExecutionError, "`null` is not a valid input for `#{to_type_signature}`, please provide a value for this argument."
|
|
59
|
+
end
|
|
60
|
+
of_type.coerce_input(value, ctx)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def coerce_result(value, ctx)
|
|
64
|
+
of_type.coerce_result(value, ctx)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# This is for implementing introspection
|
|
68
|
+
def description
|
|
69
|
+
nil
|
|
70
|
+
end
|
|
35
71
|
end
|
|
36
72
|
end
|
|
37
73
|
end
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "graphql/query/null_context"
|
|
4
|
+
|
|
3
5
|
module GraphQL
|
|
4
6
|
class Schema
|
|
5
7
|
class Object < GraphQL::Schema::Member
|
|
6
8
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
|
7
9
|
extend GraphQL::Schema::Member::HasFields
|
|
10
|
+
extend GraphQL::Schema::Member::HasInterfaces
|
|
8
11
|
|
|
9
12
|
# @return [Object] the application object this type is wrapping
|
|
10
13
|
attr_reader :object
|
|
@@ -12,6 +15,17 @@ module GraphQL
|
|
|
12
15
|
# @return [GraphQL::Query::Context] the context instance for this query
|
|
13
16
|
attr_reader :context
|
|
14
17
|
|
|
18
|
+
# @return [GraphQL::Dataloader]
|
|
19
|
+
def dataloader
|
|
20
|
+
context.dataloader
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Call this in a field method to return a value that should be returned to the client
|
|
24
|
+
# without any further handling by GraphQL.
|
|
25
|
+
def raw_value(obj)
|
|
26
|
+
GraphQL::Execution::Interpreter::RawValue.new(obj)
|
|
27
|
+
end
|
|
28
|
+
|
|
15
29
|
class << self
|
|
16
30
|
# This is protected so that we can be sure callers use the public method, {.authorized_new}
|
|
17
31
|
# @see authorized_new to make instances
|
|
@@ -35,14 +49,28 @@ module GraphQL
|
|
|
35
49
|
# @return [GraphQL::Schema::Object, GraphQL::Execution::Lazy]
|
|
36
50
|
# @raise [GraphQL::UnauthorizedError] if the user-provided hook returns `false`
|
|
37
51
|
def authorized_new(object, context)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
trace_payload = { context: context, type: self, object: object, path: context[:current_path] }
|
|
53
|
+
|
|
54
|
+
maybe_lazy_auth_val = context.query.trace("authorized", trace_payload) do
|
|
55
|
+
context.query.with_error_handling do
|
|
56
|
+
begin
|
|
57
|
+
authorized?(object, context)
|
|
58
|
+
rescue GraphQL::UnauthorizedError => err
|
|
59
|
+
context.schema.unauthorized_object(err)
|
|
60
|
+
end
|
|
43
61
|
end
|
|
44
62
|
end
|
|
45
63
|
|
|
64
|
+
auth_val = if context.schema.lazy?(maybe_lazy_auth_val)
|
|
65
|
+
GraphQL::Execution::Lazy.new do
|
|
66
|
+
context.query.trace("authorized_lazy", trace_payload) do
|
|
67
|
+
context.schema.sync_lazy(maybe_lazy_auth_val)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
maybe_lazy_auth_val
|
|
72
|
+
end
|
|
73
|
+
|
|
46
74
|
context.schema.after_lazy(auth_val) do |is_authorized|
|
|
47
75
|
if is_authorized
|
|
48
76
|
self.new(object, context)
|
|
@@ -57,13 +85,9 @@ module GraphQL
|
|
|
57
85
|
else
|
|
58
86
|
nil
|
|
59
87
|
end
|
|
60
|
-
# rescue GraphQL::ExecutionError => err
|
|
61
|
-
# err
|
|
62
88
|
end
|
|
63
89
|
end
|
|
64
90
|
end
|
|
65
|
-
# rescue GraphQL::ExecutionError => err
|
|
66
|
-
# err
|
|
67
91
|
end
|
|
68
92
|
end
|
|
69
93
|
|
|
@@ -73,37 +97,23 @@ module GraphQL
|
|
|
73
97
|
end
|
|
74
98
|
|
|
75
99
|
class << self
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Include the methods here,
|
|
84
|
-
# `.fields` will use the inheritance chain
|
|
85
|
-
# to find inherited fields
|
|
86
|
-
include(int)
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
own_interfaces.concat(new_interfaces)
|
|
100
|
+
# Set up a type-specific invalid null error to use when this object's non-null fields wrongly return `nil`.
|
|
101
|
+
# It should help with debugging and bug tracker integrations.
|
|
102
|
+
def inherited(child_class)
|
|
103
|
+
child_class.const_set(:InvalidNullError, GraphQL::InvalidNullError.subclass_for(child_class))
|
|
104
|
+
super
|
|
90
105
|
end
|
|
91
106
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def own_interfaces
|
|
97
|
-
@own_interfaces ||= []
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Include legacy-style interfaces, too
|
|
101
|
-
def fields
|
|
107
|
+
# @return [Hash<String => GraphQL::Schema::Field>] All of this object's fields, indexed by name
|
|
108
|
+
# @see get_field A faster way to find one field by name ({#fields} merges hashes of inherited fields; {#get_field} just looks up one field.)
|
|
109
|
+
def fields(context = GraphQL::Query::NullContext)
|
|
102
110
|
all_fields = super
|
|
111
|
+
# This adds fields from legacy-style interfaces only.
|
|
112
|
+
# Multi-fields are not supported here.
|
|
103
113
|
interfaces.each do |int|
|
|
104
114
|
if int.is_a?(GraphQL::InterfaceType)
|
|
105
115
|
int_f = {}
|
|
106
|
-
int.fields.each do |name, legacy_field|
|
|
116
|
+
int.fields.each do |name, legacy_field| # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
|
107
117
|
int_f[name] = field_class.from_options(name, field: legacy_field)
|
|
108
118
|
end
|
|
109
119
|
all_fields = int_f.merge(all_fields)
|
|
@@ -112,17 +122,20 @@ module GraphQL
|
|
|
112
122
|
all_fields
|
|
113
123
|
end
|
|
114
124
|
|
|
125
|
+
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
|
126
|
+
|
|
115
127
|
# @return [GraphQL::ObjectType]
|
|
116
128
|
def to_graphql
|
|
117
129
|
obj_type = GraphQL::ObjectType.new
|
|
118
130
|
obj_type.name = graphql_name
|
|
119
131
|
obj_type.description = description
|
|
120
|
-
obj_type.
|
|
132
|
+
obj_type.structural_interface_type_memberships = interface_type_memberships
|
|
121
133
|
obj_type.introspection = introspection
|
|
122
134
|
obj_type.mutation = mutation
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
135
|
+
obj_type.ast_node = ast_node
|
|
136
|
+
fields.each do |field_name, field_inst| # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
|
137
|
+
field_defn = field_inst.to_graphql(silence_deprecation_warning: true)
|
|
138
|
+
obj_type.fields[field_defn.name] = field_defn # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
|
126
139
|
end
|
|
127
140
|
|
|
128
141
|
obj_type.metadata[:type_class] = self
|