graphql 2.2.17 → 2.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +3 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/analyzer.rb +90 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +263 -0
- data/lib/graphql/analysis/{ast/query_depth.rb → query_depth.rb} +23 -25
- data/lib/graphql/analysis/visitor.rb +280 -0
- data/lib/graphql/analysis.rb +95 -1
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/table.rb +118 -55
- data/lib/graphql/backtrace.rb +1 -19
- data/lib/graphql/current.rb +57 -0
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +30 -0
- data/lib/graphql/dashboard/statics/dashboard.js +143 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/subscriptions.rb +96 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
- data/lib/graphql/dashboard.rb +158 -0
- data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
- data/lib/graphql/dataloader/active_record_source.rb +47 -0
- data/lib/graphql/dataloader/async_dataloader.rb +46 -19
- data/lib/graphql/dataloader/null_dataloader.rb +51 -10
- data/lib/graphql/dataloader/source.rb +20 -9
- data/lib/graphql/dataloader.rb +153 -45
- data/lib/graphql/date_encoding_error.rb +1 -1
- data/lib/graphql/dig.rb +2 -1
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/resolve.rb +23 -25
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +63 -5
- data/lib/graphql/execution/interpreter/runtime.rb +321 -222
- data/lib/graphql/execution/interpreter.rb +23 -30
- data/lib/graphql/execution/lookahead.rb +18 -11
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +20 -17
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +64 -35
- data/lib/graphql/language/lexer.rb +72 -42
- data/lib/graphql/language/nodes.rb +93 -52
- data/lib/graphql/language/parser.rb +168 -61
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +61 -1
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +46 -47
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/partial.rb +179 -0
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +123 -69
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- 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 +2 -0
- data/lib/graphql/schema/addition.rb +26 -13
- data/lib/graphql/schema/always_visible.rb +7 -2
- data/lib/graphql/schema/argument.rb +57 -8
- data/lib/graphql/schema/build_from_definition.rb +116 -49
- data/lib/graphql/schema/directive/flagged.rb +4 -2
- data/lib/graphql/schema/directive.rb +54 -2
- data/lib/graphql/schema/enum.rb +107 -24
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +134 -45
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +6 -2
- data/lib/graphql/schema/input_object.rb +122 -64
- data/lib/graphql/schema/interface.rb +23 -5
- data/lib/graphql/schema/introspection_system.rb +6 -17
- data/lib/graphql/schema/late_bound_type.rb +4 -0
- data/lib/graphql/schema/list.rb +3 -3
- data/lib/graphql/schema/loader.rb +3 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +44 -58
- data/lib/graphql/schema/member/has_dataloader.rb +62 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
- data/lib/graphql/schema/member/has_directives.rb +4 -4
- data/lib/graphql/schema/member/has_fields.rb +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +6 -6
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -4
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/object.rb +25 -8
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/ractor_shareable.rb +79 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +29 -23
- data/lib/graphql/schema/scalar.rb +1 -6
- data/lib/graphql/schema/subscription.rb +52 -6
- data/lib/graphql/schema/timeout.rb +19 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +92 -11
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +188 -0
- data/lib/graphql/schema/visibility/profile.rb +445 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +311 -0
- data/lib/graphql/schema/warden.rb +190 -20
- data/lib/graphql/schema.rb +695 -167
- data/lib/graphql/static_validation/all_rules.rb +2 -2
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- 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 +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- 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 +47 -13
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +88 -25
- data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
- 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_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/not_single_subscription_error.rb +25 -0
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
- 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 +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
- data/lib/graphql/static_validation/validation_context.rb +18 -2
- data/lib/graphql/static_validation/validator.rb +6 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +5 -3
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +12 -10
- data/lib/graphql/subscriptions/event.rb +13 -2
- data/lib/graphql/subscriptions/serialize.rb +1 -1
- data/lib/graphql/subscriptions.rb +7 -5
- data/lib/graphql/testing/helpers.rb +48 -16
- data/lib/graphql/testing/mock_action_cable.rb +111 -0
- data/lib/graphql/testing.rb +1 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +5 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +7 -0
- data/lib/graphql/tracing/appsignal_trace.rb +32 -59
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +46 -162
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +141 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/monitor_trace.rb +283 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -54
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +183 -37
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
- data/lib/graphql/tracing/perfetto_trace.rb +818 -0
- data/lib/graphql/tracing/platform_tracing.rb +1 -1
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
- data/lib/graphql/tracing/prometheus_trace.rb +73 -73
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -58
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +64 -98
- data/lib/graphql/tracing/statsd_trace.rb +33 -45
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +111 -1
- data/lib/graphql/tracing.rb +31 -30
- data/lib/graphql/type_kinds.rb +2 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +64 -54
- metadata +197 -22
- data/lib/graphql/analysis/ast/analyzer.rb +0 -91
- data/lib/graphql/analysis/ast/field_usage.rb +0 -82
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -182
- data/lib/graphql/analysis/ast/visitor.rb +0 -276
- data/lib/graphql/analysis/ast.rb +0 -94
- data/lib/graphql/backtrace/inspect_result.rb +0 -50
- data/lib/graphql/backtrace/trace.rb +0 -93
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/schema/null_mask.rb +0 -11
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
|
@@ -10,6 +10,14 @@ module GraphQL
|
|
|
10
10
|
|
|
11
11
|
include GraphQL::Dig
|
|
12
12
|
|
|
13
|
+
# Raised when an InputObject doesn't have any arguments defined and hasn't explicitly opted out of this requirement
|
|
14
|
+
class ArgumentsAreRequiredError < GraphQL::Error
|
|
15
|
+
def initialize(input_object_type)
|
|
16
|
+
message = "Input Object types must have arguments, but #{input_object_type.graphql_name} doesn't have any. Define an argument for this type, remove it from your schema, or add `has_no_arguments(true)` to its definition."
|
|
17
|
+
super(message)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
13
21
|
# @return [GraphQL::Query::Context] The context for this query
|
|
14
22
|
attr_reader :context
|
|
15
23
|
# @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
|
@@ -23,13 +31,14 @@ module GraphQL
|
|
|
23
31
|
@ruby_style_hash = ruby_kwargs
|
|
24
32
|
@arguments = arguments
|
|
25
33
|
# Apply prepares, not great to have it duplicated here.
|
|
26
|
-
self.class.arguments(context).each_value
|
|
34
|
+
arg_defns = context ? context.types.arguments(self.class) : self.class.arguments(context).each_value
|
|
35
|
+
arg_defns.each do |arg_defn|
|
|
27
36
|
ruby_kwargs_key = arg_defn.keyword
|
|
28
37
|
if @ruby_style_hash.key?(ruby_kwargs_key)
|
|
29
38
|
# Weirdly, procs are applied during coercion, but not methods.
|
|
30
39
|
# Probably because these methods require a `self`.
|
|
31
40
|
if arg_defn.prepare.is_a?(Symbol) || context.nil?
|
|
32
|
-
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
|
41
|
+
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key], context: context)
|
|
33
42
|
overwrite_argument(ruby_kwargs_key, prepared_value)
|
|
34
43
|
end
|
|
35
44
|
end
|
|
@@ -44,42 +53,18 @@ module GraphQL
|
|
|
44
53
|
to_h
|
|
45
54
|
end
|
|
46
55
|
|
|
47
|
-
def
|
|
48
|
-
if
|
|
49
|
-
|
|
50
|
-
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
|
51
|
-
Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
|
|
52
|
-
self
|
|
56
|
+
def deconstruct_keys(keys = nil)
|
|
57
|
+
if keys.nil?
|
|
58
|
+
@ruby_style_hash
|
|
53
59
|
else
|
|
54
|
-
|
|
60
|
+
new_h = {}
|
|
61
|
+
keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
|
|
62
|
+
new_h
|
|
55
63
|
end
|
|
56
64
|
end
|
|
57
65
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
if value.respond_to?(:key?)
|
|
61
|
-
arguments(ctx).each do |_name, input_obj_arg|
|
|
62
|
-
if value.key?(input_obj_arg.keyword) &&
|
|
63
|
-
!input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
|
64
|
-
return false
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
# It didn't early-return false:
|
|
69
|
-
true
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def self.one_of
|
|
73
|
-
if !one_of?
|
|
74
|
-
if all_argument_definitions.any? { |arg| arg.type.non_null? }
|
|
75
|
-
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
|
|
76
|
-
end
|
|
77
|
-
directive(GraphQL::Schema::Directive::OneOf)
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def self.one_of?
|
|
82
|
-
false # Re-defined when `OneOf` is added
|
|
66
|
+
def prepare
|
|
67
|
+
self
|
|
83
68
|
end
|
|
84
69
|
|
|
85
70
|
def unwrap_value(value)
|
|
@@ -119,7 +104,42 @@ module GraphQL
|
|
|
119
104
|
@ruby_style_hash.dup
|
|
120
105
|
end
|
|
121
106
|
|
|
107
|
+
# @api private
|
|
108
|
+
def validate_for(context)
|
|
109
|
+
object = context[:current_object]
|
|
110
|
+
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
|
111
|
+
Schema::Validator.validate!(self.class.validators, object, context, @ruby_style_hash, as: self.class)
|
|
112
|
+
nil
|
|
113
|
+
end
|
|
114
|
+
|
|
122
115
|
class << self
|
|
116
|
+
def authorized?(obj, value, ctx)
|
|
117
|
+
# Authorize each argument (but this doesn't apply if `prepare` is implemented):
|
|
118
|
+
if value.respond_to?(:key?)
|
|
119
|
+
ctx.types.arguments(self).each do |input_obj_arg|
|
|
120
|
+
if value.key?(input_obj_arg.keyword) &&
|
|
121
|
+
!input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
|
122
|
+
return false
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
# It didn't early-return false:
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def one_of
|
|
131
|
+
if !one_of?
|
|
132
|
+
if all_argument_definitions.any? { |arg| arg.type.non_null? }
|
|
133
|
+
raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
|
|
134
|
+
end
|
|
135
|
+
directive(GraphQL::Schema::Directive::OneOf)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def one_of?
|
|
140
|
+
false # Re-defined when `OneOf` is added
|
|
141
|
+
end
|
|
142
|
+
|
|
123
143
|
def argument(*args, **kwargs, &block)
|
|
124
144
|
argument_defn = super(*args, **kwargs, &block)
|
|
125
145
|
if one_of?
|
|
@@ -131,12 +151,9 @@ module GraphQL
|
|
|
131
151
|
end
|
|
132
152
|
end
|
|
133
153
|
# Add a method access
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
self[#{method_name.inspect}]
|
|
138
|
-
end
|
|
139
|
-
RUBY
|
|
154
|
+
suppress_redefinition_warning do
|
|
155
|
+
define_accessor_method(argument_defn.keyword)
|
|
156
|
+
end
|
|
140
157
|
argument_defn
|
|
141
158
|
end
|
|
142
159
|
|
|
@@ -148,7 +165,7 @@ module GraphQL
|
|
|
148
165
|
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
|
|
149
166
|
|
|
150
167
|
def validate_non_null_input(input, ctx, max_errors: nil)
|
|
151
|
-
|
|
168
|
+
types = ctx.types
|
|
152
169
|
|
|
153
170
|
if input.is_a?(Array)
|
|
154
171
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
@@ -159,30 +176,37 @@ module GraphQL
|
|
|
159
176
|
return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
|
|
160
177
|
end
|
|
161
178
|
|
|
162
|
-
# Inject missing required arguments
|
|
163
|
-
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
|
164
|
-
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
|
165
|
-
m[argument_name] = nil
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
m
|
|
169
|
-
end
|
|
170
179
|
|
|
171
180
|
result = nil
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
input.each do |argument_name, value|
|
|
184
|
+
argument = types.argument(self, argument_name)
|
|
185
|
+
if argument.nil? && ctx.is_a?(Query::NullContext) && argument_name.is_a?(Symbol)
|
|
186
|
+
# Validating definition directive arguments which come in as Symbols
|
|
187
|
+
argument = types.arguments(self).find { |arg| arg.keyword == argument_name }
|
|
188
|
+
end
|
|
189
|
+
# Items in the input that are unexpected
|
|
190
|
+
if argument.nil?
|
|
191
|
+
result ||= Query::InputValidationResult.new
|
|
192
|
+
result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
|
|
193
|
+
else
|
|
194
|
+
# Items in the input that are expected, but have invalid values
|
|
195
|
+
argument_result = argument.type.validate_input(value, ctx)
|
|
196
|
+
if !argument_result.valid?
|
|
182
197
|
result ||= Query::InputValidationResult.new
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
198
|
+
result.merge_result!(argument_name, argument_result)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Check for missing non-null arguments
|
|
204
|
+
ctx.types.arguments(self).each do |argument|
|
|
205
|
+
if !input.key?(argument.graphql_name) && argument.type.non_null? && !argument.default_value?
|
|
206
|
+
result ||= Query::InputValidationResult.new
|
|
207
|
+
argument_result = argument.type.validate_input(nil, ctx)
|
|
208
|
+
if !argument_result.valid?
|
|
209
|
+
result.merge_result!(argument.graphql_name, argument_result)
|
|
186
210
|
end
|
|
187
211
|
end
|
|
188
212
|
end
|
|
@@ -215,8 +239,7 @@ module GraphQL
|
|
|
215
239
|
if resolved_arguments.is_a?(GraphQL::Error)
|
|
216
240
|
raise resolved_arguments
|
|
217
241
|
else
|
|
218
|
-
|
|
219
|
-
input_obj_instance.prepare
|
|
242
|
+
self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
|
220
243
|
end
|
|
221
244
|
end
|
|
222
245
|
end
|
|
@@ -242,6 +265,41 @@ module GraphQL
|
|
|
242
265
|
|
|
243
266
|
result
|
|
244
267
|
end
|
|
268
|
+
|
|
269
|
+
# @param new_has_no_arguments [Boolean] Call with `true` to make this InputObject type ignore the requirement to have any defined arguments.
|
|
270
|
+
# @return [void]
|
|
271
|
+
def has_no_arguments(new_has_no_arguments)
|
|
272
|
+
@has_no_arguments = new_has_no_arguments
|
|
273
|
+
nil
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @return [Boolean] `true` if `has_no_arguments(true)` was configued
|
|
277
|
+
def has_no_arguments?
|
|
278
|
+
@has_no_arguments
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def arguments(context = GraphQL::Query::NullContext.instance, require_defined_arguments = true)
|
|
282
|
+
if require_defined_arguments && !has_no_arguments? && !any_arguments?
|
|
283
|
+
warn(GraphQL::Schema::InputObject::ArgumentsAreRequiredError.new(self).message + "\n\nThis will raise an error in a future GraphQL-Ruby version.")
|
|
284
|
+
end
|
|
285
|
+
super(context, false)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
private
|
|
289
|
+
|
|
290
|
+
# Suppress redefinition warning for objectId arguments
|
|
291
|
+
def suppress_redefinition_warning
|
|
292
|
+
verbose = $VERBOSE
|
|
293
|
+
$VERBOSE = nil
|
|
294
|
+
yield
|
|
295
|
+
ensure
|
|
296
|
+
$VERBOSE = verbose
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def define_accessor_method(method_name)
|
|
300
|
+
define_method(method_name) { self[method_name] }
|
|
301
|
+
alias_method(method_name, method_name)
|
|
302
|
+
end
|
|
245
303
|
end
|
|
246
304
|
|
|
247
305
|
private
|
|
@@ -13,6 +13,7 @@ module GraphQL
|
|
|
13
13
|
include GraphQL::Schema::Member::Scoped
|
|
14
14
|
include GraphQL::Schema::Member::HasAstNode
|
|
15
15
|
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
|
16
|
+
include GraphQL::Schema::Member::HasDataloader
|
|
16
17
|
include GraphQL::Schema::Member::HasDirectives
|
|
17
18
|
include GraphQL::Schema::Member::HasInterfaces
|
|
18
19
|
|
|
@@ -63,6 +64,7 @@ module GraphQL
|
|
|
63
64
|
|
|
64
65
|
child_class.introspection(introspection)
|
|
65
66
|
child_class.description(description)
|
|
67
|
+
child_class.comment(nil)
|
|
66
68
|
# If interfaces are mixed into each other, only define this class once
|
|
67
69
|
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
|
68
70
|
add_unresolved_type_error(child_class)
|
|
@@ -82,13 +84,29 @@ module GraphQL
|
|
|
82
84
|
super
|
|
83
85
|
end
|
|
84
86
|
|
|
87
|
+
# Register other Interface or Object types as implementers of this Interface.
|
|
88
|
+
#
|
|
89
|
+
# When those Interfaces or Objects aren't used as the return values of fields,
|
|
90
|
+
# they may have to be registered using this method so that GraphQL-Ruby can find them.
|
|
91
|
+
# @param types [Class, Module]
|
|
92
|
+
# @return [Array<Module, Class>] Implementers of this interface, if they're registered
|
|
85
93
|
def orphan_types(*types)
|
|
86
|
-
if types.
|
|
87
|
-
@orphan_types
|
|
94
|
+
if !types.empty?
|
|
95
|
+
@orphan_types ||= []
|
|
96
|
+
@orphan_types.concat(types)
|
|
88
97
|
else
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
if defined?(@orphan_types)
|
|
99
|
+
all_orphan_types = @orphan_types.dup
|
|
100
|
+
if defined?(super)
|
|
101
|
+
all_orphan_types += super
|
|
102
|
+
all_orphan_types.uniq!
|
|
103
|
+
end
|
|
104
|
+
all_orphan_types
|
|
105
|
+
elsif defined?(super)
|
|
106
|
+
super
|
|
107
|
+
else
|
|
108
|
+
EmptyObjects::EMPTY_ARRAY
|
|
109
|
+
end
|
|
92
110
|
end
|
|
93
111
|
end
|
|
94
112
|
|
|
@@ -25,10 +25,10 @@ module GraphQL
|
|
|
25
25
|
load_constant(:DirectiveLocationEnum)
|
|
26
26
|
]
|
|
27
27
|
@types = {}
|
|
28
|
-
@possible_types = {}
|
|
28
|
+
@possible_types = {}.compare_by_identity
|
|
29
29
|
type_defns.each do |t|
|
|
30
30
|
@types[t.graphql_name] = t
|
|
31
|
-
@possible_types[t
|
|
31
|
+
@possible_types[t] = [t]
|
|
32
32
|
end
|
|
33
33
|
@entry_point_fields =
|
|
34
34
|
if schema.disable_introspection_entry_points?
|
|
@@ -69,7 +69,7 @@ module GraphQL
|
|
|
69
69
|
def resolve_late_bindings
|
|
70
70
|
@types.each do |name, t|
|
|
71
71
|
if t.kind.fields?
|
|
72
|
-
t.
|
|
72
|
+
t.all_field_definitions.each do |field_defn|
|
|
73
73
|
field_defn.type = resolve_late_binding(field_defn.type)
|
|
74
74
|
end
|
|
75
75
|
end
|
|
@@ -90,7 +90,8 @@ module GraphQL
|
|
|
90
90
|
def resolve_late_binding(late_bound_type)
|
|
91
91
|
case late_bound_type
|
|
92
92
|
when GraphQL::Schema::LateBoundType
|
|
93
|
-
|
|
93
|
+
type_name = late_bound_type.name
|
|
94
|
+
@types[type_name] || @schema.get_type(type_name)
|
|
94
95
|
when GraphQL::Schema::List
|
|
95
96
|
resolve_late_binding(late_bound_type.of_type).to_list_type
|
|
96
97
|
when GraphQL::Schema::NonNull
|
|
@@ -113,19 +114,7 @@ module GraphQL
|
|
|
113
114
|
|
|
114
115
|
def get_fields_from_class(class_sym:)
|
|
115
116
|
object_type_defn = load_constant(class_sym)
|
|
116
|
-
|
|
117
|
-
if object_type_defn.is_a?(Module)
|
|
118
|
-
object_type_defn.fields
|
|
119
|
-
else
|
|
120
|
-
extracted_field_defns = {}
|
|
121
|
-
object_class = object_type_defn.metadata[:type_class]
|
|
122
|
-
object_type_defn.all_fields.each do |field_defn|
|
|
123
|
-
inner_resolve = field_defn.resolve_proc
|
|
124
|
-
resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
|
|
125
|
-
extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
|
|
126
|
-
end
|
|
127
|
-
extracted_field_defns
|
|
128
|
-
end
|
|
117
|
+
object_type_defn.fields
|
|
129
118
|
end
|
|
130
119
|
|
|
131
120
|
# This is probably not 100% robust -- but it has to be good enough to avoid modifying the built-in introspection types
|
data/lib/graphql/schema/list.rb
CHANGED
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
|
4
4
|
class Schema
|
|
5
5
|
# Represents a list type in the schema.
|
|
6
6
|
# Wraps a {Schema::Member} as a list type.
|
|
7
|
-
# @see
|
|
7
|
+
# @see Schema::Member::TypeSystemHelpers#to_list_type Create a list type from another GraphQL type
|
|
8
8
|
class List < GraphQL::Schema::Wrapper
|
|
9
9
|
include Schema::Member::ValidatesInput
|
|
10
10
|
|
|
@@ -52,7 +52,7 @@ module GraphQL
|
|
|
52
52
|
unless item_result.valid?
|
|
53
53
|
if max_errors
|
|
54
54
|
if max_errors == 0
|
|
55
|
-
|
|
55
|
+
add_max_errors_reached_message(result)
|
|
56
56
|
break
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -76,7 +76,7 @@ module GraphQL
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def
|
|
79
|
+
def add_max_errors_reached_message(result)
|
|
80
80
|
message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
|
|
81
81
|
item_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
|
82
82
|
result.merge_result!(nil, item_result)
|
|
@@ -32,7 +32,8 @@ module GraphQL
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
Class.new(GraphQL::Schema) do
|
|
35
|
-
|
|
35
|
+
add_type_and_traverse(types.values, root: false)
|
|
36
|
+
orphan_types(types.values.select { |t| t.kind.object? })
|
|
36
37
|
directives(directives)
|
|
37
38
|
description(schema["description"])
|
|
38
39
|
|
|
@@ -186,7 +187,7 @@ module GraphQL
|
|
|
186
187
|
camelize: false,
|
|
187
188
|
connection_extension: nil,
|
|
188
189
|
) do
|
|
189
|
-
if field_hash["args"].
|
|
190
|
+
if !field_hash["args"].empty?
|
|
190
191
|
loader.build_arguments(self, field_hash["args"], type_resolver)
|
|
191
192
|
end
|
|
192
193
|
end
|
|
@@ -50,12 +50,27 @@ module GraphQL
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# Call this method to provide a new comment; OR
|
|
54
|
+
# call it without an argument to get the comment
|
|
55
|
+
# @param new_comment [String]
|
|
56
|
+
# @return [String, nil]
|
|
57
|
+
def comment(new_comment = NOT_CONFIGURED)
|
|
58
|
+
if !NOT_CONFIGURED.equal?(new_comment)
|
|
59
|
+
@comment = new_comment
|
|
60
|
+
elsif defined?(@comment)
|
|
61
|
+
@comment
|
|
62
|
+
else
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
53
67
|
# This pushes some configurations _down_ the inheritance tree,
|
|
54
68
|
# in order to prevent repetitive lookups at runtime.
|
|
55
69
|
module ConfigurationExtension
|
|
56
70
|
def inherited(child_class)
|
|
57
71
|
child_class.introspection(introspection)
|
|
58
72
|
child_class.description(description)
|
|
73
|
+
child_class.comment(nil)
|
|
59
74
|
child_class.default_graphql_name = nil
|
|
60
75
|
|
|
61
76
|
if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
|
|
@@ -38,39 +38,6 @@ module GraphQL
|
|
|
38
38
|
end
|
|
39
39
|
arg_defn = self.argument_class.new(*args, **kwargs, &block)
|
|
40
40
|
add_argument(arg_defn)
|
|
41
|
-
|
|
42
|
-
if self.is_a?(Class) && !method_defined?(:"load_#{arg_defn.keyword}")
|
|
43
|
-
method_owner = if self < GraphQL::Schema::InputObject || self < GraphQL::Schema::Directive
|
|
44
|
-
"self."
|
|
45
|
-
elsif self < GraphQL::Schema::Resolver
|
|
46
|
-
""
|
|
47
|
-
else
|
|
48
|
-
raise "Unexpected argument owner: #{self}"
|
|
49
|
-
end
|
|
50
|
-
if loads && arg_defn.type.list?
|
|
51
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
52
|
-
def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
|
|
53
|
-
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
|
54
|
-
(context || self.context).query.after_lazy(values) do |values2|
|
|
55
|
-
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, value, context || self.context) })
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
RUBY
|
|
59
|
-
elsif loads
|
|
60
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
61
|
-
def #{method_owner}load_#{arg_defn.keyword}(value, context = nil)
|
|
62
|
-
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
|
63
|
-
load_application_object(argument, value, context || self.context)
|
|
64
|
-
end
|
|
65
|
-
RUBY
|
|
66
|
-
else
|
|
67
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
68
|
-
def #{method_owner}load_#{arg_defn.keyword}(value, _context = nil)
|
|
69
|
-
value
|
|
70
|
-
end
|
|
71
|
-
RUBY
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
41
|
arg_defn
|
|
75
42
|
end
|
|
76
43
|
|
|
@@ -109,8 +76,8 @@ module GraphQL
|
|
|
109
76
|
end
|
|
110
77
|
|
|
111
78
|
# @return [Hash<String => GraphQL::Schema::Argument] Arguments defined on this thing, keyed by name. Includes inherited definitions
|
|
112
|
-
def arguments(context = GraphQL::Query::NullContext.instance)
|
|
113
|
-
if own_arguments.
|
|
79
|
+
def arguments(context = GraphQL::Query::NullContext.instance, _require_defined_arguments = nil)
|
|
80
|
+
if !own_arguments.empty?
|
|
114
81
|
own_arguments_that_apply = {}
|
|
115
82
|
own_arguments.each do |name, args_entry|
|
|
116
83
|
if (visible_defn = Warden.visible_entry?(:visible_argument?, args_entry, context))
|
|
@@ -123,7 +90,7 @@ module GraphQL
|
|
|
123
90
|
end
|
|
124
91
|
|
|
125
92
|
def any_arguments?
|
|
126
|
-
own_arguments.
|
|
93
|
+
!own_arguments.empty?
|
|
127
94
|
end
|
|
128
95
|
|
|
129
96
|
module ClassConfigured
|
|
@@ -133,12 +100,12 @@ module GraphQL
|
|
|
133
100
|
end
|
|
134
101
|
|
|
135
102
|
module InheritedArguments
|
|
136
|
-
def arguments(context = GraphQL::Query::NullContext.instance)
|
|
137
|
-
own_arguments = super
|
|
138
|
-
inherited_arguments = superclass.arguments(context)
|
|
103
|
+
def arguments(context = GraphQL::Query::NullContext.instance, require_defined_arguments = true)
|
|
104
|
+
own_arguments = super(context, require_defined_arguments)
|
|
105
|
+
inherited_arguments = superclass.arguments(context, false)
|
|
139
106
|
|
|
140
|
-
if own_arguments.
|
|
141
|
-
if inherited_arguments.
|
|
107
|
+
if !own_arguments.empty?
|
|
108
|
+
if !inherited_arguments.empty?
|
|
142
109
|
# Local definitions override inherited ones
|
|
143
110
|
inherited_arguments.merge(own_arguments)
|
|
144
111
|
else
|
|
@@ -168,10 +135,11 @@ module GraphQL
|
|
|
168
135
|
|
|
169
136
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
|
170
137
|
warden = Warden.from_context(context)
|
|
138
|
+
skip_visible = context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)
|
|
171
139
|
for ancestor in ancestors
|
|
172
140
|
if ancestor.respond_to?(:own_arguments) &&
|
|
173
141
|
(a = ancestor.own_arguments[argument_name]) &&
|
|
174
|
-
(a = Warden.visible_entry?(:visible_argument?, a, context, warden))
|
|
142
|
+
(skip_visible || (a = Warden.visible_entry?(:visible_argument?, a, context, warden)))
|
|
175
143
|
return a
|
|
176
144
|
end
|
|
177
145
|
end
|
|
@@ -181,12 +149,12 @@ module GraphQL
|
|
|
181
149
|
end
|
|
182
150
|
|
|
183
151
|
module FieldConfigured
|
|
184
|
-
def arguments(context = GraphQL::Query::NullContext.instance)
|
|
152
|
+
def arguments(context = GraphQL::Query::NullContext.instance, _require_defined_arguments = nil)
|
|
185
153
|
own_arguments = super
|
|
186
154
|
if @resolver_class
|
|
187
155
|
inherited_arguments = @resolver_class.field_arguments(context)
|
|
188
|
-
if own_arguments.
|
|
189
|
-
if inherited_arguments.
|
|
156
|
+
if !own_arguments.empty?
|
|
157
|
+
if !inherited_arguments.empty?
|
|
190
158
|
inherited_arguments.merge(own_arguments)
|
|
191
159
|
else
|
|
192
160
|
own_arguments
|
|
@@ -230,16 +198,20 @@ module GraphQL
|
|
|
230
198
|
end
|
|
231
199
|
|
|
232
200
|
def all_argument_definitions
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
201
|
+
if !own_arguments.empty?
|
|
202
|
+
all_defns = own_arguments.values
|
|
203
|
+
all_defns.flatten!
|
|
204
|
+
all_defns
|
|
205
|
+
else
|
|
206
|
+
EmptyObjects::EMPTY_ARRAY
|
|
207
|
+
end
|
|
236
208
|
end
|
|
237
209
|
|
|
238
210
|
# @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name.
|
|
239
211
|
def get_argument(argument_name, context = GraphQL::Query::NullContext.instance)
|
|
240
212
|
warden = Warden.from_context(context)
|
|
241
|
-
if (arg_config = own_arguments[argument_name]) && (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))
|
|
242
|
-
visible_arg
|
|
213
|
+
if (arg_config = own_arguments[argument_name]) && ((context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)) || (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden)))
|
|
214
|
+
visible_arg || arg_config
|
|
243
215
|
elsif defined?(@resolver_class) && @resolver_class
|
|
244
216
|
@resolver_class.get_field_argument(argument_name, context)
|
|
245
217
|
else
|
|
@@ -259,11 +231,11 @@ module GraphQL
|
|
|
259
231
|
#
|
|
260
232
|
# @param values [Hash<String, Object>]
|
|
261
233
|
# @param context [GraphQL::Query::Context]
|
|
262
|
-
# @yield [Interpreter::Arguments, Execution::Lazy<
|
|
263
|
-
# @return [Interpreter::Arguments, Execution::Lazy<
|
|
234
|
+
# @yield [Interpreter::Arguments, Execution::Lazy<Interpreter::Arguments>]
|
|
235
|
+
# @return [Interpreter::Arguments, Execution::Lazy<Interpreter::Arguments>]
|
|
264
236
|
def coerce_arguments(parent_object, values, context, &block)
|
|
265
237
|
# Cache this hash to avoid re-merging it
|
|
266
|
-
arg_defns = context.
|
|
238
|
+
arg_defns = context.types.arguments(self)
|
|
267
239
|
total_args_count = arg_defns.size
|
|
268
240
|
|
|
269
241
|
finished_args = nil
|
|
@@ -387,7 +359,8 @@ module GraphQL
|
|
|
387
359
|
if application_object.nil?
|
|
388
360
|
nil
|
|
389
361
|
else
|
|
390
|
-
|
|
362
|
+
arg_loads_type = argument.loads
|
|
363
|
+
maybe_lazy_resolve_type = context.schema.resolve_type(arg_loads_type, application_object, context)
|
|
391
364
|
context.query.after_lazy(maybe_lazy_resolve_type) do |resolve_type_result|
|
|
392
365
|
if resolve_type_result.is_a?(Array) && resolve_type_result.size == 2
|
|
393
366
|
application_object_type, application_object = resolve_type_result
|
|
@@ -396,10 +369,17 @@ module GraphQL
|
|
|
396
369
|
# application_object is already assigned
|
|
397
370
|
end
|
|
398
371
|
|
|
399
|
-
if
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
372
|
+
passes_possible_types_check = if context.types.loadable?(arg_loads_type, context)
|
|
373
|
+
if arg_loads_type.kind.abstract?
|
|
374
|
+
# This union/interface is used in `loads:` but not otherwise visible to this query
|
|
375
|
+
context.types.loadable_possible_types(arg_loads_type, context).include?(application_object_type)
|
|
376
|
+
else
|
|
377
|
+
true
|
|
378
|
+
end
|
|
379
|
+
else
|
|
380
|
+
context.types.possible_types(arg_loads_type).include?(application_object_type)
|
|
381
|
+
end
|
|
382
|
+
if !passes_possible_types_check
|
|
403
383
|
err = GraphQL::LoadApplicationObjectFailedError.new(context: context, argument: argument, id: id, object: application_object)
|
|
404
384
|
application_object = load_application_object_failed(err)
|
|
405
385
|
end
|
|
@@ -433,6 +413,12 @@ module GraphQL
|
|
|
433
413
|
end
|
|
434
414
|
end
|
|
435
415
|
|
|
416
|
+
# Called when an argument's `loads:` configuration fails to fetch an application object.
|
|
417
|
+
# By default, this method raises the given error, but you can override it to handle failures differently.
|
|
418
|
+
#
|
|
419
|
+
# @param err [GraphQL::LoadApplicationObjectFailedError] The error that occurred
|
|
420
|
+
# @return [Object, nil] If a value is returned, it will be used instead of the failed load
|
|
421
|
+
# @api public
|
|
436
422
|
def load_application_object_failed(err)
|
|
437
423
|
raise err
|
|
438
424
|
end
|