graphql 2.3.5 → 2.3.8

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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/analyzer.rb +89 -0
  3. data/lib/graphql/analysis/field_usage.rb +82 -0
  4. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  5. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  6. data/lib/graphql/analysis/query_complexity.rb +183 -0
  7. data/lib/graphql/analysis/{ast/query_depth.rb → query_depth.rb} +23 -25
  8. data/lib/graphql/analysis/visitor.rb +283 -0
  9. data/lib/graphql/analysis.rb +92 -1
  10. data/lib/graphql/dataloader/async_dataloader.rb +2 -0
  11. data/lib/graphql/execution/interpreter/runtime.rb +6 -6
  12. data/lib/graphql/execution/interpreter.rb +1 -1
  13. data/lib/graphql/execution/lookahead.rb +10 -10
  14. data/lib/graphql/introspection/directive_type.rb +1 -1
  15. data/lib/graphql/introspection/entry_points.rb +2 -2
  16. data/lib/graphql/introspection/field_type.rb +1 -1
  17. data/lib/graphql/introspection/schema_type.rb +13 -3
  18. data/lib/graphql/introspection/type_type.rb +5 -5
  19. data/lib/graphql/language/document_from_schema_definition.rb +19 -26
  20. data/lib/graphql/language/lexer.rb +0 -3
  21. data/lib/graphql/language/sanitized_printer.rb +1 -1
  22. data/lib/graphql/language.rb +0 -1
  23. data/lib/graphql/query/context.rb +4 -0
  24. data/lib/graphql/query/null_context.rb +4 -0
  25. data/lib/graphql/query/validation_pipeline.rb +2 -2
  26. data/lib/graphql/query.rb +26 -3
  27. data/lib/graphql/schema/always_visible.rb +1 -0
  28. data/lib/graphql/schema/argument.rb +19 -5
  29. data/lib/graphql/schema/directive.rb +2 -0
  30. data/lib/graphql/schema/enum.rb +4 -4
  31. data/lib/graphql/schema/field.rb +13 -1
  32. data/lib/graphql/schema/has_single_input_argument.rb +2 -1
  33. data/lib/graphql/schema/input_object.rb +8 -7
  34. data/lib/graphql/schema/introspection_system.rb +2 -14
  35. data/lib/graphql/schema/member/has_arguments.rb +7 -6
  36. data/lib/graphql/schema/member/has_fields.rb +6 -4
  37. data/lib/graphql/schema/resolver.rb +5 -5
  38. data/lib/graphql/schema/subset.rb +397 -0
  39. data/lib/graphql/schema/type_expression.rb +2 -2
  40. data/lib/graphql/schema/validator/all_validator.rb +60 -0
  41. data/lib/graphql/schema/validator.rb +2 -0
  42. data/lib/graphql/schema/warden.rb +88 -1
  43. data/lib/graphql/schema.rb +44 -15
  44. data/lib/graphql/static_validation/base_visitor.rb +6 -5
  45. data/lib/graphql/static_validation/literal_validator.rb +4 -4
  46. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  47. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  48. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
  49. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  50. data/lib/graphql/static_validation/rules/fields_will_merge.rb +7 -7
  51. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  52. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  53. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  54. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  55. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  56. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
  57. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  58. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  59. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  60. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  61. data/lib/graphql/static_validation/validation_context.rb +2 -2
  62. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  63. data/lib/graphql/subscriptions/event.rb +1 -1
  64. data/lib/graphql/subscriptions.rb +3 -3
  65. data/lib/graphql/testing/helpers.rb +2 -2
  66. data/lib/graphql/types/relay/connection_behaviors.rb +10 -0
  67. data/lib/graphql/types/relay/edge_behaviors.rb +10 -0
  68. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  69. data/lib/graphql/version.rb +1 -1
  70. metadata +12 -13
  71. data/lib/graphql/analysis/ast/analyzer.rb +0 -91
  72. data/lib/graphql/analysis/ast/field_usage.rb +0 -84
  73. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  74. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  75. data/lib/graphql/analysis/ast/query_complexity.rb +0 -185
  76. data/lib/graphql/analysis/ast/visitor.rb +0 -284
  77. data/lib/graphql/analysis/ast.rb +0 -94
  78. data/lib/graphql/language/token.rb +0 -34
  79. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -0,0 +1,283 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Analysis
4
+ # Depth first traversal through a query AST, calling AST analyzers
5
+ # along the way.
6
+ #
7
+ # The visitor is a special case of GraphQL::Language::StaticVisitor, visiting
8
+ # only the selected operation, providing helpers for common use cases such
9
+ # as skipped fields and visiting fragment spreads.
10
+ #
11
+ # @see {GraphQL::Analysis::Analyzer} AST Analyzers for queries
12
+ class Visitor < GraphQL::Language::StaticVisitor
13
+ def initialize(query:, analyzers:)
14
+ @analyzers = analyzers
15
+ @path = []
16
+ @object_types = []
17
+ @directives = []
18
+ @field_definitions = []
19
+ @argument_definitions = []
20
+ @directive_definitions = []
21
+ @rescued_errors = []
22
+ @query = query
23
+ @schema = query.schema
24
+ @types = query.types
25
+ @response_path = []
26
+ @skip_stack = [false]
27
+ super(query.selected_operation)
28
+ end
29
+
30
+ # @return [GraphQL::Query] the query being visited
31
+ attr_reader :query
32
+
33
+ # @return [Array<GraphQL::ObjectType>] Types whose scope we've entered
34
+ attr_reader :object_types
35
+
36
+ # @return [Array<GraphQL::AnalysisError]
37
+ attr_reader :rescued_errors
38
+
39
+ def visit
40
+ return unless @document
41
+ super
42
+ end
43
+
44
+ # Visit Helpers
45
+
46
+ # @return [GraphQL::Execution::Interpreter::Arguments] Arguments for this node, merging default values, literal values and query variables
47
+ # @see {GraphQL::Query#arguments_for}
48
+ def arguments_for(ast_node, field_definition)
49
+ @query.arguments_for(ast_node, field_definition)
50
+ end
51
+
52
+ # @return [Boolean] If the visitor is currently inside a fragment definition
53
+ def visiting_fragment_definition?
54
+ @in_fragment_def
55
+ end
56
+
57
+ # @return [Boolean] If the current node should be skipped because of a skip or include directive
58
+ def skipping?
59
+ @skipping
60
+ end
61
+
62
+ # @return [Array<String>] The path to the response key for the current field
63
+ def response_path
64
+ @response_path.dup
65
+ end
66
+
67
+ # Visitor Hooks
68
+ [
69
+ :operation_definition, :fragment_definition,
70
+ :inline_fragment, :field, :directive, :argument, :fragment_spread
71
+ ].each do |node_type|
72
+ module_eval <<-RUBY, __FILE__, __LINE__
73
+ def call_on_enter_#{node_type}(node, parent)
74
+ @analyzers.each do |a|
75
+ begin
76
+ a.on_enter_#{node_type}(node, parent, self)
77
+ rescue AnalysisError => err
78
+ @rescued_errors << err
79
+ end
80
+ end
81
+ end
82
+
83
+ def call_on_leave_#{node_type}(node, parent)
84
+ @analyzers.each do |a|
85
+ begin
86
+ a.on_leave_#{node_type}(node, parent, self)
87
+ rescue AnalysisError => err
88
+ @rescued_errors << err
89
+ end
90
+ end
91
+ end
92
+
93
+ RUBY
94
+ end
95
+
96
+ def on_operation_definition(node, parent)
97
+ object_type = @schema.root_type_for_operation(node.operation_type)
98
+ @object_types.push(object_type)
99
+ @path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
100
+ call_on_enter_operation_definition(node, parent)
101
+ super
102
+ call_on_leave_operation_definition(node, parent)
103
+ @object_types.pop
104
+ @path.pop
105
+ end
106
+
107
+ def on_fragment_definition(node, parent)
108
+ on_fragment_with_type(node) do
109
+ @path.push("fragment #{node.name}")
110
+ @in_fragment_def = false
111
+ call_on_enter_fragment_definition(node, parent)
112
+ super
113
+ @in_fragment_def = false
114
+ call_on_leave_fragment_definition(node, parent)
115
+ end
116
+ end
117
+
118
+ def on_inline_fragment(node, parent)
119
+ on_fragment_with_type(node) do
120
+ @path.push("...#{node.type ? " on #{node.type.name}" : ""}")
121
+ @skipping = @skip_stack.last || skip?(node)
122
+ @skip_stack << @skipping
123
+
124
+ call_on_enter_inline_fragment(node, parent)
125
+ super
126
+ @skipping = @skip_stack.pop
127
+ call_on_leave_inline_fragment(node, parent)
128
+ end
129
+ end
130
+
131
+ def on_field(node, parent)
132
+ @response_path.push(node.alias || node.name)
133
+ parent_type = @object_types.last
134
+ # This could be nil if the previous field wasn't found:
135
+ field_definition = parent_type && @types.field(parent_type, node.name)
136
+ @field_definitions.push(field_definition)
137
+ if !field_definition.nil?
138
+ next_object_type = field_definition.type.unwrap
139
+ @object_types.push(next_object_type)
140
+ else
141
+ @object_types.push(nil)
142
+ end
143
+ @path.push(node.alias || node.name)
144
+
145
+ @skipping = @skip_stack.last || skip?(node)
146
+ @skip_stack << @skipping
147
+
148
+ call_on_enter_field(node, parent)
149
+ super
150
+ @skipping = @skip_stack.pop
151
+ call_on_leave_field(node, parent)
152
+ @response_path.pop
153
+ @field_definitions.pop
154
+ @object_types.pop
155
+ @path.pop
156
+ end
157
+
158
+ def on_directive(node, parent)
159
+ directive_defn = @schema.directives[node.name]
160
+ @directive_definitions.push(directive_defn)
161
+ call_on_enter_directive(node, parent)
162
+ super
163
+ call_on_leave_directive(node, parent)
164
+ @directive_definitions.pop
165
+ end
166
+
167
+ def on_argument(node, parent)
168
+ argument_defn = if (arg = @argument_definitions.last)
169
+ arg_type = arg.type.unwrap
170
+ if arg_type.kind.input_object?
171
+ @types.argument(arg_type, node.name)
172
+ else
173
+ nil
174
+ end
175
+ elsif (directive_defn = @directive_definitions.last)
176
+ @types.argument(directive_defn, node.name)
177
+ elsif (field_defn = @field_definitions.last)
178
+ @types.argument(field_defn, node.name)
179
+ else
180
+ nil
181
+ end
182
+
183
+ @argument_definitions.push(argument_defn)
184
+ @path.push(node.name)
185
+ call_on_enter_argument(node, parent)
186
+ super
187
+ call_on_leave_argument(node, parent)
188
+ @argument_definitions.pop
189
+ @path.pop
190
+ end
191
+
192
+ def on_fragment_spread(node, parent)
193
+ @path.push("... #{node.name}")
194
+ @skipping = @skip_stack.last || skip?(node)
195
+ @skip_stack << @skipping
196
+
197
+ call_on_enter_fragment_spread(node, parent)
198
+ enter_fragment_spread_inline(node)
199
+ super
200
+ @skipping = @skip_stack.pop
201
+ leave_fragment_spread_inline(node)
202
+ call_on_leave_fragment_spread(node, parent)
203
+ @path.pop
204
+ end
205
+
206
+ # @return [GraphQL::BaseType] The current object type
207
+ def type_definition
208
+ @object_types.last
209
+ end
210
+
211
+ # @return [GraphQL::BaseType] The type which the current type came from
212
+ def parent_type_definition
213
+ @object_types[-2]
214
+ end
215
+
216
+ # @return [GraphQL::Field, nil] The most-recently-entered GraphQL::Field, if currently inside one
217
+ def field_definition
218
+ @field_definitions.last
219
+ end
220
+
221
+ # @return [GraphQL::Field, nil] The GraphQL field which returned the object that the current field belongs to
222
+ def previous_field_definition
223
+ @field_definitions[-2]
224
+ end
225
+
226
+ # @return [GraphQL::Directive, nil] The most-recently-entered GraphQL::Directive, if currently inside one
227
+ def directive_definition
228
+ @directive_definitions.last
229
+ end
230
+
231
+ # @return [GraphQL::Argument, nil] The most-recently-entered GraphQL::Argument, if currently inside one
232
+ def argument_definition
233
+ @argument_definitions.last
234
+ end
235
+
236
+ # @return [GraphQL::Argument, nil] The previous GraphQL argument
237
+ def previous_argument_definition
238
+ @argument_definitions[-2]
239
+ end
240
+
241
+ private
242
+
243
+ # Visit a fragment spread inline instead of visiting the definition
244
+ # by itself.
245
+ def enter_fragment_spread_inline(fragment_spread)
246
+ fragment_def = query.fragments[fragment_spread.name]
247
+
248
+ object_type = if fragment_def.type
249
+ @types.type(fragment_def.type.name)
250
+ else
251
+ object_types.last
252
+ end
253
+
254
+ object_types << object_type
255
+
256
+ on_fragment_definition_children(fragment_def)
257
+ end
258
+
259
+ # Visit a fragment spread inline instead of visiting the definition
260
+ # by itself.
261
+ def leave_fragment_spread_inline(_fragment_spread)
262
+ object_types.pop
263
+ end
264
+
265
+ def skip?(ast_node)
266
+ dir = ast_node.directives
267
+ dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
268
+ end
269
+
270
+ def on_fragment_with_type(node)
271
+ object_type = if node.type
272
+ @types.type(node.type.name)
273
+ else
274
+ @object_types.last
275
+ end
276
+ @object_types.push(object_type)
277
+ yield(node)
278
+ @object_types.pop
279
+ @path.pop
280
+ end
281
+ end
282
+ end
283
+ end
@@ -1,2 +1,93 @@
1
1
  # frozen_string_literal: true
2
- require "graphql/analysis/ast"
2
+ require "graphql/analysis/visitor"
3
+ require "graphql/analysis/analyzer"
4
+ require "graphql/analysis/field_usage"
5
+ require "graphql/analysis/query_complexity"
6
+ require "graphql/analysis/max_query_complexity"
7
+ require "graphql/analysis/query_depth"
8
+ require "graphql/analysis/max_query_depth"
9
+ require "timeout"
10
+
11
+ module GraphQL
12
+ module Analysis
13
+ AST = self
14
+ module_function
15
+ # Analyze a multiplex, and all queries within.
16
+ # Multiplex analyzers are ran for all queries, keeping state.
17
+ # Query analyzers are ran per query, without carrying state between queries.
18
+ #
19
+ # @param multiplex [GraphQL::Execution::Multiplex]
20
+ # @param analyzers [Array<GraphQL::Analysis::Analyzer>]
21
+ # @return [Array<Any>] Results from multiplex analyzers
22
+ def analyze_multiplex(multiplex, analyzers)
23
+ multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
24
+
25
+ multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
26
+ query_results = multiplex.queries.map do |query|
27
+ if query.valid?
28
+ analyze_query(
29
+ query,
30
+ query.analyzers,
31
+ multiplex_analyzers: multiplex_analyzers
32
+ )
33
+ else
34
+ []
35
+ end
36
+ end
37
+
38
+ multiplex_results = multiplex_analyzers.map(&:result)
39
+ multiplex_errors = analysis_errors(multiplex_results)
40
+
41
+ multiplex.queries.each_with_index do |query, idx|
42
+ query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
43
+ end
44
+ multiplex_results
45
+ end
46
+ end
47
+
48
+ # @param query [GraphQL::Query]
49
+ # @param analyzers [Array<GraphQL::Analysis::Analyzer>]
50
+ # @return [Array<Any>] Results from those analyzers
51
+ def analyze_query(query, analyzers, multiplex_analyzers: [])
52
+ query.current_trace.analyze_query(query: query) do
53
+ query_analyzers = analyzers
54
+ .map { |analyzer| analyzer.new(query) }
55
+ .tap { _1.select!(&:analyze?) }
56
+
57
+ analyzers_to_run = query_analyzers + multiplex_analyzers
58
+ if analyzers_to_run.any?
59
+
60
+ analyzers_to_run.select!(&:visit?)
61
+ if analyzers_to_run.any?
62
+ visitor = GraphQL::Analysis::Visitor.new(
63
+ query: query,
64
+ analyzers: analyzers_to_run
65
+ )
66
+
67
+ # `nil` or `0` causes no timeout
68
+ Timeout::timeout(query.validate_timeout_remaining) do
69
+ visitor.visit
70
+ end
71
+
72
+ if visitor.rescued_errors.any?
73
+ return visitor.rescued_errors
74
+ end
75
+ end
76
+
77
+ query_analyzers.map(&:result)
78
+ else
79
+ []
80
+ end
81
+ end
82
+ rescue Timeout::Error
83
+ [GraphQL::AnalysisError.new("Timeout on validation of query")]
84
+ rescue GraphQL::UnauthorizedError
85
+ # This error was raised during analysis and will be returned the client before execution
86
+ []
87
+ end
88
+
89
+ def analysis_errors(results)
90
+ results.flatten.tap { _1.select! { |r| r.is_a?(GraphQL::AnalysisError) } }
91
+ end
92
+ end
93
+ end
@@ -21,6 +21,7 @@ module GraphQL
21
21
  manager = spawn_fiber do
22
22
  while first_pass || job_fibers.any?
23
23
  first_pass = false
24
+ fiber_vars = get_fiber_variables
24
25
 
25
26
  while (f = (job_fibers.shift || spawn_job_fiber))
26
27
  if f.alive?
@@ -34,6 +35,7 @@ module GraphQL
34
35
  next_job_fibers.clear
35
36
 
36
37
  Sync do |root_task|
38
+ set_fiber_variables(fiber_vars)
37
39
  while source_tasks.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) }
38
40
  while (task = source_tasks.shift || spawn_source_task(root_task, sources_condition))
39
41
  if task.alive?
@@ -160,9 +160,9 @@ module GraphQL
160
160
  case node
161
161
  when GraphQL::Language::Nodes::InlineFragment
162
162
  if node.type
163
- type_defn = schema.get_type(node.type.name, context)
163
+ type_defn = query.types.type(node.type.name)
164
164
 
165
- if query.warden.possible_types(type_defn).include?(owner_type)
165
+ if query.types.possible_types(type_defn).include?(owner_type)
166
166
  result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
167
167
  if !result.equal?(next_selections)
168
168
  selections_to_run = result
@@ -177,8 +177,8 @@ module GraphQL
177
177
  end
178
178
  when GraphQL::Language::Nodes::FragmentSpread
179
179
  fragment_def = query.fragments[node.name]
180
- type_defn = query.get_type(fragment_def.type.name)
181
- if query.warden.possible_types(type_defn).include?(owner_type)
180
+ type_defn = query.types.type(fragment_def.type.name)
181
+ if query.types.possible_types(type_defn).include?(owner_type)
182
182
  result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
183
183
  if !result.equal?(next_selections)
184
184
  selections_to_run = result
@@ -245,7 +245,7 @@ module GraphQL
245
245
  end
