graphql 2.3.5 → 2.3.11

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +46 -0
  3. data/lib/graphql/analysis/analyzer.rb +89 -0
  4. data/lib/graphql/analysis/field_usage.rb +82 -0
  5. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  6. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  7. data/lib/graphql/analysis/query_complexity.rb +183 -0
  8. data/lib/graphql/analysis/{ast/query_depth.rb → query_depth.rb} +23 -25
  9. data/lib/graphql/analysis/visitor.rb +283 -0
  10. data/lib/graphql/analysis.rb +92 -1
  11. data/lib/graphql/current.rb +52 -0
  12. data/lib/graphql/dataloader/async_dataloader.rb +2 -0
  13. data/lib/graphql/dataloader/source.rb +5 -2
  14. data/lib/graphql/dataloader.rb +4 -1
  15. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  16. data/lib/graphql/execution/interpreter/runtime.rb +8 -14
  17. data/lib/graphql/execution/interpreter.rb +3 -1
  18. data/lib/graphql/execution/lookahead.rb +10 -10
  19. data/lib/graphql/introspection/directive_type.rb +1 -1
  20. data/lib/graphql/introspection/entry_points.rb +2 -2
  21. data/lib/graphql/introspection/field_type.rb +1 -1
  22. data/lib/graphql/introspection/schema_type.rb +6 -11
  23. data/lib/graphql/introspection/type_type.rb +5 -5
  24. data/lib/graphql/language/document_from_schema_definition.rb +19 -26
  25. data/lib/graphql/language/lexer.rb +0 -3
  26. data/lib/graphql/language/nodes.rb +2 -2
  27. data/lib/graphql/language/parser.rb +9 -1
  28. data/lib/graphql/language/sanitized_printer.rb +1 -1
  29. data/lib/graphql/language.rb +0 -1
  30. data/lib/graphql/query/context.rb +7 -1
  31. data/lib/graphql/query/null_context.rb +2 -2
  32. data/lib/graphql/query/validation_pipeline.rb +2 -2
  33. data/lib/graphql/query.rb +26 -7
  34. data/lib/graphql/schema/always_visible.rb +1 -0
  35. data/lib/graphql/schema/argument.rb +19 -5
  36. data/lib/graphql/schema/build_from_definition.rb +8 -1
  37. data/lib/graphql/schema/directive/flagged.rb +1 -1
  38. data/lib/graphql/schema/directive.rb +2 -0
  39. data/lib/graphql/schema/enum.rb +9 -5
  40. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  41. data/lib/graphql/schema/field.rb +13 -1
  42. data/lib/graphql/schema/has_single_input_argument.rb +2 -1
  43. data/lib/graphql/schema/input_object.rb +8 -7
  44. data/lib/graphql/schema/interface.rb +20 -4
  45. data/lib/graphql/schema/introspection_system.rb +5 -16
  46. data/lib/graphql/schema/member/has_arguments.rb +14 -9
  47. data/lib/graphql/schema/member/has_fields.rb +6 -4
  48. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  49. data/lib/graphql/schema/resolver.rb +5 -5
  50. data/lib/graphql/schema/subset.rb +510 -0
  51. data/lib/graphql/schema/type_expression.rb +2 -2
  52. data/lib/graphql/schema/types_migration.rb +185 -0
  53. data/lib/graphql/schema/validator/all_validator.rb +60 -0
  54. data/lib/graphql/schema/validator.rb +2 -0
  55. data/lib/graphql/schema/warden.rb +89 -5
  56. data/lib/graphql/schema.rb +74 -37
  57. data/lib/graphql/static_validation/base_visitor.rb +6 -5
  58. data/lib/graphql/static_validation/literal_validator.rb +4 -4
  59. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  60. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  61. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
  62. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  63. data/lib/graphql/static_validation/rules/fields_will_merge.rb +7 -7
  64. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  65. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  66. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  67. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  68. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  69. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +3 -3
  70. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  71. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  72. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  73. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  74. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  75. data/lib/graphql/static_validation/validation_context.rb +2 -2
  76. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  77. data/lib/graphql/subscriptions/event.rb +1 -1
  78. data/lib/graphql/subscriptions.rb +3 -3
  79. data/lib/graphql/testing/helpers.rb +8 -5
  80. data/lib/graphql/types/relay/connection_behaviors.rb +10 -0
  81. data/lib/graphql/types/relay/edge_behaviors.rb +10 -0
  82. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  83. data/lib/graphql/version.rb +1 -1
  84. data/lib/graphql.rb +1 -0
  85. metadata +14 -13
  86. data/lib/graphql/analysis/ast/analyzer.rb +0 -91
  87. data/lib/graphql/analysis/ast/field_usage.rb +0 -84
  88. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  89. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  90. data/lib/graphql/analysis/ast/query_complexity.rb +0 -185
  91. data/lib/graphql/analysis/ast/visitor.rb +0 -284
  92. data/lib/graphql/analysis/ast.rb +0 -94
  93. data/lib/graphql/language/token.rb +0 -34
  94. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ class Validator
