graphql 1.8.0.pre11 → 1.8.0
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/generators/graphql/templates/schema.erb +1 -1
- data/lib/graphql/function.rb +2 -0
- data/lib/graphql/railtie.rb +1 -1
- data/lib/graphql/schema.rb +1 -0
- data/lib/graphql/schema/argument.rb +3 -2
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/field.rb +96 -49
- data/lib/graphql/schema/interface.rb +21 -3
- data/lib/graphql/schema/list.rb +4 -0
- data/lib/graphql/schema/member/accepts_definition.rb +2 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +4 -0
- data/lib/graphql/schema/member/build_type.rb +4 -2
- data/lib/graphql/schema/member/has_fields.rb +1 -8
- data/lib/graphql/schema/mutation.rb +19 -88
- data/lib/graphql/schema/non_null.rb +4 -0
- data/lib/graphql/schema/object.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +14 -15
- data/lib/graphql/schema/resolver.rb +122 -0
- data/lib/graphql/subscriptions/instrumentation.rb +5 -1
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/generators/graphql/install_generator_spec.rb +1 -1
- data/spec/graphql/relay/mutation_spec.rb +5 -3
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/field_spec.rb +7 -24
- data/spec/graphql/schema/interface_spec.rb +25 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +22 -0
- data/spec/graphql/schema/member/build_type_spec.rb +17 -0
- data/spec/graphql/schema/mutation_spec.rb +15 -14
- data/spec/graphql/schema/resolver_spec.rb +131 -0
- data/spec/graphql/subscriptions_spec.rb +267 -205
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
- data/spec/support/jazz.rb +6 -1
- data/spec/support/new_relic.rb +24 -0
- data/spec/support/star_trek/schema.rb +2 -2
- data/spec/support/star_wars/schema.rb +1 -2
- metadata +13 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5283bf51e22ac60f8d9368d9cc19b8c6d038d8b
|
4
|
+
data.tar.gz: 147ec429661a6fbc1aaef685ba94c8a81d87910e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06a2a8730fc1c13dc0a0d76a35b19e89dd40ad842e41618abb1b05a7f75b667eede56c106728e3e68bd531e36e29b28050b991319599b7952ac3285fb3f9be3c
|
7
|
+
data.tar.gz: 8231c7696681477decf92b0665f3e4249b308153338c8d7cf5102b7e95133b9ac7aa6156f3dddc026c4178ea9fcb25d7f181f752298d5cf38185141af653a471
|
data/lib/graphql/function.rb
CHANGED
@@ -28,6 +28,8 @@ module GraphQL
|
|
28
28
|
# field :post, function: FindRecord.new(model: Post, type: PostType)
|
29
29
|
# field :comment, function: FindRecord.new(model: Comment, type: CommentType)
|
30
30
|
# end
|
31
|
+
#
|
32
|
+
# @see {GraphQL::Schema::Resolver} for a replacement for `GraphQL::Function`
|
31
33
|
class Function
|
32
34
|
# @return [Hash<String => GraphQL::Argument>] Arguments, keyed by name
|
33
35
|
def arguments
|
data/lib/graphql/railtie.rb
CHANGED
@@ -72,7 +72,7 @@ module GraphQL
|
|
72
72
|
unless File.exists?(destination_file)
|
73
73
|
FileUtils.mkdir_p(File.dirname(destination_file))
|
74
74
|
File.open(destination_file, 'w') do |f|
|
75
|
-
f.write "
|
75
|
+
f.write "module Types::BaseInterface\n include GraphQL::Schema::Interface\nend"
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
data/lib/graphql/schema.rb
CHANGED
@@ -29,6 +29,7 @@ require "graphql/schema/enum"
|
|
29
29
|
require "graphql/schema/field"
|
30
30
|
require "graphql/schema/input_object"
|
31
31
|
require "graphql/schema/interface"
|
32
|
+
require "graphql/schema/resolver"
|
32
33
|
require "graphql/schema/mutation"
|
33
34
|
require "graphql/schema/relay_classic_mutation"
|
34
35
|
require "graphql/schema/object"
|
@@ -28,9 +28,10 @@ module GraphQL
|
|
28
28
|
# @param as [Symbol] Override the keyword name when passed to a method
|
29
29
|
# @param prepare [Symbol] A method to call to tranform this argument's valuebefore sending it to field resolution
|
30
30
|
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
31
|
-
def initialize(arg_name, type_expr, desc = nil, required:, description: nil, default_value: NO_DEFAULT, as: nil, camelize: true, prepare: nil, owner:, &definition_block)
|
31
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required:, type: nil, name: nil, description: nil, default_value: NO_DEFAULT, as: nil, camelize: true, prepare: nil, owner:, &definition_block)
|
32
|
+
arg_name ||= name
|
32
33
|
@name = camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s
|
33
|
-
@type_expr = type_expr
|
34
|
+
@type_expr = type_expr || type
|
34
35
|
@description = desc || description
|
35
36
|
@null = !required
|
36
37
|
@default_value = default_value
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -8,7 +8,7 @@ module GraphQL
|
|
8
8
|
include GraphQL::Schema::Member::HasArguments
|
9
9
|
|
10
10
|
# @return [String] the GraphQL name for this field, camelized unless `camelize: false` is provided
|
11
|
-
|
11
|
+
attr_accessor :name
|
12
12
|
|
13
13
|
# @return [String]
|
14
14
|
attr_accessor :description
|
@@ -22,9 +22,55 @@ module GraphQL
|
|
22
22
|
# @return [Class] The type that this field belongs to
|
23
23
|
attr_reader :owner
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
|
26
|
+
# @return [Class, nil] The {Schema::Resolver} this field was derived from, if there is one
|
27
|
+
def resolver
|
28
|
+
@resolver_class
|
29
|
+
end
|
30
|
+
|
31
|
+
alias :mutation :resolver
|
32
|
+
|
33
|
+
# Create a field instance from a list of arguments, keyword arguments, and a block.
|
34
|
+
#
|
35
|
+
# This method implements prioritization between the `resolver` or `mutation` defaults
|
36
|
+
# and the local overrides via other keywords.
|
37
|
+
#
|
38
|
+
# It also normalizes positional arguments into keywords for {Schema::Field#initialize}.
|
39
|
+
# @param resolver [Class] A {GraphQL::Schema::Resolver} class to use for field configuration
|
40
|
+
# @param mutation [Class] A {GraphQL::Schema::Mutation} class to use for field configuration
|
41
|
+
# @return [GraphQL::Schema:Field] an instance of `self
|
42
|
+
# @see {.initialize} for other options
|
43
|
+
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, **kwargs, &block)
|
44
|
+
if (parent_config = resolver || mutation)
|
45
|
+
# Get the parent config, merge in local overrides
|
46
|
+
kwargs = parent_config.field_options.merge(kwargs)
|
47
|
+
# Add a reference to that parent class
|
48
|
+
kwargs[:resolver_class] = parent_config
|
49
|
+
end
|
50
|
+
|
51
|
+
if name
|
52
|
+
kwargs[:name] = name
|
53
|
+
end
|
54
|
+
|
55
|
+
if !type.nil?
|
56
|
+
if type.is_a?(GraphQL::Field)
|
57
|
+
raise ArgumentError, "A GraphQL::Field was passed as the second argument, use the `field:` keyword for this instead."
|
58
|
+
end
|
59
|
+
if desc
|
60
|
+
if kwargs[:description]
|
61
|
+
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{kwargs[:description].inspect})"
|
62
|
+
end
|
63
|
+
|
64
|
+
kwargs[:description] = desc
|
65
|
+
kwargs[:type] = type
|
66
|
+
elsif (kwargs[:field] || kwargs[:function] || resolver || mutation) && type.is_a?(String)
|
67
|
+
# The return type should be copied from `field` or `function`, and the second positional argument is the description
|
68
|
+
kwargs[:description] = type
|
69
|
+
else
|
70
|
+
kwargs[:type] = type
|
71
|
+
end
|
72
|
+
end
|
73
|
+
new(**kwargs, &block)
|
28
74
|
end
|
29
75
|
|
30
76
|
# @param name [Symbol] The underscore-cased version of this field name (will be camelized for the GraphQL API)
|
@@ -42,39 +88,29 @@ module GraphQL
|
|
42
88
|
# @param resolve [<#call(obj, args, ctx)>] **deprecated** for compatibility with <1.8.0
|
43
89
|
# @param field [GraphQL::Field, GraphQL::Schema::Field] **deprecated** for compatibility with <1.8.0
|
44
90
|
# @param function [GraphQL::Function] **deprecated** for compatibility with <1.8.0
|
45
|
-
# @param
|
46
|
-
# @param
|
47
|
-
# @param arguments [{String=>GraphQL::Schema::Arguments}] Arguments for this field (may be added in the block, also)
|
91
|
+
# @param resolver_class [Class] (Private) A {Schema::Resolver} which this field was derived from. Use `resolver:` to create a field with a resolver.
|
92
|
+
# @param arguments [{String=>GraphQL::Schema::Argument, Hash}] Arguments for this field (may be added in the block, also)
|
48
93
|
# @param camelize [Boolean] If true, the field name will be camelized when building the schema
|
49
94
|
# @param complexity [Numeric] When provided, set the complexity for this field
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
if mutation && (return_type_expr || desc || description || function || field || !null.nil? || deprecation_reason || method || resolve || introspection || hash_key)
|
57
|
-
raise ArgumentError, "when keyword `mutation:` is present, all arguments are ignored, please remove them"
|
95
|
+
# @param subscription_scope [Symbol, String] A key in `context` which will be used to scope subscription payloads
|
96
|
+
def initialize(type: nil, name: 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: [], resolver_class: nil, subscription_scope: nil, arguments: {}, &definition_block)
|
97
|
+
|
98
|
+
if name.nil?
|
99
|
+
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
58
100
|
end
|
59
|
-
if !(field || function || mutation)
|
60
|
-
if
|
61
|
-
raise ArgumentError, "missing
|
101
|
+
if !(field || function || mutation || resolver)
|
102
|
+
if type.nil?
|
103
|
+
raise ArgumentError, "missing second `type` argument or keyword `type:`"
|
62
104
|
end
|
63
105
|
if null.nil?
|
64
106
|
raise ArgumentError, "missing keyword argument null:"
|
65
107
|
end
|
66
108
|
end
|
67
|
-
if (field || function || resolve ||
|
109
|
+
if (field || function || resolve || mutation) && extras.any?
|
68
110
|
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve, please remove `field:`, `function:`, `resolve:`, or `mutation:`"
|
69
111
|
end
|
70
|
-
if return_type_expr.is_a?(GraphQL::Field)
|
71
|
-
raise ArgumentError, "A GraphQL::Field was passed as the second argument, use the `field:` keyword for this instead."
|
72
|
-
end
|
73
112
|
@name = camelize ? Member::BuildType.camelize(name.to_s) : name.to_s
|
74
|
-
|
75
|
-
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{description.inspect})"
|
76
|
-
end
|
77
|
-
@description = description || desc
|
113
|
+
@description = description
|
78
114
|
if field.is_a?(GraphQL::Schema::Field)
|
79
115
|
@field_instance = field
|
80
116
|
else
|
@@ -93,17 +129,26 @@ module GraphQL
|
|
93
129
|
@method_str = method_name.to_s
|
94
130
|
@method_sym = method_name.to_sym
|
95
131
|
@complexity = complexity
|
96
|
-
@return_type_expr =
|
132
|
+
@return_type_expr = type
|
97
133
|
@return_type_null = null
|
98
134
|
@connection = connection
|
99
135
|
@max_page_size = max_page_size
|
100
136
|
@introspection = introspection
|
101
137
|
@extras = extras
|
102
|
-
@
|
103
|
-
|
138
|
+
@resolver_class = resolver_class
|
139
|
+
|
104
140
|
# Override the default from HasArguments
|
105
|
-
@own_arguments =
|
141
|
+
@own_arguments = {}
|
142
|
+
arguments.each do |name, arg|
|
143
|
+
if arg.is_a?(Hash)
|
144
|
+
argument(name: name, **arg)
|
145
|
+
else
|
146
|
+
@own_arguments[name] = arg
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
106
150
|
@owner = owner
|
151
|
+
@subscription_scope = subscription_scope
|
107
152
|
|
108
153
|
if definition_block
|
109
154
|
instance_eval(&definition_block)
|
@@ -142,9 +187,6 @@ module GraphQL
|
|
142
187
|
# this field was previously defined and passed here, so delegate to it
|
143
188
|
if @field_instance
|
144
189
|
return @field_instance.to_graphql
|
145
|
-
elsif @mutation
|
146
|
-
field_inst = @mutation.graphql_field
|
147
|
-
return field_inst.to_graphql
|
148
190
|
end
|
149
191
|
|
150
192
|
|
@@ -181,8 +223,11 @@ module GraphQL
|
|
181
223
|
field_defn.deprecation_reason = @deprecation_reason
|
182
224
|
end
|
183
225
|
|
184
|
-
if @
|
185
|
-
|
226
|
+
if @resolver_class
|
227
|
+
if @resolver_class < GraphQL::Schema::Mutation
|
228
|
+
field_defn.mutation = @resolver_class
|
229
|
+
end
|
230
|
+
field_defn.metadata[:resolver] = @resolver_class
|
186
231
|
end
|
187
232
|
|
188
233
|
field_defn.resolve = self.method(:resolve_field)
|
@@ -190,6 +235,7 @@ module GraphQL
|
|
190
235
|
field_defn.connection_max_page_size = @max_page_size
|
191
236
|
field_defn.introspection = @introspection
|
192
237
|
field_defn.complexity = @complexity
|
238
|
+
field_defn.subscription_scope = @subscription_scope
|
193
239
|
|
194
240
|
# apply this first, so it can be overriden below
|
195
241
|
if @connection
|
@@ -207,6 +253,15 @@ module GraphQL
|
|
207
253
|
field_defn.arguments[arg_graphql.name] = arg_graphql
|
208
254
|
end
|
209
255
|
|
256
|
+
# Support a passed-in proc, one way or another
|
257
|
+
@resolve_proc = if @resolve
|
258
|
+
@resolve
|
259
|
+
elsif @function
|
260
|
+
@function
|
261
|
+
elsif @field
|
262
|
+
@field.resolve_proc
|
263
|
+
end
|
264
|
+
|
210
265
|
# Ok, `self` isn't a class, but this is for consistency with the classes
|
211
266
|
field_defn.metadata[:type_class] = self
|
212
267
|
|
@@ -223,22 +278,14 @@ module GraphQL
|
|
223
278
|
#
|
224
279
|
# Eventually, we might hook up field instances to execution in another way. TBD.
|
225
280
|
def resolve_field(obj, args, ctx)
|
226
|
-
if @
|
227
|
-
# Support a passed-in proc, one way or another
|
228
|
-
prev_resolve = if @resolve
|
229
|
-
@resolve
|
230
|
-
elsif @function
|
231
|
-
@function
|
232
|
-
elsif @field
|
233
|
-
@field.resolve_proc
|
234
|
-
end
|
235
|
-
|
281
|
+
if @resolve_proc
|
236
282
|
# Might be nil, still want to call the func in that case
|
237
283
|
inner_obj = obj && obj.object
|
238
|
-
|
239
|
-
elsif @
|
240
|
-
|
241
|
-
|
284
|
+
@resolve_proc.call(inner_obj, args, ctx)
|
285
|
+
elsif @resolver_class
|
286
|
+
inner_obj = obj && obj.object
|
287
|
+
singleton_inst = @resolver_class.new(object: inner_obj, context: ctx.query.context)
|
288
|
+
public_send_field(singleton_inst, args, ctx)
|
242
289
|
else
|
243
290
|
public_send_field(obj, args, ctx)
|
244
291
|
end
|
@@ -22,12 +22,22 @@ module GraphQL
|
|
22
22
|
if !child_class.is_a?(Class)
|
23
23
|
# In this case, it's been included into another interface.
|
24
24
|
# This is how interface inheritance is implemented
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
# Use an instance variable to tell whether it's been included previously or not;
|
27
|
+
# You can't use constant detection because constants are brought into scope
|
28
|
+
# by `include`, which has already happened at this point.
|
29
|
+
if !child_class.instance_variable_defined?(:@_definition_methods)
|
30
|
+
defn_methods_module = Module.new
|
31
|
+
child_class.instance_variable_set(:@_definition_methods, defn_methods_module)
|
32
|
+
child_class.const_set(:DefinitionMethods, defn_methods_module)
|
33
|
+
child_class.extend(child_class::DefinitionMethods)
|
34
|
+
end
|
35
|
+
|
27
36
|
# We need this before we can call `own_interfaces`
|
28
37
|
child_class.extend(Schema::Interface::DefinitionMethods)
|
38
|
+
|
29
39
|
child_class.own_interfaces << self
|
30
|
-
child_class.
|
40
|
+
child_class.interfaces.each do |interface_defn|
|
31
41
|
child_class.extend(interface_defn::DefinitionMethods)
|
32
42
|
end
|
33
43
|
elsif child_class < GraphQL::Schema::Object
|
@@ -76,12 +86,20 @@ module GraphQL
|
|
76
86
|
def own_interfaces
|
77
87
|
@own_interfaces ||= []
|
78
88
|
end
|
89
|
+
|
90
|
+
def interfaces
|
91
|
+
own_interfaces + (own_interfaces.map { |i| i.own_interfaces }).flatten
|
92
|
+
end
|
79
93
|
end
|
80
94
|
|
81
95
|
# Extend this _after_ `DefinitionMethods` is defined, so it will be used
|
82
96
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
83
97
|
|
84
98
|
extend DefinitionMethods
|
99
|
+
|
100
|
+
def unwrap
|
101
|
+
self
|
102
|
+
end
|
85
103
|
end
|
86
104
|
end
|
87
105
|
end
|
data/lib/graphql/schema/list.rb
CHANGED
@@ -69,7 +69,7 @@ module GraphQL
|
|
69
69
|
if args.any?
|
70
70
|
instance_variable_set(ivar_name, args)
|
71
71
|
end
|
72
|
-
instance_variable_get(ivar_name)
|
72
|
+
instance_variable_get(ivar_name) || (superclass.respond_to?(name) ? superclass.public_send(name) : nil)
|
73
73
|
end
|
74
74
|
|
75
75
|
define_method(name) do |*args|
|
@@ -86,7 +86,7 @@ module GraphQL
|
|
86
86
|
if args.any?
|
87
87
|
instance_variable_set(ivar_name, args)
|
88
88
|
end
|
89
|
-
instance_variable_get(ivar_name)
|
89
|
+
instance_variable_get(ivar_name) || ((int = interfaces.first { |i| i.respond_to?()}) && int.public_send(name))
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
@@ -101,13 +101,15 @@ module GraphQL
|
|
101
101
|
when Array
|
102
102
|
to_type_name(something.first)
|
103
103
|
when Module
|
104
|
-
if something
|
104
|
+
if something.respond_to?(:graphql_name)
|
105
105
|
something.graphql_name
|
106
106
|
else
|
107
|
-
something.name
|
107
|
+
to_type_name(something.name)
|
108
108
|
end
|
109
109
|
when String
|
110
110
|
something.gsub(/\]\[\!/, "").split("::").last
|
111
|
+
when GraphQL::Schema::NonNull, GraphQL::Schema::List
|
112
|
+
to_type_name(something.unwrap)
|
111
113
|
else
|
112
114
|
raise "Unhandled to_type_name input: #{something} (#{something.class})"
|
113
115
|
end
|
@@ -49,7 +49,7 @@ module GraphQL
|
|
49
49
|
# @see {GraphQL::Schema::Field#initialize} for method signature
|
50
50
|
# @return [void]
|
51
51
|
def field(*args, **kwargs, &block)
|
52
|
-
field_defn =
|
52
|
+
field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
|
53
53
|
add_field(field_defn)
|
54
54
|
nil
|
55
55
|
end
|
@@ -103,13 +103,6 @@ module GraphQL
|
|
103
103
|
end
|
104
104
|
|
105
105
|
private
|
106
|
-
|
107
|
-
# Initialize a field with this class's field class, but don't attach it.
|
108
|
-
def build_field(*args, **kwargs, &block)
|
109
|
-
kwargs[:owner] = self
|
110
|
-
field_class.new(*args, **kwargs, &block)
|
111
|
-
end
|
112
|
-
|
113
106
|
# Find the magic module for holding super methods,
|
114
107
|
# and add a field named `method_name` for implementing the field
|
115
108
|
# called `field_name`.
|
@@ -58,51 +58,16 @@ module GraphQL
|
|
58
58
|
# }
|
59
59
|
# GRAPHQL
|
60
60
|
#
|
61
|
-
class Mutation < GraphQL::Schema::
|
61
|
+
class Mutation < GraphQL::Schema::Resolver
|
62
62
|
extend GraphQL::Schema::Member::HasFields
|
63
|
-
extend GraphQL::Schema::Member::HasArguments
|
64
|
-
|
65
|
-
# @param object [Object] the initialize object, pass to {Query.initialize} as `root_value`
|
66
|
-
# @param context [GraphQL::Query::Context]
|
67
|
-
def initialize(object:, context:, arguments:)
|
68
|
-
@object = object
|
69
|
-
@context = context
|
70
|
-
end
|
71
|
-
|
72
|
-
# @return [Object] the root value of the operation
|
73
|
-
attr_reader :object
|
74
|
-
|
75
|
-
# @return [GraphQL::Query::Context]
|
76
|
-
attr_reader :context
|
77
|
-
|
78
|
-
# Do the work. Everything happens here.
|
79
|
-
# @return [Hash] A key for each field in the return type
|
80
|
-
# @return [Object] An object corresponding to the return type
|
81
|
-
def resolve(**args)
|
82
|
-
raise NotImplementedError, "#{self.class.name}#resolve should execute side effects and return a Symbol-keyed hash"
|
83
|
-
end
|
84
|
-
|
85
|
-
# This is a hook for classes to intercept resolution.
|
86
|
-
# @see RelayClassicMutation for usage
|
87
|
-
def resolve_mutation(args)
|
88
|
-
resolve(args)
|
89
|
-
end
|
90
63
|
|
91
64
|
class << self
|
92
|
-
|
93
|
-
base.null(null)
|
94
|
-
super
|
95
|
-
end
|
96
|
-
|
97
|
-
# Override the method from HasFields to support `field: Mutation.field`, for backwards compat.
|
98
|
-
#
|
99
|
-
# If called without any arguments, returns a `GraphQL::Field`.
|
100
|
-
# @see {GraphQL::Schema::Member::HasFields.field} for default behavior
|
65
|
+
# Override this method to handle legacy-style usages of `MyMutation.field`
|
101
66
|
def field(*args, &block)
|
102
|
-
if args.none?
|
103
|
-
|
67
|
+
if args.none?
|
68
|
+
raise ArgumentError, "#{name}.field is used for adding fields to this mutation. Use `mutation: #{name}` to attach this mutation instead."
|
104
69
|
else
|
105
|
-
super
|
70
|
+
super
|
106
71
|
end
|
107
72
|
end
|
108
73
|
|
@@ -118,20 +83,8 @@ module GraphQL
|
|
118
83
|
@payload_type ||= generate_payload_type
|
119
84
|
end
|
120
85
|
|
121
|
-
|
122
|
-
|
123
|
-
def graphql_field
|
124
|
-
@graphql_field ||= generate_field
|
125
|
-
end
|
126
|
-
|
127
|
-
# @param new_name [String, nil] if present, override the class name to set this value
|
128
|
-
# @return [String] The name of this mutation in the GraphQL schema (used for naming derived types and fields)
|
129
|
-
def graphql_name(new_name = nil)
|
130
|
-
if new_name
|
131
|
-
@graphql_name = new_name
|
132
|
-
end
|
133
|
-
@graphql_name ||= self.name.split("::").last
|
134
|
-
end
|
86
|
+
alias :type :payload_type
|
87
|
+
alias :type_expr :payload_type
|
135
88
|
|
136
89
|
# An object class to use for deriving payload types
|
137
90
|
# @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
|
@@ -143,23 +96,22 @@ module GraphQL
|
|
143
96
|
@object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
|
144
97
|
end
|
145
98
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
@
|
99
|
+
def field_class(new_class = nil)
|
100
|
+
if new_class
|
101
|
+
@field_class = new_class
|
102
|
+
else
|
103
|
+
@field_class || find_inherited_method(:field_class, GraphQL::Schema::Field)
|
151
104
|
end
|
152
|
-
@extras || []
|
153
105
|
end
|
154
106
|
|
155
|
-
#
|
156
|
-
# @param
|
157
|
-
|
158
|
-
|
159
|
-
|
107
|
+
# An object class to use for deriving return types
|
108
|
+
# @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
|
109
|
+
# @return [Class]
|
110
|
+
def object_class(new_class = nil)
|
111
|
+
if new_class
|
112
|
+
@object_class = new_class
|
160
113
|
end
|
161
|
-
|
162
|
-
@null.nil? ? true : @null
|
114
|
+
@object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
|
163
115
|
end
|
164
116
|
|
165
117
|
private
|
@@ -180,27 +132,6 @@ module GraphQL
|
|
180
132
|
end
|
181
133
|
end
|
182
134
|
end
|
183
|
-
|
184
|
-
# This name will be used for the {.graphql_field}.
|
185
|
-
def field_name
|
186
|
-
graphql_name.sub(/^[A-Z]/, &:downcase)
|
187
|
-
end
|
188
|
-
|
189
|
-
# Build an instance of {.field_class} which will be used to execute this mutation.
|
190
|
-
# To customize field generation, override this method.
|
191
|
-
def generate_field
|
192
|
-
# TODO support deprecation_reason
|
193
|
-
self.field_class.new(
|
194
|
-
field_name,
|
195
|
-
payload_type,
|
196
|
-
description,
|
197
|
-
extras: extras,
|
198
|
-
method: :resolve_mutation,
|
199
|
-
mutation_class: self,
|
200
|
-
arguments: arguments,
|
201
|
-
null: null,
|
202
|
-
)
|
203
|
-
end
|
204
135
|
end
|
205
136
|
end
|
206
137
|
end
|