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
@@ -4,9 +4,12 @@ module GraphQL
|
|
4
4
|
class InputObject < GraphQL::Schema::Member
|
5
5
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
6
|
extend GraphQL::Delegate
|
7
|
+
extend GraphQL::Schema::Member::HasArguments
|
7
8
|
|
8
9
|
def initialize(values, context:, defaults_used:)
|
9
10
|
@arguments = self.class.arguments_class.new(values, context: context, defaults_used: defaults_used)
|
11
|
+
# Symbolized, underscored hash:
|
12
|
+
@ruby_style_hash = @arguments.to_kwargs
|
10
13
|
@context = context
|
11
14
|
end
|
12
15
|
|
@@ -16,40 +19,48 @@ module GraphQL
|
|
16
19
|
# @return [GraphQL::Query::Arguments] The underlying arguments instance
|
17
20
|
attr_reader :arguments
|
18
21
|
|
19
|
-
#
|
20
|
-
def_delegators :@
|
21
|
-
|
22
|
+
# Ruby-like hash behaviors, read-only
|
23
|
+
def_delegators :@ruby_style_hash, :to_h, :keys, :values, :each, :any?
|
24
|
+
|
25
|
+
# Lookup a key on this object, it accepts new-style underscored symbols
|
26
|
+
# Or old-style camelized identifiers.
|
27
|
+
# @param key [Symbol, String]
|
28
|
+
def [](key)
|
29
|
+
if @ruby_style_hash.key?(key)
|
30
|
+
@ruby_style_hash[key]
|
31
|
+
else
|
32
|
+
@arguments[key]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def key?(key)
|
37
|
+
@ruby_style_hash.key?(key) || @arguments.key?(key)
|
38
|
+
end
|
39
|
+
|
40
|
+
# A copy of the Ruby-style hash
|
41
|
+
def to_kwargs
|
42
|
+
@ruby_style_hash.dup
|
43
|
+
end
|
22
44
|
|
23
45
|
class << self
|
24
46
|
# @return [Class<GraphQL::Arguments>]
|
25
47
|
attr_accessor :arguments_class
|
26
48
|
|
27
|
-
def argument(*args
|
28
|
-
|
29
|
-
argument = GraphQL::Schema::Argument.new(*args, **kwargs)
|
30
|
-
arg_name = argument.graphql_definition.name
|
31
|
-
own_arguments[arg_name] = argument
|
49
|
+
def argument(*args)
|
50
|
+
argument_defn = super
|
32
51
|
# Add a method access
|
52
|
+
arg_name = argument_defn.graphql_definition.name
|
33
53
|
define_method(Member::BuildType.underscore(arg_name)) do
|
34
54
|
@arguments.public_send(arg_name)
|
35
55
|
end
|
36
56
|
end
|
37
57
|
|
38
|
-
# @return [Hash<String => GraphQL::Schema::Argument] Input fields on this input object, keyed by name.
|
39
|
-
def arguments
|
40
|
-
inherited_arguments = (superclass <= GraphQL::Schema::InputObject ? superclass.arguments : {})
|
41
|
-
# Local definitions override inherited ones
|
42
|
-
inherited_arguments.merge(own_arguments)
|
43
|
-
end
|
44
|
-
|
45
|
-
def own_arguments
|
46
|
-
@own_arguments ||= {}
|
47
|
-
end
|
48
|
-
|
49
58
|
def to_graphql
|
50
59
|
type_defn = GraphQL::InputObjectType.new
|
51
60
|
type_defn.name = graphql_name
|
52
61
|
type_defn.description = description
|
62
|
+
type_defn.metadata[:type_class] = self
|
63
|
+
type_defn.mutation = mutation
|
53
64
|
arguments.each do |name, arg|
|
54
65
|
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
|
55
66
|
end
|
@@ -4,16 +4,22 @@ module GraphQL
|
|
4
4
|
class Interface < GraphQL::Schema::Member
|
5
5
|
extend GraphQL::Schema::Member::HasFields
|
6
6
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
7
|
-
field_class GraphQL::Schema::Field
|
8
7
|
|
9
8
|
class << self
|
9
|
+
# Always set up a `self::Implementation` module,
|
10
|
+
# which may or may not be added to.
|
11
|
+
def inherited(child_cls)
|
12
|
+
# This module will be mixed in to each object class,
|
13
|
+
# so it can contain methods to implement fields.
|
14
|
+
# It's always added to interfaces, but sometimes it's left empty.
|
15
|
+
child_cls.const_set(:Implementation, Module.new)
|
16
|
+
end
|
17
|
+
|
10
18
|
# When this interface is added to a `GraphQL::Schema::Object`,
|
11
19
|
# it calls this method. We add methods to the object by convention,
|
12
20
|
# a nested module named `Implementation`
|
13
|
-
def
|
14
|
-
|
15
|
-
object_class.include(self::Implementation)
|
16
|
-
end
|
21
|
+
def implemented(object_class)
|
22
|
+
object_class.include(self::Implementation)
|
17
23
|
end
|
18
24
|
|
19
25
|
def orphan_types(*types)
|
@@ -35,6 +41,7 @@ module GraphQL
|
|
35
41
|
field_defn = field_inst.graphql_definition
|
36
42
|
type_defn.fields[field_defn.name] = field_defn
|
37
43
|
end
|
44
|
+
type_defn.metadata[:type_class] = self
|
38
45
|
if respond_to?(:resolve_type)
|
39
46
|
type_defn.resolve_type = method(:resolve_type)
|
40
47
|
end
|
@@ -87,6 +87,15 @@ module GraphQL
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
# The mutation this type was derived from, if it was derived from a mutation
|
91
|
+
# @return [Class]
|
92
|
+
def mutation(mutation_class = nil)
|
93
|
+
if mutation_class
|
94
|
+
@mutation = mutation_class
|
95
|
+
end
|
96
|
+
@mutation
|
97
|
+
end
|
98
|
+
|
90
99
|
def to_graphql
|
91
100
|
raise NotImplementedError
|
92
101
|
end
|
@@ -111,6 +120,7 @@ end
|
|
111
120
|
|
112
121
|
require 'graphql/schema/member/list_type_proxy'
|
113
122
|
require 'graphql/schema/member/non_null_type_proxy'
|
123
|
+
require 'graphql/schema/member/has_arguments'
|
114
124
|
require 'graphql/schema/member/has_fields'
|
115
125
|
require 'graphql/schema/member/instrumentation'
|
116
126
|
require 'graphql/schema/member/build_type'
|
@@ -64,12 +64,14 @@ module GraphQL
|
|
64
64
|
raise ArgumentError, LIST_TYPE_ERROR
|
65
65
|
end
|
66
66
|
when Class
|
67
|
-
if
|
67
|
+
if type_expr < GraphQL::Schema::Member
|
68
68
|
type_expr.graphql_definition
|
69
69
|
else
|
70
70
|
# Eg `String` => GraphQL::STRING_TYPE
|
71
71
|
parse_type(type_expr.name, null: true)
|
72
72
|
end
|
73
|
+
else
|
74
|
+
raise "Unexpected type_expr input: #{type_expr} (#{type_expr.class})"
|
73
75
|
end
|
74
76
|
|
75
77
|
# Apply list_type first, that way the
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Schema
|
4
|
+
class Member
|
5
|
+
module HasArguments
|
6
|
+
def self.included(cls)
|
7
|
+
cls.extend(ArgumentClassAccessor)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.extended(cls)
|
11
|
+
cls.extend(ArgumentClassAccessor)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @see {GraphQL::Schema::Argument#initialize} for parameters
|
15
|
+
# @return [GraphQL::Schema::Argument] An instance of {arguments_class}, created from `*args`
|
16
|
+
def argument(*args, **kwargs, &block)
|
17
|
+
kwargs[:owner] = self
|
18
|
+
arg_defn = self.argument_class.new(*args, **kwargs, &block)
|
19
|
+
own_arguments[arg_defn.name] = arg_defn
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Hash<String => GraphQL::Schema::Argument] Arguments defined on this thing, keyed by name. Includes inherited definitions
|
23
|
+
def arguments
|
24
|
+
inherited_arguments = ((self.is_a?(Class) && superclass <= GraphQL::Schema::Member::HasArguments) ? superclass.arguments : {})
|
25
|
+
# Local definitions override inherited ones
|
26
|
+
inherited_arguments.merge(own_arguments)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param new_arg_class [Class] A class to use for building argument definitions
|
30
|
+
def argument_class(new_arg_class = nil)
|
31
|
+
self.class.argument_class(new_arg_class)
|
32
|
+
end
|
33
|
+
|
34
|
+
module ArgumentClassAccessor
|
35
|
+
def argument_class(new_arg_class = nil)
|
36
|
+
if new_arg_class
|
37
|
+
@argument_class = new_arg_class
|
38
|
+
else
|
39
|
+
@argument_class || (superclass.respond_to?(:argument_class) ? superclass.argument_class : GraphQL::Schema::Argument)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def own_arguments
|
45
|
+
@own_arguments ||= {}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -8,9 +8,9 @@ module GraphQL
|
|
8
8
|
module_function
|
9
9
|
def instrument(type, field)
|
10
10
|
return_type = field.type.unwrap
|
11
|
-
if return_type.metadata[:
|
11
|
+
if (return_type.is_a?(GraphQL::ObjectType) && return_type.metadata[:type_class]) ||
|
12
12
|
return_type.is_a?(GraphQL::InterfaceType) ||
|
13
|
-
(return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:
|
13
|
+
(return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:type_class] })
|
14
14
|
field = apply_proxy(field)
|
15
15
|
end
|
16
16
|
|
@@ -25,7 +25,7 @@ module GraphQL
|
|
25
25
|
else
|
26
26
|
root_type = query.irep_selection.return_type
|
27
27
|
# If it has a wrapper, apply it
|
28
|
-
wrapper_class = root_type.metadata[:
|
28
|
+
wrapper_class = root_type.metadata[:type_class]
|
29
29
|
if wrapper_class
|
30
30
|
new_root_value = wrapper_class.new(query.root_value, query.context)
|
31
31
|
query.root_value = new_root_value
|
@@ -99,7 +99,7 @@ module GraphQL
|
|
99
99
|
raise "unexpected proxying type #{type} for #{obj} at #{ctx.owner_type}.#{ctx.field.name}"
|
100
100
|
end
|
101
101
|
|
102
|
-
if concrete_type && (object_class = concrete_type.metadata[:
|
102
|
+
if concrete_type && (object_class = concrete_type.metadata[:type_class])
|
103
103
|
# use the query-level context here, since it won't be field-specific anyways
|
104
104
|
query_ctx = ctx.query.context
|
105
105
|
object_class.new(obj, query_ctx)
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# This base class accepts configuration for a mutation root field,
|
6
|
+
# then it can be hooked up to your mutation root object type.
|
7
|
+
#
|
8
|
+
# If you want to customize how this class generates types, in your base class,
|
9
|
+
# override the various `generate_*` methods.
|
10
|
+
#
|
11
|
+
# @see {GraphQL::Schema::RelayClassicMutation} for an extension of this class with some conventions built-in.
|
12
|
+
#
|
13
|
+
# @example Creating a comment
|
14
|
+
# # Define the mutation:
|
15
|
+
# class Mutations::CreateComment < GraphQL::Schema::Mutation
|
16
|
+
# argument :body, String, required: true
|
17
|
+
# argument :post_id, ID, required: true
|
18
|
+
#
|
19
|
+
# field :comment, Types::Comment, null: true
|
20
|
+
# field :error_messages, [String], null: false
|
21
|
+
#
|
22
|
+
# def resolve(body:, post_id:)
|
23
|
+
# post = Post.find(post_id)
|
24
|
+
# comment = post.comments.build(body: body, author: context[:current_user])
|
25
|
+
# if comment.save
|
26
|
+
# # Successful creation, return the created object with no errors
|
27
|
+
# {
|
28
|
+
# comment: comment,
|
29
|
+
# errors: [],
|
30
|
+
# }
|
31
|
+
# else
|
32
|
+
# # Failed save, return the errors to the client
|
33
|
+
# {
|
34
|
+
# comment: nil,
|
35
|
+
# errors: comment.errors.full_messages
|
36
|
+
# }
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # Hook it up to your mutation:
|
42
|
+
# class Types::Mutation < GraphQL::Schema::Object
|
43
|
+
# field :create_comment, mutation: Mutations::CreateComment
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# # Call it from GraphQL:
|
47
|
+
# result = MySchema.execute <<-GRAPHQL
|
48
|
+
# mutation {
|
49
|
+
# createComment(postId: "1", body: "Nice Post!") {
|
50
|
+
# errors
|
51
|
+
# comment {
|
52
|
+
# body
|
53
|
+
# author {
|
54
|
+
# login
|
55
|
+
# }
|
56
|
+
# }
|
57
|
+
# }
|
58
|
+
# }
|
59
|
+
# GRAPHQL
|
60
|
+
#
|
61
|
+
class Mutation < GraphQL::Schema::Member
|
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
|
+
class << self
|
86
|
+
# Override the method from HasFields to support `field: Mutation.field`, for backwards compat.
|
87
|
+
#
|
88
|
+
# If called without any arguments, returns a `GraphQL::Field`.
|
89
|
+
# @see {GraphQL::Schema::Member::HasFields.field} for default behavior
|
90
|
+
def field(*args, &block)
|
91
|
+
if args.none? && !block_given?
|
92
|
+
graphql_field.graphql_definition
|
93
|
+
else
|
94
|
+
super(*args, &block)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Call this method to get the derived return type of the mutation,
|
99
|
+
# or use it as a configuration method to assign a return type
|
100
|
+
# instead of generating one.
|
101
|
+
# @param new_payload_type [Class, nil] If a type definition class is provided, it will be used as the return type of the mutation field
|
102
|
+
# @return [Class] The object type which this mutation returns.
|
103
|
+
def payload_type(new_payload_type = nil)
|
104
|
+
if new_payload_type
|
105
|
+
@payload_type = new_payload_type
|
106
|
+
end
|
107
|
+
@payload_type ||= generate_payload_type
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [GraphQL::Schema::Field] The generated field instance for this mutation
|
111
|
+
# @see {GraphQL::Schema::Field}'s `mutation:` option, don't call this directly
|
112
|
+
def graphql_field
|
113
|
+
@graphql_field ||= generate_field
|
114
|
+
end
|
115
|
+
|
116
|
+
# @param new_name [String, nil] if present, override the class name to set this value
|
117
|
+
# @return [String] The name of this mutation in the GraphQL schema (used for naming derived types and fields)
|
118
|
+
def graphql_name(new_name = nil)
|
119
|
+
if new_name
|
120
|
+
@graphql_name = new_name
|
121
|
+
end
|
122
|
+
@graphql_name ||= self.name.split("::").last
|
123
|
+
end
|
124
|
+
|
125
|
+
# An object class to use for deriving payload types
|
126
|
+
# @param new_class [Class, nil] Defaults to {GraphQL::Schema::Object}
|
127
|
+
# @return [Class]
|
128
|
+
def object_class(new_class = nil)
|
129
|
+
if new_class
|
130
|
+
@object_class = new_class
|
131
|
+
end
|
132
|
+
@object_class || (superclass.respond_to?(:object_class) ? superclass.object_class : GraphQL::Schema::Object)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Additional info injected into {#resolve}
|
136
|
+
# @see {GraphQL::Schema::Field#extras}
|
137
|
+
def extras(new_extras = nil)
|
138
|
+
if new_extras
|
139
|
+
@extras = new_extras
|
140
|
+
end
|
141
|
+
@extras || []
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
# Build a subclass of {.object_class} based on `self`.
|
147
|
+
# This value will be cached as `{.payload_type}`.
|
148
|
+
# Override this hook to customize return type generation.
|
149
|
+
def generate_payload_type
|
150
|
+
mutation_name = graphql_name
|
151
|
+
mutation_fields = fields
|
152
|
+
mutation_class = self
|
153
|
+
Class.new(object_class) do
|
154
|
+
graphql_name("#{mutation_name}Payload")
|
155
|
+
description("Autogenerated return type of #{mutation_name}")
|
156
|
+
mutation(mutation_class)
|
157
|
+
mutation_fields.each do |name, f|
|
158
|
+
field(name, field: f)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# This name will be used for the {.graphql_field}.
|
164
|
+
def field_name
|
165
|
+
graphql_name.sub(/^[A-Z]/, &:downcase)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Build an instance of {.field_class} which will be used to execute this mutation.
|
169
|
+
# To customize field generation, override this method.
|
170
|
+
def generate_field
|
171
|
+
# TODO support deprecation_reason
|
172
|
+
self.field_class.new(
|
173
|
+
field_name,
|
174
|
+
payload_type,
|
175
|
+
description,
|
176
|
+
resolve: self.method(:resolve_field),\
|
177
|
+
mutation_class: self,
|
178
|
+
arguments: arguments,
|
179
|
+
null: true,
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
# This is basically the `.call` behavior for the generated field,
|
184
|
+
# instantiating the Mutation class and calling its {#resolve} method
|
185
|
+
# with Ruby keyword arguments.
|
186
|
+
def resolve_field(obj, args, ctx)
|
187
|
+
mutation = self.new(object: obj, arguments: args, context: ctx.query.context)
|
188
|
+
ruby_kwargs = args.to_kwargs
|
189
|
+
extras.each { |e| ruby_kwargs[e] = ctx.public_send(e) }
|
190
|
+
mutation.resolve(**ruby_kwargs)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -4,6 +4,7 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
class Object < GraphQL::Schema::Member
|
6
6
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
7
|
+
extend GraphQL::Schema::Member::HasFields
|
7
8
|
|
8
9
|
# @return [Object] the application object this type is wrapping
|
9
10
|
attr_reader :object
|
@@ -16,9 +17,6 @@ module GraphQL
|
|
16
17
|
@context = context
|
17
18
|
end
|
18
19
|
|
19
|
-
extend GraphQL::Schema::Member::HasFields
|
20
|
-
field_class GraphQL::Schema::Field
|
21
|
-
|
22
20
|
class << self
|
23
21
|
def implements(*new_interfaces)
|
24
22
|
new_interfaces.each do |int|
|
@@ -28,7 +26,7 @@ module GraphQL
|
|
28
26
|
own_fields[name] = field
|
29
27
|
end
|
30
28
|
# And call the implemented hook
|
31
|
-
int.
|
29
|
+
int.implemented(self)
|
32
30
|
else
|
33
31
|
int.all_fields.each do |f|
|
34
32
|
field(f.name, field: f)
|
@@ -53,13 +51,14 @@ module GraphQL
|
|
53
51
|
obj_type.description = description
|
54
52
|
obj_type.interfaces = interfaces
|
55
53
|
obj_type.introspection = introspection
|
54
|
+
obj_type.mutation = mutation
|
56
55
|
|
57
56
|
fields.each do |field_name, field_inst|
|
58
57
|
field_defn = field_inst.to_graphql
|
59
58
|
obj_type.fields[field_defn.name] = field_defn
|
60
59
|
end
|
61
60
|
|
62
|
-
obj_type.metadata[:
|
61
|
+
obj_type.metadata[:type_class] = self
|
63
62
|
|
64
63
|
obj_type
|
65
64
|
end
|