6
+ # Use this to validate each member of an array value.
7
+ #
8
+ # @example validate format of all strings in an array
9
+ #
10
+ # argument :handles, [String],
11
+ # validates: { all: { format: { with: /\A[a-z0-9_]+\Z/ } } }
12
+ #
13
+ # @example multiple validators can be combined
14
+ #
15
+ # argument :handles, [String],
16
+ # validates: { all: { format: { with: /\A[a-z0-9_]+\Z/ }, length: { maximum: 32 } } }
17
+ #
18
+ # @example any type can be used
19
+ #
20
+ # argument :choices, [Integer],
21
+ # validates: { all: { inclusion: { in: 1..12 } } }
22
+ #
23
+ class AllValidator < Validator
24
+ def initialize(validated:, allow_blank: false, allow_null: false, **validators)
25
+ super(validated: validated, allow_blank: allow_blank, allow_null: allow_null)
26
+
27
+ @validators = Validator.from_config(validated, validators)
28
+ end
29
+
30
+ def validate(object, context, value)
31
+ all_errors = EMPTY_ARRAY
32
+
33
+ value.each do |subvalue|
34
+ @validators.each do |validator|
35
+ errors = validator.validate(object, context, subvalue)
36
+ if errors &&
37
+ (errors.is_a?(Array) && errors != EMPTY_ARRAY) ||
38
+ (errors.is_a?(String))
39
+ if all_errors.frozen? # It's empty
40
+ all_errors = []
41
+ end
42
+ if errors.is_a?(String)
43
+ all_errors << errors
44
+ else
45
+ all_errors.concat(errors)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ unless all_errors.frozen?
52
+ all_errors.uniq!
53
+ end
54
+
55
+ all_errors
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -169,3 +169,5 @@ require "graphql/schema/validator/allow_null_validator"
169
169
  GraphQL::Schema::Validator.install(:allow_null, GraphQL::Schema::Validator::AllowNullValidator)
170
170
  require "graphql/schema/validator/allow_blank_validator"
171
171
  GraphQL::Schema::Validator.install(:allow_blank, GraphQL::Schema::Validator::AllowBlankValidator)
172
+ require "graphql/schema/validator/all_validator"
173
+ GraphQL::Schema::Validator.install(:all, GraphQL::Schema::Validator::AllValidator)
@@ -61,14 +61,27 @@ module GraphQL
61
61
  def interface_type_memberships(obj_t, ctx); obj_t.interface_type_memberships; end
62
62
  def arguments(owner, ctx); owner.arguments(ctx); end
63
63
  def loadable?(type, ctx); type.visible?(ctx); end
64
+ def schema_subset
65
+ @schema_subset ||= Warden::SchemaSubset.new(self)
66
+ end
64
67
  end
65
68
  end
66
69
 
67
70
  class NullWarden
68
71
  def initialize(_filter = nil, context:, schema:)
69
72
  @schema = schema
73
+ @schema_subset = Warden::SchemaSubset.new(self)
74
+ end
75
+
76
+ # @api private
77
+ module NullSubset
78
+ def self.new(context:, schema:)
79
+ NullWarden.new(context: context, schema: schema).schema_subset
80
+ end
70
81
  end
71
82
 
