graphql 2.0.12 → 2.0.13

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d299fcfe61f486f9370dac7dfcd66df417ca4697932d7861822fb12c61a5889
4
- data.tar.gz: 45e03854d6248c63f80d3b80e141a28970303516ab5f78375d9d3362b9e04ba5
3
+ metadata.gz: b8f389d3b7c8052a74ccd4bd9e8412a1fa9d93415e6caeec883b8f179a167395
4
+ data.tar.gz: f2e6ab7ba5c1e76b0c44557855ab3af55fb2b718b8de1ff6483917de603734b3
5
5
  SHA512:
6
- metadata.gz: d756a4c5213a8e17910233b0e472a037b6dad007676f5399f6192b93df53e78611915bd066ac619b59d7d44a0f35efbd7bb329cb4189246bce0c077f584b049b
7
- data.tar.gz: 277f7623f5bcc351bed49b3e95156166e16a92c3041a905f1e88399b15839eff8a0c733c16f4ae33c82213a4a47c3184d5c763e43ac2ca01a613caa419000513
6
+ metadata.gz: 10a24271a65c65a402d3243d2e43b3b257f74eb7bbc0ec13c254304bdce3122c444a41fbccf943bd3d626d301aec4b973485f742b831e8658ea252a0c95cfcfa
7
+ data.tar.gz: 9762008c699f2a53b14913e057dc31ec6c97b4203b1dd28a7a2a4fc18153d5bc200d0a95e3d2a04da80d0486131f5b1ce8d597e1ad6a7085b0766e35e0982959
@@ -401,8 +401,7 @@ module GraphQL
401
401
  end
402
402
  return_type = field_defn.type
403
403
 
404
- next_path = path.dup
405
- next_path << result_name
404
+ next_path = path + [result_name]
406
405
  next_path.freeze
407
406
 
408
407
  # This seems janky, but we need to know
@@ -768,8 +767,7 @@ module GraphQL
768
767
  set_result(selection_result, result_name, response_list)
769
768
  result_was_set = true
770
769
  end
771
- next_path = path.dup
772
- next_path << idx
770
+ next_path = path + [idx]
773
771
  this_idx = idx
774
772
  next_path.freeze
775
773
  idx += 1
@@ -4,11 +4,11 @@ module GraphQL
4
4
  class VariableValidationError < GraphQL::ExecutionError
5
5
  attr_accessor :value, :validation_result
6
6
 
7
- def initialize(variable_ast, type, value, validation_result)
7
+ def initialize(variable_ast, type, value, validation_result, msg: nil)
8
8
  @value = value
9
9
  @validation_result = validation_result
10
10
 
11
- msg = "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
11
+ msg ||= "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
12
12
 
13
13
  if problem_fields.any?
14
14
  msg += " for #{problem_fields.join(", ")}"
@@ -17,6 +17,10 @@ module GraphQL
17
17
  @provided_variables = deep_stringify(provided_variables)
18
18
  @errors = []
19
19
  @storage = ast_variables.each_with_object({}) do |ast_variable, memo|
20
+ if schema.validate_max_errors && schema.validate_max_errors <= @errors.count
21
+ add_max_errors_reached_message
22
+ break
23
+ end
20
24
  # Find the right value for this variable:
21
25
  # - First, use the value provided at runtime
22
26
  # - Then, fall back to the default value from the query string
@@ -29,8 +33,9 @@ module GraphQL
29
33
  default_value = ast_variable.default_value
30
34
  provided_value = @provided_variables[variable_name]
31
35
  value_was_provided = @provided_variables.key?(variable_name)
36
+ max_errors = schema.validate_max_errors - @errors.count if schema.validate_max_errors
32
37
  begin
33
- validation_result = variable_type.validate_input(provided_value, ctx)
38
+ validation_result = variable_type.validate_input(provided_value, ctx, max_errors: max_errors)
34
39
  if validation_result.valid?
