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 +4 -4
- data/lib/graphql/execution/interpreter/runtime.rb +2 -4
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +13 -3
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/schema/argument.rb +15 -3
- data/lib/graphql/schema/enum.rb +1 -1
- data/lib/graphql/schema/field.rb +12 -11
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/list.rb +19 -5
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- data/lib/graphql/schema/non_null.rb +2 -2
- data/lib/graphql/schema/scalar.rb +1 -1
- data/lib/graphql/static_validation/error.rb +2 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
- data/lib/graphql/subscriptions.rb +2 -5
- data/lib/graphql/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8f389d3b7c8052a74ccd4bd9e8412a1fa9d93415e6caeec883b8f179a167395
|
4
|
+
data.tar.gz: f2e6ab7ba5c1e76b0c44557855ab3af55fb2b718b8de1ff6483917de603734b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
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.
|
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
|
-
# @
|
22
|
-
|
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
|
-
|
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?
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -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
|
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -666,7 +666,18 @@ module GraphQL
|
|
666
666
|
inner_object = obj.object
|
667
667
|
|
668
668
|
if defined?(@hash_key)
|
669
|
-
|
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)
|
data/lib/graphql/schema/list.rb
CHANGED
@@ -45,16 +45,24 @@ module GraphQL
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def validate_non_null_input(value, ctx)
|
49
|
-
result =
|
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
|
-
|
53
|
-
|
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
|
|
@@ -9,11 +9,17 @@ module GraphQL
|
|
9
9
|
|
10
10
|
def on_directive(node, parent)
|
11
11
|
if !@directive_names.include?(node.name)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
66
|
-
|
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:
|
data/lib/graphql/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2022-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|