83
+ attr_reader :schema_subset
84
+
72
85
  def visible_field?(field_defn, _ctx = nil, owner = nil); true; end
73
86
  def visible_argument?(arg_defn, _ctx = nil); true; end
74
87
  def visible_type?(type_defn, _ctx = nil); true; end
@@ -91,6 +104,80 @@ module GraphQL
91
104
  def interfaces(obj_type); obj_type.interfaces; end
92
105
  end
93
106
 
107
+ def schema_subset
108
+ @schema_subset ||= SchemaSubset.new(self)
109
+ end
110
+
111
+ class SchemaSubset
112
+ def initialize(warden)
113
+ @warden = warden
114
+ end
115
+
116
+ def directives
117
+ @warden.directives
118
+ end
119
+
120
+ def directive_exists?(dir_name)
121
+ @warden.directives.any? { |d| d.graphql_name == dir_name }
122
+ end
123
+
124
+ def type(name)
125
+ @warden.get_type(name)
126
+ end
127
+
128
+ def field(owner, field_name)
129
+ @warden.get_field(owner, field_name)
130
+ end
131
+
132
+ def argument(owner, arg_name)
133
+ @warden.get_argument(owner, arg_name)
134
+ end
135
+
136
+ def query_root
137
+ @warden.root_type_for_operation("query")
138
+ end
139
+
140
+ def mutation_root
141
+ @warden.root_type_for_operation("mutation")
142
+ end
143
+
144
+ def subscription_root
145
+ @warden.root_type_for_operation("subscription")
146
+ end
147
+
148
+ def arguments(owner)
149
+ @warden.arguments(owner)
150
+ end
151
+
152
+ def fields(owner)
153
+ @warden.fields(owner)
154
+ end
155
+
156
+ def possible_types(type)
157
+ @warden.possible_types(type)
158
+ end
159
+
160
+ def enum_values(enum_type)
161
+ @warden.enum_values(enum_type)
162
+ end
163
+
164
+ def all_types
165
+ @warden.reachable_types
166
+ end
167
+
168
+ def interfaces(obj_type)
169
+ @warden.interfaces(obj_type)
170
+ end
171
+
172
+ def loadable?(t, ctx) # TODO remove ctx here?
173
+ @warden.loadable?(t, ctx)
174
+ end
175
+
176
+ def reachable_type?(type_name)
177
+ !!@warden.reachable_type?(type_name)
178
+ end
179
+ end
180
+
94
181
  # @param context [GraphQL::Query::Context]
95
182
  # @param schema [GraphQL::Schema]
96
183
  def initialize(context:, schema:)
@@ -101,13 +188,12 @@ module GraphQL
101
188
  @subscription = @schema.subscription
102
189
  @context = context
103
190
  @visibility_cache = read_through { |m| schema.visible?(m, context) }
104
- @visibility_cache.compare_by_identity
105
191
  # Initialize all ivars to improve object shape consistency:
106
192
  @types = @visible_types = @reachable_types = @visible_parent_fields =
107
193
  @visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays =
108
194
  @visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships =
109
195
  @visible_and_reachable_type = @unions = @unfiltered_interfaces =
110
- @reachable_type_set =
196
+ @reachable_type_set = @schema_subset =
111
197
  nil
112
198
  end
113
199
 
@@ -376,9 +462,7 @@ module GraphQL
376
462
  end
377
463
 
378
464
  def read_through
379
- h = Hash.new { |h, k| h[k] = yield(k) }
380
- h.compare_by_identity
381
- h
465
+ Hash.new { |h, k| h[k] = yield(k) }.compare_by_identity
382
466
  end
383
467
 
384
468
  def reachable_type_set
@@ -5,7 +5,6 @@ require "graphql/schema/always_visible"
5
5
  require "graphql/schema/base_64_encoder"
6
6
  require "graphql/schema/find_inherited_value"
7
7
  require "graphql/schema/finder"
8
- require "graphql/schema/invalid_type_error"
9
8
  require "graphql/schema/introspection_system"
10
9
  require "graphql/schema/late_bound_type"
11
10
  require "graphql/schema/null_mask"