246
246
  field_name = ast_node.name
247
247
  owner_type = selections_result.graphql_result_type
248
- field_defn = query.warden.get_field(owner_type, field_name)
248
+ field_defn = query.types.field(owner_type, field_name)
249
249
 
250
250
  # Set this before calling `run_with_directives`, so that the directive can have the latest path
251
251
  runtime_state = get_current_runtime_state
@@ -579,7 +579,7 @@ module GraphQL
579
579
  resolved_value = value
580
580
  end
581
581
 
582
- possible_types = query.possible_types(current_type)
582
+ possible_types = query.types.possible_types(current_type)
583
583
  if !possible_types.include?(resolved_type)
584
584
  parent_type = field.owner_type
585
585
  err_class = current_type::UnresolvedTypeError
@@ -40,7 +40,7 @@ module GraphQL
40
40
  lazies_at_depth = Hash.new { |h, k| h[k] = [] }
41
41
  multiplex_analyzers = schema.multiplex_analyzers
42
42
  if multiplex.max_complexity
43
- multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
43
+ multiplex_analyzers += [GraphQL::Analysis::MaxQueryComplexity]
44
44
  end
45
45
 
46
46
  schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
@@ -108,16 +108,16 @@ module GraphQL
108
108
  def selection(field_name, selected_type: @selected_type, arguments: nil)
