graphql 1.11.1 → 1.11.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +8 -0
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_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 +13 -9
- 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/object.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/scalar.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +2 -0
- data/lib/generators/graphql/templates/union.erb +3 -1
- data/lib/graphql.rb +16 -0
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/tracer.rb +2 -1
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/directive.rb +4 -0
- data/lib/graphql/execution/interpreter.rb +10 -0
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/runtime.rb +59 -45
- data/lib/graphql/field.rb +4 -0
- data/lib/graphql/input_object_type.rb +4 -0
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/introspection/field_type.rb +7 -3
- data/lib/graphql/introspection/input_value_type.rb +6 -0
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/type_type.rb +7 -3
- data/lib/graphql/language/block_string.rb +24 -5
- data/lib/graphql/language/lexer.rb +7 -3
- data/lib/graphql/language/lexer.rl +7 -3
- data/lib/graphql/language/nodes.rb +2 -1
- data/lib/graphql/language/parser.rb +107 -103
- data/lib/graphql/language/parser.y +4 -0
- data/lib/graphql/language/sanitized_printer.rb +59 -26
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/name_validator.rb +6 -7
- data/lib/graphql/pagination/connection.rb +6 -8
- data/lib/graphql/pagination/connections.rb +23 -3
- data/lib/graphql/query.rb +2 -2
- data/lib/graphql/query/context.rb +30 -3
- data/lib/graphql/query/fingerprint.rb +2 -0
- data/lib/graphql/query/validation_pipeline.rb +3 -0
- data/lib/graphql/relay/range_add.rb +14 -5
- data/lib/graphql/schema.rb +40 -31
- data/lib/graphql/schema/argument.rb +56 -5
- data/lib/graphql/schema/build_from_definition.rb +67 -38
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/enum_value.rb +1 -0
- data/lib/graphql/schema/field.rb +17 -10
- data/lib/graphql/schema/field/connection_extension.rb +44 -34
- data/lib/graphql/schema/input_object.rb +21 -18
- data/lib/graphql/schema/interface.rb +1 -1
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/loader.rb +20 -1
- data/lib/graphql/schema/member/build_type.rb +14 -4
- data/lib/graphql/schema/member/has_arguments.rb +19 -1
- data/lib/graphql/schema/member/has_fields.rb +17 -7
- data/lib/graphql/schema/member/type_system_helpers.rb +2 -2
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +3 -1
- data/lib/graphql/schema/resolver.rb +6 -0
- data/lib/graphql/schema/resolver/has_payload_type.rb +2 -1
- data/lib/graphql/schema/subscription.rb +2 -12
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/union.rb +29 -0
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +8 -0
- data/lib/graphql/schema/warden.rb +8 -3
- data/lib/graphql/static_validation/literal_validator.rb +7 -7
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -2
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/static_validation/validator.rb +7 -4
- data/lib/graphql/subscriptions.rb +32 -22
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +45 -20
- data/lib/graphql/subscriptions/serialize.rb +22 -4
- data/lib/graphql/tracing/appoptics_tracing.rb +10 -2
- data/lib/graphql/types/iso_8601_date_time.rb +2 -1
- data/lib/graphql/types/relay/base_connection.rb +6 -5
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- metadata +3 -3
@@ -45,7 +45,8 @@ module GraphQL
|
|
45
45
|
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
46
46
|
# @param from_resolver [Boolean] if true, a Resolver class defined this argument
|
47
47
|
# @param method_access [Boolean] If false, don't build method access on legacy {Query::Arguments} instances.
|
48
|
-
|
48
|
+
# @param deprecation_reason [String]
|
49
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required:, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, method_access: true, owner:, deprecation_reason: nil, &definition_block)
|
49
50
|
arg_name ||= name
|
50
51
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
51
52
|
@type_expr = type_expr || type
|
@@ -60,6 +61,7 @@ module GraphQL
|
|
60
61
|
@ast_node = ast_node
|
61
62
|
@from_resolver = from_resolver
|
62
63
|
@method_access = method_access
|
64
|
+
self.deprecation_reason = deprecation_reason
|
63
65
|
|
64
66
|
if definition_block
|
65
67
|
if definition_block.arity == 1
|
@@ -89,6 +91,18 @@ module GraphQL
|
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
94
|
+
# @return [String] Deprecation reason for this argument
|
95
|
+
def deprecation_reason(text = nil)
|
96
|
+
if text
|
97
|
+
validate_deprecated_or_optional(null: @null, deprecation_reason: text)
|
98
|
+
@deprecation_reason = text
|
99
|
+
else
|
100
|
+
@deprecation_reason
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
alias_method :deprecation_reason=, :deprecation_reason
|
105
|
+
|
92
106
|
def visible?(context)
|
93
107
|
true
|
94
108
|
end
|
@@ -143,15 +157,32 @@ module GraphQL
|
|
143
157
|
if NO_DEFAULT != @default_value
|
144
158
|
argument.default_value = @default_value
|
145
159
|
end
|
160
|
+
if @deprecation_reason
|
161
|
+
argument.deprecation_reason = @deprecation_reason
|
162
|
+
end
|
146
163
|
argument
|
147
164
|
end
|
148
165
|
|
149
|
-
|
166
|
+
def type=(new_type)
|
167
|
+
validate_input_type(new_type)
|
168
|
+
# This isn't true for LateBoundTypes, but we can assume those will
|
169
|
+
# be updated via this codepath later in schema setup.
|
170
|
+
if new_type.respond_to?(:non_null?)
|
171
|
+
validate_deprecated_or_optional(null: !new_type.non_null?, deprecation_reason: deprecation_reason)
|
172
|
+
end
|
173
|
+
@type = new_type
|
174
|
+
end
|
150
175
|
|
151
176
|
def type
|
152
|
-
@type ||=
|
153
|
-
|
154
|
-
|
177
|
+
@type ||= begin
|
178
|
+
parsed_type = begin
|
179
|
+
Member::BuildType.parse_type(@type_expr, null: @null)
|
180
|
+
rescue StandardError => err
|
181
|
+
raise ArgumentError, "Couldn't build type for Argument #{@owner.name}.#{name}: #{err.class.name}: #{err.message}", err.backtrace
|
182
|
+
end
|
183
|
+
# Use the setter method to get validations
|
184
|
+
self.type = parsed_type
|
185
|
+
end
|
155
186
|
end
|
156
187
|
|
157
188
|
def statically_coercible?
|
@@ -186,6 +217,26 @@ module GraphQL
|
|
186
217
|
raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}"
|
187
218
|
end
|
188
219
|
end
|
220
|
+
|
221
|
+
private
|
222
|
+
|
223
|
+
def validate_input_type(input_type)
|
224
|
+
if input_type.is_a?(String) || input_type.is_a?(GraphQL::Schema::LateBoundType)
|
225
|
+
# Do nothing; assume this will be validated later
|
226
|
+
elsif input_type.kind.non_null? || input_type.kind.list?
|
227
|
+
validate_input_type(input_type.unwrap)
|
228
|
+
elsif !input_type.kind.input?
|
229
|
+
raise ArgumentError, "Invalid input type for #{path}: #{input_type.graphql_name}. Must be scalar, enum, or input object, not #{input_type.kind.name}."
|
230
|
+
else
|
231
|
+
# It's an input type, we're OK
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def validate_deprecated_or_optional(null:, deprecation_reason:)
|
236
|
+
if deprecation_reason && !null
|
237
|
+
raise ArgumentError, "Required arguments cannot be deprecated: #{path}."
|
238
|
+
end
|
239
|
+
end
|
189
240
|
end
|
190
241
|
end
|
191
242
|
end
|
@@ -4,17 +4,24 @@ require "graphql/schema/build_from_definition/resolve_map"
|
|
4
4
|
module GraphQL
|
5
5
|
class Schema
|
6
6
|
module BuildFromDefinition
|
7
|
+
if !String.method_defined?(:-@)
|
8
|
+
using GraphQL::StringDedupBackport
|
9
|
+
end
|
10
|
+
|
7
11
|
class << self
|
8
12
|
# @see {Schema.from_definition}
|
9
|
-
def from_definition(definition_string,
|
10
|
-
|
11
|
-
default_resolve ||= {}
|
12
|
-
Builder.build(document, default_resolve: default_resolve, relay: relay, using: using, interpreter: interpreter)
|
13
|
+
def from_definition(definition_string, parser: GraphQL.default_parser, **kwargs)
|
14
|
+
from_document(parser.parse(definition_string), **kwargs)
|
13
15
|
end
|
14
|
-
end
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
def from_definition_path(definition_path, parser: GraphQL.default_parser, **kwargs)
|
18
|
+
from_document(parser.parse_file(definition_path), **kwargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
def from_document(document, default_resolve:, using: {}, relay: false, interpreter: true)
|
22
|
+
Builder.build(document, default_resolve: default_resolve || {}, relay: relay, using: using, interpreter: interpreter)
|
23
|
+
end
|
24
|
+
end
|
18
25
|
|
19
26
|
# @api private
|
20
27
|
module Builder
|
@@ -43,7 +50,7 @@ module GraphQL
|
|
43
50
|
when GraphQL::Language::Nodes::EnumTypeDefinition
|
44
51
|
types[definition.name] = build_enum_type(definition, type_resolver)
|
45
52
|
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
46
|
-
types[definition.name] = build_object_type(definition, type_resolver
|
53
|
+
types[definition.name] = build_object_type(definition, type_resolver)
|
47
54
|
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
48
55
|
types[definition.name] = build_interface_type(definition, type_resolver)
|
49
56
|
when GraphQL::Language::Nodes::UnionTypeDefinition
|
@@ -111,11 +118,11 @@ module GraphQL
|
|
111
118
|
end
|
112
119
|
|
113
120
|
if default_resolve.respond_to?(:resolve_type)
|
114
|
-
|
115
|
-
|
121
|
+
def self.resolve_type(*args)
|
122
|
+
self.definition_default_resolve.resolve_type(*args)
|
116
123
|
end
|
117
124
|
else
|
118
|
-
|
125
|
+
def self.resolve_type(*args)
|
119
126
|
NullResolveType.call(*args)
|
120
127
|
end
|
121
128
|
end
|
@@ -141,6 +148,20 @@ module GraphQL
|
|
141
148
|
|
142
149
|
# Empty `orphan_types` -- this will make unreachable types ... unreachable.
|
143
150
|
own_orphan_types.clear
|
151
|
+
|
152
|
+
class << self
|
153
|
+
attr_accessor :definition_default_resolve
|
154
|
+
end
|
155
|
+
|
156
|
+
self.definition_default_resolve = default_resolve
|
157
|
+
|
158
|
+
def definition_default_resolve
|
159
|
+
self.class.definition_default_resolve
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.inherited(child_class)
|
163
|
+
child_class.definition_default_resolve = self.definition_default_resolve
|
164
|
+
end
|
144
165
|
end
|
145
166
|
end
|
146
167
|
|
@@ -176,23 +197,27 @@ module GraphQL
|
|
176
197
|
end
|
177
198
|
|
178
199
|
def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
|
200
|
+
builder = self
|
179
201
|
Class.new(GraphQL::Schema::Scalar) do
|
180
202
|
graphql_name(scalar_type_definition.name)
|
181
203
|
description(scalar_type_definition.description)
|
182
204
|
ast_node(scalar_type_definition)
|
183
205
|
|
184
206
|
if default_resolve.respond_to?(:coerce_input)
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
define_singleton_method(:coerce_result) do |val, ctx|
|
190
|
-
default_resolve.coerce_result(self, val, ctx)
|
191
|
-
end
|
207
|
+
# Put these method definitions in another method to avoid retaining `type_resolve`
|
208
|
+
# from this method's bindiing
|
209
|
+
builder.build_scalar_type_coerce_method(self, :coerce_input, default_resolve)
|
210
|
+
builder.build_scalar_type_coerce_method(self, :coerce_result, default_resolve)
|
192
211
|
end
|
193
212
|
end
|
194
213
|
end
|
195
214
|
|
215
|
+
def build_scalar_type_coerce_method(scalar_class, method_name, default_definition_resolve)
|
216
|
+
scalar_class.define_singleton_method(method_name) do |val, ctx|
|
217
|
+
default_definition_resolve.public_send(method_name, self, val, ctx)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
196
221
|
def build_union_type(union_type_definition, type_resolver)
|
197
222
|
Class.new(GraphQL::Schema::Union) do
|
198
223
|
graphql_name(union_type_definition.name)
|
@@ -202,13 +227,10 @@ module GraphQL
|
|
202
227
|
end
|
203
228
|
end
|
204
229
|
|
205
|
-
def build_object_type(object_type_definition, type_resolver
|
230
|
+
def build_object_type(object_type_definition, type_resolver)
|
206
231
|
builder = self
|
207
|
-
type_def = nil
|
208
|
-
typed_resolve_fn = ->(field, obj, args, ctx) { default_resolve.call(type_def, field, obj, args, ctx) }
|
209
232
|
|
210
233
|
Class.new(GraphQL::Schema::Object) do
|
211
|
-
type_def = self
|
212
234
|
graphql_name(object_type_definition.name)
|
213
235
|
description(object_type_definition.description)
|
214
236
|
ast_node(object_type_definition)
|
@@ -218,7 +240,7 @@ module GraphQL
|
|
218
240
|
implements(interface_defn)
|
219
241
|
end
|
220
242
|
|
221
|
-
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve:
|
243
|
+
builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
|
222
244
|
end
|
223
245
|
end
|
224
246
|
|
@@ -247,13 +269,16 @@ module GraphQL
|
|
247
269
|
end
|
248
270
|
end
|
249
271
|
|
272
|
+
NO_DEFAULT_VALUE = {}.freeze
|
273
|
+
|
250
274
|
def build_arguments(type_class, arguments, type_resolver)
|
251
275
|
builder = self
|
252
276
|
|
253
277
|
arguments.each do |argument_defn|
|
254
|
-
default_value_kwargs =
|
255
|
-
|
256
|
-
|
278
|
+
default_value_kwargs = if !argument_defn.default_value.nil?
|
279
|
+
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
280
|
+
else
|
281
|
+
NO_DEFAULT_VALUE
|
257
282
|
end
|
258
283
|
|
259
284
|
type_class.argument(
|
@@ -261,6 +286,7 @@ module GraphQL
|
|
261
286
|
type: type_resolver.call(argument_defn.type),
|
262
287
|
required: false,
|
263
288
|
description: argument_defn.description,
|
289
|
+
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
264
290
|
ast_node: argument_defn,
|
265
291
|
camelize: false,
|
266
292
|
method_access: false,
|
@@ -295,10 +321,10 @@ module GraphQL
|
|
295
321
|
def build_fields(owner, field_definitions, type_resolver, default_resolve:)
|
296
322
|
builder = self
|
297
323
|
|
298
|
-
field_definitions.
|
324
|
+
field_definitions.each do |field_definition|
|
299
325
|
type_name = resolve_type_name(field_definition.type)
|
300
|
-
resolve_method_name = "resolve_field_#{field_definition.name}"
|
301
|
-
owner.field(
|
326
|
+
resolve_method_name = -"resolve_field_#{field_definition.name}"
|
327
|
+
schema_field_defn = owner.field(
|
302
328
|
field_definition.name,
|
303
329
|
description: field_definition.description,
|
304
330
|
type: type_resolver.call(field_definition.type),
|
@@ -310,16 +336,19 @@ module GraphQL
|
|
310
336
|
method_conflict_warning: false,
|
311
337
|
camelize: false,
|
312
338
|
resolver_method: resolve_method_name,
|
313
|
-
)
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
339
|
+
)
|
340
|
+
|
341
|
+
builder.build_arguments(schema_field_defn, field_definition.arguments, type_resolver)
|
342
|
+
|
343
|
+
# Don't do this for interfaces
|
344
|
+
if default_resolve
|
345
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
346
|
+
# frozen_string_literal: true
|
347
|
+
def #{resolve_method_name}(**args)
|
348
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
349
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
321
350
|
end
|
322
|
-
|
351
|
+
RUBY
|
323
352
|
end
|
324
353
|
end
|
325
354
|
end
|
@@ -45,8 +45,10 @@ module GraphQL
|
|
45
45
|
@resolve_hash[type_name_s][field_name.to_s] = resolve_fn
|
46
46
|
end
|
47
47
|
when Proc
|
48
|
-
# for example,
|
48
|
+
# for example, "resolve_type"
|
49
49
|
@resolve_hash[type_name_s] = fields
|
50
|
+
else
|
51
|
+
raise ArgumentError, "Unexpected resolve hash value for #{type_name.inspect}: #{fields.inspect} (#{fields.class})"
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
class Directive < GraphQL::Schema::Member
|
5
5
|
class Deprecated < GraphQL::Schema::Directive
|
6
6
|
description "Marks an element of a GraphQL schema as no longer supported."
|
7
|
-
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE)
|
7
|
+
locations(GraphQL::Schema::Directive::FIELD_DEFINITION, GraphQL::Schema::Directive::ENUM_VALUE, GraphQL::Schema::Directive::ARGUMENT_DEFINITION, GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION)
|
8
8
|
|
9
9
|
reason_description = "Explains why this element was deprecated, usually also including a "\
|
10
10
|
"suggestion for how to access supported similar data. Formatted "\
|
@@ -41,6 +41,7 @@ module GraphQL
|
|
41
41
|
|
42
42
|
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, description: nil, value: nil, deprecation_reason: nil, &block)
|
43
43
|
@graphql_name = graphql_name.to_s
|
44
|
+
GraphQL::NameValidator.validate!(@graphql_name)
|
44
45
|
@description = desc || description
|
45
46
|
@value = value.nil? ? @graphql_name : value
|
46
47
|
@deprecation_reason = deprecation_reason
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -203,7 +203,7 @@ module GraphQL
|
|
203
203
|
# @param broadcastable [Boolean] Whether or not this field can be distributed in subscription broadcasts
|
204
204
|
# @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
|
205
205
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
206
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, ast_node: nil, extras:
|
206
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, &definition_block)
|
207
207
|
if name.nil?
|
208
208
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
209
209
|
end
|
@@ -250,7 +250,7 @@ module GraphQL
|
|
250
250
|
method_name = method || hash_key || name_s
|
251
251
|
resolver_method ||= name_s.to_sym
|
252
252
|
|
253
|
-
@method_str = method_name.to_s
|
253
|
+
@method_str = -method_name.to_s
|
254
254
|
@method_sym = method_name.to_sym
|
255
255
|
@resolver_method = resolver_method
|
256
256
|
@complexity = complexity
|
@@ -274,7 +274,7 @@ module GraphQL
|
|
274
274
|
if arg.is_a?(Hash)
|
275
275
|
argument(name: name, **arg)
|
276
276
|
else
|
277
|
-
|
277
|
+
add_argument(arg)
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
@@ -282,7 +282,7 @@ module GraphQL
|
|
282
282
|
@subscription_scope = subscription_scope
|
283
283
|
|
284
284
|
# Do this last so we have as much context as possible when initializing them:
|
285
|
-
@extensions =
|
285
|
+
@extensions = EMPTY_ARRAY
|
286
286
|
if extensions.any?
|
287
287
|
self.extensions(extensions)
|
288
288
|
end
|
@@ -343,6 +343,9 @@ module GraphQL
|
|
343
343
|
# Read the value
|
344
344
|
@extensions
|
345
345
|
else
|
346
|
+
if @extensions.frozen?
|
347
|
+
@extensions = @extensions.dup
|
348
|
+
end
|
346
349
|
new_extensions.each do |extension|
|
347
350
|
if extension.is_a?(Hash)
|
348
351
|
extension = extension.to_a[0]
|
@@ -380,6 +383,9 @@ module GraphQL
|
|
380
383
|
# Read the value
|
381
384
|
@extras
|
382
385
|
else
|
386
|
+
if @extras.frozen?
|
387
|
+
@extras = @extras.dup
|
388
|
+
end
|
383
389
|
# Append to the set of extras on this field
|
384
390
|
@extras.concat(new_extras)
|
385
391
|
end
|
@@ -719,20 +725,21 @@ module GraphQL
|
|
719
725
|
if @extensions.empty?
|
720
726
|
yield(obj, args)
|
721
727
|
else
|
722
|
-
|
723
|
-
|
724
|
-
original_obj = obj
|
728
|
+
extended_obj = obj
|
729
|
+
extended_args = args
|
725
730
|
|
726
731
|
memos = []
|
727
|
-
value = run_extensions_before_resolve(memos, obj, args, ctx) do |
|
728
|
-
|
732
|
+
value = run_extensions_before_resolve(memos, obj, args, ctx) do |obj, args|
|
733
|
+
extended_obj = obj
|
734
|
+
extended_args = args
|
735
|
+
yield(obj, args)
|
729
736
|
end
|
730
737
|
|
731
738
|
ctx.schema.after_lazy(value) do |resolved_value|
|
732
739
|
@extensions.each_with_index do |ext, idx|
|
733
740
|
memo = memos[idx]
|
734
741
|
# TODO after_lazy?
|
735
|
-
resolved_value = ext.after_resolve(object:
|
742
|
+
resolved_value = ext.after_resolve(object: extended_obj, arguments: extended_args, context: ctx, value: resolved_value, memo: memo)
|
736
743
|
end
|
737
744
|
resolved_value
|
738
745
|
end
|
@@ -18,44 +18,54 @@ module GraphQL
|
|
18
18
|
next_args.delete(:last)
|
19
19
|
next_args.delete(:before)
|
20
20
|
next_args.delete(:after)
|
21
|
-
yield(object, next_args)
|
21
|
+
yield(object, next_args, arguments)
|
22
22
|
end
|
23
23
|
|
24
24
|
def after_resolve(value:, object:, arguments:, context:, memo:)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
value.
|
36
|
-
|
37
|
-
value.
|
38
|
-
|
39
|
-
|
40
|
-
value.
|
25
|
+
original_arguments = memo
|
26
|
+
# rename some inputs to avoid conflicts inside the block
|
27
|
+
maybe_lazy = value
|
28
|
+
value = nil
|
29
|
+
context.schema.after_lazy(maybe_lazy) do |resolved_value|
|
30
|
+
value = resolved_value
|
31
|
+
if value.is_a? GraphQL::ExecutionError
|
32
|
+
# This isn't even going to work because context doesn't have ast_node anymore
|
33
|
+
context.add_error(value)
|
34
|
+
nil
|
35
|
+
elsif value.nil?
|
36
|
+
nil
|
37
|
+
elsif value.is_a?(GraphQL::Pagination::Connection)
|
38
|
+
# update the connection with some things that may not have been provided
|
39
|
+
value.context ||= context
|
40
|
+
value.parent ||= object.object
|
41
|
+
value.first_value ||= original_arguments[:first]
|
42
|
+
value.after_value ||= original_arguments[:after]
|
43
|
+
value.last_value ||= original_arguments[:last]
|
44
|
+
value.before_value ||= original_arguments[:before]
|
45
|
+
if field.has_max_page_size? && !value.has_max_page_size_override?
|
46
|
+
value.max_page_size = field.max_page_size
|
47
|
+
end
|
48
|
+
if context.schema.new_connections? && (custom_t = context.schema.connections.edge_class_for_field(@field))
|
49
|
+
value.edge_class = custom_t
|
50
|
+
end
|
51
|
+
value
|
52
|
+
elsif context.schema.new_connections?
|
53
|
+
wrappers = context.namespace(:connections)[:all_wrappers] ||= context.schema.connections.all_wrappers
|
54
|
+
context.schema.connections.wrap(field, object.object, value, original_arguments, context, wrappers: wrappers)
|
55
|
+
else
|
56
|
+
if object.is_a?(GraphQL::Schema::Object)
|
57
|
+
object = object.object
|
58
|
+
end
|
59
|
+
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(value)
|
60
|
+
connection_class.new(
|
61
|
+
value,
|
62
|
+
original_arguments,
|
63
|
+
field: field,
|
64
|
+
max_page_size: field.max_page_size,
|
65
|
+
parent: object,
|
66
|
+
context: context,
|
67
|
+
)
|
41
68
|
end
|
42
|
-
value
|
43
|
-
elsif context.schema.new_connections?
|
44
|
-
wrappers = context.namespace(:connections)[:all_wrappers] ||= context.schema.connections.all_wrappers
|
45
|
-
context.schema.connections.wrap(field, object.object, value, arguments, context, wrappers: wrappers)
|
46
|
-
else
|
47
|
-
if object.is_a?(GraphQL::Schema::Object)
|
48
|
-
object = object.object
|
49
|
-
end
|
50
|
-
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(value)
|
51
|
-
connection_class.new(
|
52
|
-
value,
|
53
|
-
arguments,
|
54
|
-
field: field,
|
55
|
-
max_page_size: field.max_page_size,
|
56
|
-
parent: object,
|
57
|
-
context: context,
|
58
|
-
)
|
59
69
|
end
|
60
70
|
end
|
61
71
|
end
|