@@ -46,6 +45,8 @@ require "graphql/schema/mutation"
46
45
  require "graphql/schema/has_single_input_argument"
47
46
  require "graphql/schema/relay_classic_mutation"
48
47
  require "graphql/schema/subscription"
48
+ require "graphql/schema/subset"
49
+ require "graphql/schema/types_migration"
49
50
 
50
51
  module GraphQL
51
52
  # A GraphQL schema which may be queried with {GraphQL::Query}.
@@ -338,6 +339,9 @@ module GraphQL
338
339
  # @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
339
340
  # @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
340
341
  def types(context = GraphQL::Query::NullContext.instance)
342
+ if use_schema_subset?
343
+ return Subset.from_context(context, self).all_types_h
344
+ end
341
345
  all_types = non_introspection_types.merge(introspection_system.types)
342
346
  visible_types = {}
343
347
  all_types.each do |k, v|
@@ -365,25 +369,32 @@ module GraphQL
365
369
  # @param type_name [String]
366
370
  # @return [Module, nil] A type, or nil if there's no type called `type_name`
367
371
  def get_type(type_name, context = GraphQL::Query::NullContext.instance)
372
+ if use_schema_subset?
373
+ return Subset.from_context(context, self).type(type_name)
374
+ end
368
375
  local_entry = own_types[type_name]
369
376
  type_defn = case local_entry
370
377
  when nil
371
378
  nil
372
379
  when Array
373
- visible_t = nil
374
- warden = Warden.from_context(context)
375
- local_entry.each do |t|
376
- if warden.visible_type?(t, context)
377
- if visible_t.nil?
378
- visible_t = t
379
- else
380
- raise DuplicateNamesError.new(
381
- duplicated_name: type_name, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect
382
- )
380
+ if context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Subset)
381
+ local_entry
382
+ else
383
+ visible_t = nil
384
+ warden = Warden.from_context(context)
385
+ local_entry.each do |t|
386
+ if warden.visible_type?(t, context)
387
+ if visible_t.nil?
388
+ visible_t = t
389
+ else
390
+ raise DuplicateNamesError.new(
391
+ duplicated_name: type_name, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect
392
+ )
393
+ end
383
394
  end
384
395
  end
396
+ visible_t
385
397
  end
386
- visible_t
387
398
  when Module
388
399
  local_entry
389
400
  else
@@ -419,17 +430,13 @@ module GraphQL
419
430
  end
420
431
  end
421
432
 
422
- def new_connections?
423
- !!connections
424
- end
425
-
426
433
  def query(new_query_object = nil)
427
434
  if new_query_object
428
435
  if @query_object
429
436
  raise GraphQL::Error, "Second definition of `query(...)` (#{new_query_object.inspect}) is invalid, already configured with #{@query_object.inspect}"
430
437
  else
431
438
  @query_object = new_query_object
432
- add_type_and_traverse(new_query_object, root: true)
439
+ add_type_and_traverse(new_query_object, root: true) unless use_schema_subset?
433
440
  nil
434
441
  end
435
442
  else
@@ -443,7 +450,7 @@ module GraphQL
443
450
  raise GraphQL::Error, "Second definition of `mutation(...)` (#{new_mutation_object.inspect}) is invalid, already configured with #{@mutation_object.inspect}"
444
451
  else
445
452
  @mutation_object = new_mutation_object
446
- add_type_and_traverse(new_mutation_object, root: true)
453
+ add_type_and_traverse(new_mutation_object, root: true) unless use_schema_subset?
447
454
  nil
448
455
  end
449
456
  else
@@ -458,7 +465,7 @@ module GraphQL
458
465
  else
459
466
  @subscription_object = new_subscription_object
460
467
  add_subscription_extension_if_necessary
461
- add_type_and_traverse(new_subscription_object, root: true)
468
+ add_type_and_traverse(new_subscription_object, root: true) unless use_schema_subset?
462
469
  nil
463
470
  end
464
471
  else
@@ -482,7 +489,11 @@ module GraphQL
482
489
  end
483
490
 
484
491
  def root_types
