graphql 1.11.1 → 1.11.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/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
|