graphql 1.11.11 → 1.11.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d5cb52d52c7bff9e3ec317756e7f2d171fac202208ca3bfe4bce711b4f3216b
4
- data.tar.gz: 0d087f84cd41caaea9e8953b78b4bef69349209a8e62321bb604cc68f5a3765d
3
+ metadata.gz: ee8b1fd3f821af97c7baeab840141edf4251ad4cf2edd538d204b230d73d3388
4
+ data.tar.gz: a72a7d21e223f349f75f66e28e0a3cb421dceb21ad9085aca804ed912cba142f
5
5
  SHA512:
6
- metadata.gz: 68ae0b7fec852524c7527b3222a06c217dd03723120204baed3a6bc67b87e5e629010b2b393c9e4c2c0747e10655f17d1cc06196ac6864bf899569039d9d3b21
7
- data.tar.gz: 56ed8bd3fb0b5e3c27cee6180a91b9b8ece3364a7682a90e2a4e4604663e2744d30d46ac85988394b00f41c2341b4c761c09c83d21925e08e1223a91fdba333f
6
+ metadata.gz: 71bf8a12a950c16ca7f2fdd5ffc752a469088926bab9955bf6df406dd2a264994506ed98f144ca0b1c5e6dea45f387f3e8c97091bfb1e9e829f2d815c10beac8
7
+ data.tar.gz: ef9a2d5ca4e871099e11f39601431968c38f8af288f92de0c50e571dc5088171b9dbbee55602e9d68000036ab6c530a297c57b1945d1b96eff76136b0142531d
@@ -72,7 +72,7 @@ module GraphQL
72
72
  elsif @operation_name_error
73
73
  @validation_errors << @operation_name_error
74
74
  else
75
- validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout)
75
+ validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
76
76
  @validation_errors.concat(validation_result[:errors])
77
77
  @internal_representation = validation_result[:irep]
78
78
 
@@ -157,7 +157,7 @@ module GraphQL
157
157
 
158
158
  accepts_definitions \
159
159
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
160
- :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
160
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
161
161
  :orphan_types, :resolve_type, :type_error, :parse_error,
162
162
  :error_bubbling,
163
163
  :raise_definition_error,
@@ -196,7 +196,7 @@ module GraphQL
196
196
  attr_accessor \
197
197
  :query, :mutation, :subscription,
198
198
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
199
- :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
199
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
200
200
  :orphan_types, :directives,
201
201
  :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
202
202
  :cursor_encoder,
@@ -366,7 +366,7 @@ module GraphQL
366
366
  validator_opts = { schema: self }
367
367
  rules && (validator_opts[:rules] = rules)
368
368
  validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
369
- res = validator.validate(query, timeout: validate_timeout)
369
+ res = validator.validate(query, timeout: validate_timeout, max_errors: validate_max_errors)
370
370
  res[:errors]
371
371
  end
372
372
 
@@ -951,6 +951,7 @@ module GraphQL
951
951
  schema_defn.mutation = mutation && mutation.graphql_definition
952
952
  schema_defn.subscription = subscription && subscription.graphql_definition
953
953
  schema_defn.validate_timeout = validate_timeout
954
+ schema_defn.validate_max_errors = validate_max_errors
954
955
  schema_defn.max_complexity = max_complexity
955
956
  schema_defn.error_bubbling = error_bubbling
956
957
  schema_defn.max_depth = max_depth
@@ -1119,14 +1120,15 @@ module GraphQL
1119
1120
  type.possible_types(context: context)
1120
1121
  else
1121
1122
  stored_possible_types = own_possible_types[type.graphql_name]
1122
- visible_possible_types = stored_possible_types.select do |possible_type|
1123
- next true unless type.kind.interface?
1124
- next true unless possible_type.kind.object?
1125
-
1126
- # Use `.graphql_name` comparison to match legacy vs class-based types.
1127
- # When we don't need to support legacy `.define` types, use `.include?(type)` instead.
1128
- possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
1129
- end if stored_possible_types
1123
+ visible_possible_types = if stored_possible_types && type.kind.interface?
1124
+ stored_possible_types.select do |possible_type|
1125
+ # Use `.graphql_name` comparison to match legacy vs class-based types.
1126
+ # When we don't need to support legacy `.define` types, use `.include?(type)` instead.
1127
+ possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
1128
+ end
1129
+ else
1130
+ stored_possible_types
1131
+ end
1130
1132
  visible_possible_types ||
1131
1133
  introspection_system.possible_types[type.graphql_name] ||