485
- @root_types
492
+ if use_schema_subset?
493
+ [query, mutation, subscription].compact
494
+ else
495
+ @root_types
496
+ end
486
497
  end
487
498
 
488
499
  def warden_class
@@ -497,10 +508,39 @@ module GraphQL
497
508
 
498
509
  attr_writer :warden_class
499
510
 
511
+ def subset_class
512
+ if defined?(@subset_class)
513
+ @subset_class
514
+ elsif superclass.respond_to?(:subset_class)
515
+ superclass.subset_class
516
+ else
517
+ GraphQL::Schema::Subset
518
+ end
519
+ end
520
+
521
+ attr_writer :subset_class, :use_schema_subset
522
+
523
+ def use_schema_subset?
524
+ if defined?(@use_schema_subset)
525
+ @use_schema_subset
526
+ elsif superclass.respond_to?(:use_schema_subset?)
527
+ superclass.use_schema_subset?
528
+ else
529
+ false
530
+ end
531
+ end
532
+
500
533
  # @param type [Module] The type definition whose possible types you want to see
501
534
  # @return [Hash<String, Module>] All possible types, if no `type` is given.
502
535
  # @return [Array<Module>] Possible types for `type`, if it's given.
503
536
  def possible_types(type = nil, context = GraphQL::Query::NullContext.instance)
537
+ if use_schema_subset?
538
+ if type
539
+ return Subset.from_context(context, self).possible_types(type)
540
+ else
541
+ raise "Schema.possible_types is not implemented for `use_schema_subset?`"
542
+ end
543
+ end
504
544
  if type
505
545
  # TODO duck-typing `.possible_types` would probably be nicer here
506
546
  if type.kind.union?
@@ -573,9 +613,8 @@ module GraphQL
573
613
  end
574
614
  end
575
615
 
576
- def type_from_ast(ast_node, context: nil)
577
- type_owner = context ? context.warden : self
578
- GraphQL::Schema::TypeExpression.build_type(type_owner, ast_node)
616
+ def type_from_ast(ast_node, context: self.query_class.new(self, "{ __typename }").context)
617
+ GraphQL::Schema::TypeExpression.build_type(context.query.types, ast_node)
579
618
  end
580
619
 
581
620
  def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext.instance)
@@ -769,16 +808,6 @@ module GraphQL
769
808
  @analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine)
770
809
  end
771
810
 
772
- def using_ast_analysis?
773
- true
774
- end
775
-
776
- def interpreter?
777
- true
778
- end
779
-
780
- attr_writer :interpreter
781
-
782
811
  def error_bubbling(new_error_bubbling = nil)
783
812
  if !new_error_bubbling.nil?
784
813
  warn("error_bubbling(#{new_error_bubbling.inspect}) is deprecated; the default value of `false` will be the only option in GraphQL-Ruby 3.0")
@@ -887,7 +916,7 @@ module GraphQL
887
916
  To add other types to your schema, you might want `extra_types`: https://graphql-ruby.org/schema/definition.html#extra-types
888
917
  ERR
889
918
  end
890
- add_type_and_traverse(new_orphan_types, root: false)
919
+ add_type_and_traverse(new_orphan_types, root: false) unless use_schema_subset?
891
920
  own_orphan_types.concat(new_orphan_types.flatten)
892
921
  end
893
922
 
@@ -1053,6 +1082,10 @@ module GraphQL
1053
1082
  Member::HasDirectives.get_directives(self, @own_schema_directives, :schema_directives)
1054
1083
  end
1055
1084
 
1085
+ # Called when a type is needed by name at runtime
1086
+ def load_type(type_name, ctx)
1087
+ get_type(type_name, ctx)
1088
+ end
1056
1089
  # This hook is called when an object fails an `authorized?` check.
1057
1090
  # You might report to your bug tracker here, so you can correct
1058
1091
  # the field resolvers not to return unauthorized objects.
@@ -1142,7 +1175,11 @@ module GraphQL
1142
1175
  # @param new_directive [Class]
1143
1176
  # @return void
1144
1177
  def directive(new_directive)
1145
- add_type_and_traverse(new_directive, root: false)
1178
+ if use_schema_subset?
1179
+ own_directives[new_directive.graphql_name] = new_directive
1180
+ else
1181
+ add_type_and_traverse(new_directive, root: false)
1182
+ end
1146
1183
  end
1147
1184
 
1148
1185
  def default_directives
@@ -1485,7 +1522,7 @@ module GraphQL
1485
1522
  end
1486
1523
 
1487
1524
  def own_references_to
1488
- @own_references_to ||= {}.tap(&:compare_by_identity)
1525
+ @own_references_to ||= {}.compare_by_identity
1489
1526
  end
1490
1527
 
1491
1528
  def non_introspection_types
@@ -1501,7 +1538,7 @@ module GraphQL
1501
1538
  end
1502
1539
 
1503
1540
  def own_possible_types
1504
- @own_possible_types ||= {}.tap(&:compare_by_identity)
1541
+ @own_possible_types ||= {}.compare_by_identity
1505
1542
  end
1506
1543
 
1507
1544
  def own_union_memberships
@@ -10,6 +10,7 @@ module GraphQL
10
10
  @argument_definitions = []
11
11
  @directive_definitions = []
12
12
  @context = context
13
+ @types = context.query.types
13
14
  @schema = context.schema
14
15
  super(document)
15
16
  end
@@ -77,7 +78,7 @@ module GraphQL
77
78
 
78
79
  def on_field(node, parent)
79
80
  parent_type = @object_types.last
80
- field_definition = @schema.get_field(parent_type, node.name, @context.query.context)
81
+ field_definition = @types.field(parent_type, node.name)
81
82
  @field_definitions.push(field_definition)
82
83
  if !field_definition.nil?
83
84
  next_object_type = field_definition.type.unwrap
@@ -103,14 +104,14 @@ module GraphQL
103
104
  argument_defn = if (arg = @argument_definitions.last)
104
105
  arg_type = arg.type.unwrap
105
106
  if arg_type.kind.input_object?
106
- @context.warden.get_argument(arg_type, node.name)
107
+ @types.argument(arg_type, node.name)
107
108
  else
108
109
  nil
109
110
  end
110
111
  elsif (directive_defn = @directive_definitions.last)
111
- @context.warden.get_argument(directive_defn, node.name)
112
+ @types.argument(directive_defn, node.name)
112
113
  elsif (field_defn = @field_definitions.last)
113
- @context.warden.get_argument(field_defn, node.name)
114
+ @types.argument(field_defn, node.name)
114
115
  else
115
116
  nil
116
117
  end
@@ -170,7 +171,7 @@ module GraphQL
170
171
 
171
172
  def on_fragment_with_type(node)
172
173
  object_type = if node.type
173
- @context.warden.get_type(node.type.name)
174
+ @types.type(node.type.name)
174
175
  else
175
176
  @object_types.last
176
177
  end
@@ -5,7 +5,7 @@ module GraphQL
5
5
  class LiteralValidator
6
6
  def initialize(context:)
7
7
  @context = context
8
- @warden = context.warden
8
+ @types = context.types
9
9
  @invalid_response = GraphQL::Query::InputValidationResult.new(valid: false, problems: [])
10
10
  @valid_response = GraphQL::Query::InputValidationResult.new(valid: true, problems: [])
11
11
  end
@@ -109,7 +109,7 @@ module GraphQL
109
109
  def required_input_fields_are_present(type, ast_node)
110
110
  # TODO - would be nice to use these to create an error message so the caller knows
111
111
  # that required fields are missing
112
- required_field_names = @warden.arguments(type)
112
+ required_field_names = @types.arguments(type)
113
113
  .select { |argument| argument.type.kind.non_null? && !argument.default_value? }
114
114
  .map!(&:name)
115
115
 
@@ -119,7 +119,7 @@ module GraphQL
119
119
  missing_required_field_names.empty? ? @valid_response : @invalid_response
120
120
  else
121
121
  results = missing_required_field_names.map do |name|
122
- arg_type = @warden.get_argument(type, name).type
122
+ arg_type = @types.argument(type, name).type
123
123
  recursively_validate(GraphQL::Language::Nodes::NullValue.new(name: name), arg_type)
124
124
  end
