graphql 2.1.5 → 2.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/backtrace/trace.rb +12 -15
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/interpreter.rb +1 -1
- data/lib/graphql/language/block_string.rb +6 -2
- data/lib/graphql/query/null_context.rb +2 -1
- data/lib/graphql/query.rb +0 -2
- data/lib/graphql/railtie.rb +9 -6
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +1 -1
- data/lib/graphql/schema.rb +12 -4
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
- data/lib/graphql/subscriptions/event.rb +7 -1
- data/lib/graphql/subscriptions.rb +2 -2
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +13 -0
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0e3e74b44a52e45b992da7fe79d28ff53ea9871ac621517888f887c1a0bd8fb
|
4
|
+
data.tar.gz: fc0a67822082dfc133b1b7f44135df17a5181de2e8404d4b756c4ac0b69a9761
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00bcdc566706f6fc323b0872c5c36230e7964a518e37825dc14a49cc274cbcac099ab3dca8a24608fafb598dcdfb5c239abb2be81359fd234dbce6954530c044
|
7
|
+
data.tar.gz: efb58609553a215455f026bd686b01c699ea858a732733554198150c1c6a0b8f4b60b514c3aa0532bdc611267039c413cb82b5a63bff7a2a7f6b948a3c154814
|
@@ -2,6 +2,12 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Backtrace
|
4
4
|
module Trace
|
5
|
+
def initialize(*args, **kwargs, &block)
|
6
|
+
@__backtrace_contexts = {}
|
7
|
+
@__backtrace_last_context = nil
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
5
11
|
def validate(query:, validate:)
|
6
12
|
if query.multiplex
|
7
13
|
push_query_backtrace_context(query)
|
@@ -42,36 +48,27 @@ module GraphQL
|
|
42
48
|
rescue StandardError => err
|
43
49
|
# This is an unhandled error from execution,
|
44
50
|
# Re-raise it with a GraphQL trace.
|
45
|
-
|
46
|
-
potential_context = multiplex_context[:last_graphql_backtrace_context]
|
47
|
-
|
51
|
+
potential_context = @__backtrace_last_context
|
48
52
|
if potential_context.is_a?(GraphQL::Query::Context) ||
|
49
53
|
potential_context.is_a?(Backtrace::Frame)
|
50
54
|
raise TracedError.new(err, potential_context)
|
51
55
|
else
|
52
56
|
raise
|
53
57
|
end
|
54
|
-
ensure
|
55
|
-
multiplex_context = multiplex.context
|
56
|
-
multiplex_context.delete(:graphql_backtrace_contexts)
|
57
|
-
multiplex_context.delete(:last_graphql_backtrace_context)
|
58
58
|
end
|
59
59
|
|
60
60
|
private
|
61
61
|
|
62
62
|
def push_query_backtrace_context(query)
|
63
63
|
push_data = query
|
64
|
-
multiplex = query.multiplex
|
65
64
|
push_key = []
|
66
|
-
|
67
|
-
|
68
|
-
multiplex.context[:last_graphql_backtrace_context] = push_data
|
65
|
+
@__backtrace_contexts[push_key] = push_data
|
66
|
+
@__backtrace_last_context = push_data
|
69
67
|
end
|
70
68
|
|
71
69
|
def push_field_backtrace_context(field, query, ast_node, arguments, object)
|
72
|
-
multiplex = query.multiplex
|
73
70
|
push_key = query.context[:current_path]
|
74
|
-
push_storage =
|
71
|
+
push_storage = @__backtrace_contexts
|
75
72
|
parent_frame = push_storage[push_key[0..-2]]
|
76
73
|
|
77
74
|
if parent_frame.is_a?(GraphQL::Query)
|
@@ -87,10 +84,10 @@ module GraphQL
|
|
87
84
|
arguments: arguments,
|
88
85
|
parent_frame: parent_frame,
|
89
86
|
)
|
90
|
-
|
91
87
|
push_storage[push_key] = push_data
|
92
|
-
|
88
|
+
@__backtrace_last_context = push_data
|
93
89
|
end
|
90
|
+
|
94
91
|
end
|
95
92
|
end
|
96
93
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
# This error is raised when `Types::ISO8601Duration` is asked to return a value
|
4
|
+
# that cannot be parsed as an ISO8601-formatted duration by ActiveSupport::Duration.
|
5
|
+
#
|
6
|
+
# @see GraphQL::Types::ISO8601Duration which raises this error
|
7
|
+
class DurationEncodingError < GraphQL::RuntimeTypeError
|
8
|
+
# The value which couldn't be encoded
|
9
|
+
attr_reader :duration_value
|
10
|
+
|
11
|
+
def initialize(value)
|
12
|
+
@duration_value = value
|
13
|
+
super("Duration cannot be parsed: #{value}. \nDuration must be an ISO8601-formatted duration.")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -47,10 +47,10 @@ module GraphQL
|
|
47
47
|
end
|
48
48
|
|
49
49
|
# Remove leading & trailing blank lines
|
50
|
-
while lines.size > 0 && lines
|
50
|
+
while lines.size > 0 && contains_only_whitespace?(lines.first)
|
51
51
|
lines.shift
|
52
52
|
end
|
53
|
-
while lines.size > 0 && lines
|
53
|
+
while lines.size > 0 && contains_only_whitespace?(lines.last)
|
54
54
|
lines.pop
|
55
55
|
end
|
56
56
|
|
@@ -106,6 +106,10 @@ module GraphQL
|
|
106
106
|
|
107
107
|
nil
|
108
108
|
end
|
109
|
+
|
110
|
+
def self.contains_only_whitespace?(line)
|
111
|
+
line.match?(/^\s*$/)
|
112
|
+
end
|
109
113
|
end
|
110
114
|
end
|
111
115
|
end
|
data/lib/graphql/query.rb
CHANGED
@@ -115,8 +115,6 @@ module GraphQL
|
|
115
115
|
if schema.trace_class <= GraphQL::Tracing::CallLegacyTracers
|
116
116
|
context_tracers += [GraphQL::Backtrace::Tracer]
|
117
117
|
@tracers << GraphQL::Backtrace::Tracer
|
118
|
-
elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
|
119
|
-
raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
|
120
118
|
end
|
121
119
|
end
|
122
120
|
|
data/lib/graphql/railtie.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module GraphQL
|
3
4
|
class Railtie < Rails::Railtie
|
4
|
-
config.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
if
|
9
|
-
Language::Parser.cache ||= Language::Cache.new(
|
5
|
+
config.graphql = ActiveSupport::OrderedOptions.new
|
6
|
+
config.graphql.parser_cache = false
|
7
|
+
|
8
|
+
initializer("graphql.cache") do |app|
|
9
|
+
if config.graphql.parser_cache
|
10
|
+
Language::Parser.cache ||= Language::Cache.new(
|
11
|
+
app.root.join("tmp/cache/graphql")
|
12
|
+
)
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
@@ -145,7 +145,7 @@ module GraphQL
|
|
145
145
|
end
|
146
146
|
|
147
147
|
# @api private
|
148
|
-
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object
|
148
|
+
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
|
149
149
|
|
150
150
|
def validate_non_null_input(input, ctx, max_errors: nil)
|
151
151
|
warden = ctx.warden
|
@@ -21,7 +21,7 @@ module GraphQL
|
|
21
21
|
if @reauthorize_scoped_objects != nil
|
22
22
|
@reauthorize_scoped_objects
|
23
23
|
else
|
24
|
-
find_inherited_value(:reauthorize_scoped_objects,
|
24
|
+
find_inherited_value(:reauthorize_scoped_objects, true)
|
25
25
|
end
|
26
26
|
else
|
27
27
|
@reauthorize_scoped_objects = new_value
|
data/lib/graphql/schema.rb
CHANGED
@@ -171,9 +171,9 @@ module GraphQL
|
|
171
171
|
end
|
172
172
|
|
173
173
|
# @return [Class] Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn't have one defined.
|
174
|
-
def trace_class_for(mode)
|
174
|
+
def trace_class_for(mode, build: true)
|
175
175
|
own_trace_modes[mode] ||
|
176
|
-
(superclass.respond_to?(:trace_class_for) ? superclass.trace_class_for(mode) : (own_trace_modes[mode] = build_trace_mode(mode)))
|
176
|
+
(superclass.respond_to?(:trace_class_for) ? superclass.trace_class_for(mode, build: build) : (build ? (own_trace_modes[mode] = build_trace_mode(mode)) : nil))
|
177
177
|
end
|
178
178
|
|
179
179
|
# Configure `trace_class` to be used whenever `context: { trace_mode: mode_name }` is requested.
|
@@ -218,7 +218,7 @@ module GraphQL
|
|
218
218
|
else
|
219
219
|
# First, see if the superclass has a custom-defined class for this.
|
220
220
|
# Then, if it doesn't, use this class's default trace
|
221
|
-
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || trace_class_for(:default)
|
221
|
+
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode, build: false)) || trace_class_for(:default)
|
222
222
|
# Prepare the default trace class if it hasn't been initialized yet
|
223
223
|
base_class ||= (own_trace_modes[:default] = build_trace_mode(:default))
|
224
224
|
mods = trace_modules_for(mode)
|
@@ -680,7 +680,7 @@ module GraphQL
|
|
680
680
|
else
|
681
681
|
string_or_document
|
682
682
|
end
|
683
|
-
query =
|
683
|
+
query = query_class.new(self, document: doc, context: context)
|
684
684
|
validator_opts = { schema: self }
|
685
685
|
rules && (validator_opts[:rules] = rules)
|
686
686
|
validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
|
@@ -688,6 +688,14 @@ module GraphQL
|
|
688
688
|
res[:errors]
|
689
689
|
end
|
690
690
|
|
691
|
+
def query_class(new_query_class = NOT_CONFIGURED)
|
692
|
+
if NOT_CONFIGURED.equal?(new_query_class)
|
693
|
+
@query_class || (superclass.respond_to?(:query_class) ? superclass.query_class : GraphQL::Query)
|
694
|
+
else
|
695
|
+
@query_class = new_query_class
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
691
699
|
attr_writer :validate_max_errors
|
692
700
|
|
693
701
|
def validate_max_errors(new_validate_max_errors = nil)
|
@@ -126,7 +126,13 @@ module GraphQL
|
|
126
126
|
when GraphQL::Schema::InputObject
|
127
127
|
stringify_args(arg_owner, args.to_h, context)
|
128
128
|
else
|
129
|
-
|
129
|
+
if arg_owner.is_a?(Class) && arg_owner < GraphQL::Schema::Enum
|
130
|
+
# `prepare:` may have made the value something other than
|
131
|
+
# a defined value of this enum -- use _that_ in this case.
|
132
|
+
arg_owner.coerce_isolated_input(args) || args
|
133
|
+
else
|
134
|
+
args
|
135
|
+
end
|
130
136
|
end
|
131
137
|
end
|
132
138
|
|
@@ -62,7 +62,7 @@ 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
|
-
dummy_query =
|
65
|
+
dummy_query = @schema.query_class.new(@schema, "{ __typename }", validate: false, context: context)
|
66
66
|
context = dummy_query.context
|
67
67
|
event_name = event_name.to_s
|
68
68
|
|
@@ -234,7 +234,7 @@ module GraphQL
|
|
234
234
|
|
235
235
|
# @return [Boolean] if true, then a query like this one would be broadcasted
|
236
236
|
def broadcastable?(query_str, **query_options)
|
237
|
-
query =
|
237
|
+
query = @schema.query_class.new(@schema, query_str, **query_options)
|
238
238
|
if !query.valid?
|
239
239
|
raise "Invalid query: #{query.validation_errors.map(&:to_h).inspect}"
|
240
240
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Types
|
4
|
+
# This scalar takes `Duration`s and transmits them as strings,
|
5
|
+
# using ISO 8601 format. ActiveSupport >= 5.0 must be loaded to use
|
6
|
+
# this scalar.
|
7
|
+
#
|
8
|
+
# Use it for fields or arguments as follows:
|
9
|
+
#
|
10
|
+
# field :age, GraphQL::Types::ISO8601Duration, null: false
|
11
|
+
#
|
12
|
+
# argument :interval, GraphQL::Types::ISO8601Duration, null: false
|
13
|
+
#
|
14
|
+
# Alternatively, use this built-in scalar as inspiration for your
|
15
|
+
# own Duration type.
|
16
|
+
class ISO8601Duration < GraphQL::Schema::Scalar
|
17
|
+
description "An ISO 8601-encoded duration"
|
18
|
+
|
19
|
+
# @return [Integer, nil]
|
20
|
+
def self.seconds_precision
|
21
|
+
# ActiveSupport::Duration precision defaults to whatever input was given
|
22
|
+
@seconds_precision
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Integer, nil] value
|
26
|
+
def self.seconds_precision=(value)
|
27
|
+
@seconds_precision = value
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param value [ActiveSupport::Duration, String]
|
31
|
+
# @return [String]
|
32
|
+
# @raise [GraphQL::Error] if ActiveSupport::Duration is not defined or if an incompatible object is passed
|
33
|
+
def self.coerce_result(value, _ctx)
|
34
|
+
unless defined?(ActiveSupport::Duration)
|
35
|
+
raise GraphQL::Error, "ActiveSupport >= 5.0 must be loaded to use the built-in ISO8601Duration type."
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
case value
|
40
|
+
when ActiveSupport::Duration
|
41
|
+
value.iso8601(precision: seconds_precision)
|
42
|
+
when ::String
|
43
|
+
ActiveSupport::Duration.parse(value).iso8601(precision: seconds_precision)
|
44
|
+
else
|
45
|
+
# Try calling as ActiveSupport::Duration compatible as a fallback
|
46
|
+
value.iso8601(precision: seconds_precision)
|
47
|
+
end
|
48
|
+
rescue StandardError => error
|
49
|
+
raise GraphQL::Error, "An incompatible object (#{value.class}) was given to #{self}. Make sure that only ActiveSupport::Durations and well-formatted Strings are used with this type. (#{error.message})"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param value [String, ActiveSupport::Duration]
|
54
|
+
# @return [ActiveSupport::Duration, nil]
|
55
|
+
# @raise [GraphQL::Error] if ActiveSupport::Duration is not defined
|
56
|
+
# @raise [GraphQL::DurationEncodingError] if duration cannot be parsed
|
57
|
+
def self.coerce_input(value, ctx)
|
58
|
+
unless defined?(ActiveSupport::Duration)
|
59
|
+
raise GraphQL::Error, "ActiveSupport >= 5.0 must be loaded to use the built-in ISO8601Duration type."
|
60
|
+
end
|
61
|
+
|
62
|
+
begin
|
63
|
+
if value.is_a?(ActiveSupport::Duration)
|
64
|
+
value
|
65
|
+
elsif value.nil?
|
66
|
+
nil
|
67
|
+
else
|
68
|
+
ActiveSupport::Duration.parse(value)
|
69
|
+
end
|
70
|
+
rescue ArgumentError, TypeError
|
71
|
+
err = GraphQL::DurationEncodingError.new(value)
|
72
|
+
ctx.schema.type_error(err, ctx)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -87,6 +87,19 @@ module GraphQL
|
|
87
87
|
node_type.scope_items(items, context)
|
88
88
|
end
|
89
89
|
|
90
|
+
# The connection will skip auth on its nodes if the node_type is configured for that
|
91
|
+
def reauthorize_scoped_objects(new_value = nil)
|
92
|
+
if new_value.nil?
|
93
|
+
if @reauthorize_scoped_objects != nil
|
94
|
+
@reauthorize_scoped_objects
|
95
|
+
else
|
96
|
+
node_type.reauthorize_scoped_objects
|
97
|
+
end
|
98
|
+
else
|
99
|
+
@reauthorize_scoped_objects = new_value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
90
103
|
# Add the shortcut `nodes` field to this connection and its subclasses
|
91
104
|
def nodes_field(node_nullable: self.node_nullable, field_options: nil)
|
92
105
|
define_nodes_field(node_nullable, field_options: field_options)
|
data/lib/graphql/types.rb
CHANGED
@@ -6,6 +6,7 @@ require "graphql/types/id"
|
|
6
6
|
require "graphql/types/int"
|
7
7
|
require "graphql/types/iso_8601_date"
|
8
8
|
require "graphql/types/iso_8601_date_time"
|
9
|
+
require "graphql/types/iso_8601_duration"
|
9
10
|
require "graphql/types/json"
|
10
11
|
require "graphql/types/string"
|
11
12
|
require "graphql/types/relay"
|
data/lib/graphql/version.rb
CHANGED
data/lib/graphql.rb
CHANGED
@@ -88,6 +88,7 @@ require "graphql/integer_decoding_error"
|
|
88
88
|
require "graphql/integer_encoding_error"
|
89
89
|
require "graphql/string_encoding_error"
|
90
90
|
require "graphql/date_encoding_error"
|
91
|
+
require "graphql/duration_encoding_error"
|
91
92
|
require "graphql/type_kinds"
|
92
93
|
require "graphql/name_validator"
|
93
94
|
require "graphql/language"
|
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.1.
|
4
|
+
version: 2.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: racc
|
@@ -315,6 +315,7 @@ files:
|
|
315
315
|
- lib/graphql/date_encoding_error.rb
|
316
316
|
- lib/graphql/deprecation.rb
|
317
317
|
- lib/graphql/dig.rb
|
318
|
+
- lib/graphql/duration_encoding_error.rb
|
318
319
|
- lib/graphql/execution.rb
|
319
320
|
- lib/graphql/execution/directive_checks.rb
|
320
321
|
- lib/graphql/execution/errors.rb
|
@@ -584,6 +585,7 @@ files:
|
|
584
585
|
- lib/graphql/types/int.rb
|
585
586
|
- lib/graphql/types/iso_8601_date.rb
|
586
587
|
- lib/graphql/types/iso_8601_date_time.rb
|
588
|
+
- lib/graphql/types/iso_8601_duration.rb
|
587
589
|
- lib/graphql/types/json.rb
|
588
590
|
- lib/graphql/types/relay.rb
|
589
591
|
- lib/graphql/types/relay/base_connection.rb
|