35
40
  if value_was_provided
36
41
  # Add the variable if a value was provided
@@ -48,8 +53,7 @@ module GraphQL
48
53
  # like InputValidationResults generated by validate_non_null_input but unfortunately we don't
49
54
  # have this information available in the coerce_input call chain. Note this path is the path
50
55
  # that appears under errors.extensions.problems.path and NOT the result path under errors.path.
51
- validation_result = GraphQL::Query::InputValidationResult.new
52
- validation_result.add_problem(ex.message)
56
+ validation_result = GraphQL::Query::InputValidationResult.from_problem(ex.message)
53
57
  end
54
58
 
55
59
  if !validation_result.valid?
@@ -76,6 +80,12 @@ module GraphQL
76
80
  else
77
81
  val
78
82
  end
83
+ end
84
+
85
+ def add_max_errors_reached_message
86
+ message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
87
+ validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
88
+ errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
79
89
  end
80
90
  end
81
91
  end
@@ -15,7 +15,7 @@ module GraphQL
15
15
  puts "Validating graphql-pro v#{version}"
16
16
  puts " - Checking for graphql-pro credentials..."
17
17
 
18
- creds = `bundle config gems.graphql.pro`[/[a-z0-9]{11}:[a-z0-9]{11}/]
18
+ creds = `bundle config gems.graphql.pro --parseable`[/[a-z0-9]{11}:[a-z0-9]{11}/]
19
19
  if creds.nil?
20
20
  puts " #{ex} failed, please set with `bundle config gems.graphql.pro $MY_CREDENTIALS`"
21
21
  exit(1)
@@ -18,8 +18,14 @@ module GraphQL
18
18
  # @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
19
19
  attr_reader :owner
20
20
 
21
- # @return [Symbol] A method to call to transform this value before sending it to field resolution method
22
- attr_reader :prepare
21
+ # @param new_prepare [Method, Proc]
22
+ # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
23
+ def prepare(new_prepare = NO_DEFAULT)
24
+ if new_prepare != NO_DEFAULT
25
+ @prepare = new_prepare
26
+ end
27
+ @prepare
28
+ end
23
29
 
24
30
  # @return [Symbol] This argument's name in Ruby keyword arguments
25
31
  attr_reader :keyword
@@ -96,8 +102,14 @@ module GraphQL
96
102
  "#<#{self.class} #{path}: #{type.to_type_signature}#{description ? " @description=#{description.inspect}" : ""}>"
97
103
  end
98
104
 
105
+ # @param default_value [Object] The value to use when the client doesn't provide one
99
106
  # @return [Object] the value used when the client doesn't provide a value for this argument
100
- attr_reader :default_value
107
+ def default_value(new_default_value = NO_DEFAULT)
108
+ if new_default_value != NO_DEFAULT
109
+ @default_value = new_default_value
110
+ end
111
+ @default_value
112
+ end
101
113
 
102
114
  # @return [Boolean] True if this argument has a default value
103
115
  def default_value?
@@ -122,7 +122,7 @@ module GraphQL
122
122
  GraphQL::TypeKinds::ENUM
123
123
  end
124
124
 
125
- def validate_non_null_input(value_name, ctx)
125
+ def validate_non_null_input(value_name, ctx, max_errors: nil)
126
126
  allowed_values = ctx.warden.enum_values(self)
127
127
  matching_value = allowed_values.find { |v| v.graphql_name == value_name }
128
128
 
@@ -666,7 +666,18 @@ module GraphQL
666
666
  inner_object = obj.object
667
667
 
668
668
  if defined?(@hash_key)