125
125
  if type.one_of? && ast_node.arguments.size != 1
@@ -131,7 +131,7 @@ module GraphQL
131
131
 
132
132
  def present_input_field_values_are_valid(type, ast_node)
133
133
  results = ast_node.arguments.map do |value|
134
- field = @warden.get_argument(type, value.name)
134
+ field = @types.argument(type, value.name)
135
135
  # we want to call validate on an argument even if it's an invalid one
136
136
  # so that our raise exception is on it instead of the entire InputObject
137
137
  field_type = field && field.type
@@ -15,7 +15,7 @@ module GraphQL
15
15
  if @context.schema.error_bubbling || context.errors.none? { |err| err.path.take(@path.size) == @path }
16
16
  parent_defn = parent_definition(parent)
17
17
 
18
- if parent_defn && (arg_defn = context.warden.get_argument(parent_defn, node.name))
18
+ if parent_defn && (arg_defn = @types.argument(parent_defn, node.name))
19
19
  validation_result = context.validate_literal(node.value, arg_defn.type)
20
20
  if !validation_result.valid?
21
21
  kind_of_node = node_type(parent)
@@ -5,7 +5,7 @@ module GraphQL
5
5
  def on_argument(node, parent)
6
6
  parent_defn = parent_definition(parent)
7
7
 
8
- if parent_defn && context.warden.get_argument(parent_defn, node.name)
8
+ if parent_defn && @types.argument(parent_defn, node.name)
9
9
  super
10
10
  elsif parent_defn
11
11
  kind_of_node = node_type(parent)
@@ -4,11 +4,10 @@ module GraphQL
4
4
  module DirectivesAreDefined
5
5
  def initialize(*)
6
6
  super
7
- @directive_names = context.warden.directives.map(&:graphql_name)
8
7
  end
9
8
 
10
9
  def on_directive(node, parent)
11
- if !@directive_names.include?(node.name)
10
+ if !@types.directive_exists?(node.name)
12
11
  @directives_are_defined_errors_by_name ||= {}
13
12
  error = @directives_are_defined_errors_by_name[node.name] ||= begin