109
109
  next_field_defn = case field_name
110
110
  when String
111
- @query.get_field(selected_type, field_name)
111
+ @query.types.field(selected_type, field_name)
112
112
  when Symbol
113
113
  # Try to avoid the `.to_s` below, if possible
114
114
  all_fields = if selected_type.kind.fields?
115
- @query.warden.fields(selected_type)
115
+ @query.types.fields(selected_type)
116
116
  else
117
117
  # Handle unions by checking possible
118
- @query.warden
118
+ @query.types
119
119
  .possible_types(selected_type)
120
- .map { |t| @query.warden.fields(t) }
120
+ .map { |t| @query.types.fields(t) }
121
121
  .tap(&:flatten!)
122
122
  end
123
123
 
@@ -128,7 +128,7 @@ module GraphQL
128
128
  # Symbol#name is only present on 3.0+
129
129
  sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
130
130
  guessed_name = Schema::Member::BuildType.camelize(sym_s)
131
- @query.get_field(selected_type, guessed_name)
131
+ @query.types.field(selected_type, guessed_name)
132
132
  end
133
133
  end
134
134
  lookahead_for_selection(next_field_defn, selected_type, arguments)
@@ -144,7 +144,7 @@ module GraphQL
144
144
  alias_node = lookup_alias_node(ast_nodes, alias_name)
145
145
  return NULL_LOOKAHEAD unless alias_node
146
146
 
147
- next_field_defn = @query.get_field(selected_type, alias_node.name)
147
+ next_field_defn = @query.types.field(selected_type, alias_node.name)
148
148
 
149
149
  alias_arguments = @query.arguments_for(alias_node, next_field_defn)
150
150
  if alias_arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments)
@@ -183,7 +183,7 @@ module GraphQL
183
183
 
184
184
  subselections_by_type.each do |type, ast_nodes_by_response_key|
185
185
  ast_nodes_by_response_key.each do |response_key, ast_nodes|
186
- field_defn = @query.get_field(type, ast_nodes.first.name)
186
+ field_defn = @query.types.field(type, ast_nodes.first.name)
187
187
  lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
188
188
  subselections.push(lookahead)
189
189
  end
@@ -266,7 +266,7 @@ module GraphQL
266
266
  elsif arguments.nil? || arguments.empty?
267
267
  selections_on_type[response_key] = [ast_selection]
268
268
  else
269
- field_defn = @query.get_field(selected_type, ast_selection.name)
269
+ field_defn = @query.types.field(selected_type, ast_selection.name)
270
270
  if arguments_match?(arguments, field_defn, ast_selection)
271
271
  selections_on_type[response_key] = [ast_selection]
272
272
  end
@@ -276,14 +276,14 @@ module GraphQL
276
276
  subselections_on_type = selections_on_type
277
277
  if (t = ast_selection.type)
278
278
  # Assuming this is valid, that `t` will be found.
279
- on_type = @query.get_type(t.name)
279
+ on_type = @query.types.type(t.name)
280
280
  subselections_on_type = subselections_by_type[on_type] ||= {}
281
281
  end
282
282
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
283
283
  when GraphQL::Language::Nodes::FragmentSpread
284
284
  frag_defn = lookup_fragment(ast_selection)
285
285
  # Again, assuming a valid AST
286
- on_type = @query.get_type(frag_defn.type.name)
286
+ on_type = @query.types.type(frag_defn.type.name)
287
287
  subselections_on_type = subselections_by_type[on_type] ||= {}