1132
1134
  (
@@ -1285,6 +1287,19 @@ module GraphQL
1285
1287
  end
1286
1288
  end
1287
1289
 
1290
+ attr_writer :validate_max_errors
1291
+
1292
+ def validate_max_errors(new_validate_max_errors = nil)
1293
+ if new_validate_max_errors
1294
+ @validate_max_errors = new_validate_max_errors
1295
+ elsif defined?(@validate_max_errors)
1296
+ @validate_max_errors
1297
+ else
1298
+ find_inherited_value(:validate_max_errors)
1299
+ end
1300
+ end
1301
+
1302
+
1288
1303
  attr_writer :max_complexity
1289
1304
 
1290
1305
  def max_complexity(max_complexity = nil)
@@ -205,6 +205,9 @@ module GraphQL
205
205
  private
206
206
 
207
207
  def add_error(error, path: nil)
208
+ if @context.too_many_errors?
209
+ throw :too_many_validation_errors
210
+ end
208
211
  error.path ||= (path || @path.dup)
209
212
  context.errors << error
210
213
  end
@@ -193,26 +193,26 @@ module GraphQL
193
193
  if node1.name != node2.name
194
194
  errored_nodes = [node1.name, node2.name].sort.join(" or ")
195
195
  msg = "Field '#{response_key}' has a field conflict: #{errored_nodes}?"
196
- context.errors << GraphQL::StaticValidation::FieldsWillMergeError.new(
196
+ add_error(GraphQL::StaticValidation::FieldsWillMergeError.new(
197
197
  msg,
198
198
  nodes: [node1, node2],
199
199
  path: [],
200
200
  field_name: response_key,
201
201
  conflicts: errored_nodes
202
- )
202
+ ))
203
203
  end
204
204
 
205
205
  if !same_arguments?(node1, node2)
206
206
  args = [serialize_field_args(node1), serialize_field_args(node2)]
207
207
  conflicts = args.map { |arg| GraphQL::Language.serialize(arg) }.join(" or ")
208
208
  msg = "Field '#{response_key}' has an argument conflict: #{conflicts}?"
209
- context.errors << GraphQL::StaticValidation::FieldsWillMergeError.new(
209
+ add_error(GraphQL::StaticValidation::FieldsWillMergeError.new(
210
210
  msg,
211
211
  nodes: [node1, node2],
212
212
  path: [],
213
213
  field_name: response_key,
214
214
  conflicts: conflicts
215
- )
215
+ ))
216
216
  end
217
217
  end
218
218
 
@@ -7,12 +7,12 @@ module GraphQL
7
7
  dependency_map = context.dependencies
8
8
  dependency_map.cyclical_definitions.each do |defn|
9
9
  if defn.node.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
10
- context.errors << GraphQL::StaticValidation::FragmentsAreFiniteError.new(
10
+ add_error(GraphQL::StaticValidation::FragmentsAreFiniteError.new(
11
11
  "Fragment #{defn.name} contains an infinite loop",
12
12
  nodes: defn.node,
13
13
  path: defn.path,
14
14
  name: defn.name
15
- )
15
+ ))
16
16
  end
17
17
  end
18
18
  end
@@ -19,10 +19,11 @@ module GraphQL
19
19
 
20
20
  def_delegators :@query, :schema, :document, :fragments, :operations, :warden
21
21
 
22
- def initialize(query, visitor_class)
22
+ def initialize(query, visitor_class, max_errors)
23
23
  @query = query
24
24
  @literal_validator = LiteralValidator.new(context: query.context)
25
25
  @errors = []
26
+ @max_errors = max_errors || Float::INFINITY
26
27
  @on_dependency_resolve_handlers = []
27
28
  @visitor = visitor_class.new(document, self)
28
29
  end
@@ -38,6 +39,10 @@ module GraphQL
38
39
  def validate_literal(ast_value, type)
39
40
  @literal_validator.validate(ast_value, type)
40
41
  end
42
+
43
+ def too_many_errors?
44
+ @errors.length >= @max_errors
45
+ end
41
46
  end
42
47
  end
43
48
  end
@@ -22,8 +22,9 @@ module GraphQL
22
22
  # @param query [GraphQL::Query]
23
23
  # @param validate [Boolean]
24
24
  # @param timeout [Float] Number of seconds to wait before aborting validation. Any positive number may be used, including Floats to specify fractional seconds.
25
+ # @param max_errors [Integer] Maximum number of errors before aborting validation. Any positive number will limit the number of errors. Defaults to nil for no limit.
25
26
  # @return [Array<Hash>]
26
- def validate(query, validate: true, timeout: nil)
27
+ def validate(query, validate: true, timeout: nil, max_errors: nil)
27
28
  query.trace("validate", { validate: validate, query: query }) do
28
29
  can_skip_rewrite = query.context.interpreter? && query.schema.using_ast_analysis? && query.schema.is_a?(Class)
29
30
  errors = if validate == false && can_skip_rewrite
@@ -32,23 +33,26 @@ module GraphQL
32
33
  rules_to_use = validate ? @rules : []
33
34
  visitor_class = BaseVisitor.including_rules(rules_to_use, rewrite: !can_skip_rewrite)
34
35
 
35
- context = GraphQL::StaticValidation::ValidationContext.new(query, visitor_class)
36
+ context = GraphQL::StaticValidation::ValidationContext.new(query, visitor_class, max_errors)
36
37
 
37
38
  begin
38
39
  # CAUTION: Usage of the timeout module makes the assumption that validation rules are stateless Ruby code that requires no cleanup if process was interrupted. This means no blocking IO calls, native gems, locks, or `rescue` clauses that must be reached.
39
40
  # A timeout value of 0 or nil will execute the block without any timeout.
40
41
  Timeout::timeout(timeout) do
41
- # Attach legacy-style rules.
42
- # Only loop through rules if it has legacy-style rules
43
- unless (legacy_rules = rules_to_use - GraphQL::StaticValidation::ALL_RULES).empty?
44
- legacy_rules.each do |rule_class_or_module|
45
- if rule_class_or_module.method_defined?(:validate)
46
- rule_class_or_module.new.validate(context)
42
+
43
+ catch(:too_many_validation_errors) do
44
+ # Attach legacy-style rules.
45
+ # Only loop through rules if it has legacy-style rules
46
+ unless (legacy_rules = rules_to_use - GraphQL::StaticValidation::ALL_RULES).empty?
47
+ legacy_rules.each do |rule_class_or_module|
48
+ if rule_class_or_module.method_defined?(:validate)
49
+ rule_class_or_module.new.validate(context)
50
+ end
47
51
  end
48
52
  end
49
- end
50
53
 
51
- context.visitor.visit
54
+ context.visitor.visit
55
+ end
52
56
  end
53
57
  rescue Timeout::Error
54
58
  handle_timeout(query, context)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.11.11"
3
+ VERSION = "1.11.12"
4
4
  end
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: 1.11.11
4
+ version: 1.11.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-12 00:00:00.000000000 Z
11
+ date: 2025-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips