graphql 1.10.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +18 -2
- data/lib/generators/graphql/install_generator.rb +36 -6
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +2 -1
- data/lib/generators/graphql/object_generator.rb +54 -9
- data/lib/generators/graphql/relay.rb +63 -0
- data/lib/generators/graphql/relay_generator.rb +21 -0
- 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_mutation.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 +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
- data/lib/generators/graphql/templates/interface.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +9 -0
- data/lib/generators/graphql/templates/object.erb +3 -1
- data/lib/generators/graphql/templates/query_type.erb +3 -3
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +21 -33
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyze_query.rb +7 -0
- data/lib/graphql/analysis/ast/field_usage.rb +24 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +126 -109
- data/lib/graphql/analysis/ast/visitor.rb +13 -5
- data/lib/graphql/analysis/ast.rb +11 -2
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
- data/lib/graphql/backtrace/table.rb +34 -3
- 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 +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.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/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/instance_definable.rb +34 -4
- 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.rb +4 -4
- data/lib/graphql/enum_type.rb +7 -1
- data/lib/graphql/execution/errors.rb +110 -7
- 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 +103 -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 +685 -421
- data/lib/graphql/execution/interpreter.rb +42 -13
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/execution/lookahead.rb +25 -110
- data/lib/graphql/execution/multiplex.rb +37 -25
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/function.rb +4 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/integer_encoding_error.rb +18 -2
- data/lib/graphql/interface_type.rb +7 -0
- 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/directive_type.rb +8 -4
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +9 -5
- data/lib/graphql/introspection/input_value_type.rb +15 -3
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/schema_type.rb +4 -4
- data/lib/graphql/introspection/type_type.rb +16 -12
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/block_string.rb +20 -5
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/document_from_schema_definition.rb +73 -25
- data/lib/graphql/language/lexer.rb +4 -3
- data/lib/graphql/language/lexer.rl +3 -3
- data/lib/graphql/language/nodes.rb +51 -89
- data/lib/graphql/language/parser.rb +552 -530
- data/lib/graphql/language/parser.y +114 -99
- data/lib/graphql/language/printer.rb +7 -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 +2 -0
- data/lib/graphql/name_validator.rb +2 -7
- data/lib/graphql/object_type.rb +44 -35
- data/lib/graphql/pagination/active_record_relation_connection.rb +14 -1
- data/lib/graphql/pagination/array_connection.rb +2 -2
- data/lib/graphql/pagination/connection.rb +75 -20
- data/lib/graphql/pagination/connections.rb +83 -31
- data/lib/graphql/pagination/relation_connection.rb +34 -14
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query/arguments.rb +4 -3
- data/lib/graphql/query/arguments_cache.rb +1 -2
- data/lib/graphql/query/context.rb +42 -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 +23 -6
- data/lib/graphql/query/literal_input.rb +1 -1
- 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 +5 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +14 -4
- data/lib/graphql/query.rb +68 -13
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/rake_task.rb +12 -9
- data/lib/graphql/relay/array_connection.rb +10 -12
- data/lib/graphql/relay/base_connection.rb +26 -13
- data/lib/graphql/relay/connection_instrumentation.rb +4 -4
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/mutation.rb +1 -0
- data/lib/graphql/relay/node.rb +3 -0
- data/lib/graphql/relay/range_add.rb +23 -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 +16 -1
- data/lib/graphql/schema/addition.rb +247 -0
- data/lib/graphql/schema/argument.rb +210 -12
- data/lib/graphql/schema/base_64_encoder.rb +2 -0
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/build_from_definition.rb +213 -86
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +57 -0
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +14 -2
- data/lib/graphql/schema/directive.rb +78 -2
- data/lib/graphql/schema/enum.rb +80 -9
- data/lib/graphql/schema/enum_value.rb +17 -6
- data/lib/graphql/schema/field/connection_extension.rb +46 -30
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +285 -133
- data/lib/graphql/schema/find_inherited_value.rb +4 -1
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +97 -89
- data/lib/graphql/schema/interface.rb +24 -19
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +7 -1
- data/lib/graphql/schema/loader.rb +137 -103
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -19
- data/lib/graphql/schema/member/build_type.rb +14 -7
- data/lib/graphql/schema/member/has_arguments.rb +205 -12
- data/lib/graphql/schema/member/has_ast_node.rb +4 -1
- 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 +95 -30
- data/lib/graphql/schema/member/has_interfaces.rb +90 -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.rb +6 -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 +5 -0
- data/lib/graphql/schema/object.rb +47 -46
- data/lib/graphql/schema/possible_types.rb +9 -4
- data/lib/graphql/schema/printer.rb +16 -34
- data/lib/graphql/schema/relay_classic_mutation.rb +32 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
- data/lib/graphql/schema/resolver.rb +123 -63
- data/lib/graphql/schema/scalar.rb +11 -1
- 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/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +41 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +12 -2
- data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
- data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
- data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
- data/lib/graphql/schema/validator/format_validator.rb +48 -0
- data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
- data/lib/graphql/schema/validator/length_validator.rb +59 -0
- data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
- data/lib/graphql/schema/validator/required_validator.rb +68 -0
- data/lib/graphql/schema/validator.rb +174 -0
- data/lib/graphql/schema/warden.rb +153 -28
- data/lib/graphql/schema.rb +364 -330
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +8 -5
- 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 +44 -87
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +79 -43
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -8
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validation_context.rb +9 -3
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +42 -8
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/string_encoding_error.rb +13 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +118 -19
- 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 +81 -30
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +33 -6
- data/lib/graphql/subscriptions/subscription_root.rb +15 -4
- data/lib/graphql/subscriptions.rb +88 -45
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
- data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +43 -17
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/tracing.rb +9 -33
- 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 +3 -3
- data/lib/graphql/types/iso_8601_date_time.rb +25 -10
- data/lib/graphql/types/relay/base_connection.rb +6 -90
- data/lib/graphql/types/relay/base_edge.rb +2 -34
- data/lib/graphql/types/relay/connection_behaviors.rb +156 -0
- data/lib/graphql/types/relay/default_relay.rb +27 -0
- data/lib/graphql/types/relay/edge_behaviors.rb +53 -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 +2 -20
- data/lib/graphql/types/relay/nodes_field.rb +2 -20
- 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 +2 -0
- 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 +65 -31
- data/readme.md +3 -6
- metadata +77 -112
- 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
@@ -24,10 +24,11 @@ module GraphQL
|
|
24
24
|
# Really we only need description from here, but:
|
25
25
|
extend Schema::Member::BaseDSLMethods
|
26
26
|
extend GraphQL::Schema::Member::HasArguments
|
27
|
+
extend GraphQL::Schema::Member::HasValidators
|
27
28
|
include Schema::Member::HasPath
|
28
29
|
extend Schema::Member::HasPath
|
29
30
|
|
30
|
-
# @param object [Object]
|
31
|
+
# @param object [Object] The application object that this field is being resolved on
|
31
32
|
# @param context [GraphQL::Query::Context]
|
32
33
|
# @param field [GraphQL::Schema::Field]
|
33
34
|
def initialize(object:, context:, field:)
|
@@ -36,10 +37,10 @@ module GraphQL
|
|
36
37
|
@field = field
|
37
38
|
# Since this hash is constantly rebuilt, cache it for this call
|
38
39
|
@arguments_by_keyword = {}
|
39
|
-
self.class.arguments.each do |name, arg|
|
40
|
+
self.class.arguments(context).each do |name, arg|
|
40
41
|
@arguments_by_keyword[arg.keyword] = arg
|
41
42
|
end
|
42
|
-
@
|
43
|
+
@prepared_arguments = nil
|
43
44
|
end
|
44
45
|
|
45
46
|
# @return [Object] The application object this field is being resolved on
|
@@ -48,9 +49,18 @@ module GraphQL
|
|
48
49
|
# @return [GraphQL::Query::Context]
|
49
50
|
attr_reader :context
|
50
51
|
|
52
|
+
# @return [GraphQL::Dataloader]
|
53
|
+
def dataloader
|
54
|
+
context.dataloader
|
55
|
+
end
|
56
|
+
|
51
57
|
# @return [GraphQL::Schema::Field]
|
52
58
|
attr_reader :field
|
53
59
|
|
60
|
+
def arguments
|
61
|
+
@prepared_arguments || raise("Arguments have not been prepared yet, still waiting for #load_arguments to resolve. (Call `.arguments` later in the code.)")
|
62
|
+
end
|
63
|
+
|
54
64
|
# This method is _actually_ called by the runtime,
|
55
65
|
# it does some preparation and then eventually calls
|
56
66
|
# the user-defined `#resolve` method.
|
@@ -74,6 +84,8 @@ module GraphQL
|
|
74
84
|
# for that argument, or may return a lazy object
|
75
85
|
load_arguments_val = load_arguments(args)
|
76
86
|
context.schema.after_lazy(load_arguments_val) do |loaded_args|
|
87
|
+
@prepared_arguments = loaded_args
|
88
|
+
Schema::Validator.validate!(self.class.validators, object, context, loaded_args, as: @field)
|
77
89
|
# Then call `authorized?`, which may raise or may return a lazy object
|
78
90
|
authorized_val = if loaded_args.any?
|
79
91
|
authorized?(**loaded_args)
|
@@ -97,7 +109,7 @@ module GraphQL
|
|
97
109
|
public_send(self.class.resolve_method)
|
98
110
|
end
|
99
111
|
else
|
100
|
-
|
112
|
+
raise GraphQL::UnauthorizedFieldError.new(context: context, object: object, type: field.owner, field: field)
|
101
113
|
end
|
102
114
|
end
|
103
115
|
end
|
@@ -133,7 +145,7 @@ module GraphQL
|
|
133
145
|
# @raise [GraphQL::UnauthorizedError] To signal an authorization failure
|
134
146
|
# @return [Boolean, early_return_data] If `false`, execution will stop (and `early_return_data` will be returned instead, if present.)
|
135
147
|
def authorized?(**inputs)
|
136
|
-
self.class.arguments.each_value do |argument|
|
148
|
+
self.class.arguments(context).each_value do |argument|
|
137
149
|
arg_keyword = argument.keyword
|
138
150
|
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
139
151
|
arg_auth, err = argument.authorized?(self, arg_value, context)
|
@@ -148,6 +160,16 @@ module GraphQL
|
|
148
160
|
end
|
149
161
|
end
|
150
162
|
|
163
|
+
# Called when an object loaded by `loads:` fails the `.authorized?` check for its resolved GraphQL object type.
|
164
|
+
#
|
165
|
+
# By default, the error is re-raised and passed along to {{Schema.unauthorized_object}}.
|
166
|
+
#
|
167
|
+
# Any value returned here will be used _instead of_ of the loaded object.
|
168
|
+
# @param err [GraphQL::UnauthorizedError]
|
169
|
+
def unauthorized_object(err)
|
170
|
+
raise err
|
171
|
+
end
|
172
|
+
|
151
173
|
private
|
152
174
|
|
153
175
|
def load_arguments(args)
|
@@ -157,18 +179,14 @@ module GraphQL
|
|
157
179
|
args.each do |key, value|
|
158
180
|
arg_defn = @arguments_by_keyword[key]
|
159
181
|
if arg_defn
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
if context.schema.lazy?(prepped_value)
|
165
|
-
prepare_lazies << context.schema.after_lazy(prepped_value) do |finished_prepped_value|
|
166
|
-
prepared_args[key] = finished_prepped_value
|
167
|
-
end
|
182
|
+
prepped_value = prepared_args[key] = arg_defn.load_and_authorize_value(self, value, context)
|
183
|
+
if context.schema.lazy?(prepped_value)
|
184
|
+
prepare_lazies << context.schema.after_lazy(prepped_value) do |finished_prepped_value|
|
185
|
+
prepared_args[key] = finished_prepped_value
|
168
186
|
end
|
169
187
|
end
|
170
188
|
else
|
171
|
-
#
|
189
|
+
# these are `extras:`
|
172
190
|
prepared_args[key] = value
|
173
191
|
end
|
174
192
|
end
|
@@ -181,8 +199,8 @@ module GraphQL
|
|
181
199
|
end
|
182
200
|
end
|
183
201
|
|
184
|
-
def
|
185
|
-
|
202
|
+
def get_argument(name, context = GraphQL::Query::NullContext)
|
203
|
+
self.class.get_argument(name, context)
|
186
204
|
end
|
187
205
|
|
188
206
|
class << self
|
@@ -205,8 +223,10 @@ module GraphQL
|
|
205
223
|
own_extras + (superclass.respond_to?(:extras) ? superclass.extras : [])
|
206
224
|
end
|
207
225
|
|
208
|
-
#
|
209
|
-
#
|
226
|
+
# If `true` (default), then the return type for this resolver will be nullable.
|
227
|
+
# If `false`, then the return type is non-null.
|
228
|
+
#
|
229
|
+
# @see #type which sets the return type of this field and accepts a `null:` option
|
210
230
|
# @param allow_null [Boolean] Whether or not the response can be null
|
211
231
|
def null(allow_null = nil)
|
212
232
|
if !allow_null.nil?
|
@@ -220,7 +240,7 @@ module GraphQL
|
|
220
240
|
# or use it as a configuration method to assign a return type
|
221
241
|
# instead of generating one.
|
222
242
|
# TODO unify with {#null}
|
223
|
-
# @param new_type [Class, nil] If a type definition class is provided, it will be used as the return type of the field
|
243
|
+
# @param new_type [Class, Array<Class>, nil] If a type definition class is provided, it will be used as the return type of the field
|
224
244
|
# @param null [true, false] Whether or not the field may return `nil`
|
225
245
|
# @return [Class] The type which this field returns.
|
226
246
|
def type(new_type = nil, null: nil)
|
@@ -250,18 +270,78 @@ module GraphQL
|
|
250
270
|
@complexity || (superclass.respond_to?(:complexity) ? superclass.complexity : 1)
|
251
271
|
end
|
252
272
|
|
273
|
+
def broadcastable(new_broadcastable)
|
274
|
+
@broadcastable = new_broadcastable
|
275
|
+
end
|
276
|
+
|
277
|
+
# @return [Boolean, nil]
|
278
|
+
def broadcastable?
|
279
|
+
if defined?(@broadcastable)
|
280
|
+
@broadcastable
|
281
|
+
else
|
282
|
+
(superclass.respond_to?(:broadcastable?) ? superclass.broadcastable? : nil)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
# Get or set the `max_page_size:` which will be configured for fields using this resolver
|
287
|
+
# (`nil` means "unlimited max page size".)
|
288
|
+
# @param max_page_size [Integer, nil] Set a new value
|
289
|
+
# @return [Integer, nil] The `max_page_size` assigned to fields that use this resolver
|
290
|
+
def max_page_size(new_max_page_size = :not_given)
|
291
|
+
if new_max_page_size != :not_given
|
292
|
+
@max_page_size = new_max_page_size
|
293
|
+
elsif defined?(@max_page_size)
|
294
|
+
@max_page_size
|
295
|
+
elsif superclass.respond_to?(:max_page_size)
|
296
|
+
superclass.max_page_size
|
297
|
+
else
|
298
|
+
nil
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
# @return [Boolean] `true` if this resolver or a superclass has an assigned `max_page_size`
|
303
|
+
def has_max_page_size?
|
304
|
+
defined?(@max_page_size) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?)
|
305
|
+
end
|
306
|
+
|
253
307
|
def field_options
|
254
|
-
|
308
|
+
|
309
|
+
all_args = {}
|
310
|
+
all_argument_definitions.each do |arg|
|
311
|
+
if (prev_entry = all_args[arg.graphql_name])
|
312
|
+
if prev_entry.is_a?(Array)
|
313
|
+
prev_entry << arg
|
314
|
+
else
|
315
|
+
all_args[arg.graphql_name] = [prev_entry, arg]
|
316
|
+
end
|
317
|
+
else
|
318
|
+
all_args[arg.graphql_name] = arg
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
field_opts = {
|
255
323
|
type: type_expr,
|
256
324
|
description: description,
|
257
325
|
extras: extras,
|
258
326
|
resolver_method: :resolve_with_support,
|
259
327
|
resolver_class: self,
|
260
|
-
arguments:
|
328
|
+
arguments: all_args,
|
261
329
|
null: null,
|
262
330
|
complexity: complexity,
|
263
|
-
|
331
|
+
broadcastable: broadcastable?,
|
264
332
|
}
|
333
|
+
|
334
|
+
# If there aren't any, then the returned array is `[].freeze`,
|
335
|
+
# but passing that along breaks some user code.
|
336
|
+
if (exts = extensions).any?
|
337
|
+
field_opts[:extensions] = exts
|
338
|
+
end
|
339
|
+
|
340
|
+
if has_max_page_size?
|
341
|
+
field_opts[:max_page_size] = max_page_size
|
342
|
+
end
|
343
|
+
|
344
|
+
field_opts
|
265
345
|
end
|
266
346
|
|
267
347
|
# A non-normalized type configuration, without `null` applied
|
@@ -273,63 +353,43 @@ module GraphQL
|
|
273
353
|
# also add some preparation hook methods which will be used for this argument
|
274
354
|
# @see {GraphQL::Schema::Argument#initialize} for the signature
|
275
355
|
def argument(*args, **kwargs, &block)
|
276
|
-
loads = kwargs[:loads]
|
277
356
|
# Use `from_resolver: true` to short-circuit the InputObject's own `loads:` implementation
|
278
357
|
# so that we can support `#load_{x}` methods below.
|
279
|
-
|
280
|
-
own_arguments_loads_as_type[arg_defn.keyword] = loads if loads
|
281
|
-
|
282
|
-
if loads && arg_defn.type.list?
|
283
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
284
|
-
def load_#{arg_defn.keyword}(values)
|
285
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
286
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
287
|
-
context.schema.after_lazy(values) do |values2|
|
288
|
-
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, lookup_as_type, value) })
|
289
|
-
end
|
290
|
-
end
|
291
|
-
RUBY
|
292
|
-
elsif loads
|
293
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
294
|
-
def load_#{arg_defn.keyword}(value)
|
295
|
-
argument = @arguments_by_keyword[:#{arg_defn.keyword}]
|
296
|
-
lookup_as_type = @arguments_loads_as_type[:#{arg_defn.keyword}]
|
297
|
-
load_application_object(argument, lookup_as_type, value)
|
298
|
-
end
|
299
|
-
RUBY
|
300
|
-
else
|
301
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
302
|
-
def load_#{arg_defn.keyword}(value)
|
303
|
-
value
|
304
|
-
end
|
305
|
-
RUBY
|
306
|
-
end
|
307
|
-
|
308
|
-
arg_defn
|
309
|
-
end
|
310
|
-
|
311
|
-
# @api private
|
312
|
-
def arguments_loads_as_type
|
313
|
-
inherited_lookups = superclass.respond_to?(:arguments_loads_as_type) ? superclass.arguments_loads_as_type : {}
|
314
|
-
inherited_lookups.merge(own_arguments_loads_as_type)
|
358
|
+
super(*args, from_resolver: true, **kwargs)
|
315
359
|
end
|
316
360
|
|
317
361
|
# Registers new extension
|
318
362
|
# @param extension [Class] Extension class
|
319
363
|
# @param options [Hash] Optional extension options
|
320
364
|
def extension(extension, **options)
|
321
|
-
|
365
|
+
@own_extensions ||= []
|
366
|
+
@own_extensions << {extension => options}
|
322
367
|
end
|
323
368
|
|
324
369
|
# @api private
|
325
370
|
def extensions
|
326
|
-
|
371
|
+
own_exts = @own_extensions
|
372
|
+
# Jump through some hoops to avoid creating arrays when we don't actually need them
|
373
|
+
if superclass.respond_to?(:extensions)
|
374
|
+
s_exts = superclass.extensions
|
375
|
+
if own_exts
|
376
|
+
if s_exts.any?
|
377
|
+
own_exts + s_exts
|
378
|
+
else
|
379
|
+
own_exts
|
380
|
+
end
|
381
|
+
else
|
382
|
+
s_exts
|
383
|
+
end
|
384
|
+
else
|
385
|
+
own_exts || EMPTY_ARRAY
|
386
|
+
end
|
327
387
|
end
|
328
388
|
|
329
389
|
private
|
330
390
|
|
331
|
-
def
|
332
|
-
@
|
391
|
+
def own_extensions
|
392
|
+
@own_extensions
|
333
393
|
end
|
334
394
|
end
|
335
395
|
end
|
@@ -43,13 +43,23 @@ module GraphQL
|
|
43
43
|
|
44
44
|
def validate_non_null_input(value, ctx)
|
45
45
|
result = Query::InputValidationResult.new
|
46
|
-
|
46
|
+
coerced_result = begin
|
47
|
+
ctx.query.with_error_handling do
|
48
|
+
coerce_input(value, ctx)
|
49
|
+
end
|
50
|
+
rescue GraphQL::CoercionError => err
|
51
|
+
err
|
52
|
+
end
|
53
|
+
|
54
|
+
if coerced_result.nil?
|
47
55
|
str_value = if value == Float::INFINITY
|
48
56
|
""
|
49
57
|
else
|
50
58
|
" #{GraphQL::Language.serialize(value)}"
|
51
59
|
end
|
52
60
|
result.add_problem("Could not coerce value#{str_value} to #{graphql_name}")
|
61
|
+
elsif coerced_result.is_a?(GraphQL::CoercionError)
|
62
|
+
result.add_problem(coerced_result.message, message: coerced_result.message, extensions: coerced_result.extensions)
|
53
63
|
end
|
54
64
|
result
|
55
65
|
end
|
@@ -12,19 +12,9 @@ module GraphQL
|
|
12
12
|
#
|
13
13
|
# Also, `#unsubscribe` terminates the subscription.
|
14
14
|
class Subscription < GraphQL::Schema::Resolver
|
15
|
-
class EarlyTerminationError < StandardError
|
16
|
-
end
|
17
|
-
|
18
|
-
# Raised when `unsubscribe` is called; caught by `subscriptions.rb`
|
19
|
-
class UnsubscribedError < EarlyTerminationError
|
20
|
-
end
|
21
|
-
|
22
|
-
# Raised when `no_update` is returned; caught by `subscriptions.rb`
|
23
|
-
class NoUpdateError < EarlyTerminationError
|
24
|
-
end
|
25
15
|
extend GraphQL::Schema::Resolver::HasPayloadType
|
26
16
|
extend GraphQL::Schema::Member::HasFields
|
27
|
-
|
17
|
+
NO_UPDATE = :no_update
|
28
18
|
# The generated payload type is required; If there's no payload,
|
29
19
|
# propagate null.
|
30
20
|
null false
|
@@ -35,6 +25,22 @@ module GraphQL
|
|
35
25
|
@mode = context.query.subscription_update? ? :update : :subscribe
|
36
26
|
end
|
37
27
|
|
28
|
+
def resolve_with_support(**args)
|
29
|
+
result = nil
|
30
|
+
unsubscribed = true
|
31
|
+
catch :graphql_subscription_unsubscribed do
|
32
|
+
result = super
|
33
|
+
unsubscribed = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
if unsubscribed
|
38
|
+
context.skip
|
39
|
+
else
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
38
44
|
# Implement the {Resolve} API
|
39
45
|
def resolve(**args)
|
40
46
|
# Dispatch based on `@mode`, which will raise a `NoMethodError` if we ever
|
@@ -52,11 +58,9 @@ module GraphQL
|
|
52
58
|
end
|
53
59
|
end
|
54
60
|
|
55
|
-
#
|
61
|
+
# The default implementation returns nothing on subscribe.
|
56
62
|
# Override it to return an object or
|
57
|
-
# `:no_response` to return nothing.
|
58
|
-
#
|
59
|
-
# The default is `:no_response`.
|
63
|
+
# `:no_response` to (explicitly) return nothing.
|
60
64
|
def subscribe(args = {})
|
61
65
|
:no_response
|
62
66
|
end
|
@@ -64,15 +68,16 @@ module GraphQL
|
|
64
68
|
# Wrap the user-provided `#update` hook
|
65
69
|
def resolve_update(**args)
|
66
70
|
ret_val = args.any? ? update(**args) : update
|
67
|
-
if ret_val ==
|
68
|
-
|
71
|
+
if ret_val == NO_UPDATE
|
72
|
+
context.namespace(:subscriptions)[:no_update] = true
|
73
|
+
context.skip
|
69
74
|
else
|
70
75
|
ret_val
|
71
76
|
end
|
72
77
|
end
|
73
78
|
|
74
79
|
# The default implementation returns the root object.
|
75
|
-
# Override it to return
|
80
|
+
# Override it to return {NO_UPDATE} if you want to
|
76
81
|
# skip updates sometimes. Or override it to return a different object.
|
77
82
|
def update(args = {})
|
78
83
|
object
|
@@ -90,17 +95,20 @@ module GraphQL
|
|
90
95
|
|
91
96
|
# Call this to halt execution and remove this subscription from the system
|
92
97
|
def unsubscribe
|
93
|
-
|
98
|
+
context.namespace(:subscriptions)[:unsubscribed] = true
|
99
|
+
throw :graphql_subscription_unsubscribed
|
94
100
|
end
|
95
101
|
|
102
|
+
READING_SCOPE = ::Object.new
|
96
103
|
# Call this method to provide a new subscription_scope; OR
|
97
104
|
# call it without an argument to get the subscription_scope
|
98
105
|
# @param new_scope [Symbol]
|
106
|
+
# @param optional [Boolean] If true, then don't require `scope:` to be provided to updates to this subscription.
|
99
107
|
# @return [Symbol]
|
100
|
-
|
101
|
-
def self.subscription_scope(new_scope = READING_SCOPE)
|
108
|
+
def self.subscription_scope(new_scope = READING_SCOPE, optional: false)
|
102
109
|
if new_scope != READING_SCOPE
|
103
110
|
@subscription_scope = new_scope
|
111
|
+
@subscription_scope_optional = optional
|
104
112
|
elsif defined?(@subscription_scope)
|
105
113
|
@subscription_scope
|
106
114
|
else
|
@@ -108,6 +116,34 @@ module GraphQL
|
|
108
116
|
end
|
109
117
|
end
|
110
118
|
|
119
|
+
def self.subscription_scope_optional?
|
120
|
+
if defined?(@subscription_scope_optional)
|
121
|
+
@subscription_scope_optional
|
122
|
+
else
|
123
|
+
find_inherited_value(:subscription_scope_optional, false)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# This is called during initial subscription to get a "name" for this subscription.
|
128
|
+
# Later, when `.trigger` is called, this will be called again to build another "name".
|
129
|
+
# Any subscribers with matching topic will begin the update flow.
|
130
|
+
#
|
131
|
+
# The default implementation creates a string using the field name, subscription scope, and argument keys and values.
|
132
|
+
# In that implementation, only `.trigger` calls with _exact matches_ result in updates to subscribers.
|
133
|
+
#
|
134
|
+
# To implement a filtered stream-type subscription flow, override this method to return a string with field name and subscription scope.
|
135
|
+
# Then, implement {#update} to compare its arguments to the current `object` and return {NO_UPDATE} when an
|
136
|
+
# update should be filtered out.
|
137
|
+
#
|
138
|
+
# @see {#update} for how to skip updates when an event comes with a matching topic.
|
139
|
+
# @param arguments [Hash<String => Object>] The arguments for this topic, in GraphQL-style (camelized strings)
|
140
|
+
# @param field [GraphQL::Schema::Field]
|
141
|
+
# @param scope [Object, nil] A value corresponding to `.trigger(... scope:)` (for updates) or the `subscription_scope` found in `context` (for initial subscriptions).
|
142
|
+
# @return [String] An identifier corresponding to a stream of updates
|
143
|
+
def self.topic_for(arguments:, field:, scope:)
|
144
|
+
Subscriptions::Serialize.dump_recursive([scope, field.graphql_name, arguments])
|
145
|
+
end
|
146
|
+
|
111
147
|
# Overriding Resolver#field_options to include subscription_scope
|
112
148
|
def self.field_options
|
113
149
|
super.merge(
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
7
7
|
# to the `errors` key. Any already-resolved fields will be in the `data` key, so
|
8
8
|
# you'll get a partial response.
|
9
9
|
#
|
10
|
-
# You can subclass `GraphQL::Schema::Timeout` and override
|
10
|
+
# You can subclass `GraphQL::Schema::Timeout` and override `max_seconds` and/or `handle_timeout`
|
11
11
|
# to provide custom logic when a timeout error occurs.
|
12
12
|
#
|
13
13
|
# Note that this will stop a query _in between_ field resolutions, but
|
@@ -33,8 +33,6 @@ module GraphQL
|
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
class Timeout
|
36
|
-
attr_reader :max_seconds
|
37
|
-
|
38
36
|
def self.use(schema, **options)
|
39
37
|
tracer = new(**options)
|
40
38
|
schema.tracer(tracer)
|
@@ -48,32 +46,39 @@ module GraphQL
|
|
48
46
|
def trace(key, data)
|
49
47
|
case key
|
50
48
|
when 'execute_multiplex'
|
51
|
-
timeout_state = {
|
52
|
-
timeout_at: Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) + max_seconds * 1000,
|
53
|
-
timed_out: false
|
54
|
-
}
|
55
|
-
|
56
49
|
data.fetch(:multiplex).queries.each do |query|
|
50
|
+
timeout_duration_s = max_seconds(query)
|
51
|
+
timeout_state = if timeout_duration_s == false
|
52
|
+
# if the method returns `false`, don't apply a timeout
|
53
|
+
false
|
54
|
+
else
|
55
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
56
|
+
timeout_at = now + (max_seconds(query) * 1000)
|
57
|
+
{
|
58
|
+
timeout_at: timeout_at,
|
59
|
+
timed_out: false
|
60
|
+
}
|
61
|
+
end
|
57
62
|
query.context.namespace(self.class)[:state] = timeout_state
|
58
63
|
end
|
59
64
|
|
60
65
|
yield
|
61
66
|
when 'execute_field', 'execute_field_lazy'
|
62
|
-
|
63
|
-
timeout_state =
|
64
|
-
|
67
|
+
query_context = data[:context] || data[:query].context
|
68
|
+
timeout_state = query_context.namespace(self.class).fetch(:state)
|
69
|
+
# If the `:state` is `false`, then `max_seconds(query)` opted out of timeout for this query.
|
70
|
+
if timeout_state != false && Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) > timeout_state.fetch(:timeout_at)
|
65
71
|
error = if data[:context]
|
66
|
-
|
67
|
-
GraphQL::Schema::Timeout::TimeoutError.new(context.parent_type, context.field)
|
72
|
+
GraphQL::Schema::Timeout::TimeoutError.new(query_context.parent_type, query_context.field)
|
68
73
|
else
|
69
74
|
field = data.fetch(:field)
|
70
75
|
GraphQL::Schema::Timeout::TimeoutError.new(field.owner, field)
|
71
76
|
end
|
72
77
|
|
73
78
|
# Only invoke the timeout callback for the first timeout
|
74
|
-
|
79
|
+
if !timeout_state[:timed_out]
|
75
80
|
timeout_state[:timed_out] = true
|
76
|
-
handle_timeout(error, query)
|
81
|
+
handle_timeout(error, query_context.query)
|
77
82
|
end
|
78
83
|
|
79
84
|
error
|
@@ -85,6 +90,15 @@ module GraphQL
|
|
85
90
|
end
|
86
91
|
end
|
87
92
|
|
93
|
+
# Called at the start of each query.
|
94
|
+
# The default implementation returns the `max_seconds:` value from installing this plugin.
|
95
|
+
#
|
96
|
+
# @param query [GraphQL::Query] The query that's about to run
|
97
|
+
# @return [Integer, false] The number of seconds after which to interrupt query execution and call {#handle_error}, or `false` to bypass the timeout.
|
98
|
+
def max_seconds(query)
|
99
|
+
@max_seconds
|
100
|
+
end
|
101
|
+
|
88
102
|
# Invoked when a query times out.
|
89
103
|
# @param error [GraphQL::Schema::Timeout::TimeoutError]
|
90
104
|
# @param query [GraphQL::Error]
|
@@ -23,12 +23,14 @@ module GraphQL
|
|
23
23
|
# Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
|
24
24
|
# end
|
25
25
|
#
|
26
|
+
# @api deprecated
|
27
|
+
# @see Schema::Timeout
|
26
28
|
class TimeoutMiddleware
|
27
29
|
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
28
30
|
def initialize(max_seconds:, context_key: nil, &block)
|
29
31
|
@max_seconds = max_seconds
|
30
32
|
if context_key
|
31
|
-
warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
33
|
+
GraphQL::Deprecation.warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
32
34
|
end
|
33
35
|
@error_handler = block
|
34
36
|
end
|
@@ -11,7 +11,7 @@ module GraphQL
|
|
11
11
|
def self.build_type(type_owner, ast_node)
|
12
12
|
case ast_node
|
13
13
|
when GraphQL::Language::Nodes::TypeName
|
14
|
-
type_owner.get_type(ast_node.name)
|
14
|
+
type_owner.get_type(ast_node.name) # rubocop:disable Development/ContextIsPassedCop -- this is a `context` or `warden`, it's already query-aware
|
15
15
|
when GraphQL::Language::Nodes::NonNullType
|
16
16
|
ast_inner_type = ast_node.of_type
|
17
17
|
inner_type = build_type(type_owner, ast_inner_type)
|
@@ -4,8 +4,6 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
# This class joins an object type to an abstract type (interface or union) of which
|
6
6
|
# it is a member.
|
7
|
-
#
|
8
|
-
# TODO: Not yet implemented for interfaces.
|
9
7
|
class TypeMembership
|
10
8
|
# @return [Class<GraphQL::Schema::Object>]
|
11
9
|
attr_accessor :object_type
|
@@ -26,9 +24,25 @@ module GraphQL
|
|
26
24
|
end
|
27
25
|
|
28
26
|
# @return [Boolean] if false, {#object_type} will be treated as _not_ a member of {#abstract_type}
|
29
|
-
def visible?(
|
30
|
-
|
27
|
+
def visible?(ctx)
|
28
|
+
warden = Warden.from_context(ctx)
|
29
|
+
(@object_type.respond_to?(:visible?) ? warden.visible_type?(@object_type, ctx) : true) &&
|
30
|
+
(@abstract_type.respond_to?(:visible?) ? warden.visible_type?(@abstract_type, ctx) : true)
|
31
31
|
end
|
32
|
+
|
33
|
+
def graphql_name
|
34
|
+
"#{@object_type.graphql_name}.#{@abstract_type.kind.interface? ? "implements" : "belongsTo" }.#{@abstract_type.graphql_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def path
|
38
|
+
graphql_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
"#<#{self.class} #{@object_type.inspect} => #{@abstract_type.inspect}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
alias :type_class :itself
|
32
46
|
end
|
33
47
|
end
|
34
48
|
end
|