288
288
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
289
289
  else
@@ -22,7 +22,7 @@ module GraphQL
22
22
  field :is_repeatable, Boolean, method: :repeatable?
23
23
 
24
24
  def args(include_deprecated:)
25
- args = @context.warden.arguments(@object)
25
+ args = @context.types.arguments(@object)
26
26
  args = args.reject(&:deprecation_reason) unless include_deprecated
27
27
  args
28
28
  end
@@ -15,8 +15,8 @@ module GraphQL
15
15
  end
16
16
 
17
17
  def __type(name:)
18
- if context.warden.reachable_type?(name)
19
- context.warden.get_type(name)
18
+ if context.types.reachable_type?(name)
19
+ context.types.type(name)
20
20
  elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
21
21
  type
22
22
  else
@@ -19,7 +19,7 @@ module GraphQL
19
19
  end
20
20
 
21
21
  def args(include_deprecated:)
22
- args = @context.warden.arguments(@object)
22
+ args = @context.types.arguments(@object)
23
23
  args = args.reject(&:deprecation_reason) unless include_deprecated
24
24
  args
25
25
  end
@@ -20,7 +20,8 @@ module GraphQL
20
20
  end
21
21
 
22
22
  def types
23
- types = context.warden.reachable_types + context.schema.extra_types
23
+ query_types = context.types.all_types
24
+ types = query_types + context.schema.extra_types
24
25
  types.sort_by!(&:graphql_name)
25
26
  types
26
27
  end
@@ -38,13 +39,22 @@ module GraphQL
38
39
  end
39
40
 
40
41
  def directives
41
- @context.warden.directives
42
+ @context.types.directives
42
43
  end
43
44
 
44
45
  private
45
46
 
46
47
  def permitted_root_type(op_type)
47
- @context.warden.root_type_for_operation(op_type)
48
+ case op_type
49
+ when "query"
50
+ @context.types.query_root
51
+ when "mutation"
52
+ @context.types.mutation_root
53
+ when "subcription"
54
+ @context.types.subscription_root
55
+ else
56
+ nil
57
+ end
48
58
  end
49
59
  end
50
60
  end
@@ -52,7 +52,7 @@ module GraphQL
52
52
  if !@object.kind.enum?
53
53
  nil
54
54
  else
55
- enum_values = @context.warden.enum_values(@object)
55
+ enum_values = @context.types.enum_values(@object)
56
56
 
57
57
  if !include_deprecated
58
58
  enum_values = enum_values.select {|f| !f.deprecation_reason }
@@ -64,7 +64,7 @@ module GraphQL
64
64
 
65
65
  def interfaces
66
66
  if @object.kind.object? || @object.kind.interface?
67
- @context.warden.interfaces(@object).sort_by(&:graphql_name)
67
+ @context.types.interfaces(@object).sort_by(&:graphql_name)
68
68
  else
69
69
  nil
70
70
  end
@@ -72,7 +72,7 @@ module GraphQL
72
72
 
73
73
  def input_fields(include_deprecated:)
74
74
  if @object.kind.input_object?
75
- args = @context.warden.arguments(@object)
75
+ args = @context.types.arguments(@object)
76
76
  args = args.reject(&:deprecation_reason) unless include_deprecated
77
77
  args
78
78
  else
@@ -82,7 +82,7 @@ module GraphQL
82
82
 
83
83
  def possible_types
84
84
  if @object.kind.abstract?
85
- @context.warden.possible_types(@object).sort_by(&:graphql_name)
85
+ @context.types.possible_types(@object).sort_by(&:graphql_name)
86
86
  else
87
87
  nil
88
88
  end
@@ -92,7 +92,7 @@ module GraphQL
92
92
  if !@object.kind.fields?
93
93
  nil
94
94
  else
95
- fields = @context.warden.fields(@object)
95
+ fields = @context.types.fields(@object)
96
96
  if !include_deprecated
97
97
  fields = fields.select {|f| !f.deprecation_reason }
98
98
  end