669
- inner_object[@hash_key] || inner_object[@hash_key_str] || (@fallback_value != :not_given ? @fallback_value : nil)
669
+ hash_value = if inner_object.is_a?(Hash)
670
+ inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str]
671
+ elsif inner_object.respond_to?(:[])
672
+ inner_object[@hash_key]
673
+ else
674
+ nil
675
+ end
676
+ if hash_value == false
677
+ hash_value
678
+ else
679
+ hash_value || (@fallback_value != :not_given ? @fallback_value : nil)
680
+ end
670
681
  elsif obj.respond_to?(resolver_method)
671
682
  method_to_call = resolver_method
672
683
  method_receiver = obj
@@ -679,16 +690,6 @@ module GraphQL
679
690
  elsif inner_object.is_a?(Hash)
680
691
  if @dig_keys
681
692
  inner_object.dig(*@dig_keys)
682
- elsif defined?(@hash_key)
683
- if inner_object.key?(@hash_key)
684
- inner_object[@hash_key]
685
- elsif inner_object.key?(@hash_key_str)
686
- inner_object[@hash_key_str]
687
- elsif @fallback_value != :not_given
688
- @fallback_value
689
- else
690
- nil
691
- end
692
693
  elsif inner_object.key?(@method_sym)
693
694
  inner_object[@method_sym]
694
695
  elsif inner_object.key?(@method_str)
@@ -126,7 +126,7 @@ module GraphQL
126
126
  # @api private
127
127
  INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
128
128
 
129
- def validate_non_null_input(input, ctx)
129
+ def validate_non_null_input(input, ctx, max_errors: nil)
130
130
  warden = ctx.warden
131
131
 
132
132
  if input.is_a?(Array)
@@ -45,16 +45,24 @@ module GraphQL
45
45
  end
46
46
  end
47
47
 
48
- def validate_non_null_input(value, ctx)
49
- result = nil
48
+ def validate_non_null_input(value, ctx, max_errors: nil)
49
+ result = GraphQL::Query::InputValidationResult.new
50
50
  ensure_array(value).each_with_index do |item, index|
51
51
  item_result = of_type.validate_input(item, ctx)
52
- if !item_result.valid?
53
- result ||= GraphQL::Query::InputValidationResult.new
52
+ unless item_result.valid?
53
+ if max_errors
54
+ if max_errors == 0
55
+ add_max_errros_reached_message(result)
56
+ break
57
+ end
58
+
59
+ max_errors -= 1
60
+ end
61
+
54
62
  result.merge_result!(index, item_result)
55
63
  end
56
64
  end
57
- result
65
+ result.valid? ? nil : result
58
66
  end
59
67
 
60
68
  private
@@ -67,6 +75,12 @@ module GraphQL
67
75
  [value]
68
76
  end
69
77
  end
78
+
79
+ def add_max_errros_reached_message(result)
80
+ message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
81
+ item_result = GraphQL::Query::InputValidationResult.from_problem(message)
82
+ result.merge_result!(nil, item_result)
83
+ end
70
84
  end
71
85
  end
72
86
  end
@@ -8,11 +8,11 @@ module GraphQL
8
8
  validate_input(val, ctx).valid?
9
9
  end
10
10
 
11
- def validate_input(val, ctx)
11
+ def validate_input(val, ctx, max_errors: nil)
12
12
  if val.nil?
13
13
  Query::InputValidationResult::VALID
14
14
  else
15
- validate_non_null_input(val, ctx) || Query::InputValidationResult::VALID
15
+ validate_non_null_input(val, ctx, max_errors: max_errors) || Query::InputValidationResult::VALID
16
16
  end
17
17
  end
18
18
 
@@ -31,13 +31,13 @@ module GraphQL
31
31
  "#<#{self.class.name} @of_type=#{@of_type.inspect}>"
32
32
  end
33
33
 
34
- def validate_input(value, ctx)
34
+ def validate_input(value, ctx, max_errors: nil)
35
35
  if value.nil?
36
36
  result = GraphQL::Query::InputValidationResult.new
37
37
  result.add_problem("Expected value to not be null")
38
38
  result
39
39
  else
40
- of_type.validate_input(value, ctx)
40
+ of_type.validate_input(value, ctx, max_errors: max_errors)
41
41
  end
42
42
  end
43
43
 
@@ -40,7 +40,7 @@ module GraphQL
40
40
  @default_scalar ||= false
41
41
  end
42
42
 
43
- def validate_non_null_input(value, ctx)
43
+ def validate_non_null_input(value, ctx, max_errors: nil)
44
44
  coerced_result = begin
45
45
  coerce_input(value, ctx)
46
46
  rescue GraphQL::CoercionError => err
@@ -30,10 +30,10 @@ module GraphQL
30
30
  }.tap { |h| h["path"] = path unless path.nil? }
31
31
  end
32
32
 
33
- private
34
-
35
33
  attr_reader :nodes
36
34
 
35
+ private
36
+
37
37
  def locations
38
38
  nodes.map do |node|
39
39
  h = {"line" => node.line, "column" => node.col}
@@ -9,11 +9,17 @@ module GraphQL
9
9
 
10
10
  def on_directive(node, parent)
11
11
  if !@directive_names.include?(node.name)
12
- add_error(GraphQL::StaticValidation::DirectivesAreDefinedError.new(
13
- "Directive @#{node.name} is not defined",
14
- nodes: node,
15
- directive: node.name
16
- ))
12
+ @directives_are_defined_errors_by_name ||= {}
13
+ error = @directives_are_defined_errors_by_name[node.name] ||= begin
14
+ err = GraphQL::StaticValidation::DirectivesAreDefinedError.new(
15
+ "Directive @#{node.name} is not defined",
16
+ nodes: [],
17
+ directive: node.name
18
+ )
19
+ add_error(err)
20
+ err
21
+ end
22
+ error.nodes << node
17
23
  else
18
24
  super
19
25
  end
@@ -34,12 +34,18 @@ module GraphQL
34
34
  used_directives = {}
35
35
  node.directives.each do |ast_directive|
36
36
  directive_name = ast_directive.name
37
- if used_directives[directive_name]
38
- add_error(GraphQL::StaticValidation::UniqueDirectivesPerLocationError.new(
39
- "The directive \"#{directive_name}\" can only be used once at this location.",
40
- nodes: [used_directives[directive_name], ast_directive],
41
- directive: directive_name,
42
- ))
37
+ if (first_node = used_directives[directive_name])
38
+ @directives_are_unique_errors_by_first_node ||= {}
39
+ err = @directives_are_unique_errors_by_first_node[first_node] ||= begin
40
+ error = GraphQL::StaticValidation::UniqueDirectivesPerLocationError.new(
41
+ "The directive \"#{directive_name}\" can only be used once at this location.",
42
+ nodes: [used_directives[directive_name]],
43
+ directive: directive_name,
44
+ )
45
+ add_error(error)
46
+ error
47
+ end
48
+ err.nodes << ast_directive
43
49
  elsif !((dir_defn = context.schema_directives[directive_name]) && dir_defn.repeatable?)
44
50
  used_directives[directive_name] = ast_directive
45
51
  end
@@ -62,11 +62,8 @@ module GraphQL
62
62
  # @return [void]
63
63
  def trigger(event_name, args, object, scope: nil, context: {})
64
64
  # Make something as context-like as possible, even though there isn't a current query:
65
- context = @schema.context_class.new(
66
- query: GraphQL::Query.new(@schema, "", validate: false),
67
- object: nil,
68
- values: context
69
- )
65
+ dummy_query = GraphQL::Query.new(@schema, "", validate: false, context: context)
66
+ context = dummy_query.context
70
67
  event_name = event_name.to_s
71
68
 
72
69
  # Try with the verbatim input first:
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.12"
3
+ VERSION = "2.0.13"
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: 2.0.12
4
+ version: 2.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-19 00:00:00.000000000 Z
11
+ date: 2022-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips