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
@@ -16,11 +16,11 @@ module GraphQL
16
16
  private
17
17
 
18
18
  def assert_required_args(ast_node, defn)
19
- args = defn.arguments(context.query.context)
19
+ args = @context.query.types.arguments(defn)
20
20
  return if args.empty?
21
21
  present_argument_names = ast_node.arguments.map(&:name)
22
- required_argument_names = context.warden.arguments(defn)
23
- .select { |a| a.type.kind.non_null? && !a.default_value? && context.warden.get_argument(defn, a.name) }
22
+ required_argument_names = context.query.types.arguments(defn)
23
+ .select { |a| a.type.kind.non_null? && !a.default_value? && context.query.types.argument(defn, a.name) }
24
24
  .map!(&:name)
25
25
 
26
26
  missing_names = required_argument_names - present_argument_names
@@ -26,7 +26,7 @@ module GraphQL
26
26
  context.directive_definition || context.field_definition
27
27
  end
28
28
 
29
- parent_type = context.warden.get_argument(defn, parent_name(parent, defn))
29
+ parent_type = context.types.argument(defn, parent_name(parent, defn))
30
30
  parent_type ? parent_type.type.unwrap : nil
31
31
  end
32
32
 
@@ -34,7 +34,7 @@ module GraphQL
34
34
  parent_type = get_parent_type(context, parent)
35
35
  return unless parent_type && parent_type.kind.input_object?
36
36
 
37
- required_fields = context.warden.arguments(parent_type)
37
+ required_fields = context.types.arguments(parent_type)
38
38
  .select{ |arg| arg.type.kind.non_null? && !arg.default_value? }
39
39
  .map!(&:graphql_name)
40
40
 
@@ -43,7 +43,7 @@ module GraphQL
43
43
 
44
44
  missing_fields.each do |missing_field|
45
45
  path = [*context.path, missing_field]
46
- missing_field_type = context.warden.get_argument(parent_type, missing_field).type
46
+ missing_field_type = context.types.argument(parent_type, missing_field).type
47
47
  add_error(RequiredInputObjectAttributesArePresentError.new(
48
48
  "Argument '#{missing_field}' on InputObject '#{parent_type.to_type_signature}' is required. Expected type #{missing_field_type.to_type_signature}",
49
49
  argument_name: missing_field,
@@ -3,7 +3,7 @@ module GraphQL
3
3
  module StaticValidation
4
4
  module SubscriptionRootExists
5
5
  def on_operation_definition(node, _parent)
6
- if node.operation_type == "subscription" && context.warden.root_type_for_operation("subscription").nil?
6
+ if node.operation_type == "subscription" && context.types.subscription_root.nil?
7
7
  add_error(GraphQL::StaticValidation::SubscriptionRootExistsError.new(
8
8
  'Schema is not configured for subscriptions',
9
9
  nodes: node
@@ -5,36 +5,27 @@ module GraphQL
5
5
  def on_variable_definition(node, parent)
6
6
  if !node.default_value.nil?
7
7
  value = node.default_value
8
- if node.type.is_a?(GraphQL::Language::Nodes::NonNullType)
9
- add_error(GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTypedError.new(
10
- "Non-null variable $#{node.name} can't have a default value",
11
- nodes: node,
12
- name: node.name,
13
- error_type: VariableDefaultValuesAreCorrectlyTypedError::VIOLATIONS[:INVALID_ON_NON_NULL]
14
- ))
8
+ type = context.schema.type_from_ast(node.type, context: context)
9
+ if type.nil?
10
+ # This is handled by another validator
15
11
  else
16
- type = context.schema.type_from_ast(node.type, context: context)
17
- if type.nil?
18
- # This is handled by another validator
19
- else
20
- validation_result = context.validate_literal(value, type)
12
+ validation_result = context.validate_literal(value, type)
21
13
 
22
- if !validation_result.valid?
23
- problems = validation_result.problems
24
- first_problem = problems && problems.first
25
- if first_problem
26
- error_message = first_problem["explanation"]
27
- end
28
-
29
- error_message ||= "Default value for $#{node.name} doesn't match type #{type.to_type_signature}"
30
- add_error(GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTypedError.new(
31
- error_message,
32
- nodes: node,
33
- name: node.name,
34
- type: type.to_type_signature,
35
- error_type: VariableDefaultValuesAreCorrectlyTypedError::VIOLATIONS[:INVALID_TYPE],
36
- ))
14
+ if !validation_result.valid?
15
+ problems = validation_result.problems
16
+ first_problem = problems && problems.first
17
+ if first_problem
18
+ error_message = first_problem["explanation"]
37
19
  end
20
+
21
+ error_message ||= "Default value for $#{node.name} doesn't match type #{type.to_type_signature}"
22
+ add_error(GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTypedError.new(
23
+ error_message,
24
+ nodes: node,
25
+ name: node.name,
26
+ type: type.to_type_signature,
27
+ error_type: VariableDefaultValuesAreCorrectlyTypedError::VIOLATIONS[:INVALID_TYPE],
28
+ ))
38
29
  end
39
30
  end
40
31
  end
@@ -65,7 +65,7 @@ module GraphQL
65
65
  end
66
66
  end
67
67
 
68
- arg_defn = context.warden.get_argument(argument_owner, arg_node.name)
68
+ arg_defn = @types.argument(argument_owner, arg_node.name)
69
69
  arg_defn_type = arg_defn.type
70
70
 
71
71
  # If the argument is non-null, but it was given a default value,
@@ -4,7 +4,7 @@ module GraphQL
4
4
  module VariablesAreInputTypes
5
5
  def on_variable_definition(node, parent)
6
6
  type_name = get_type_name(node.type)
7
- type = context.warden.get_type(type_name)
7
+ type = context.query.types.type(type_name)
8
8
 
9
9
  if type.nil?
10
10
  add_error(GraphQL::StaticValidation::VariablesAreInputTypesError.new(
@@ -13,14 +13,14 @@ module GraphQL
13
13
 
14
14
  attr_reader :query, :errors, :visitor,
15
15
  :on_dependency_resolve_handlers,
16
- :max_errors, :warden, :schema
16
+ :max_errors, :types, :schema
17
17
 
18
18
 
19
19
  def_delegators :@query, :document, :fragments, :operations
20
20
 
21
21
  def initialize(query, visitor_class, max_errors)
22
22
  @query = query
23
- @warden = query.warden
23
+ @types = query.types # TODO update migrated callers to use this accessor
24
24
  @schema = query.schema
25
25
  @literal_validator = LiteralValidator.new(context: query.context)
26
26
  @errors = []
@@ -9,7 +9,7 @@ module GraphQL
9
9
  # Assign the result to `context.namespace(:subscriptions)[:subscription_broadcastable]`
10
10
  # @api private
11
11
  # @see Subscriptions#broadcastable? for a public API
12
- class BroadcastAnalyzer < GraphQL::Analysis::AST::Analyzer
12
+ class BroadcastAnalyzer < GraphQL::Analysis::Analyzer
13
13
  def initialize(subject)
14
14
  super
15
15
  @default_broadcastable = subject.schema.subscriptions.default_broadcastable
@@ -28,9 +28,8 @@ module GraphQL
28
28
  end
29
29
 
30
30
  current_field = visitor.field_definition
31
- apply_broadcastable(current_field)
32
-
33
31
  current_type = visitor.parent_type_definition
32
+ apply_broadcastable(current_type, current_field)
34
33
  if current_type.kind.interface?
35
34
  pt = @query.possible_types(current_type)
36
35
  pt.each do |object_type|
@@ -38,7 +37,7 @@ module GraphQL
38
37
  # Inherited fields would be exactly the same object;
39
38
  # only check fields that are overrides of the inherited one
40
39
  if ot_field && ot_field != current_field
41
- apply_broadcastable(ot_field)
40
+ apply_broadcastable(object_type, ot_field)
42
41
  end
43
42
  end
44
43
  end
@@ -55,10 +54,16 @@ module GraphQL
55
54
  private
56
55
 
57
56
  # Modify `@subscription_broadcastable` based on `field_defn`'s configuration (and/or the default value)
58
- def apply_broadcastable(field_defn)
57
+ def apply_broadcastable(owner_type, field_defn)
59
58
  current_field_broadcastable = field_defn.introspection? || field_defn.broadcastable?
59
+
60
+ if current_field_broadcastable.nil? && owner_type.respond_to?(:default_broadcastable?)
61
+ current_field_broadcastable = owner_type.default_broadcastable?
62
+ end
63
+
60
64
  case current_field_broadcastable
61
65
  when nil
66
+ query.logger.debug { "`broadcastable: nil` for field: #{field_defn.path}" }
62
67
  # If the value wasn't set, mix in the default value:
63
68
  # - If the default is false and the current value is true, make it false
64
69
  # - If the default is true and the current value is true, it stays true
@@ -66,6 +71,7 @@ module GraphQL
66
71
  # - If the default is true and the current value is false, keep it false
67
72
  @subscription_broadcastable = @subscription_broadcastable && @default_broadcastable
68
73
  when false
74
+ query.logger.debug { "`broadcastable: false` for field: #{field_defn.path}" }
69
75
  # One non-broadcastable field is enough to make the whole subscription non-broadcastable
70
76
  @subscription_broadcastable = false
71
77
  when true
@@ -137,7 +137,7 @@ module GraphQL
137
137
  end
138
138
 
139
139
  def get_arg_definition(arg_owner, arg_name, context)
140
- arg_owner.get_argument(arg_name, context) || arg_owner.arguments(context).each_value.find { |v| v.keyword.to_s == arg_name }
140
+ context.types.argument(arg_owner, arg_name) || context.types.arguments(arg_owner).find { |v| v.keyword.to_s == arg_name }
141
141
  end
142
142
  end
143
143
  end
@@ -64,12 +64,12 @@ module GraphQL
64
64
  event_name = event_name.to_s
65
65
 
66
66
  # Try with the verbatim input first:
67
- field = @schema.get_field(@schema.subscription, event_name, context)
67
+ field = dummy_query.types.field(@schema.subscription, event_name) # rubocop:disable Development/ContextIsPassedCop
68
68
 
69
69
  if field.nil?
70
70
  # And if it wasn't found, normalize it:
71
71
  normalized_event_name = normalize_name(event_name)
72
- field = @schema.get_field(@schema.subscription, normalized_event_name, context)
72
+ field = dummy_query.types.field(@schema.subscription, normalized_event_name) # rubocop:disable Development/ContextIsPassedCop
73
73
  if field.nil?
74
74
  raise InvalidTriggerError, "No subscription matching trigger: #{event_name} (looked for #{@schema.subscription.graphql_name}.#{normalized_event_name})"
75
75
  end
@@ -235,7 +235,7 @@ module GraphQL
235
235
  if !query.valid?
236
236
  raise "Invalid query: #{query.validation_errors.map(&:to_h).inspect}"
237
237
  end
238
- GraphQL::Analysis::AST.analyze_query(query, @schema.query_analyzers)
238
+ GraphQL::Analysis.analyze_query(query, @schema.query_analyzers)
239
239
  query.context.namespace(:subscriptions)[:subscription_broadcastable]
240
240
  end
241
241
 
@@ -43,7 +43,7 @@ module GraphQL
43
43
  type_name, *field_names = field_path.split(".")
44
44
  dummy_query = GraphQL::Query.new(schema, "{ __typename }", context: context)
45
45
  query_context = dummy_query.context
46
- object_type = dummy_query.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
46
+ object_type = dummy_query.types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
47
47
  if object_type
48
48
  graphql_result = object
49
49
  field_names.each do |field_name|
@@ -52,7 +52,7 @@ module GraphQL
52
52
  if graphql_result.nil?
53
53
  return nil
54
54
  end
55
- visible_field = dummy_query.get_field(object_type, field_name)
55
+ visible_field = dummy_query.types.field(object_type, field_name) # rubocop:disable Development/ContextIsPassedCop
56
56
  if visible_field
57
57
  dummy_query.context.dataloader.run_isolated {
58
58
  field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
@@ -90,10 +90,13 @@ module GraphQL
90
90
  end
91
91
  end
92
92
  graphql_result
93
- elsif schema.has_defined_type?(type_name)
94
- raise TypeNotVisibleError.new(type_name: type_name)
95
93
  else
96
- raise TypeNotDefinedError.new(type_name: type_name)
94
+ unfiltered_type = Schema::Subset.pass_thru(schema: schema, context: context).type(type_name)
95
+ if unfiltered_type
96
+ raise TypeNotVisibleError.new(type_name: type_name)
97
+ else
98
+ raise TypeNotDefinedError.new(type_name: type_name)
99
+ end
97
100
  end
98
101
  end
99
102
 
@@ -18,6 +18,7 @@ module GraphQL
18
18
  self.node_type = nil
19
19
  self.edge_class = nil
20
20
  }
21
+ child_class.default_broadcastable(nil)
21
22
  add_page_info_field(child_class)
22
23
  end
23
24
 
@@ -31,12 +32,21 @@ module GraphQL
31
32
  child_class.edge_type = nil
32
33
  child_class.node_type = nil
33
34
  child_class.edge_class = nil
35
+ child_class.default_broadcastable(default_broadcastable?)
34
36
  end
35
37
 
36
38
  def default_relay?
37
39
  true
38
40
  end
39
41
 
42
+ def default_broadcastable?
43
+ @default_broadcastable
44
+ end
45
+
46
+ def default_broadcastable(new_value)
47
+ @default_broadcastable = new_value
48
+ end
49
+
40
50
  # @return [Class]
41
51
  attr_reader :node_type
42
52
 
@@ -10,6 +10,7 @@ module GraphQL
10
10
  child_class.extend(ClassMethods)
11
11
  child_class.class_eval { self.node_type = nil }
12
12
  child_class.node_nullable(true)
13
+ child_class.default_broadcastable(nil)
13
14
  end
14
15
 
15
16
  def node
@@ -24,12 +25,21 @@ module GraphQL
24
25
  super
25
26
  child_class.node_type = nil
26
27
  child_class.node_nullable = nil
28
+ child_class.default_broadcastable(default_broadcastable?)
27
29
  end
28
30
 
29
31
  def default_relay?
30
32
  true
31
33
  end
32
34
 
35
+ def default_broadcastable?
36
+ @default_broadcastable
37
+ end
38
+
39
+ def default_broadcastable(new_value)
40
+ @default_broadcastable = new_value
41
+ end
42
+
33
43
  # Get or set the Object type that this edge wraps.
34
44
  #
35
45
  # @param node_type [Class] A `Schema::Object` subclass
@@ -24,6 +24,10 @@ module GraphQL
24
24
  def default_relay?
25
25
  true
26
26
  end
27
+
28
+ def default_broadcastable?
29
+ true
30
+ end
27
31
  end
28
32
  end
29
33
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.3.5"
3
+ VERSION = "2.3.11"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -121,3 +121,4 @@ require "graphql/unauthorized_error"
121
121
  require "graphql/unauthorized_field_error"
122
122
  require "graphql/load_application_object_failed_error"
123
123
  require "graphql/testing"
124
+ require "graphql/current"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.5
4
+ version: 2.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-13 00:00:00.000000000 Z
11
+ date: 2024-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64
@@ -306,14 +306,13 @@ files:
306
306
  - lib/generators/graphql/union_generator.rb
307
307
  - lib/graphql.rb
308
308
  - lib/graphql/analysis.rb
309
- - lib/graphql/analysis/ast.rb
310
- - lib/graphql/analysis/ast/analyzer.rb
311
- - lib/graphql/analysis/ast/field_usage.rb
312
- - lib/graphql/analysis/ast/max_query_complexity.rb
313
- - lib/graphql/analysis/ast/max_query_depth.rb
314
- - lib/graphql/analysis/ast/query_complexity.rb
315
- - lib/graphql/analysis/ast/query_depth.rb
316
- - lib/graphql/analysis/ast/visitor.rb
309
+ - lib/graphql/analysis/analyzer.rb
310
+ - lib/graphql/analysis/field_usage.rb
311
+ - lib/graphql/analysis/max_query_complexity.rb
312
+ - lib/graphql/analysis/max_query_depth.rb
313
+ - lib/graphql/analysis/query_complexity.rb
314
+ - lib/graphql/analysis/query_depth.rb
315
+ - lib/graphql/analysis/visitor.rb
317
316
  - lib/graphql/analysis_error.rb
318
317
  - lib/graphql/backtrace.rb
319
318
  - lib/graphql/backtrace/inspect_result.rb
@@ -322,6 +321,7 @@ files:
322
321
  - lib/graphql/backtrace/traced_error.rb
323
322
  - lib/graphql/backtrace/tracer.rb
324
323
  - lib/graphql/coercion_error.rb
324
+ - lib/graphql/current.rb
325
325
  - lib/graphql/dataloader.rb
326
326
  - lib/graphql/dataloader/async_dataloader.rb
327
327
  - lib/graphql/dataloader/null_dataloader.rb
@@ -377,7 +377,6 @@ files:
377
377
  - lib/graphql/language/printer.rb
378
378
  - lib/graphql/language/sanitized_printer.rb
379
379
  - lib/graphql/language/static_visitor.rb
380
- - lib/graphql/language/token.rb
381
380
  - lib/graphql/language/visitor.rb
382
381
  - lib/graphql/load_application_object_failed_error.rb
383
382
  - lib/graphql/name_validator.rb
@@ -440,7 +439,6 @@ files:
440
439
  - lib/graphql/schema/input_object.rb
441
440
  - lib/graphql/schema/interface.rb
442
441
  - lib/graphql/schema/introspection_system.rb
443
- - lib/graphql/schema/invalid_type_error.rb
444
442
  - lib/graphql/schema/late_bound_type.rb
445
443
  - lib/graphql/schema/list.rb
446
444
  - lib/graphql/schema/loader.rb
@@ -471,12 +469,15 @@ files:
471
469
  - lib/graphql/schema/resolver/has_payload_type.rb
472
470
  - lib/graphql/schema/scalar.rb
473
471
  - lib/graphql/schema/subscription.rb
472
+ - lib/graphql/schema/subset.rb
474
473
  - lib/graphql/schema/timeout.rb
475
474
  - lib/graphql/schema/type_expression.rb
476
475
  - lib/graphql/schema/type_membership.rb
476
+ - lib/graphql/schema/types_migration.rb
477
477
  - lib/graphql/schema/union.rb
478
478
  - lib/graphql/schema/unique_within_type.rb
479
479
  - lib/graphql/schema/validator.rb
480
+ - lib/graphql/schema/validator/all_validator.rb
480
481
  - lib/graphql/schema/validator/allow_blank_validator.rb
481
482
  - lib/graphql/schema/validator/allow_null_validator.rb
482
483
  - lib/graphql/schema/validator/exclusion_validator.rb
@@ -645,7 +646,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
645
646
  - !ruby/object:Gem::Version
646
647
  version: '0'
647
648
  requirements: []
648
- rubygems_version: 3.5.3
649
+ rubygems_version: 3.5.12
649
650
  signing_key:
650
651
  specification_version: 4
651
652
  summary: A GraphQL language and runtime for Ruby
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module Analysis
4
- module AST
5
- # Query analyzer for query ASTs. Query analyzers respond to visitor style methods
6
- # but are prefixed by `enter` and `leave`.
7
- #
8
- # When an analyzer is initialized with a Multiplex, you can always get the current query from
9
- # `visitor.query` in the visit methods.
10
- #
11
- # @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
12
- class Analyzer
13
- def initialize(subject)
14
- @subject = subject
15
-
16
- if subject.is_a?(GraphQL::Query)
17
- @query = subject
18
- @multiplex = nil
19
- else
20
- @multiplex = subject
21
- @query = nil
22
- end
23
- end
24
-
25
- # Analyzer hook to decide at analysis time whether a query should
26
- # be analyzed or not.
27
- # @return [Boolean] If the query should be analyzed or not
28
- def analyze?
29
- true
30
- end
31
-
32
- # Analyzer hook to decide at analysis time whether analysis
33
- # requires a visitor pass; can be disabled for precomputed results.
34
- # @return [Boolean] If analysis requires visitation or not
35
- def visit?
36
- true
37
- end
38
-
39
- # The result for this analyzer. Returning {GraphQL::AnalysisError} results
40
- # in a query error.
41
- # @return [Any] The analyzer result
42
- def result
43
- raise GraphQL::RequiredImplementationMissingError
44
- end
45
-
46
- class << self
47
- private
48
-
49
- def build_visitor_hooks(member_name)
50
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
51
- def on_enter_#{member_name}(node, parent, visitor)
52
- end
53
-
54
- def on_leave_#{member_name}(node, parent, visitor)
55
- end
56
- EOS
57
- end
58
- end
59
-
60
- build_visitor_hooks :argument
61
- build_visitor_hooks :directive
62
- build_visitor_hooks :document
63
- build_visitor_hooks :enum
64
- build_visitor_hooks :field
65
- build_visitor_hooks :fragment_spread
66
- build_visitor_hooks :inline_fragment
67
- build_visitor_hooks :input_object
68
- build_visitor_hooks :list_type
69
- build_visitor_hooks :non_null_type
70
- build_visitor_hooks :null_value
71
- build_visitor_hooks :operation_definition
72
- build_visitor_hooks :type_name
73
- build_visitor_hooks :variable_definition
74
- build_visitor_hooks :variable_identifier
75
- build_visitor_hooks :abstract_node
76
-
77
- protected
78
-
79
- # @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
80
- attr_reader :subject
81
-
82
- # @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
83
- # (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
84
- attr_reader :query
85
-
86
- # @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
87
- attr_reader :multiplex
88
- end
89
- end
90
- end
91
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module Analysis
4
- module AST
5
- class FieldUsage < Analyzer
6
- def initialize(query)
7
- super
8
- @used_fields = Set.new
9
- @used_deprecated_fields = Set.new
10
- @used_deprecated_arguments = Set.new
11
- @used_deprecated_enum_values = Set.new
12
- end
13
-
14
- def on_leave_field(node, parent, visitor)
15
- field_defn = visitor.field_definition
16
- field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
17
- @used_fields << field
18
- @used_deprecated_fields << field if field_defn.deprecation_reason
19
- arguments = visitor.query.arguments_for(node, field_defn)
20
- # If there was an error when preparing this argument object,
21
- # then this might be an error or something:
22
- if arguments.respond_to?(:argument_values)
23
- extract_deprecated_arguments(arguments.argument_values)
24
- end
25
- end
26
-
27
- def result
28
- {
29
- used_fields: @used_fields.to_a,
30
- used_deprecated_fields: @used_deprecated_fields.to_a,
31
- used_deprecated_arguments: @used_deprecated_arguments.to_a,
32
- used_deprecated_enum_values: @used_deprecated_enum_values.to_a,
33
- }
34
- end
35
-
36
- private
37
-
38
- def extract_deprecated_arguments(argument_values)
39
- argument_values.each_pair do |_argument_name, argument|
40
- if argument.definition.deprecation_reason
41
- @used_deprecated_arguments << argument.definition.path
42
- end
43
-
44
- arg_val = argument.value
45
-
46
- next if arg_val.nil?
47
-
48
- argument_type = argument.definition.type
49
- if argument_type.non_null?
50
- argument_type = argument_type.of_type
51
- end
52
-
53
- if argument_type.kind.input_object?
54
- extract_deprecated_arguments(argument.original_value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
55
- elsif argument_type.kind.enum?
56
- extract_deprecated_enum_value(argument_type, arg_val)
57
- elsif argument_type.list?
58
- inner_type = argument_type.unwrap
59
- case inner_type.kind
60
- when TypeKinds::INPUT_OBJECT
61
- argument.original_value.each do |value|
62
- extract_deprecated_arguments(value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
63
- end
64
- when TypeKinds::ENUM
65
- arg_val.each do |value|
66
- extract_deprecated_enum_value(inner_type, value)
67
- end
68
- else
69
- # Not a kind of input that we track
70
- end
71
- end
72
- end
73
- end
74
-
75
- def extract_deprecated_enum_value(enum_type, value)
76
- enum_value = @query.warden.enum_values(enum_type).find { |ev| ev.value == value }
77
- if enum_value&.deprecation_reason
78
- @used_deprecated_enum_values << enum_value.path
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module Analysis
4
- module AST
5
- # Used under the hood to implement complexity validation,
6
- # see {Schema#max_complexity} and {Query#max_complexity}
7
- class MaxQueryComplexity < QueryComplexity
8
- def result
9
- return if subject.max_complexity.nil?
10
-
11
- total_complexity = max_possible_complexity
12
-
13
- if total_complexity > subject.max_complexity
14
- GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
15
- else
16
- nil
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module Analysis
4
- module AST
5
- class MaxQueryDepth < QueryDepth
6
- def result
7
- configured_max_depth = if query
8
- query.max_depth
9
- else
10
- multiplex.schema.max_depth
11
- end
12
-
13
- if configured_max_depth && @max_depth > configured_max_depth
14
- GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
15
- else
16
- nil
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end