graphql 2.2.5 → 2.3.3
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/generators/graphql/templates/schema.erb +3 -0
- data/lib/graphql/analysis/ast/field_usage.rb +36 -9
- data/lib/graphql/analysis/ast/query_complexity.rb +3 -0
- data/lib/graphql/analysis/ast/visitor.rb +8 -0
- data/lib/graphql/analysis/ast.rb +10 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +6 -4
- data/lib/graphql/execution/interpreter/runtime.rb +93 -106
- data/lib/graphql/execution/interpreter.rb +90 -150
- data/lib/graphql/introspection/entry_points.rb +9 -3
- data/lib/graphql/introspection/schema_type.rb +3 -1
- data/lib/graphql/language/document_from_schema_definition.rb +2 -3
- data/lib/graphql/language/lexer.rb +48 -30
- data/lib/graphql/language/nodes.rb +11 -16
- data/lib/graphql/language/parser.rb +94 -45
- data/lib/graphql/language/printer.rb +4 -0
- data/lib/graphql/language.rb +60 -0
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/query/context.rb +30 -33
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +3 -3
- data/lib/graphql/schema/argument.rb +18 -2
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +9 -1
- data/lib/graphql/schema/field.rb +33 -30
- data/lib/graphql/schema/input_object.rb +1 -2
- data/lib/graphql/schema/interface.rb +5 -1
- data/lib/graphql/schema/loader.rb +2 -1
- data/lib/graphql/schema/member/has_arguments.rb +2 -2
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/resolver.rb +19 -10
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema.rb +129 -29
- data/lib/graphql/static_validation/literal_validator.rb +1 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -0
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +0 -3
- data/lib/graphql/testing/helpers.rb +32 -6
- data/lib/graphql/tracing/data_dog_trace.rb +21 -34
- data/lib/graphql/tracing/data_dog_tracing.rb +7 -21
- data/lib/graphql/tracing/legacy_hooks_trace.rb +74 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +3 -1
- data/lib/graphql/tracing/prometheus_trace.rb +2 -2
- data/lib/graphql/tracing/sentry_trace.rb +112 -0
- data/lib/graphql/tracing.rb +3 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +10 -2
- metadata +38 -23
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1511256e7812b5c2de2a01ffa44f8a77f2e8959837344eaf1c8780d0b1bf700
|
4
|
+
data.tar.gz: 87a0734b541d8f2cbbd3fb293a63663cbc57c61e6ab39242449596c6ca759442
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fff5ef36d8e8dff310cac664178ebf0e902cd067a893fedd164902625751fe457a070f1daf2a2251d0dd2ec57fb16daccc81b54267048bbb71c027caf7905100
|
7
|
+
data.tar.gz: 5fc4e6c4a44398e9f77d99c5224d22128a9c80e64a17a156500337b4d658270da9aa7af71f8d06cc065939cc42b41de3e07d66cb7622704ad179424c312dd7a0
|
@@ -26,6 +26,9 @@ class <%= schema_name %> < GraphQL::Schema
|
|
26
26
|
raise(GraphQL::RequiredImplementationMissingError)
|
27
27
|
end
|
28
28
|
|
29
|
+
# Limit the size of incoming queries:
|
30
|
+
max_query_string_tokens(5000)
|
31
|
+
|
29
32
|
# Stop validating when it encounters this many errors:
|
30
33
|
validate_max_errors(100)
|
31
34
|
end
|
@@ -8,6 +8,7 @@ module GraphQL
|
|
8
8
|
@used_fields = Set.new
|
9
9
|
@used_deprecated_fields = Set.new
|
10
10
|
@used_deprecated_arguments = Set.new
|
11
|
+
@used_deprecated_enum_values = Set.new
|
11
12
|
end
|
12
13
|
|
13
14
|
def on_leave_field(node, parent, visitor)
|
@@ -15,7 +16,7 @@ module GraphQL
|
|
15
16
|
field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
|
16
17
|
@used_fields << field
|
17
18
|
@used_deprecated_fields << field if field_defn.deprecation_reason
|
18
|
-
arguments = visitor.query.arguments_for(node,
|
19
|
+
arguments = visitor.query.arguments_for(node, field_defn)
|
19
20
|
# If there was an error when preparing this argument object,
|
20
21
|
# then this might be an error or something:
|
21
22
|
if arguments.respond_to?(:argument_values)
|
@@ -28,6 +29,7 @@ module GraphQL
|
|
28
29
|
used_fields: @used_fields.to_a,
|
29
30
|
used_deprecated_fields: @used_deprecated_fields.to_a,
|
30
31
|
used_deprecated_arguments: @used_deprecated_arguments.to_a,
|
32
|
+
used_deprecated_enum_values: @used_deprecated_enum_values.to_a,
|
31
33
|
}
|
32
34
|
end
|
33
35
|
|
@@ -39,18 +41,43 @@ module GraphQL
|
|
39
41
|
@used_deprecated_arguments << argument.definition.path
|
40
42
|
end
|
41
43
|
|
42
|
-
|
44
|
+
arg_val = argument.value
|
43
45
|
|
44
|
-
if
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
51
71
|
end
|
52
72
|
end
|
53
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
|
54
81
|
end
|
55
82
|
end
|
56
83
|
end
|
@@ -8,6 +8,7 @@ module GraphQL
|
|
8
8
|
# - `complexities_on_type` holds complexity scores for each type
|
9
9
|
def initialize(query)
|
10
10
|
super
|
11
|
+
@skip_introspection_fields = !query.schema.max_complexity_count_introspection_fields
|
11
12
|
@complexities_on_type_by_query = {}
|
12
13
|
end
|
13
14
|
|
@@ -51,6 +52,7 @@ module GraphQL
|
|
51
52
|
# we'll visit them when we hit the spreads instead
|
52
53
|
return if visitor.visiting_fragment_definition?
|
53
54
|
return if visitor.skipping?
|
55
|
+
return if @skip_introspection_fields && visitor.field_definition.introspection?
|
54
56
|
parent_type = visitor.parent_type_definition
|
55
57
|
field_key = node.alias || node.name
|
56
58
|
|
@@ -68,6 +70,7 @@ module GraphQL
|
|
68
70
|
# we'll visit them when we hit the spreads instead
|
69
71
|
return if visitor.visiting_fragment_definition?
|
70
72
|
return if visitor.skipping?
|
73
|
+
return if @skip_introspection_fields && visitor.field_definition.introspection?
|
71
74
|
scopes_stack = @complexities_on_type_by_query[visitor.query]
|
72
75
|
scopes_stack.pop
|
73
76
|
end
|
@@ -118,8 +118,12 @@ module GraphQL
|
|
118
118
|
def on_inline_fragment(node, parent)
|
119
119
|
on_fragment_with_type(node) do
|
120
120
|
@path.push("...#{node.type ? " on #{node.type.name}" : ""}")
|
121
|
+
@skipping = @skip_stack.last || skip?(node)
|
122
|
+
@skip_stack << @skipping
|
123
|
+
|
121
124
|
call_on_enter_inline_fragment(node, parent)
|
122
125
|
super
|
126
|
+
@skipping = @skip_stack.pop
|
123
127
|
call_on_leave_inline_fragment(node, parent)
|
124
128
|
end
|
125
129
|
end
|
@@ -187,9 +191,13 @@ module GraphQL
|
|
187
191
|
|
188
192
|
def on_fragment_spread(node, parent)
|
189
193
|
@path.push("... #{node.name}")
|
194
|
+
@skipping = @skip_stack.last || skip?(node)
|
195
|
+
@skip_stack << @skipping
|
196
|
+
|
190
197
|
call_on_enter_fragment_spread(node, parent)
|
191
198
|
enter_fragment_spread_inline(node)
|
192
199
|
super
|
200
|
+
@skipping = @skip_stack.pop
|
193
201
|
leave_fragment_spread_inline(node)
|
194
202
|
call_on_leave_fragment_spread(node, parent)
|
195
203
|
@path.pop
|
data/lib/graphql/analysis/ast.rb
CHANGED
@@ -6,6 +6,7 @@ require "graphql/analysis/ast/query_complexity"
|
|
6
6
|
require "graphql/analysis/ast/max_query_complexity"
|
7
7
|
require "graphql/analysis/ast/query_depth"
|
8
8
|
require "graphql/analysis/ast/max_query_depth"
|
9
|
+
require "timeout"
|
9
10
|
|
10
11
|
module GraphQL
|
11
12
|
module Analysis
|
@@ -63,7 +64,10 @@ module GraphQL
|
|
63
64
|
analyzers: analyzers_to_run
|
64
65
|
)
|
65
66
|
|
66
|
-
|
67
|
+
# `nil` or `0` causes no timeout
|
68
|
+
Timeout::timeout(query.validate_timeout_remaining) do
|
69
|
+
visitor.visit
|
70
|
+
end
|
67
71
|
|
68
72
|
if visitor.rescued_errors.any?
|
69
73
|
return visitor.rescued_errors
|
@@ -75,6 +79,11 @@ module GraphQL
|
|
75
79
|
[]
|
76
80
|
end
|
77
81
|
end
|
82
|
+
rescue Timeout::Error
|
83
|
+
[GraphQL::AnalysisError.new("Timeout on validation of query")]
|
84
|
+
rescue GraphQL::UnauthorizedError
|
85
|
+
# This error was raised during analysis and will be returned the client before execution
|
86
|
+
[]
|
78
87
|
end
|
79
88
|
|
80
89
|
def analysis_errors(results)
|
@@ -16,12 +16,6 @@ module GraphQL
|
|
16
16
|
"[" +
|
17
17
|
obj.map { |v| inspect_truncated(v) }.join(", ") +
|
18
18
|
"]"
|
19
|
-
when Query::Context::SharedMethods
|
20
|
-
if obj.invalid_null?
|
21
|
-
"nil"
|
22
|
-
else
|
23
|
-
inspect_truncated(obj.value)
|
24
|
-
end
|
25
19
|
else
|
26
20
|
inspect_truncated(obj)
|
27
21
|
end
|
@@ -33,12 +27,6 @@ module GraphQL
|
|
33
27
|
"{...}"
|
34
28
|
when Array
|
35
29
|
"[...]"
|
36
|
-
when Query::Context::SharedMethods
|
37
|
-
if obj.invalid_null?
|
38
|
-
"nil"
|
39
|
-
else
|
40
|
-
inspect_truncated(obj.value)
|
41
|
-
end
|
42
30
|
when GraphQL::Execution::Lazy
|
43
31
|
"(unresolved)"
|
44
32
|
else
|
@@ -1,13 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
|
-
class CoercionError < GraphQL::
|
4
|
-
# @return [Hash] Optional custom data for error objects which will be added
|
5
|
-
# under the `extensions` key.
|
6
|
-
attr_accessor :extensions
|
7
|
-
|
8
|
-
def initialize(message, extensions: nil)
|
9
|
-
@extensions = extensions
|
10
|
-
super(message)
|
11
|
-
end
|
3
|
+
class CoercionError < GraphQL::ExecutionError
|
12
4
|
end
|
13
5
|
end
|
@@ -14,6 +14,11 @@ module GraphQL
|
|
14
14
|
def load
|
15
15
|
@source.load(@key)
|
16
16
|
end
|
17
|
+
|
18
|
+
def load_with_deprecation_warning
|
19
|
+
warn("Returning `.request(...)` from GraphQL::Dataloader is deprecated, use `.load(...)` instead. (See usage of #{@source} with #{@key.inspect}).")
|
20
|
+
load
|
21
|
+
end
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -6,15 +6,19 @@ module GraphQL
|
|
6
6
|
# A container for metadata regarding arguments present in a GraphQL query.
|
7
7
|
# @see Interpreter::Arguments#argument_values for a hash of these objects.
|
8
8
|
class ArgumentValue
|
9
|
-
def initialize(definition:, value:, default_used:)
|
9
|
+
def initialize(definition:, value:, original_value:, default_used:)
|
10
10
|
@definition = definition
|
11
11
|
@value = value
|
12
|
+
@original_value = original_value
|
12
13
|
@default_used = default_used
|
13
14
|
end
|
14
15
|
|
15
16
|
# @return [Object] The Ruby-ready value for this Argument
|
16
17
|
attr_reader :value
|
17
18
|
|
19
|
+
# @return [Object] The value of this argument _before_ `prepare` is applied.
|
20
|
+
attr_reader :original_value
|
21
|
+
|
18
22
|
# @return [GraphQL::Schema::Argument] The definition instance for this argument
|
19
23
|
attr_reader :definition
|
20
24
|
|
@@ -5,8 +5,10 @@ module GraphQL
|
|
5
5
|
class Interpreter
|
6
6
|
class Runtime
|
7
7
|
module GraphQLResult
|
8
|
-
def initialize(result_name, parent_result, is_non_null_in_parent)
|
8
|
+
def initialize(result_name, result_type, application_value, parent_result, is_non_null_in_parent)
|
9
9
|
@graphql_parent = parent_result
|
10
|
+
@graphql_application_value = application_value
|
11
|
+
@graphql_result_type = result_type
|
10
12
|
if parent_result && parent_result.graphql_dead
|
11
13
|
@graphql_dead = true
|
12
14
|
end
|
@@ -26,14 +28,14 @@ module GraphQL
|
|
26
28
|
end
|
27
29
|
|
28
30
|
attr_accessor :graphql_dead
|
29
|
-
attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent
|
31
|
+
attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent, :graphql_application_value, :graphql_result_type
|
30
32
|
|
31
33
|
# @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
|
32
34
|
attr_accessor :graphql_result_data
|
33
35
|
end
|
34
36
|
|
35
37
|
class GraphQLResultHash
|
36
|
-
def initialize(_result_name, _parent_result, _is_non_null_in_parent)
|
38
|
+
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent)
|
37
39
|
super
|
38
40
|
@graphql_result_data = {}
|
39
41
|
end
|
@@ -121,7 +123,7 @@ module GraphQL
|
|
121
123
|
class GraphQLResultArray
|
122
124
|
include GraphQLResult
|
123
125
|
|
124
|
-
def initialize(_result_name, _parent_result, _is_non_null_in_parent)
|
126
|
+
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent)
|
125
127
|
super
|
126
128
|
@graphql_result_data = []
|
127
129
|
end
|