graphql 1.8.0.pre9 → 1.8.0.pre10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/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
|