graphql 2.0.16 → 2.0.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/visitor.rb +42 -35
  3. data/lib/graphql/execution/interpreter/runtime.rb +14 -4
  4. data/lib/graphql/execution/interpreter.rb +10 -0
  5. data/lib/graphql/execution/lazy.rb +4 -8
  6. data/lib/graphql/introspection/directive_type.rb +2 -2
  7. data/lib/graphql/introspection/field_type.rb +1 -1
  8. data/lib/graphql/introspection/schema_type.rb +2 -2
  9. data/lib/graphql/introspection/type_type.rb +5 -5
  10. data/lib/graphql/language/nodes.rb +39 -31
  11. data/lib/graphql/language/visitor.rb +191 -83
  12. data/lib/graphql/schema/argument.rb +0 -4
  13. data/lib/graphql/schema/directive.rb +12 -2
  14. data/lib/graphql/schema/enum.rb +24 -17
  15. data/lib/graphql/schema/enum_value.rb +5 -3
  16. data/lib/graphql/schema/field.rb +22 -26
  17. data/lib/graphql/schema/interface.rb +0 -10
  18. data/lib/graphql/schema/late_bound_type.rb +2 -0
  19. data/lib/graphql/schema/member/base_dsl_methods.rb +15 -14
  20. data/lib/graphql/schema/member/has_arguments.rb +104 -57
  21. data/lib/graphql/schema/member/has_fields.rb +8 -1
  22. data/lib/graphql/schema/member/has_interfaces.rb +49 -8
  23. data/lib/graphql/schema/member/has_validators.rb +31 -5
  24. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  25. data/lib/graphql/schema/warden.rb +18 -3
  26. data/lib/graphql/schema.rb +3 -19
  27. data/lib/graphql/static_validation/literal_validator.rb +15 -1
  28. data/lib/graphql/subscriptions/event.rb +2 -7
  29. data/lib/graphql/types/relay/connection_behaviors.rb +0 -4
  30. data/lib/graphql/types/relay/edge_behaviors.rb +0 -4
  31. data/lib/graphql/types/string.rb +1 -1
  32. data/lib/graphql/version.rb +1 -1
  33. metadata +3 -3
@@ -65,7 +65,9 @@ module GraphQL
65
65
  # Visit `document` and all children, applying hooks as you go
66
66
  # @return [void]
67
67
  def visit
68
- result = on_node_with_modifications(@document, nil)
68
+ # `@document` may be any kind of node:
69
+ visit_method = :"#{@document.visit_method}_with_modifications"
70
+ result = public_send(visit_method, @document, nil)
69
71
  @result = if result.is_a?(Array)
70
72
  result.first
71
73
  else
@@ -74,104 +76,210 @@ module GraphQL
74
76
  end
75
77
  end
76
78
 
77
- # Call the user-defined handler for `node`.
78
- def visit_node(node, parent)
79
- public_send(node.visit_method, node, parent)
80
- end
79
+ # We don't use `alias` here because it breaks `super`
80
+ def self.make_visit_methods(ast_node_class)
81
+ node_method = ast_node_class.visit_method
82
+ children_of_type = ast_node_class.children_of_type
83
+ child_visit_method = :"#{node_method}_children"
81
84
 
82
- # The default implementation for visiting an AST node.
83
- # It doesn't _do_ anything, but it continues to visiting the node's children.
84
- # To customize this hook, override one of its make_visit_methodes (or the base method?)
85
- # in your subclasses.
86
- #
87
- # For compatibility, it calls hook procs, too.
88
- # @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
89
- # @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
90
- # @return [Array, nil] If there were modifications, it returns an array of new nodes, otherwise, it returns `nil`.
91
- def on_abstract_node(node, parent)
92
- if node.equal?(DELETE_NODE)
93
- # This might be passed to `super(DELETE_NODE, ...)`
94
- # by a user hook, don't want to keep visiting in that case.
95
- nil
96
- else
97
- # Run hooks if there are any
98
- new_node = node
99
- no_hooks = !@visitors.key?(node.class)
100
- if no_hooks || begin_visit(new_node, parent)
101
- node.children.each do |child_node|
102
- new_child_and_node = on_node_with_modifications(child_node, new_node)
103
- # Reassign `node` in case the child hook makes a modification
104
- if new_child_and_node.is_a?(Array)
105
- new_node = new_child_and_node[1]
85
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
86
+ # The default implementation for visiting an AST node.
87
+ # It doesn't _do_ anything, but it continues to visiting the node's children.
88
+ # To customize this hook, override one of its make_visit_methods (or the base method?)
89
+ # in your subclasses.
90
+ #
91
+ # For compatibility, it calls hook procs, too.
92
+ # @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
93
+ # @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
94
+ # @return [Array, nil] If there were modifications, it returns an array of new nodes, otherwise, it returns `nil`.
95
+ def #{node_method}(node, parent)
96
+ if node.equal?(DELETE_NODE)
97
+ # This might be passed to `super(DELETE_NODE, ...)`
98
+ # by a user hook, don't want to keep visiting in that case.
99
+ [node, parent]
100
+ else
101
+ # Run hooks if there are any
102
+ new_node = node
103
+ no_hooks = !@visitors.key?(node.class)
104
+ if no_hooks || begin_visit(new_node, parent)
105
+ #{
106
+ if method_defined?(child_visit_method)
107
+ "new_node = #{child_visit_method}(new_node)"
108
+ elsif children_of_type
109
+ children_of_type.map do |child_accessor, child_class|
110
+ "node.#{child_accessor}.each do |child_node|
111
+ new_child_and_node = #{child_class.visit_method}_with_modifications(child_node, new_node)
112
+ # Reassign `node` in case the child hook makes a modification
113
+ if new_child_and_node.is_a?(Array)
114
+ new_node = new_child_and_node[1]
115
+ end
116
+ end"
117
+ end.join("\n")
118
+ else
119
+ ""
120
+ end
121
+ }
122
+ end
123
+ end_visit(new_node, parent) unless no_hooks
124
+
125
+ if new_node.equal?(node)
126
+ [node, parent]
127
+ else
128
+ [new_node, parent]
106
129
  end
107
130
  end
108
131
  end
109
- end_visit(new_node, parent) unless no_hooks
110
132
 
111
- if new_node.equal?(node)
112
- nil
133
+ def #{node_method}_with_modifications(node, parent)
134
+ new_node_and_new_parent = #{node_method}(node, parent)
135
+ apply_modifications(node, parent, new_node_and_new_parent)
136
+ end
137
+ RUBY
138
+ end
139
+
140
+ def on_document_children(document_node)
141
+ new_node = document_node
142
+ document_node.children.each do |child_node|
143
+ visit_method = :"#{child_node.visit_method}_with_modifications"
144
+ new_child_and_node = public_send(visit_method, child_node, new_node)
145
+ # Reassign `node` in case the child hook makes a modification
146
+ if new_child_and_node.is_a?(Array)
147
+ new_node = new_child_and_node[1]
148
+ end
149
+ end
150
+ new_node
151
+ end
152
+
153
+ def on_field_children(new_node)
154
+ new_node.arguments.each do |arg_node| # rubocop:disable Development/ContextIsPassedCop
155
+ new_child_and_node = on_argument_with_modifications(arg_node, new_node)
156
+ # Reassign `node` in case the child hook makes a modification
157
+ if new_child_and_node.is_a?(Array)
158
+ new_node = new_child_and_node[1]
159
+ end
160
+ end
161
+ new_node = visit_directives(new_node)
162
+ new_node = visit_selections(new_node)
163
+ new_node
164
+ end
165
+
166
+ def visit_directives(new_node)
167
+ new_node.directives.each do |dir_node|
168
+ new_child_and_node = on_directive_with_modifications(dir_node, new_node)
169
+ # Reassign `node` in case the child hook makes a modification
170
+ if new_child_and_node.is_a?(Array)
171
+ new_node = new_child_and_node[1]
172
+ end
173
+ end
174
+ new_node
175
+ end
176
+
177
+ def visit_selections(new_node)
178
+ new_node.selections.each do |selection|
179
+ new_child_and_node = case selection
180
+ when GraphQL::Language::Nodes::Field
181
+ on_field_with_modifications(selection, new_node)
182
+ when GraphQL::Language::Nodes::InlineFragment
183
+ on_inline_fragment_with_modifications(selection, new_node)
184
+ when GraphQL::Language::Nodes::FragmentSpread
185
+ on_fragment_spread_with_modifications(selection, new_node)
113
186
  else
114
- [new_node, parent]
187
+ raise ArgumentError, "Invariant: unexpected field selection #{selection.class} (#{selection.inspect})"
188
+ end
189
+ # Reassign `node` in case the child hook makes a modification
190
+ if new_child_and_node.is_a?(Array)
191
+ new_node = new_child_and_node[1]
115
192
  end
116
193
  end
194
+ new_node
117
195
  end
118
196
 
119
- # We don't use `alias` here because it breaks `super`
120
- def self.make_visit_method(node_method)
121
- class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
122
- def #{node_method}(node, parent)
123
- child_mod = on_abstract_node(node, parent)
124
- # If visiting the children returned changes, continue passing those.
125
- child_mod || [node, parent]
197
+ def on_fragment_definition_children(new_node)
198
+ new_node = visit_directives(new_node)
199
+ new_node = visit_selections(new_node)
200
+ new_node
201
+ end
202
+
203
+ alias :on_inline_fragment_children :on_fragment_definition_children
204
+
205
+ def on_operation_definition_children(new_node)
206
+ new_node.variables.each do |arg_node|
207
+ new_child_and_node = on_variable_definition_with_modifications(arg_node, new_node)
208
+ # Reassign `node` in case the child hook makes a modification
209
+ if new_child_and_node.is_a?(Array)
210
+ new_node = new_child_and_node[1]
126
211
  end
127
- RUBY
212
+ end
213
+ new_node = visit_directives(new_node)
214
+ new_node = visit_selections(new_node)
215
+ new_node
216
+ end
217
+
218
+ def on_argument_children(new_node)
219
+ new_node.children.each do |value_node|
220
+ new_child_and_node = case value_node
221
+ when Language::Nodes::VariableIdentifier
222
+ on_variable_identifier_with_modifications(value_node, new_node)
223
+ when Language::Nodes::InputObject
224
+ on_input_object_with_modifications(value_node, new_node)
225
+ when Language::Nodes::Enum
226
+ on_enum_with_modifications(value_node, new_node)
227
+ when Language::Nodes::NullValue
228
+ on_null_value_with_modifications(value_node, new_node)
229
+ else
230
+ raise ArgumentError, "Invariant: unexpected argument value node #{value_node.class} (#{value_node.inspect})"
231
+ end
232
+ # Reassign `node` in case the child hook makes a modification
233
+ if new_child_and_node.is_a?(Array)
234
+ new_node = new_child_and_node[1]
235
+ end
236
+ end
237
+ new_node
128
238
  end
129
239
 
130
- make_visit_method :on_argument
131
- make_visit_method :on_directive
132
- make_visit_method :on_directive_definition
133
- make_visit_method :on_directive_location
134
- make_visit_method :on_document
135
- make_visit_method :on_enum
136
- make_visit_method :on_enum_type_definition
137
- make_visit_method :on_enum_type_extension
138
- make_visit_method :on_enum_value_definition
139
- make_visit_method :on_field
140
- make_visit_method :on_field_definition
141
- make_visit_method :on_fragment_definition
142
- make_visit_method :on_fragment_spread
143
- make_visit_method :on_inline_fragment
144
- make_visit_method :on_input_object
145
- make_visit_method :on_input_object_type_definition
146
- make_visit_method :on_input_object_type_extension
147
- make_visit_method :on_input_value_definition
148
- make_visit_method :on_interface_type_definition
149
- make_visit_method :on_interface_type_extension
150
- make_visit_method :on_list_type
151
- make_visit_method :on_non_null_type
152
- make_visit_method :on_null_value
153
- make_visit_method :on_object_type_definition
154
- make_visit_method :on_object_type_extension
155
- make_visit_method :on_operation_definition
156
- make_visit_method :on_scalar_type_definition
157
- make_visit_method :on_scalar_type_extension
158
- make_visit_method :on_schema_definition
159
- make_visit_method :on_schema_extension
160
- make_visit_method :on_type_name
161
- make_visit_method :on_union_type_definition
162
- make_visit_method :on_union_type_extension
163
- make_visit_method :on_variable_definition
164
- make_visit_method :on_variable_identifier
240
+ [
241
+ Language::Nodes::Argument,
242
+ Language::Nodes::Directive,
243
+ Language::Nodes::DirectiveDefinition,
244
+ Language::Nodes::DirectiveLocation,
245
+ Language::Nodes::Document,
246
+ Language::Nodes::Enum,
247
+ Language::Nodes::EnumTypeDefinition,
248
+ Language::Nodes::EnumTypeExtension,
249
+ Language::Nodes::EnumValueDefinition,
250
+ Language::Nodes::Field,
251
+ Language::Nodes::FieldDefinition,
252
+ Language::Nodes::FragmentDefinition,
253
+ Language::Nodes::FragmentSpread,
254
+ Language::Nodes::InlineFragment,
255
+ Language::Nodes::InputObject,
256
+ Language::Nodes::InputObjectTypeDefinition,
257
+ Language::Nodes::InputObjectTypeExtension,
258
+ Language::Nodes::InputValueDefinition,
259
+ Language::Nodes::InterfaceTypeDefinition,
260
+ Language::Nodes::InterfaceTypeExtension,
261
+ Language::Nodes::ListType,
262
+ Language::Nodes::NonNullType,
263
+ Language::Nodes::NullValue,
264
+ Language::Nodes::ObjectTypeDefinition,
265
+ Language::Nodes::ObjectTypeExtension,
266
+ Language::Nodes::OperationDefinition,
267
+ Language::Nodes::ScalarTypeDefinition,
268
+ Language::Nodes::ScalarTypeExtension,
269
+ Language::Nodes::SchemaDefinition,
270
+ Language::Nodes::SchemaExtension,
271
+ Language::Nodes::TypeName,
272
+ Language::Nodes::UnionTypeDefinition,
273
+ Language::Nodes::UnionTypeExtension,
274
+ Language::Nodes::VariableDefinition,
275
+ Language::Nodes::VariableIdentifier,
276
+ ].each do |ast_node_class|
277
+ make_visit_methods(ast_node_class)
278
+ end
165
279
 
166
280
  private
167
281
 
168
- # Run the hooks for `node`, and if the hooks return a copy of `node`,
169
- # copy `parent` so that it contains the copy of that node as a child,
170
- # then return the copies
171
- # If a non-array value is returned, consuming functions should ignore
172
- # said value
173
- def on_node_with_modifications(node, parent)
174
- new_node_and_new_parent = visit_node(node, parent)
282
+ def apply_modifications(node, parent, new_node_and_new_parent)
175
283
  if new_node_and_new_parent.is_a?(Array)
176
284
  new_node = new_node_and_new_parent[0]
177
285
  new_parent = new_node_and_new_parent[1]
@@ -149,10 +149,6 @@ module GraphQL
149
149
  true
150
150
  end
151
151
 
152
- def accessible?(context)
153
- true
154
- end
155
-
156
152
  def authorized?(obj, value, ctx)
157
153
  authorized_as_type?(obj, value, ctx, as_type: type)
158
154
  end
@@ -8,6 +8,7 @@ module GraphQL
8
8
  # - {.resolve}: Wraps field resolution (so it should call `yield` to continue)
9
9
  class Directive < GraphQL::Schema::Member
10
10
  extend GraphQL::Schema::Member::HasArguments
11
+ extend GraphQL::Schema::Member::HasArguments::HasDirectiveArguments
11
12
 
12
13
  class << self
13
14
  # Directives aren't types, they don't have kinds.
@@ -21,9 +22,9 @@ module GraphQL
21
22
  # but downcase the first letter.
22
23
  def default_graphql_name
23
24
  @default_graphql_name ||= begin
24
- camelized_name = super
25
+ camelized_name = super.dup
25
26
  camelized_name[0] = camelized_name[0].downcase
26
- camelized_name
27
+ -camelized_name
27
28
  end
28
29
  end
29
30
 
@@ -93,6 +94,15 @@ module GraphQL
93
94
  def repeatable(new_value)
94
95
  @repeatable = new_value
95
96
  end
97
+
98
+ private
99
+
100
+ def inherited(subclass)
101
+ super
102
+ subclass.class_eval do
103
+ @default_graphql_name ||= nil
104
+ end
105
+ end
96
106
  end
97
107
 
98
108
  # @return [GraphQL::Schema::Field, GraphQL::Schema::Argument, Class, Module]
@@ -1,24 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphQL
4
- # Extend this class to define GraphQL enums in your schema.
5
- #
6
- # By default, GraphQL enum values are translated into Ruby strings.
7
- # You can provide a custom value with the `value:` keyword.
8
- #
9
- # @example
10
- # # equivalent to
11
- # # enum PizzaTopping {
12
- # # MUSHROOMS
13
- # # ONIONS
14
- # # PEPPERS
15
- # # }
16
- # class PizzaTopping < GraphQL::Enum
17
- # value :MUSHROOMS
18
- # value :ONIONS
19
- # value :PEPPERS
20
- # end
21
4
  class Schema
5
+ # Extend this class to define GraphQL enums in your schema.
6
+ #
7
+ # By default, GraphQL enum values are translated into Ruby strings.
8
+ # You can provide a custom value with the `value:` keyword.
9
+ #
10
+ # @example
11
+ # # equivalent to
12
+ # # enum PizzaTopping {
13
+ # # MUSHROOMS
14
+ # # ONIONS
15
+ # # PEPPERS
16
+ # # }
17
+ # class PizzaTopping < GraphQL::Enum
18
+ # value :MUSHROOMS
19
+ # value :ONIONS
20
+ # value :PEPPERS
21
+ # end
22
22
  class Enum < GraphQL::Schema::Member
23
23
  extend GraphQL::Schema::Member::ValidatesInput
24
24
 
@@ -34,6 +34,13 @@ module GraphQL
34
34
  end
35
35
  end
36
36
 
37
+ class MissingValuesError < GraphQL::Error
38
+ def initialize(enum_type)
39
+ @enum_type = enum_type
40
+ super("Enum types require at least one value, but #{enum_type.graphql_name} didn't provide any for this query. Make sure at least one value is defined and visible for this query.")
41
+ end
42
+ end
43
+
37
44
  class << self
38
45
  # Define a value for this enum
39
46
  # @param graphql_name [String, Symbol] the GraphQL value for this, usually `SCREAMING_CASE`
@@ -25,16 +25,19 @@ module GraphQL
25
25
  include GraphQL::Schema::Member::HasDirectives
26
26
  include GraphQL::Schema::Member::HasDeprecationReason
27
27
 
28
+ UNDEFINED_VALUE = Object.new.freeze
29
+ private_constant :UNDEFINED_VALUE
30
+
28
31
  attr_reader :graphql_name
29
32
 
30
33
  # @return [Class] The enum type that owns this value
31
34
  attr_reader :owner
32
35
 
33
- def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: nil, deprecation_reason: nil, &block)
36
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: UNDEFINED_VALUE, deprecation_reason: nil, &block)
34
37
  @graphql_name = graphql_name.to_s
35
38
  GraphQL::NameValidator.validate!(@graphql_name)
36
39
  @description = desc || description
37
- @value = value.nil? ? @graphql_name : value
40
+ @value = value === UNDEFINED_VALUE ? @graphql_name : value
38
41
  if deprecation_reason
39
42
  self.deprecation_reason = deprecation_reason
40
43
  end
@@ -70,7 +73,6 @@ module GraphQL
70
73
  end
71
74
 
72
75
  def visible?(_ctx); true; end
73
- def accessible?(_ctx); true; end
74
76
  def authorized?(_ctx); true; end
75
77
  end
76
78
  end
@@ -6,6 +6,7 @@ module GraphQL
6
6
  class Schema
7
7
  class Field
8
8
  include GraphQL::Schema::Member::HasArguments
9
+ include GraphQL::Schema::Member::HasArguments::FieldConfigured
9
10
  include GraphQL::Schema::Member::HasAstNode
10
11
  include GraphQL::Schema::Member::HasPath
11
12
  include GraphQL::Schema::Member::HasValidators
@@ -229,6 +230,7 @@ module GraphQL
229
230
  end
230
231
  @original_name = name
231
232
  name_s = -name.to_s
233
+
232
234
  @underscored_name = -Member::BuildType.underscore(name_s)
233
235
  @name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
234
236
  if description != :not_given
@@ -589,14 +591,6 @@ module GraphQL
589
591
  end
590
592
  end
591
593
 
592
- def accessible?(context)
593
- if @resolver_class
594
- @resolver_class.accessible?(context)
595
- else
596
- true
597
- end
598
- end
599
-
600
594
  def authorized?(object, args, context)
601
595
  if @resolver_class
602
596
  # The resolver _instance_ will check itself during `resolve()`
@@ -610,27 +604,29 @@ module GraphQL
610
604
  arg_values = args
611
605
  using_arg_values = false
612
606
  end
