graphql 1.12.1 → 1.12.6
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/install_generator.rb +4 -1
- data/lib/generators/graphql/loader_generator.rb +1 -0
- data/lib/generators/graphql/mutation_generator.rb +1 -0
- data/lib/generators/graphql/relay.rb +55 -0
- data/lib/generators/graphql/relay_generator.rb +4 -46
- data/lib/generators/graphql/type_generator.rb +1 -0
- data/lib/graphql.rb +5 -3
- data/lib/graphql/analysis/analyze_query.rb +1 -1
- data/lib/graphql/analysis/ast.rb +1 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -1
- data/lib/graphql/backtrace/table.rb +0 -1
- data/lib/graphql/backtrace/traced_error.rb +0 -1
- data/lib/graphql/backtrace/tracer.rb +4 -8
- data/lib/graphql/backwards_compatibility.rb +1 -1
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification.rb +1 -1
- data/lib/graphql/compatibility/lazy_execution_specification.rb +1 -1
- data/lib/graphql/compatibility/query_parser_specification.rb +1 -1
- data/lib/graphql/compatibility/schema_parser_specification.rb +1 -1
- data/lib/graphql/dataloader.rb +102 -92
- data/lib/graphql/dataloader/null_dataloader.rb +5 -5
- data/lib/graphql/dataloader/request.rb +1 -6
- data/lib/graphql/dataloader/request_all.rb +1 -4
- data/lib/graphql/dataloader/source.rb +20 -6
- data/lib/graphql/define/instance_definable.rb +1 -1
- data/lib/graphql/deprecated_dsl.rb +4 -4
- data/lib/graphql/deprecation.rb +13 -0
- data/lib/graphql/execution/errors.rb +1 -1
- data/lib/graphql/execution/execute.rb +1 -1
- data/lib/graphql/execution/interpreter.rb +3 -3
- data/lib/graphql/execution/interpreter/arguments_cache.rb +37 -14
- data/lib/graphql/execution/interpreter/resolve.rb +33 -25
- data/lib/graphql/execution/interpreter/runtime.rb +36 -74
- data/lib/graphql/execution/multiplex.rb +22 -23
- data/lib/graphql/function.rb +1 -1
- data/lib/graphql/internal_representation/document.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/cache.rb +37 -0
- data/lib/graphql/language/parser.rb +15 -5
- data/lib/graphql/language/parser.y +15 -5
- data/lib/graphql/object_type.rb +0 -2
- data/lib/graphql/pagination/connection.rb +15 -1
- data/lib/graphql/pagination/connections.rb +2 -1
- data/lib/graphql/pagination/relation_connection.rb +5 -1
- data/lib/graphql/parse_error.rb +0 -1
- data/lib/graphql/query.rb +8 -2
- data/lib/graphql/query/arguments.rb +1 -1
- data/lib/graphql/query/arguments_cache.rb +0 -1
- data/lib/graphql/query/context.rb +1 -3
- data/lib/graphql/query/executor.rb +0 -1
- data/lib/graphql/query/null_context.rb +3 -2
- data/lib/graphql/query/serial_execution.rb +1 -1
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/railtie.rb +9 -1
- data/lib/graphql/relay/base_connection.rb +2 -2
- data/lib/graphql/relay/mutation.rb +1 -1
- data/lib/graphql/relay/node.rb +3 -3
- data/lib/graphql/relay/range_add.rb +10 -5
- data/lib/graphql/relay/type_extensions.rb +2 -2
- data/lib/graphql/schema.rb +14 -13
- data/lib/graphql/schema/argument.rb +61 -0
- data/lib/graphql/schema/field.rb +12 -7
- data/lib/graphql/schema/field/connection_extension.rb +1 -0
- data/lib/graphql/schema/find_inherited_value.rb +3 -1
- data/lib/graphql/schema/input_object.rb +6 -2
- data/lib/graphql/schema/member/has_arguments.rb +43 -56
- data/lib/graphql/schema/member/has_fields.rb +1 -4
- data/lib/graphql/schema/member/instrumentation.rb +0 -1
- data/lib/graphql/schema/middleware_chain.rb +1 -1
- data/lib/graphql/schema/resolver.rb +28 -1
- data/lib/graphql/schema/timeout_middleware.rb +1 -1
- data/lib/graphql/schema/validation.rb +2 -2
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/validator.rb +2 -2
- data/lib/graphql/subscriptions/event.rb +0 -1
- data/lib/graphql/subscriptions/instrumentation.rb +0 -1
- data/lib/graphql/subscriptions/serialize.rb +0 -1
- data/lib/graphql/subscriptions/subscription_root.rb +1 -1
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
- data/lib/graphql/tracing/skylight_tracing.rb +1 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +25 -3
- data/lib/graphql/upgrader/member.rb +1 -1
- data/lib/graphql/upgrader/schema.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- metadata +6 -87
@@ -30,7 +30,7 @@ module GraphQL
|
|
30
30
|
alias :input_fields :arguments
|
31
31
|
|
32
32
|
def initialize
|
33
|
-
warn "GraphQL::Relay::Mutation will be removed from GraphQL-Ruby 2.0, use GraphQL::Schema::RelayClassicMutation instead: https://graphql-ruby.org/mutations/mutation_classes"
|
33
|
+
GraphQL::Deprecation.warn "GraphQL::Relay::Mutation will be removed from GraphQL-Ruby 2.0, use GraphQL::Schema::RelayClassicMutation instead: https://graphql-ruby.org/mutations/mutation_classes"
|
34
34
|
@fields = {}
|
35
35
|
@arguments = {}
|
36
36
|
@has_generated_return_type = false
|
data/lib/graphql/relay/node.rb
CHANGED
@@ -5,7 +5,7 @@ module GraphQL
|
|
5
5
|
module Node
|
6
6
|
# @return [GraphQL::Field] a field for finding objects by their global ID.
|
7
7
|
def self.field(**kwargs, &block)
|
8
|
-
warn "GraphQL::Relay::Node.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodeField instead"
|
8
|
+
GraphQL::Deprecation.warn "GraphQL::Relay::Node.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodeField instead"
|
9
9
|
# We have to define it fresh each time because
|
10
10
|
# its name will be modified and its description
|
11
11
|
# _may_ be modified.
|
@@ -19,7 +19,7 @@ module GraphQL
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.plural_field(**kwargs, &block)
|
22
|
-
warn "GraphQL::Relay::Nodes.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodesField instead"
|
22
|
+
GraphQL::Deprecation.warn "GraphQL::Relay::Nodes.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodesField instead"
|
23
23
|
field = GraphQL::Types::Relay::NodesField.graphql_definition
|
24
24
|
|
25
25
|
if kwargs.any? || block
|
@@ -31,7 +31,7 @@ module GraphQL
|
|
31
31
|
|
32
32
|
# @return [GraphQL::InterfaceType] The interface which all Relay types must implement
|
33
33
|
def self.interface
|
34
|
-
warn "GraphQL::Relay::Node.interface will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::Node instead"
|
34
|
+
GraphQL::Deprecation.warn "GraphQL::Relay::Node.interface will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::Node instead"
|
35
35
|
@interface ||= GraphQL::Types::Relay::Node.graphql_definition
|
36
36
|
end
|
37
37
|
end
|
@@ -9,7 +9,7 @@ module GraphQL
|
|
9
9
|
# should be ordered and paginated before providing it here.
|
10
10
|
#
|
11
11
|
# @example Adding a comment to list of comments
|
12
|
-
# post = Post.find(args[:
|
12
|
+
# post = Post.find(args[:post_id])
|
13
13
|
# comments = post.comments
|
14
14
|
# new_comment = comments.build(body: args[:body])
|
15
15
|
# new_comment.save!
|
@@ -18,13 +18,13 @@ module GraphQL
|
|
18
18
|
# parent: post,
|
19
19
|
# collection: comments,
|
20
20
|
# item: new_comment,
|
21
|
-
# context:
|
21
|
+
# context: context,
|
22
22
|
# )
|
23
23
|
#
|
24
24
|
# response = {
|
25
25
|
# post: post,
|
26
|
-
#
|
27
|
-
#
|
26
|
+
# comments_connection: range_add.connection,
|
27
|
+
# new_comment_edge: range_add.edge,
|
28
28
|
# }
|
29
29
|
class RangeAdd
|
30
30
|
attr_reader :edge, :connection, :parent
|
@@ -39,7 +39,12 @@ module GraphQL
|
|
39
39
|
conn_class = context.schema.connections.wrapper_for(collection)
|
40
40
|
# The rest will be added by ConnectionExtension
|
41
41
|
@connection = conn_class.new(collection, parent: parent, context: context, edge_class: edge_class)
|
42
|
-
|
42
|
+
# Check if this connection supports it, to support old versions of GraphQL-Pro
|
43
|
+
@edge = if @connection.respond_to?(:range_add_edge)
|
44
|
+
@connection.range_add_edge(item)
|
45
|
+
else
|
46
|
+
@connection.edge_class.new(item, @connection)
|
47
|
+
end
|
43
48
|
else
|
44
49
|
connection_class = BaseConnection.connection_for_nodes(collection)
|
45
50
|
@connection = connection_class.new(collection, {}, parent: parent, context: context)
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
# Define a custom connection type for this object type
|
13
13
|
# @return [GraphQL::ObjectType]
|
14
14
|
def define_connection(**kwargs, &block)
|
15
|
-
warn ".connection_type and .define_connection will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
|
15
|
+
GraphQL::Deprecation.warn ".connection_type and .define_connection will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
|
16
16
|
GraphQL::Relay::ConnectionType.create_type(self, **kwargs, &block)
|
17
17
|
end
|
18
18
|
|
@@ -24,7 +24,7 @@ module GraphQL
|
|
24
24
|
# Define a custom edge type for this object type
|
25
25
|
# @return [GraphQL::ObjectType]
|
26
26
|
def define_edge(**kwargs, &block)
|
27
|
-
warn ".edge_type and .define_edge will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
|
27
|
+
GraphQL::Deprecation.warn ".edge_type and .define_edge will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
|
28
28
|
GraphQL::Relay::EdgeType.create_type(self, **kwargs, &block)
|
29
29
|
end
|
30
30
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -184,7 +184,7 @@ module GraphQL
|
|
184
184
|
},
|
185
185
|
query_analyzer: ->(schema, analyzer) {
|
186
186
|
if analyzer == GraphQL::Authorization::Analyzer
|
187
|
-
warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
|
187
|
+
GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
|
188
188
|
end
|
189
189
|
schema.query_analyzers << analyzer
|
190
190
|
},
|
@@ -1118,14 +1118,15 @@ module GraphQL
|
|
1118
1118
|
type.possible_types(context: context)
|
1119
1119
|
else
|
1120
1120
|
stored_possible_types = own_possible_types[type.graphql_name]
|
1121
|
-
visible_possible_types = stored_possible_types
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1121
|
+
visible_possible_types = if stored_possible_types && type.kind.interface?
|
1122
|
+
stored_possible_types.select do |possible_type|
|
1123
|
+
# Use `.graphql_name` comparison to match legacy vs class-based types.
|
1124
|
+
# When we don't need to support legacy `.define` types, use `.include?(type)` instead.
|
1125
|
+
possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
|
1126
|
+
end
|
1127
|
+
else
|
1128
|
+
stored_possible_types
|
1129
|
+
end
|
1129
1130
|
visible_possible_types ||
|
1130
1131
|
introspection_system.possible_types[type.graphql_name] ||
|
1131
1132
|
(
|
@@ -1564,7 +1565,7 @@ module GraphQL
|
|
1564
1565
|
|
1565
1566
|
def instrument(instrument_step, instrumenter, options = {})
|
1566
1567
|
if instrument_step == :field
|
1567
|
-
warn "Field instrumentation (#{instrumenter.inspect}) will be removed in GraphQL-Ruby 2.0, please upgrade to field extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
|
1568
|
+
GraphQL::Deprecation.warn "Field instrumentation (#{instrumenter.inspect}) will be removed in GraphQL-Ruby 2.0, please upgrade to field extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
|
1568
1569
|
end
|
1569
1570
|
|
1570
1571
|
step = if instrument_step == :field && options[:after_built_ins]
|
@@ -1614,7 +1615,7 @@ module GraphQL
|
|
1614
1615
|
|
1615
1616
|
def query_analyzer(new_analyzer)
|
1616
1617
|
if new_analyzer == GraphQL::Authorization::Analyzer
|
1617
|
-
warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
|
1618
|
+
GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
|
1618
1619
|
end
|
1619
1620
|
own_query_analyzers << new_analyzer
|
1620
1621
|
end
|
@@ -1625,7 +1626,7 @@ module GraphQL
|
|
1625
1626
|
|
1626
1627
|
def middleware(new_middleware = nil)
|
1627
1628
|
if new_middleware
|
1628
|
-
warn "Middleware will be removed in GraphQL-Ruby 2.0, please upgrade to Field Extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
|
1629
|
+
GraphQL::Deprecation.warn "Middleware will be removed in GraphQL-Ruby 2.0, please upgrade to Field Extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
|
1629
1630
|
own_middleware << new_middleware
|
1630
1631
|
else
|
1631
1632
|
# TODO make sure this is cached when running a query
|
@@ -1702,7 +1703,7 @@ module GraphQL
|
|
1702
1703
|
if interpreter? && !defined?(@subscription_extension_added) && subscription && self.subscriptions
|
1703
1704
|
@subscription_extension_added = true
|
1704
1705
|
if subscription.singleton_class.ancestors.include?(Subscriptions::SubscriptionRoot)
|
1705
|
-
warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
|
1706
|
+
GraphQL::Deprecation.warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
|
1706
1707
|
else
|
1707
1708
|
subscription.fields.each do |name, field|
|
1708
1709
|
field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
|
@@ -236,6 +236,67 @@ module GraphQL
|
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
239
|
+
# @api private
|
240
|
+
def coerce_into_values(parent_object, values, context, argument_values)
|
241
|
+
arg_name = graphql_name
|
242
|
+
arg_key = keyword
|
243
|
+
has_value = false
|
244
|
+
default_used = false
|
245
|
+
if values.key?(arg_name)
|
246
|
+
has_value = true
|
247
|
+
value = values[arg_name]
|
248
|
+
elsif values.key?(arg_key)
|
249
|
+
has_value = true
|
250
|
+
value = values[arg_key]
|
251
|
+
elsif default_value?
|
252
|
+
has_value = true
|
253
|
+
value = default_value
|
254
|
+
default_used = true
|
255
|
+
end
|
256
|
+
|
257
|
+
if has_value
|
258
|
+
loaded_value = nil
|
259
|
+
coerced_value = context.schema.error_handler.with_error_handling(context) do
|
260
|
+
type.coerce_input(value, context)
|
261
|
+
end
|
262
|
+
|
263
|
+
# TODO this should probably be inside after_lazy
|
264
|
+
if loads && !from_resolver?
|
265
|
+
loaded_value = if type.list?
|
266
|
+
loaded_values = coerced_value.map { |val| owner.load_application_object(self, loads, val, context) }
|
267
|
+
context.schema.after_any_lazies(loaded_values) { |result| result }
|
268
|
+
else
|
269
|
+
owner.load_application_object(self, loads, coerced_value, context)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
coerced_value = if loaded_value
|
274
|
+
loaded_value
|
275
|
+
else
|
276
|
+
coerced_value
|
277
|
+
end
|
278
|
+
|
279
|
+
# If this isn't lazy, then the block returns eagerly and assigns the result here
|
280
|
+
# If it _is_ lazy, then we write the lazy to the hash, then update it later
|
281
|
+
argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |coerced_value|
|
282
|
+
owner.validate_directive_argument(self, coerced_value)
|
283
|
+
prepared_value = context.schema.error_handler.with_error_handling(context) do
|
284
|
+
prepare_value(parent_object, coerced_value, context: context)
|
285
|
+
end
|
286
|
+
|
287
|
+
# TODO code smell to access such a deeply-nested constant in a distant module
|
288
|
+
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
289
|
+
value: prepared_value,
|
290
|
+
definition: self,
|
291
|
+
default_used: default_used,
|
292
|
+
)
|
293
|
+
end
|
294
|
+
else
|
295
|
+
# has_value is false
|
296
|
+
owner.validate_directive_argument(self, nil)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
239
300
|
private
|
240
301
|
|
241
302
|
def validate_input_type(input_type)
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# test_via: ../object.rb
|
3
2
|
require "graphql/schema/field/connection_extension"
|
4
3
|
require "graphql/schema/field/scope_extension"
|
5
4
|
|
@@ -61,6 +60,10 @@ module GraphQL
|
|
61
60
|
@introspection
|
62
61
|
end
|
63
62
|
|
63
|
+
def inspect
|
64
|
+
"#<#{self.class} #{path}#{arguments.any? ? "(...)" : ""}: #{type.to_type_signature}>"
|
65
|
+
end
|
66
|
+
|
64
67
|
alias :mutation :resolver
|
65
68
|
|
66
69
|
# @return [Boolean] Apply tracing to this field? (Default: skip scalars, this is the override value)
|
@@ -83,10 +86,10 @@ module GraphQL
|
|
83
86
|
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
|
84
87
|
if kwargs[:field]
|
85
88
|
if kwargs[:field].is_a?(GraphQL::Field) && kwargs[:field] == GraphQL::Types::Relay::NodeField.graphql_definition
|
86
|
-
warn("Legacy-style `GraphQL::Relay::Node.field` is being added to a class-based type. See `GraphQL::Types::Relay::NodeField` for a replacement.")
|
89
|
+
GraphQL::Deprecation.warn("Legacy-style `GraphQL::Relay::Node.field` is being added to a class-based type. See `GraphQL::Types::Relay::NodeField` for a replacement.")
|
87
90
|
return GraphQL::Types::Relay::NodeField
|
88
91
|
elsif kwargs[:field].is_a?(GraphQL::Field) && kwargs[:field] == GraphQL::Types::Relay::NodesField.graphql_definition
|
89
|
-
warn("Legacy-style `GraphQL::Relay::Node.plural_field` is being added to a class-based type. See `GraphQL::Types::Relay::NodesField` for a replacement.")
|
92
|
+
GraphQL::Deprecation.warn("Legacy-style `GraphQL::Relay::Node.plural_field` is being added to a class-based type. See `GraphQL::Types::Relay::NodesField` for a replacement.")
|
90
93
|
return GraphQL::Types::Relay::NodesField
|
91
94
|
end
|
92
95
|
end
|
@@ -285,22 +288,24 @@ module GraphQL
|
|
285
288
|
@owner = owner
|
286
289
|
@subscription_scope = subscription_scope
|
287
290
|
|
288
|
-
# Do this last so we have as much context as possible when initializing them:
|
289
291
|
@extensions = EMPTY_ARRAY
|
290
|
-
if extensions.any?
|
291
|
-
self.extensions(extensions)
|
292
|
-
end
|
293
292
|
# This should run before connection extension,
|
294
293
|
# but should it run after the definition block?
|
295
294
|
if scoped?
|
296
295
|
self.extension(ScopeExtension)
|
297
296
|
end
|
297
|
+
|
298
298
|
# The problem with putting this after the definition_block
|
299
299
|
# is that it would override arguments
|
300
300
|
if connection? && connection_extension
|
301
301
|
self.extension(connection_extension)
|
302
302
|
end
|
303
303
|
|
304
|
+
# Do this last so we have as much context as possible when initializing them:
|
305
|
+
if extensions.any?
|
306
|
+
self.extensions(extensions)
|
307
|
+
end
|
308
|
+
|
304
309
|
if directives.any?
|
305
310
|
directives.each do |(dir_class, options)|
|
306
311
|
self.directive(dir_class, **options)
|
@@ -42,6 +42,7 @@ module GraphQL
|
|
42
42
|
value.after_value ||= original_arguments[:after]
|
43
43
|
value.last_value ||= original_arguments[:last]
|
44
44
|
value.before_value ||= original_arguments[:before]
|
45
|
+
value.arguments ||= original_arguments
|
45
46
|
value.field ||= field
|
46
47
|
if field.has_max_page_size? && !value.has_max_page_size_override?
|
47
48
|
value.max_page_size = field.max_page_size
|
@@ -20,7 +20,9 @@ module GraphQL
|
|
20
20
|
if self.is_a?(Class)
|
21
21
|
superclass.respond_to?(method_name, true) ? superclass.send(method_name) : default_value
|
22
22
|
else
|
23
|
-
|
23
|
+
ancestors_except_self = ancestors
|
24
|
+
ancestors_except_self.delete(self)
|
25
|
+
ancestors_except_self.each do |ancestor|
|
24
26
|
if ancestor.respond_to?(method_name, true)
|
25
27
|
return ancestor.send(method_name)
|
26
28
|
end
|
@@ -214,8 +214,12 @@ module GraphQL
|
|
214
214
|
arguments = coerce_arguments(nil, value, ctx)
|
215
215
|
|
216
216
|
ctx.schema.after_lazy(arguments) do |resolved_arguments|
|
217
|
-
|
218
|
-
|
217
|
+
if resolved_arguments.is_a?(GraphQL::Error)
|
218
|
+
raise resolved_arguments
|
219
|
+
else
|
220
|
+
input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
|
221
|
+
input_obj_instance.prepare
|
222
|
+
end
|
219
223
|
end
|
220
224
|
end
|
221
225
|
|
@@ -81,79 +81,66 @@ module GraphQL
|
|
81
81
|
end
|
82
82
|
|
83
83
|
# @api private
|
84
|
+
# If given a block, it will eventually yield the loaded args to the block.
|
85
|
+
#
|
86
|
+
# If no block is given, it will immediately dataload (but might return a Lazy).
|
87
|
+
#
|
84
88
|
# @param values [Hash<String, Object>]
|
85
89
|
# @param context [GraphQL::Query::Context]
|
86
|
-
# @
|
87
|
-
|
90
|
+
# @yield [Interpreter::Arguments, Execution::Lazy<Interpeter::Arguments>]
|
91
|
+
# @return [Interpreter::Arguments, Execution::Lazy<Interpeter::Arguments>]
|
92
|
+
def coerce_arguments(parent_object, values, context, &block)
|
88
93
|
# Cache this hash to avoid re-merging it
|
89
94
|
arg_defns = self.arguments
|
95
|
+
total_args_count = arg_defns.size
|
90
96
|
|
91
|
-
if
|
92
|
-
GraphQL::Execution::Interpreter::Arguments::EMPTY
|
97
|
+
if total_args_count == 0
|
98
|
+
final_args = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
99
|
+
if block_given?
|
100
|
+
block.call(final_args)
|
101
|
+
nil
|
102
|
+
else
|
103
|
+
final_args
|
104
|
+
end
|
93
105
|
else
|
106
|
+
finished_args = nil
|
94
107
|
argument_values = {}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
elsif arg_defn.default_value?
|
106
|
-
has_value = true
|
107
|
-
value = arg_defn.default_value
|
108
|
-
default_used = true
|
109
|
-
end
|
110
|
-
|
111
|
-
if has_value
|
112
|
-
loads = arg_defn.loads
|
113
|
-
loaded_value = nil
|
114
|
-
coerced_value = context.schema.error_handler.with_error_handling(context) do
|
115
|
-
arg_defn.type.coerce_input(value, context)
|
116
|
-
end
|
117
|
-
|
118
|
-
# TODO this should probably be inside after_lazy
|
119
|
-
if loads && !arg_defn.from_resolver?
|
120
|
-
loaded_value = if arg_defn.type.list?
|
121
|
-
loaded_values = coerced_value.map { |val| load_application_object(arg_defn, loads, val, context) }
|
122
|
-
context.schema.after_any_lazies(loaded_values) { |result| result }
|
108
|
+
resolved_args_count = 0
|
109
|
+
raised_error = false
|
110
|
+
arg_defns.each do |arg_name, arg_defn|
|
111
|
+
context.dataloader.append_job do
|
112
|
+
begin
|
113
|
+
arg_defn.coerce_into_values(parent_object, values, context, argument_values)
|
114
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => err
|
115
|
+
raised_error = true
|
116
|
+
if block_given?
|
117
|
+
block.call(err)
|
123
118
|
else
|
124
|
-
|
119
|
+
finished_args = err
|
125
120
|
end
|
126
121
|
end
|
127
122
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
123
|
+
resolved_args_count += 1
|
124
|
+
if resolved_args_count == total_args_count && !raised_error
|
125
|
+
finished_args = context.schema.after_any_lazies(argument_values.values) {
|
126
|
+
GraphQL::Execution::Interpreter::Arguments.new(
|
127
|
+
argument_values: argument_values,
|
128
|
+
)
|
129
|
+
}
|
133
130
|
|
134
|
-
|
135
|
-
|
136
|
-
prepared_value = context.schema.error_handler.with_error_handling(context) do
|
137
|
-
arg_defn.prepare_value(parent_object, coerced_value, context: context)
|
131
|
+
if block_given?
|
132
|
+
block.call(finished_args)
|
138
133
|
end
|
139
|
-
|
140
|
-
# TODO code smell to access such a deeply-nested constant in a distant module
|
141
|
-
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
142
|
-
value: prepared_value,
|
143
|
-
definition: arg_defn,
|
144
|
-
default_used: default_used,
|
145
|
-
)
|
146
134
|
end
|
147
|
-
else
|
148
|
-
# has_value is false
|
149
|
-
validate_directive_argument(arg_defn, nil)
|
150
135
|
end
|
151
136
|
end
|
152
137
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
138
|
+
if block_given?
|
139
|
+
nil
|
140
|
+
else
|
141
|
+
# This API returns eagerly, gotta run it now
|
142
|
+
context.dataloader.run
|
143
|
+
finished_args
|
157
144
|
end
|
158
145
|
end
|
159
146
|
end
|