graphql 1.8.0.pre9 → 1.8.0.pre10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/argument.rb +1 -0
- data/lib/graphql/base_type.rb +2 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +110 -0
- data/lib/graphql/deprecated_dsl.rb +15 -3
- data/lib/graphql/directive.rb +1 -0
- data/lib/graphql/enum_type.rb +2 -0
- data/lib/graphql/execution/multiplex.rb +1 -1
- data/lib/graphql/field.rb +2 -0
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/schema_field.rb +1 -1
- data/lib/graphql/introspection/type_by_name_field.rb +1 -1
- data/lib/graphql/language/parser.rb +25 -25
- data/lib/graphql/language/parser.y +7 -7
- data/lib/graphql/query/arguments.rb +12 -0
- data/lib/graphql/relay/mutation/instrumentation.rb +1 -1
- data/lib/graphql/relay/mutation/resolve.rb +5 -1
- data/lib/graphql/schema.rb +5 -1
- data/lib/graphql/schema/argument.rb +1 -0
- data/lib/graphql/schema/build_from_definition.rb +60 -18
- data/lib/graphql/schema/enum.rb +1 -0
- data/lib/graphql/schema/enum_value.rb +1 -0
- data/lib/graphql/schema/field.rb +44 -31
- data/lib/graphql/schema/field/dynamic_resolve.rb +4 -8
- data/lib/graphql/schema/input_object.rb +30 -19
- data/lib/graphql/schema/interface.rb +12 -5
- data/lib/graphql/schema/member.rb +10 -0
- data/lib/graphql/schema/member/build_type.rb +3 -1
- data/lib/graphql/schema/member/has_arguments.rb +50 -0
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/instrumentation.rb +4 -4
- data/lib/graphql/schema/mutation.rb +195 -0
- data/lib/graphql/schema/object.rb +4 -5
- data/lib/graphql/schema/relay_classic_mutation.rb +85 -0
- data/lib/graphql/schema/scalar.rb +1 -0
- data/lib/graphql/schema/traversal.rb +1 -1
- data/lib/graphql/schema/union.rb +1 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
- data/lib/graphql/unresolved_type_error.rb +3 -2
- data/lib/graphql/upgrader/member.rb +194 -19
- data/lib/graphql/version.rb +1 -1
- data/spec/fixtures/upgrader/delete_project.original.rb +28 -0
- data/spec/fixtures/upgrader/delete_project.transformed.rb +27 -0
- data/spec/fixtures/upgrader/increment_count.original.rb +59 -0
- data/spec/fixtures/upgrader/increment_count.transformed.rb +50 -0
- data/spec/graphql/execution/multiplex_spec.rb +1 -1
- data/spec/graphql/language/parser_spec.rb +0 -74
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -8
- data/spec/graphql/query_spec.rb +26 -0
- data/spec/graphql/relay/mutation_spec.rb +2 -2
- data/spec/graphql/schema/build_from_definition_spec.rb +59 -0
- data/spec/graphql/schema/field_spec.rb +24 -0
- data/spec/graphql/schema/input_object_spec.rb +1 -0
- data/spec/graphql/schema/interface_spec.rb +4 -1
- data/spec/graphql/schema/mutation_spec.rb +99 -0
- data/spec/graphql/schema/relay_classic_mutation_spec.rb +28 -0
- data/spec/support/jazz.rb +25 -1
- data/spec/support/star_wars/schema.rb +17 -27
- metadata +17 -2
@@ -10,7 +10,7 @@ module GraphQL
|
|
10
10
|
# By using an instrumention, we can apply our wrapper _last_,
|
11
11
|
# giving users access to the original resolve function in earlier instrumentation.
|
12
12
|
def self.instrument(type, field)
|
13
|
-
if field.mutation
|
13
|
+
if field.mutation.is_a?(GraphQL::Relay::Mutation) || (field.mutation.is_a?(Class) && field.mutation < GraphQL::Schema::RelayClassicMutation)
|
14
14
|
new_resolve = Mutation::Resolve.new(field.mutation, field.resolve_proc)
|
15
15
|
new_lazy_resolve = Mutation::Resolve.new(field.mutation, field.lazy_resolve_proc)
|
16
16
|
field.redefine(resolve: new_resolve, lazy_resolve: new_lazy_resolve)
|
@@ -10,7 +10,8 @@ module GraphQL
|
|
10
10
|
def initialize(mutation, resolve)
|
11
11
|
@mutation = mutation
|
12
12
|
@resolve = resolve
|
13
|
-
@wrap_result = mutation.has_generated_return_type?
|
13
|
+
@wrap_result = mutation.is_a?(GraphQL::Relay::Mutation) && mutation.has_generated_return_type?
|
14
|
+
@class_based = mutation.is_a?(Class)
|
14
15
|
end
|
15
16
|
|
16
17
|
def call(obj, args, ctx)
|
@@ -44,6 +45,9 @@ module GraphQL
|
|
44
45
|
end
|
45
46
|
|
46
47
|
@mutation.result_class.new(client_mutation_id: args[:input][:clientMutationId], result: mutation_result)
|
48
|
+
elsif @class_based
|
49
|
+
mutation_result[:client_mutation_id] = args[:input][:client_mutation_id]
|
50
|
+
mutation_result
|
47
51
|
else
|
48
52
|
mutation_result
|
49
53
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -27,6 +27,8 @@ require "graphql/schema/enum"
|
|
27
27
|
require "graphql/schema/field"
|
28
28
|
require "graphql/schema/input_object"
|
29
29
|
require "graphql/schema/interface"
|
30
|
+
require "graphql/schema/mutation"
|
31
|
+
require "graphql/schema/relay_classic_mutation"
|
30
32
|
require "graphql/schema/object"
|
31
33
|
require "graphql/schema/scalar"
|
32
34
|
require "graphql/schema/union"
|
@@ -96,7 +98,9 @@ module GraphQL
|
|
96
98
|
:orphan_types, :directives,
|
97
99
|
:query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
|
98
100
|
:cursor_encoder,
|
99
|
-
:
|
101
|
+
:ast_node,
|
102
|
+
:raise_definition_error,
|
103
|
+
:introspection_namespace
|
100
104
|
|
101
105
|
# Single, long-lived instance of the provided subscriptions class, if there is one.
|
102
106
|
# @return [GraphQL::Subscriptions]
|
@@ -107,6 +107,8 @@ module GraphQL
|
|
107
107
|
directives directives.values
|
108
108
|
end
|
109
109
|
|
110
|
+
schema.ast_node = schema_definition if schema_definition
|
111
|
+
|
110
112
|
schema
|
111
113
|
end
|
112
114
|
|
@@ -117,18 +119,26 @@ module GraphQL
|
|
117
119
|
NullScalarCoerce = ->(val, _ctx) { val }
|
118
120
|
|
119
121
|
def build_enum_type(enum_type_definition, type_resolver)
|
120
|
-
GraphQL::EnumType.define(
|
122
|
+
enum = GraphQL::EnumType.define(
|
121
123
|
name: enum_type_definition.name,
|
122
124
|
description: enum_type_definition.description,
|
123
125
|
values: enum_type_definition.values.map do |enum_value_definition|
|
124
|
-
EnumType::EnumValue.define(
|
126
|
+
value = EnumType::EnumValue.define(
|
125
127
|
name: enum_value_definition.name,
|
126
128
|
value: enum_value_definition.name,
|
127
129
|
deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
|
128
130
|
description: enum_value_definition.description,
|
129
131
|
)
|
132
|
+
|
133
|
+
value.ast_node = enum_value_definition
|
134
|
+
|
135
|
+
value
|
130
136
|
end
|
131
137
|
)
|
138
|
+
|
139
|
+
enum.ast_node = enum_type_definition
|
140
|
+
|
141
|
+
enum
|
132
142
|
end
|
133
143
|
|
134
144
|
def build_deprecation_reason(directives)
|
@@ -148,6 +158,8 @@ module GraphQL
|
|
148
158
|
coerce: NullScalarCoerce,
|
149
159
|
)
|
150
160
|
|
161
|
+
scalar_type.ast_node = scalar_type_definition
|
162
|
+
|
151
163
|
if default_resolve.respond_to?(:coerce_input)
|
152
164
|
scalar_type = scalar_type.redefine(
|
153
165
|
coerce_input: ->(val, ctx) { default_resolve.coerce_input(scalar_type, val, ctx) },
|
@@ -159,11 +171,15 @@ module GraphQL
|
|
159
171
|
end
|
160
172
|
|
161
173
|
def build_union_type(union_type_definition, type_resolver)
|
162
|
-
GraphQL::UnionType.define(
|
174
|
+
union = GraphQL::UnionType.define(
|
163
175
|
name: union_type_definition.name,
|
164
176
|
description: union_type_definition.description,
|
165
177
|
possible_types: union_type_definition.types.map{ |type_name| type_resolver.call(type_name) },
|
166
178
|
)
|
179
|
+
|
180
|
+
union.ast_node = union_type_definition
|
181
|
+
|
182
|
+
union
|
167
183
|
end
|
168
184
|
|
169
185
|
def build_object_type(object_type_definition, type_resolver, default_resolve:)
|
@@ -175,14 +191,20 @@ module GraphQL
|
|
175
191
|
fields: Hash[build_fields(object_type_definition.fields, type_resolver, default_resolve: typed_resolve_fn)],
|
176
192
|
interfaces: object_type_definition.interfaces.map{ |interface_name| type_resolver.call(interface_name) },
|
177
193
|
)
|
194
|
+
type_def.ast_node = object_type_definition
|
195
|
+
type_def
|
178
196
|
end
|
179
197
|
|
180
198
|
def build_input_object_type(input_object_type_definition, type_resolver)
|
181
|
-
GraphQL::InputObjectType.define(
|
199
|
+
input = GraphQL::InputObjectType.define(
|
182
200
|
name: input_object_type_definition.name,
|
183
201
|
description: input_object_type_definition.description,
|
184
202
|
arguments: Hash[build_input_arguments(input_object_type_definition, type_resolver)],
|
185
203
|
)
|
204
|
+
|
205
|
+
input.ast_node = input_object_type_definition
|
206
|
+
|
207
|
+
input
|
186
208
|
end
|
187
209
|
|
188
210
|
def build_default_value(default_value)
|
@@ -208,25 +230,33 @@ module GraphQL
|
|
208
230
|
kwargs[:default_value] = build_default_value(input_argument.default_value)
|
209
231
|
end
|
210
232
|
|
233
|
+
argument = GraphQL::Argument.define(
|
234
|
+
name: input_argument.name,
|
235
|
+
type: type_resolver.call(input_argument.type),
|
236
|
+
description: input_argument.description,
|
237
|
+
**kwargs,
|
238
|
+
)
|
239
|
+
|
240
|
+
argument.ast_node = input_object_type_definition
|
241
|
+
|
211
242
|
[
|
212
243
|
input_argument.name,
|
213
|
-
|
214
|
-
name: input_argument.name,
|
215
|
-
type: type_resolver.call(input_argument.type),
|
216
|
-
description: input_argument.description,
|
217
|
-
**kwargs,
|
218
|
-
)
|
244
|
+
argument
|
219
245
|
]
|
220
246
|
end
|
221
247
|
end
|
222
248
|
|
223
249
|
def build_directive(directive_definition, type_resolver)
|
224
|
-
GraphQL::Directive.define(
|
250
|
+
directive = GraphQL::Directive.define(
|
225
251
|
name: directive_definition.name,
|
226
252
|
description: directive_definition.description,
|
227
253
|
arguments: Hash[build_directive_arguments(directive_definition, type_resolver)],
|
228
254
|
locations: directive_definition.locations.map(&:to_sym),
|
229
255
|
)
|
256
|
+
|
257
|
+
directive.ast_node = directive_definition
|
258
|
+
|
259
|
+
directive
|
230
260
|
end
|
231
261
|
|
232
262
|
def build_directive_arguments(directive_definition, type_resolver)
|
@@ -237,24 +267,32 @@ module GraphQL
|
|
237
267
|
kwargs[:default_value] = build_default_value(directive_argument.default_value)
|
238
268
|
end
|
239
269
|
|
270
|
+
argument = GraphQL::Argument.define(
|
271
|
+
name: directive_argument.name,
|
272
|
+
type: type_resolver.call(directive_argument.type),
|
273
|
+
description: directive_argument.description,
|
274
|
+
**kwargs,
|
275
|
+
)
|
276
|
+
|
277
|
+
argument.ast_node = directive_argument
|
278
|
+
|
240
279
|
[
|
241
280
|
directive_argument.name,
|
242
|
-
|
243
|
-
name: directive_argument.name,
|
244
|
-
type: type_resolver.call(directive_argument.type),
|
245
|
-
description: directive_argument.description,
|
246
|
-
**kwargs,
|
247
|
-
)
|
281
|
+
argument
|
248
282
|
]
|
249
283
|
end
|
250
284
|
end
|
251
285
|
|
252
286
|
def build_interface_type(interface_type_definition, type_resolver)
|
253
|
-
GraphQL::InterfaceType.define(
|
287
|
+
interface = GraphQL::InterfaceType.define(
|
254
288
|
name: interface_type_definition.name,
|
255
289
|
description: interface_type_definition.description,
|
256
290
|
fields: Hash[build_fields(interface_type_definition.fields, type_resolver, default_resolve: nil)],
|
257
291
|
)
|
292
|
+
|
293
|
+
interface.ast_node = interface_type_definition
|
294
|
+
|
295
|
+
interface
|
258
296
|
end
|
259
297
|
|
260
298
|
def build_fields(field_definitions, type_resolver, default_resolve:)
|
@@ -273,6 +311,8 @@ module GraphQL
|
|
273
311
|
**kwargs,
|
274
312
|
)
|
275
313
|
|
314
|
+
arg.ast_node = argument
|
315
|
+
|
276
316
|
[argument.name, arg]
|
277
317
|
end]
|
278
318
|
|
@@ -285,6 +325,8 @@ module GraphQL
|
|
285
325
|
deprecation_reason: build_deprecation_reason(field_definition.directives),
|
286
326
|
)
|
287
327
|
|
328
|
+
field.ast_node = field_definition
|
329
|
+
|
288
330
|
type_name = resolve_type_name(field_definition.type)
|
289
331
|
field.connection = type_name.end_with?("Connection")
|
290
332
|
[field_definition.name, field]
|
data/lib/graphql/schema/enum.rb
CHANGED
data/lib/graphql/schema/field.rb
CHANGED
@@ -7,6 +7,7 @@ module GraphQL
|
|
7
7
|
class Field
|
8
8
|
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
9
9
|
include GraphQL::Schema::Member::AcceptsDefinition
|
10
|
+
include GraphQL::Schema::Member::HasArguments
|
10
11
|
|
11
12
|
# @return [String]
|
12
13
|
attr_reader :name
|
@@ -14,15 +15,17 @@ module GraphQL
|
|
14
15
|
# @return [String]
|
15
16
|
attr_accessor :description
|
16
17
|
|
17
|
-
# @return [Hash{String => GraphQL::Schema::Argument}]
|
18
|
-
attr_reader :arguments
|
19
|
-
|
20
18
|
# @return [Symbol]
|
21
19
|
attr_reader :method
|
22
20
|
|
23
21
|
# @return [Class] The type that this field belongs to
|
24
22
|
attr_reader :owner
|
25
23
|
|
24
|
+
# @return [Class, nil] The mutation this field was derived from, if there is one
|
25
|
+
def mutation
|
26
|
+
@mutation || @mutation_class
|
27
|
+
end
|
28
|
+
|
26
29
|
# @param name [Symbol] The underscore-cased version of this field name (will be camelized for the GraphQL API)
|
27
30
|
# @param return_type_expr [Class, GraphQL::BaseType, Array] The return type of this field
|
28
31
|
# @param desc [String] Field description
|
@@ -36,17 +39,23 @@ module GraphQL
|
|
36
39
|
# @param max_page_size [Integer] For connections, the maximum number of items to return from this field
|
37
40
|
# @param introspection [Boolean] If true, this field will be marked as `#introspection?` and the name may begin with `__`
|
38
41
|
# @param resolve [<#call(obj, args, ctx)>] **deprecated** for compatibility with <1.8.0
|
39
|
-
# @param field [GraphQL::Field] **deprecated** for compatibility with <1.8.0
|
42
|
+
# @param field [GraphQL::Field, GraphQL::Schema::Field] **deprecated** for compatibility with <1.8.0
|
40
43
|
# @param function [GraphQL::Function] **deprecated** for compatibility with <1.8.0
|
44
|
+
# @param mutation [Class] A {Schema::Mutation} class for serving this field
|
45
|
+
# @param mutation_class [Class] (Private) A {Schema::Mutation} which this field was derived from.
|
46
|
+
# @param arguments [{String=>GraphQL::Schema::Arguments}] Arguments for this field (may be added in the block, also)
|
41
47
|
# @param camelize [Boolean] If true, the field name will be camelized when building the schema
|
42
48
|
# @param complexity [Numeric] When provided, set the complexity for this field
|
43
|
-
def initialize(name, return_type_expr = nil, desc = nil, owner
|
49
|
+
def initialize(name, return_type_expr = nil, desc = nil, owner: nil, null: nil, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, connection: nil, max_page_size: nil, resolve: nil, introspection: false, hash_key: nil, camelize: true, complexity: 1, extras: [], mutation: nil, mutation_class: nil, arguments: {}, &definition_block)
|
44
50
|
if (field || function) && desc.nil? && return_type_expr.is_a?(String)
|
45
51
|
# The return type should be copied from `field` or `function`, and the second positional argument is the description
|
46
52
|
desc = return_type_expr
|
47
53
|
return_type_expr = nil
|
48
54
|
end
|
49
|
-
if
|
55
|
+
if mutation && (return_type_expr || desc || description || function || field || null || deprecation_reason || method || resolve || introspection || hash_key)
|
56
|
+
raise ArgumentError, "when keyword `mutation:` is present, all arguments are ignored, please remove them"
|
57
|
+
end
|
58
|
+
if !(field || function || mutation)
|
50
59
|
if return_type_expr.nil?
|
51
60
|
raise ArgumentError, "missing positional argument `type`"
|
52
61
|
end
|
@@ -54,15 +63,19 @@ module GraphQL
|
|
54
63
|
raise ArgumentError, "missing keyword argument null:"
|
55
64
|
end
|
56
65
|
end
|
57
|
-
if (field || function || resolve) && extras.any?
|
58
|
-
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve, please remove `field:`, `function:`, or `
|
66
|
+
if (field || function || resolve || resolve) && extras.any?
|
67
|
+
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve, please remove `field:`, `function:`, `resolve:`, or `mutation:`"
|
59
68
|
end
|
60
69
|
@name = name.to_s
|
61
70
|
if description && desc
|
62
71
|
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{description.inspect})"
|
63
72
|
end
|
64
73
|
@description = description || desc
|
65
|
-
|
74
|
+
if field.is_a?(GraphQL::Schema::Field)
|
75
|
+
@field_instance = field
|
76
|
+
else
|
77
|
+
@field = field
|
78
|
+
end
|
66
79
|
@function = function
|
67
80
|
@resolve = resolve
|
68
81
|
@deprecation_reason = deprecation_reason
|
@@ -78,8 +91,11 @@ module GraphQL
|
|
78
91
|
@max_page_size = max_page_size
|
79
92
|
@introspection = introspection
|
80
93
|
@extras = extras
|
81
|
-
@arguments = {}
|
82
94
|
@camelize = camelize
|
95
|
+
@mutation = mutation
|
96
|
+
@mutation_class = mutation_class
|
97
|
+
# Override the default from HasArguments
|
98
|
+
@own_arguments = arguments
|
83
99
|
@owner = owner
|
84
100
|
|
85
101
|
if definition_block
|
@@ -87,13 +103,6 @@ module GraphQL
|
|
87
103
|
end
|
88
104
|
end
|
89
105
|
|
90
|
-
# This is the `argument(...)` DSL for class-based field definitons
|
91
|
-
def argument(*args, **kwargs, &block)
|
92
|
-
kwargs[:owner] = self
|
93
|
-
arg_defn = self.class.argument_class.new(*args, **kwargs, &block)
|
94
|
-
arguments[arg_defn.name] = arg_defn
|
95
|
-
end
|
96
|
-
|
97
106
|
def description(text = nil)
|
98
107
|
if text
|
99
108
|
@description = text
|
@@ -123,6 +132,14 @@ module GraphQL
|
|
123
132
|
|
124
133
|
# @return [GraphQL::Field]
|
125
134
|
def to_graphql
|
135
|
+
# this field was previously defined and passed here, so delegate to it
|
136
|
+
if @field_instance
|
137
|
+
return @field_instance.to_graphql
|
138
|
+
elsif @mutation
|
139
|
+
field_inst = @mutation.graphql_field
|
140
|
+
return field_inst.to_graphql
|
141
|
+
end
|
142
|
+
|
126
143
|
method_name = @method || @hash_key || Member::BuildType.underscore(@name)
|
127
144
|
|
128
145
|
field_defn = if @field
|
@@ -138,7 +155,11 @@ module GraphQL
|
|
138
155
|
return_type_name = Member::BuildType.to_type_name(@return_type_expr)
|
139
156
|
connection = @connection.nil? ? return_type_name.end_with?("Connection") : @connection
|
140
157
|
field_defn.type = -> {
|
141
|
-
|
158
|
+
begin
|
159
|
+
Member::BuildType.parse_type(@return_type_expr, null: @return_type_null)
|
160
|
+
rescue
|
161
|
+
raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: #{$!.message}", $!.backtrace
|
162
|
+
end
|
142
163
|
}
|
143
164
|
elsif @connection.nil? && (@field || @function)
|
144
165
|
return_type_name = Member::BuildType.to_type_name(field_defn.type)
|
@@ -155,6 +176,10 @@ module GraphQL
|
|
155
176
|
field_defn.deprecation_reason = @deprecation_reason
|
156
177
|
end
|
157
178
|
|
179
|
+
if @mutation_class
|
180
|
+
field_defn.mutation = @mutation_class
|
181
|
+
end
|
182
|
+
|
158
183
|
field_defn.resolve = if @resolve || @function || @field
|
159
184
|
prev_resolve = @resolve || field_defn.resolve_proc
|
160
185
|
UnwrappedResolve.new(inner_resolve: prev_resolve)
|
@@ -182,25 +207,13 @@ module GraphQL
|
|
182
207
|
argument :last, "Int", "Returns the last _n_ elements from the list.", required: false
|
183
208
|
end
|
184
209
|
|
185
|
-
|
210
|
+
arguments.each do |name, defn|
|
186
211
|
arg_graphql = defn.to_graphql
|
187
212
|
field_defn.arguments[arg_graphql.name] = arg_graphql
|
188
213
|
end
|
189
214
|
|
190
215
|
field_defn
|
191
216
|
end
|
192
|
-
|
193
|
-
private
|
194
|
-
|
195
|
-
class << self
|
196
|
-
def argument_class(new_arg_class = nil)
|
197
|
-
if new_arg_class
|
198
|
-
@argument_class = new_arg_class
|
199
|
-
else
|
200
|
-
@argument_class || GraphQL::Schema::Argument
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
217
|
end
|
205
218
|
end
|
206
219
|
end
|
@@ -14,18 +14,18 @@ module GraphQL
|
|
14
14
|
def call(obj, args, ctx)
|
15
15
|
if obj.respond_to?(@method_name)
|
16
16
|
public_send_field(obj, @method_name, args, ctx)
|
17
|
-
elsif obj.object.respond_to?(@method_name)
|
18
|
-
public_send_field(obj.object, @method_name, args, ctx)
|
19
17
|
elsif obj.object.is_a?(Hash)
|
20
18
|
inner_object = obj.object
|
21
19
|
inner_object[@method_name] || inner_object[@method_sym]
|
20
|
+
elsif obj.object.respond_to?(@method_name)
|
21
|
+
public_send_field(obj.object, @method_name, args, ctx)
|
22
22
|
else
|
23
23
|
raise <<-ERR
|
24
24
|
Failed to implement #{ctx.irep_node.owner_type.name}.#{ctx.field.name}, tried:
|
25
25
|
|
26
26
|
- `#{obj.class}##{@method_name}`, which did not exist
|
27
27
|
- `#{obj.object.class}##{@method_name}`, which did not exist
|
28
|
-
- Looking up hash key `#{@method_name.inspect}` on `#{obj}`, but it wasn't a Hash
|
28
|
+
- Looking up hash key `#{@method_name.inspect}` on `#{obj.object}`, but it wasn't a Hash
|
29
29
|
|
30
30
|
To implement this field, define one of the methods above (and check for typos)
|
31
31
|
ERR
|
@@ -39,11 +39,7 @@ ERR
|
|
39
39
|
def public_send_field(obj, method_name, graphql_args, field_ctx)
|
40
40
|
if graphql_args.any? || @extras.any?
|
41
41
|
# Splat the GraphQL::Arguments to Ruby keyword arguments
|
42
|
-
ruby_kwargs =
|
43
|
-
|
44
|
-
graphql_args.keys.each do |key|
|
45
|
-
ruby_kwargs[Schema::Member::BuildType.underscore(key).to_sym] = graphql_args[key]
|
46
|
-
end
|
42
|
+
ruby_kwargs = graphql_args.to_kwargs
|
47
43
|
|
48
44
|
if @connection
|
49
45
|
# Remove pagination args before passing it to a user method
|