613
- # Faster than `.any?`
614
- arguments(context).each_value do |arg|
615
- arg_key = arg.keyword
616
- if arg_values.key?(arg_key)
617
- arg_value = arg_values[arg_key]
618
- if using_arg_values
619
- if arg_value.default_used?
620
- # pass -- no auth required for default used
621
- next
622
- else
623
- application_arg_value = arg_value.value
624
- if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
625
- application_arg_value.keyword_arguments
607
+ if args.size > 0
608
+ args = context.warden.arguments(self)
609
+ args.each do |arg|
610
+ arg_key = arg.keyword
611
+ if arg_values.key?(arg_key)
612
+ arg_value = arg_values[arg_key]
613
+ if using_arg_values
614
+ if arg_value.default_used?
615
+ # pass -- no auth required for default used
616
+ next
617
+ else
618
+ application_arg_value = arg_value.value
619
+ if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
620
+ application_arg_value.keyword_arguments
621
+ end
626
622
  end
623
+ else
624
+ application_arg_value = arg_value
627
625
  end
628
- else
629
- application_arg_value = arg_value
630
- end
631
626
 
632
- if !arg.authorized?(object, application_arg_value, context)
633
- return false
627
+ if !arg.authorized?(object, application_arg_value, context)
628
+ return false
629
+ end
634
630
  end
635
631
  end
636
632
  end
@@ -28,16 +28,6 @@ module GraphQL
28
28
  true
29
29
  end
30
30
 
31
- # The interface is accessible if any of its possible types are accessible
32
- def accessible?(context)
33
- context.schema.possible_types(self, context).each do |type|
34
- if context.schema.accessible?(type, context)
35
- return true
36
- end
37
- end
38
- false
39
- end
40
-
41
31
  def type_membership_class(membership_class = nil)
42
32
  if membership_class
43
33
  @type_membership_class = membership_class
@@ -9,6 +9,8 @@ module GraphQL
9
9
  alias :graphql_name :name
10
10
  def initialize(local_name)
11
11
  @name = local_name
12
+ @to_non_null_type = nil
13
+ @to_list_type = nil
12
14
  end
13
15
 
14
16
  def unwrap
@@ -22,14 +22,10 @@ module GraphQL
22
22
  GraphQL::NameValidator.validate!(new_name)
23
23
  @graphql_name = new_name
24
24
  else
25
- overridden_graphql_name || default_graphql_name
25
+ @graphql_name ||= default_graphql_name
26
26
  end
27
27
  end
28
28
 
29
- def overridden_graphql_name
30
- defined?(@graphql_name) ? @graphql_name : nil
31
- end
32
-
33
29
  # Just a convenience method to point out that people should use graphql_name instead
34
30
  def name(new_name = nil)
35
31
  return super() if new_name.nil?
@@ -60,8 +56,8 @@ module GraphQL
60
56
  def inherited(child_class)
61
57
  child_class.introspection(introspection)
62
58
  child_class.description(description)
63
- if overridden_graphql_name
64
- child_class.graphql_name(overridden_graphql_name)
59
+ if defined?(@graphql_name) && (self.name.nil? || graphql_name != default_graphql_name)
60
+ child_class.graphql_name(graphql_name)
65
61
  end
66
62
  super
67
63
  end
@@ -79,7 +75,7 @@ module GraphQL
79
75
  end
80
76
 
81
77
  def introspection?
82
- introspection
78
+ !!@introspection
83
79
  end
84
80
 
85
81
  # The mutation this type was derived from, if it was derived from a mutation
@@ -102,21 +98,26 @@ module GraphQL
102
98
  def default_graphql_name
103
99
  @default_graphql_name ||= begin
104
100
  raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
105
-
106
- name.split("::").last.sub(/Type\Z/, "")
107
- end
101
+ -name.split("::").last.sub(/Type\Z/, "") end
108
102
  end
109
103
 
110
104
  def visible?(context)
111
105
  true
112
106
  end
113
107
 
114
- def accessible?(context)
108
+ def authorized?(object, context)
115
109
  true
116
110
  end
117
111
 
118
- def authorized?(object, context)
119
- true
112
+ protected
113
+
114
+ attr_writer :default_graphql_name
115
+
116
+ private
117
+
118
+ def inherited(subclass)
119
+ super
120
+ subclass.default_graphql_name = nil
120
121
  end
121
122
  end
122
123
  end