14
13
  err = GraphQL::StaticValidation::DirectivesAreDefinedError.new(
@@ -4,7 +4,7 @@ module GraphQL
4
4
  module FieldsAreDefinedOnType
5
5
  def on_field(node, parent)
6
6
  parent_type = @object_types[-2]
7
- field = context.warden.get_field(parent_type, node.name)
7
+ field = context.query.types.field(parent_type, node.name)
8
8
 
9
9
  if field.nil?
10
10
  if parent_type.kind.union?
@@ -117,8 +117,8 @@ module GraphQL
117
117
 
118
118
  return if fragment1.nil? || fragment2.nil?
119
119
 
120
- fragment_type1 = context.warden.get_type(fragment1.type.name)
121
- fragment_type2 = context.warden.get_type(fragment2.type.name)
120
+ fragment_type1 = context.query.types.type(fragment1.type.name)
121
+ fragment_type2 = context.query.types.type(fragment2.type.name)
122
122
 
123
123
  return if fragment_type1.nil? || fragment_type2.nil?
124
124
 
@@ -170,7 +170,7 @@ module GraphQL
170
170
  fragment = context.fragments[fragment_name]
171
171
  return if fragment.nil?
172
172
 
173
- fragment_type = context.warden.get_type(fragment.type.name)
173
+ fragment_type = @types.type(fragment.type.name)
174
174
  return if fragment_type.nil?
175
175
 
176
176
  fragment_fields, fragment_spreads = fields_and_fragments_from_selection(fragment, owner_type: fragment_type, parents: [*fragment_spread.parents, fragment_type])
@@ -340,10 +340,10 @@ module GraphQL
340
340
  selections.each do |node|
341
341
  case node
342
342
  when GraphQL::Language::Nodes::Field
343
- definition = context.warden.get_field(owner_type, node.name)
343
+ definition = @types.field(owner_type, node.name)
344
344
  fields << Field.new(node, definition, owner_type, parents)
345
345
  when GraphQL::Language::Nodes::InlineFragment
346
- fragment_type = node.type ? context.warden.get_type(node.type.name) : owner_type
346
+ fragment_type = node.type ? @types.type(node.type.name) : owner_type
347
347
  find_fields_and_fragments(node.selections, parents: [*parents, fragment_type], owner_type: owner_type, fields: fields, fragment_spreads: fragment_spreads) if fragment_type
348
348
  when GraphQL::Language::Nodes::FragmentSpread
349
349
  fragment_spreads << FragmentSpread.new(node.name, parents)
@@ -411,8 +411,8 @@ module GraphQL
411
411
  false
412
412
  else
413
413
  # Check if these two scopes have _any_ types in common.
414
- possible_right_types = context.query.possible_types(type1)
415
- possible_left_types = context.query.possible_types(type2)
414
+ possible_right_types = context.types.possible_types(type1)
415
+ possible_left_types = context.types.possible_types(type2)
416
416
  (possible_right_types & possible_left_types).empty?
417
417
  end
418
418
  end
@@ -28,7 +28,7 @@ module GraphQL
28
28
  frag_node = context.fragments[frag_spread.node.name]
29
29
  if frag_node
30
30
  fragment_child_name = frag_node.type.name
31
- fragment_child = context.warden.get_type(fragment_child_name)
31
+ fragment_child = @types.type(fragment_child_name)
32
32
  # Might be non-existent type name
33
33
  if fragment_child
34
34
  validate_fragment_in_scope(frag_spread.parent_type, fragment_child, frag_spread.node, context, frag_spread.path)
@@ -44,8 +44,8 @@ module GraphQL
44
44
  # It's not a valid fragment type, this error was handled someplace else
45
45
  return
46
46
  end
47
- parent_types = context.warden.possible_types(parent_type.unwrap)
48
- child_types = context.warden.possible_types(child_type.unwrap)
47
+ parent_types = @types.possible_types(parent_type.unwrap)
48
+ child_types = @types.possible_types(child_type.unwrap)
49
49
 
50
50
  if child_types.none? { |c| parent_types.include?(c) }
51
51
  name = node.respond_to?(:name) ? " #{node.name}" : ""
@@ -21,7 +21,7 @@ module GraphQL
21
21
  true
22
22
  else
23
23
  type_name = fragment_node.type.name
24
- type = context.warden.get_type(type_name)
24
+ type = @types.type(type_name)
25
25
  if type.nil?
26
26
  add_error(GraphQL::StaticValidation::FragmentTypesExistError.new(
27
27
  "No such type #{type_name}, so it can't be a fragment condition",
@@ -19,7 +19,7 @@ module GraphQL
19
19
  true
20
20
  else
21
21
  type_name = node_type.to_query_string
22
- type_def = context.warden.get_type(type_name)
22
+ type_def = @types.type(type_name)
23
23
  if type_def.nil? || !type_def.kind.composite?
24
24
  add_error(GraphQL::StaticValidation::FragmentsAreOnCompositeTypesError.new(
25
25
  "Invalid fragment on type #{type_name} (must be Union, Interface or Object)",
@@ -3,7 +3,7 @@ module GraphQL
3
3
  module StaticValidation
4
4
  module MutationRootExists
5
5
  def on_operation_definition(node, _parent)
6
- if node.operation_type == 'mutation' && context.warden.root_type_for_operation("mutation").nil?
6
+ if node.operation_type == 'mutation' && context.query.types.mutation_root.nil?
7
7
  add_error(GraphQL::StaticValidation::MutationRootExistsError.new(
8
8
  'Schema is not configured for mutations',
9
9
  nodes: node
@@ -3,7 +3,7 @@ module GraphQL
3
3
  module StaticValidation
4
4
  module QueryRootExists
5
5
  def on_operation_definition(node, _parent)
6
- if (node.operation_type == 'query' || node.operation_type.nil?) && context.warden.root_type_for_operation("query").nil?
6
+ if (node.operation_type == 'query' || node.operation_type.nil?) && context.query.types.query_root.nil?
7
7
  add_error(GraphQL::StaticValidation::QueryRootExistsError.new(
8
8
  'Schema is not configured for queries',
9
9
  nodes: node