graphql 1.8.0.pre11 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/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
|