graphql 1.12.23 → 1.13.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/core.rb +3 -1
- data/lib/generators/graphql/install_generator.rb +9 -2
- data/lib/generators/graphql/mutation_generator.rb +1 -1
- data/lib/generators/graphql/type_generator.rb +0 -1
- data/lib/graphql/analysis/ast/field_usage.rb +2 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
- data/lib/graphql/analysis/ast/visitor.rb +4 -4
- data/lib/graphql/backtrace/table.rb +1 -1
- data/lib/graphql/base_type.rb +4 -2
- data/lib/graphql/boolean_type.rb +1 -1
- data/lib/graphql/dataloader.rb +55 -22
- data/lib/graphql/directive/deprecated_directive.rb +1 -1
- data/lib/graphql/directive/include_directive.rb +1 -1
- data/lib/graphql/directive/skip_directive.rb +1 -1
- data/lib/graphql/directive.rb +0 -4
- data/lib/graphql/enum_type.rb +5 -1
- data/lib/graphql/execution/errors.rb +1 -0
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -2
- data/lib/graphql/execution/interpreter/runtime.rb +31 -19
- data/lib/graphql/execution/lookahead.rb +2 -2
- data/lib/graphql/execution/multiplex.rb +4 -1
- data/lib/graphql/float_type.rb +1 -1
- data/lib/graphql/id_type.rb +1 -1
- data/lib/graphql/int_type.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +2 -2
- data/lib/graphql/introspection/input_value_type.rb +4 -4
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +10 -10
- data/lib/graphql/language/block_string.rb +2 -6
- data/lib/graphql/language/document_from_schema_definition.rb +10 -4
- data/lib/graphql/language/lexer.rb +0 -3
- data/lib/graphql/language/lexer.rl +0 -4
- data/lib/graphql/language/nodes.rb +3 -2
- data/lib/graphql/language/parser.rb +442 -434
- data/lib/graphql/language/parser.y +5 -4
- data/lib/graphql/language/printer.rb +6 -1
- data/lib/graphql/language/sanitized_printer.rb +5 -5
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/pagination/active_record_relation_connection.rb +43 -6
- data/lib/graphql/pagination/relation_connection.rb +55 -28
- data/lib/graphql/query/arguments.rb +1 -1
- data/lib/graphql/query/arguments_cache.rb +1 -1
- data/lib/graphql/query/context.rb +15 -2
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +12 -7
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/variables.rb +5 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/relay/global_id_resolve.rb +1 -1
- data/lib/graphql/relay/page_info.rb +1 -1
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/schema/addition.rb +37 -28
- data/lib/graphql/schema/argument.rb +13 -15
- data/lib/graphql/schema/build_from_definition.rb +5 -5
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +7 -3
- data/lib/graphql/schema/enum.rb +60 -10
- data/lib/graphql/schema/enum_value.rb +6 -0
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +229 -77
- data/lib/graphql/schema/field_extension.rb +89 -2
- data/lib/graphql/schema/find_inherited_value.rb +1 -0
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +23 -5
- data/lib/graphql/schema/interface.rb +11 -20
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/list.rb +3 -1
- data/lib/graphql/schema/member/accepts_definition.rb +15 -3
- data/lib/graphql/schema/member/build_type.rb +0 -4
- data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
- data/lib/graphql/schema/member/has_arguments.rb +55 -13
- data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +76 -18
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/non_null.rb +7 -1
- data/lib/graphql/schema/object.rb +10 -75
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +37 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
- data/lib/graphql/schema/resolver.rb +37 -17
- data/lib/graphql/schema/scalar.rb +2 -0
- data/lib/graphql/schema/subscription.rb +11 -1
- data/lib/graphql/schema/traversal.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +8 -1
- data/lib/graphql/schema/validator/format_validator.rb +0 -4
- data/lib/graphql/schema/validator/numericality_validator.rb +1 -0
- data/lib/graphql/schema/validator/required_validator.rb +29 -15
- data/lib/graphql/schema/validator.rb +4 -7
- data/lib/graphql/schema/warden.rb +116 -52
- data/lib/graphql/schema.rb +111 -23
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +5 -5
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/literal_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
- data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
- data/lib/graphql/string_type.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -4
- data/lib/graphql/subscriptions/event.rb +20 -12
- data/lib/graphql/subscriptions/serialize.rb +22 -2
- data/lib/graphql/subscriptions.rb +17 -19
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
- data/lib/graphql/tracing/notifications_tracing.rb +59 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +26 -9
- data/lib/graphql/types/relay/default_relay.rb +5 -1
- data/lib/graphql/types/relay/edge_behaviors.rb +13 -2
- data/lib/graphql/types/relay/has_node_field.rb +1 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
- data/lib/graphql/types/relay/node_field.rb +14 -3
- data/lib/graphql/types/relay/nodes_field.rb +13 -3
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +10 -32
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2638039468d2557513228b7bda7e148a91c02b818090fee27ddc92c9c3ea88a
|
4
|
+
data.tar.gz: 7ae7b8ba26ec64075dd226e3be092cd1216c4b137ce8935e8972e66df3c09c35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54c9be19ab4e29e59af43c251fc661b4d9ae47208eab4461361aef3f460f54422cef1215f4311bb6e10d18571629ea176b46aae78b9bdb9181670dcd72a0fa1d
|
7
|
+
data.tar.gz: b2c3ec10e2600b39d555946d9ba88092eba38f8dd9b7cfd3836ab5341ec59878a1df3d1d295d9889692ed32c9e6e07e1bf307928f8f3d8a199380709070ced4c
|
@@ -19,7 +19,9 @@ module Graphql
|
|
19
19
|
sentinel = /< GraphQL::Schema\s*\n/m
|
20
20
|
|
21
21
|
in_root do
|
22
|
-
|
22
|
+
if File.exist?(schema_file_path)
|
23
|
+
inject_into_file schema_file_path, " #{type}(Types::#{name})\n", after: sentinel, verbose: false, force: false
|
24
|
+
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -122,8 +122,15 @@ module Graphql
|
|
122
122
|
if options.api?
|
123
123
|
say("Skipped graphiql, as this rails project is API only")
|
124
124
|
say(" You may wish to use GraphiQL.app for development: https://github.com/skevy/graphiql-app")
|
125
|
-
elsif !options[:skip_graphiql]
|
126
|
-
gem(
|
125
|
+
elsif !options[:skip_graphiql]
|
126
|
+
# `gem(...)` uses `gsub_file(...)` under the hood, which is a no-op for `rails destroy...` (when `behavior == :revoke`).
|
127
|
+
# So handle that case by calling `gsub_file` with `force: true`.
|
128
|
+
if behavior == :invoke && !File.read(Rails.root.join("Gemfile")).include?("graphiql-rails")
|
129
|
+
gem("graphiql-rails", group: :development)
|
130
|
+
elsif behavior == :revoke
|
131
|
+
gemfile_pattern = /\n\s*gem ('|")graphiql-rails('|"), :?group(:| =>) :development/
|
132
|
+
gsub_file Rails.root.join("Gemfile"), gemfile_pattern, "", { force: true }
|
133
|
+
end
|
127
134
|
|
128
135
|
# This is a little cheat just to get cleaner shell output:
|
129
136
|
log :route, 'graphiql-rails'
|
@@ -17,7 +17,7 @@ module Graphql
|
|
17
17
|
|
18
18
|
argument :name, type: :string
|
19
19
|
|
20
|
-
def initialize(args, *options)
|
20
|
+
def initialize(args, *options) # :nodoc:
|
21
21
|
# Unfreeze name in case it's given as a frozen string
|
22
22
|
args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
|
23
23
|
super
|
@@ -40,12 +40,12 @@ module GraphQL
|
|
40
40
|
end
|
41
41
|
|
42
42
|
if argument.definition.type.kind.input_object?
|
43
|
-
extract_deprecated_arguments(argument.value.arguments.argument_values)
|
43
|
+
extract_deprecated_arguments(argument.value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
44
44
|
elsif argument.definition.type.list? && !argument.value.nil?
|
45
45
|
argument
|
46
46
|
.value
|
47
47
|
.select { |value| value.respond_to?(:arguments) }
|
48
|
-
.each { |value| extract_deprecated_arguments(value.arguments.argument_values) }
|
48
|
+
.each { |value| extract_deprecated_arguments(value.arguments.argument_values) } # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -23,18 +23,22 @@ module GraphQL
|
|
23
23
|
|
24
24
|
attr_reader :field_definition, :response_path, :query
|
25
25
|
|
26
|
-
# @param
|
26
|
+
# @param parent_type [Class] The owner of `field_definition`
|
27
27
|
# @param field_definition [GraphQL::Field, GraphQL::Schema::Field] Used for getting the `.complexity` configuration
|
28
28
|
# @param query [GraphQL::Query] Used for `query.possible_types`
|
29
29
|
# @param response_path [Array<String>] The path to the response key for the field
|
30
|
-
def initialize(
|
31
|
-
@
|
30
|
+
def initialize(parent_type, field_definition, query, response_path)
|
31
|
+
@parent_type = parent_type
|
32
32
|
@field_definition = field_definition
|
33
33
|
@query = query
|
34
34
|
@response_path = response_path
|
35
35
|
@scoped_children = nil
|
36
|
+
@nodes = []
|
36
37
|
end
|
37
38
|
|
39
|
+
# @return [Array<GraphQL::Language::Nodes::Field>]
|
40
|
+
attr_reader :nodes
|
41
|
+
|
38
42
|
# Returns true if this field has no selections, ie, it's a scalar.
|
39
43
|
# We need a quick way to check whether we should continue traversing.
|
40
44
|
def terminal?
|
@@ -50,16 +54,7 @@ module GraphQL
|
|
50
54
|
end
|
51
55
|
|
52
56
|
def own_complexity(child_complexity)
|
53
|
-
|
54
|
-
case defined_complexity
|
55
|
-
when Proc
|
56
|
-
arguments = @query.arguments_for(@node, @field_definition)
|
57
|
-
defined_complexity.call(@query.context, arguments.keyword_arguments, child_complexity)
|
58
|
-
when Numeric
|
59
|
-
defined_complexity + child_complexity
|
60
|
-
else
|
61
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{@field_definition.name}")
|
62
|
-
end
|
57
|
+
@field_definition.calculate_complexity(query: @query, nodes: @nodes, child_complexity: child_complexity)
|
63
58
|
end
|
64
59
|
end
|
65
60
|
|
@@ -79,7 +74,8 @@ module GraphQL
|
|
79
74
|
# then the query would have been rejected as invalid.
|
80
75
|
complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query, visitor.response_path)]
|
81
76
|
|
82
|
-
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(
|
77
|
+
complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(parent_type, visitor.field_definition, visitor.query, visitor.response_path)
|
78
|
+
complexity.nodes.push(node)
|
83
79
|
# Push it on the stack.
|
84
80
|
complexities_on_type.push(complexity)
|
85
81
|
end
|
@@ -100,7 +100,7 @@ module GraphQL
|
|
100
100
|
def on_field(node, parent)
|
101
101
|
@response_path.push(node.alias || node.name)
|
102
102
|
parent_type = @object_types.last
|
103
|
-
field_definition = @schema.get_field(parent_type, node.name)
|
103
|
+
field_definition = @schema.get_field(parent_type, node.name, @query.context)
|
104
104
|
@field_definitions.push(field_definition)
|
105
105
|
if !field_definition.nil?
|
106
106
|
next_object_type = field_definition.type.unwrap
|
@@ -138,14 +138,14 @@ module GraphQL
|
|
138
138
|
argument_defn = if (arg = @argument_definitions.last)
|
139
139
|
arg_type = arg.type.unwrap
|
140
140
|
if arg_type.kind.input_object?
|
141
|
-
arg_type.
|
141
|
+
arg_type.get_argument(node.name, @query.context)
|
142
142
|
else
|
143
143
|
nil
|
144
144
|
end
|
145
145
|
elsif (directive_defn = @directive_definitions.last)
|
146
|
-
directive_defn.
|
146
|
+
directive_defn.get_argument(node.name, @query.context)
|
147
147
|
elsif (field_defn = @field_definitions.last)
|
148
|
-
field_defn.
|
148
|
+
field_defn.get_argument(node.name, @query.context)
|
149
149
|
else
|
150
150
|
nil
|
151
151
|
end
|
@@ -89,7 +89,7 @@ module GraphQL
|
|
89
89
|
"#{context_entry.ast_node ? context_entry.ast_node.position.join(":") : ""}",
|
90
90
|
"#{context_entry.field.path}#{field_alias ? " as #{field_alias}" : ""}",
|
91
91
|
"#{context_entry.object.object.inspect}",
|
92
|
-
context_entry.arguments.to_h.inspect,
|
92
|
+
context_entry.arguments.to_h.inspect, # rubocop:disable Development/ContextIsPassedCop -- unrelated method
|
93
93
|
Backtrace::InspectResult.inspect_result(value),
|
94
94
|
]
|
95
95
|
if (parent = context_entry.parent_frame)
|
data/lib/graphql/base_type.rb
CHANGED
@@ -41,7 +41,9 @@ module GraphQL
|
|
41
41
|
alias :graphql_name :name
|
42
42
|
# Future-compatible alias
|
43
43
|
# @see {GraphQL::SchemaMember}
|
44
|
-
|
44
|
+
def graphql_definition(silence_deprecation_warning: false)
|
45
|
+
itself
|
46
|
+
end
|
45
47
|
|
46
48
|
def type_class
|
47
49
|
metadata[:type_class]
|
@@ -194,7 +196,7 @@ module GraphQL
|
|
194
196
|
resolve_related_type(Object.const_get(type_arg))
|
195
197
|
else
|
196
198
|
if type_arg.respond_to?(:graphql_definition)
|
197
|
-
type_arg.graphql_definition
|
199
|
+
type_arg.graphql_definition(silence_deprecation_warning: true)
|
198
200
|
else
|
199
201
|
type_arg
|
200
202
|
end
|
data/lib/graphql/boolean_type.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::BOOLEAN_TYPE = GraphQL::Types::Boolean.graphql_definition
|
2
|
+
GraphQL::BOOLEAN_TYPE = GraphQL::Types::Boolean.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/dataloader.rb
CHANGED
@@ -23,8 +23,18 @@ module GraphQL
|
|
23
23
|
# end
|
24
24
|
#
|
25
25
|
class Dataloader
|
26
|
-
|
27
|
-
|
26
|
+
class << self
|
27
|
+
attr_accessor :default_nonblocking
|
28
|
+
end
|
29
|
+
|
30
|
+
AsyncDataloader = Class.new(self) { self.default_nonblocking = true }
|
31
|
+
|
32
|
+
def self.use(schema, nonblocking: nil)
|
33
|
+
schema.dataloader_class = if nonblocking
|
34
|
+
AsyncDataloader
|
35
|
+
else
|
36
|
+
self
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
# Call the block with a Dataloader instance,
|
@@ -39,9 +49,16 @@ module GraphQL
|
|
39
49
|
result
|
40
50
|
end
|
41
51
|
|
42
|
-
def initialize
|
52
|
+
def initialize(nonblocking: self.class.default_nonblocking)
|
43
53
|
@source_cache = Hash.new { |h, k| h[k] = {} }
|
44
54
|
@pending_jobs = []
|
55
|
+
if !nonblocking.nil?
|
56
|
+
@nonblocking = nonblocking
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def nonblocking?
|
61
|
+
@nonblocking
|
45
62
|
end
|
46
63
|
|
47
64
|
# Get a Source instance from this dataloader, for calling `.load(...)` or `.request(...)` on.
|
@@ -50,7 +67,7 @@ module GraphQL
|
|
50
67
|
# @param batch_parameters [Array<Object>]
|
51
68
|
# @return [GraphQL::Dataloader::Source] An instance of {source_class}, initialized with `self, *batch_parameters`,
|
52
69
|
# and cached for the lifetime of this {Multiplex}.
|
53
|
-
if RUBY_VERSION < "3"
|
70
|
+
if RUBY_VERSION < "3" || RUBY_ENGINE != "ruby" # truffle-ruby wasn't doing well with the implementation below
|
54
71
|
def with(source_class, *batch_args)
|
55
72
|
batch_key = source_class.batch_key_for(*batch_args)
|
56
73
|
@source_cache[source_class][batch_key] ||= begin
|
@@ -117,6 +134,9 @@ module GraphQL
|
|
117
134
|
|
118
135
|
# @api private Move along, move along
|
119
136
|
def run
|
137
|
+
if @nonblocking && !Fiber.scheduler
|
138
|
+
raise "`nonblocking: true` requires `Fiber.scheduler`, assign one with `Fiber.set_scheduler(...)` before executing GraphQL."
|
139
|
+
end
|
120
140
|
# At a high level, the algorithm is:
|
121
141
|
#
|
122
142
|
# A) Inside Fibers, run jobs from the queue one-by-one
|
@@ -137,6 +157,8 @@ module GraphQL
|
|
137
157
|
#
|
138
158
|
pending_fibers = []
|
139
159
|
next_fibers = []
|
160
|
+
pending_source_fibers = []
|
161
|
+
next_source_fibers = []
|
140
162
|
first_pass = true
|
141
163
|
|
142
164
|
while first_pass || (f = pending_fibers.shift)
|
@@ -174,31 +196,27 @@ module GraphQL
|
|
174
196
|
# This is where an evented approach would be even better -- can we tell which
|
175
197
|
# fibers are ready to continue, and continue execution there?
|
176
198
|
#
|
177
|
-
|
178
|
-
|
179
|
-
else
|
180
|
-
nil
|
199
|
+
if (first_source_fiber = create_source_fiber)
|
200
|
+
pending_source_fibers << first_source_fiber
|
181
201
|
end
|
182
202
|
|
183
|
-
|
184
|
-
while (outer_source_fiber =
|
203
|
+
while pending_source_fibers.any?
|
204
|
+
while (outer_source_fiber = pending_source_fibers.pop)
|
185
205
|
resume(outer_source_fiber)
|
186
|
-
|
187
|
-
# If this source caused more sources to become pending, run those before running this one again:
|
188
|
-
next_source_fiber = create_source_fiber
|
189
|
-
if next_source_fiber
|
190
|
-
source_fiber_queue << next_source_fiber
|
191
|
-
end
|
192
|
-
|
193
206
|
if outer_source_fiber.alive?
|
194
|
-
|
207
|
+
next_source_fibers << outer_source_fiber
|
208
|
+
end
|
209
|
+
if (next_source_fiber = create_source_fiber)
|
210
|
+
pending_source_fibers << next_source_fiber
|
195
211
|
end
|
196
212
|
end
|
213
|
+
join_queues(pending_source_fibers, next_source_fibers)
|
214
|
+
next_source_fibers.clear
|
197
215
|
end
|
198
216
|
# Move newly-enqueued Fibers on to the list to be resumed.
|
199
217
|
# Clear out the list of next-round Fibers, so that
|
200
218
|
# any Fibers that pause can be put on it.
|
201
|
-
pending_fibers
|
219
|
+
join_queues(pending_fibers, next_fibers)
|
202
220
|
next_fibers.clear
|
203
221
|
end
|
204
222
|
end
|
@@ -213,6 +231,14 @@ module GraphQL
|
|
213
231
|
nil
|
214
232
|
end
|
215
233
|
|
234
|
+
def join_queues(previous_queue, next_queue)
|
235
|
+
if @nonblocking
|
236
|
+
Fiber.scheduler.run
|
237
|
+
next_queue.select!(&:alive?)
|
238
|
+
end
|
239
|
+
previous_queue.concat(next_queue)
|
240
|
+
end
|
241
|
+
|
216
242
|
private
|
217
243
|
|
218
244
|
# If there are pending sources, return a fiber for running them.
|
@@ -266,9 +292,16 @@ module GraphQL
|
|
266
292
|
fiber_locals[fiber_var_key] = Thread.current[fiber_var_key]
|
267
293
|
end
|
268
294
|
|
269
|
-
|
270
|
-
|
271
|
-
|
295
|
+
if @nonblocking
|
296
|
+
Fiber.new(blocking: false) do
|
297
|
+
fiber_locals.each { |k, v| Thread.current[k] = v }
|
298
|
+
yield
|
299
|
+
end
|
300
|
+
else
|
301
|
+
Fiber.new do
|
302
|
+
fiber_locals.each { |k, v| Thread.current[k] = v }
|
303
|
+
yield
|
304
|
+
end
|
272
305
|
end
|
273
306
|
end
|
274
307
|
end
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition
|
2
|
+
GraphQL::Directive::DeprecatedDirective = GraphQL::Schema::Directive::Deprecated.graphql_definition(silence_deprecation_warning: true)
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition
|
2
|
+
GraphQL::Directive::IncludeDirective = GraphQL::Schema::Directive::Include.graphql_definition(silence_deprecation_warning: true)
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition
|
2
|
+
GraphQL::Directive::SkipDirective = GraphQL::Schema::Directive::Skip.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/directive.rb
CHANGED
data/lib/graphql/enum_type.rb
CHANGED
@@ -34,10 +34,14 @@ module GraphQL
|
|
34
34
|
end
|
35
35
|
|
36
36
|
# @return [Hash<String => EnumValue>] `{name => value}` pairs contained in this type
|
37
|
-
def values
|
37
|
+
def values(_context = nil)
|
38
38
|
@values_by_name
|
39
39
|
end
|
40
40
|
|
41
|
+
def enum_values(_context = nil)
|
42
|
+
values.values
|
43
|
+
end
|
44
|
+
|
41
45
|
def kind
|
42
46
|
GraphQL::TypeKinds::ENUM
|
43
47
|
end
|
@@ -111,6 +111,7 @@ module GraphQL
|
|
111
111
|
runtime_info = ctx.namespace(:interpreter) || {}
|
112
112
|
obj = runtime_info[:current_object]
|
113
113
|
args = runtime_info[:current_arguments]
|
114
|
+
args = args && args.keyword_arguments
|
114
115
|
field = runtime_info[:current_field]
|
115
116
|
if obj.is_a?(GraphQL::Schema::Object)
|
116
117
|
obj = obj.object
|
@@ -59,7 +59,7 @@ module GraphQL
|
|
59
59
|
@empty
|
60
60
|
end
|
61
61
|
|
62
|
-
def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values
|
62
|
+
def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values, :size, :to_h
|
63
63
|
def_delegators :argument_values, :each_value
|
64
64
|
|
65
65
|
def inspect
|
@@ -71,11 +71,11 @@ module GraphQL
|
|
71
71
|
when Array
|
72
72
|
ast_arg_or_hash_or_value.map { |v| prepare_args_hash(query, v) }
|
73
73
|
when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
|
74
|
-
if ast_arg_or_hash_or_value.arguments.empty?
|
74
|
+
if ast_arg_or_hash_or_value.arguments.empty? # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
75
75
|
return NO_ARGUMENTS
|
76
76
|
end
|
77
77
|
args_hash = {}
|
78
|
-
ast_arg_or_hash_or_value.arguments.each do |arg|
|
78
|
+
ast_arg_or_hash_or_value.arguments.each do |arg| # rubocop:disable Development/ContextIsPassedCop -- AST-related
|
79
79
|
v = prepare_args_hash(query, arg.value)
|
80
80
|
if v != NO_VALUE_GIVEN
|
81
81
|
args_hash[arg.name] = v
|
@@ -314,7 +314,7 @@ module GraphQL
|
|
314
314
|
case node
|
315
315
|
when GraphQL::Language::Nodes::InlineFragment
|
316
316
|
if node.type
|
317
|
-
type_defn = schema.get_type(node.type.name)
|
317
|
+
type_defn = schema.get_type(node.type.name, context)
|
318
318
|
|
319
319
|
# Faster than .map{}.include?()
|
320
320
|
query.warden.possible_types(type_defn).each do |t|
|
@@ -329,7 +329,7 @@ module GraphQL
|
|
329
329
|
end
|
330
330
|
when GraphQL::Language::Nodes::FragmentSpread
|
331
331
|
fragment_def = query.fragments[node.name]
|
332
|
-
type_defn =
|
332
|
+
type_defn = query.get_type(fragment_def.type.name)
|
333
333
|
possible_types = query.warden.possible_types(type_defn)
|
334
334
|
possible_types.each do |t|
|
335
335
|
if t == owner_type
|
@@ -384,7 +384,9 @@ module GraphQL
|
|
384
384
|
ast_node = field_ast_nodes_or_ast_node
|
385
385
|
end
|
386
386
|
field_name = ast_node.name
|
387
|
-
|
387
|
+
# This can't use `query.get_field` because it gets confused on introspection below if `field_defn` isn't `nil`,
|
388
|
+
# because of how `is_introspection` is used to call `.authorized_new` later on.
|
389
|
+
field_defn = @fields_cache[owner_type][field_name] ||= owner_type.get_field(field_name, @context)
|
388
390
|
is_introspection = false
|
389
391
|
if field_defn.nil?
|
390
392
|
field_defn = if owner_type == schema.query && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
|
@@ -419,10 +421,10 @@ module GraphQL
|
|
419
421
|
object = authorized_new(field_defn.owner, object, context)
|
420
422
|
end
|
421
423
|
|
422
|
-
total_args_count = field_defn.arguments.size
|
424
|
+
total_args_count = field_defn.arguments(context).size
|
423
425
|
if total_args_count == 0
|
424
|
-
|
425
|
-
evaluate_selection_with_args(
|
426
|
+
resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
427
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, next_path, ast_node, field_ast_nodes, scoped_context, owner_type, object, is_eager_field, result_name, selections_result, parent_object)
|
426
428
|
else
|
427
429
|
# TODO remove all arguments(...) usages?
|
428
430
|
@query.arguments_cache.dataload_for(ast_node, field_defn, object) do |resolved_arguments|
|
@@ -431,10 +433,10 @@ module GraphQL
|
|
431
433
|
end
|
432
434
|
end
|
433
435
|
|
434
|
-
def evaluate_selection_with_args(
|
436
|
+
def evaluate_selection_with_args(arguments, field_defn, next_path, ast_node, field_ast_nodes, scoped_context, owner_type, object, is_eager_field, result_name, selection_result, parent_object) # rubocop:disable Metrics/ParameterLists
|
435
437
|
context.scoped_context = scoped_context
|
436
438
|
return_type = field_defn.type
|
437
|
-
after_lazy(
|
439
|
+
after_lazy(arguments, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, scoped_context: context.scoped_context, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result) do |resolved_arguments|
|
438
440
|
if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
|
439
441
|
continue_value(next_path, resolved_arguments, owner_type, field_defn, return_type.non_null?, ast_node, result_name, selection_result)
|
440
442
|
next
|
@@ -485,7 +487,7 @@ module GraphQL
|
|
485
487
|
resolved_arguments.keyword_arguments
|
486
488
|
end
|
487
489
|
|
488
|
-
set_all_interpreter_context(nil, nil,
|
490
|
+
set_all_interpreter_context(nil, nil, resolved_arguments, nil)
|
489
491
|
|
490
492
|
# Optimize for the case that field is selected only once
|
491
493
|
if field_ast_nodes.nil? || field_ast_nodes.size == 1
|
@@ -511,10 +513,10 @@ module GraphQL
|
|
511
513
|
rescue GraphQL::ExecutionError => err
|
512
514
|
err
|
513
515
|
end
|
514
|
-
after_lazy(app_result, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, scoped_context: context.scoped_context, owner_object: object, arguments:
|
516
|
+
after_lazy(app_result, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, scoped_context: context.scoped_context, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result) do |inner_result|
|
515
517
|
continue_value = continue_value(next_path, inner_result, owner_type, field_defn, return_type.non_null?, ast_node, result_name, selection_result)
|
516
518
|
if HALT != continue_value
|
517
|
-
continue_field(next_path, continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object,
|
519
|
+
continue_field(next_path, continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result)
|
518
520
|
end
|
519
521
|
end
|
520
522
|
end
|
@@ -637,14 +639,20 @@ module GraphQL
|
|
637
639
|
when Array
|
638
640
|
# It's an array full of execution errors; add them all.
|
639
641
|
if value.any? && value.all? { |v| v.is_a?(GraphQL::ExecutionError) }
|
642
|
+
list_type_at_all = (field && (field.type.list?))
|
640
643
|
if selection_result.nil? || !dead_result?(selection_result)
|
641
644
|
value.each_with_index do |error, index|
|
642
645
|
error.ast_node ||= ast_node
|
643
|
-
error.path ||= path + (
|
646
|
+
error.path ||= path + (list_type_at_all ? [index] : [])
|
644
647
|
context.errors << error
|
645
648
|
end
|
646
649
|
if selection_result
|
647
|
-
|
650
|
+
if list_type_at_all
|
651
|
+
result_without_errors = value.map { |v| v.is_a?(GraphQL::ExecutionError) ? nil : v }
|
652
|
+
set_result(selection_result, result_name, result_without_errors)
|
653
|
+
else
|
654
|
+
set_result(selection_result, result_name, nil)
|
655
|
+
end
|
648
656
|
end
|
649
657
|
end
|
650
658
|
HALT
|
@@ -862,16 +870,20 @@ module GraphQL
|
|
862
870
|
# but don't wrap the continuation below
|
863
871
|
inner_obj = begin
|
864
872
|
query.with_error_handling do
|
865
|
-
|
866
|
-
|
873
|
+
begin
|
874
|
+
if trace
|
875
|
+
query.trace("execute_field_lazy", {owner: owner, field: field, path: path, query: query, object: owner_object, arguments: arguments, ast_node: ast_node}) do
|
876
|
+
schema.sync_lazy(lazy_obj)
|
877
|
+
end
|
878
|
+
else
|
867
879
|
schema.sync_lazy(lazy_obj)
|
868
880
|
end
|
869
|
-
|
870
|
-
|
881
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => err
|
882
|
+
err
|
871
883
|
end
|
872
884
|
end
|
873
|
-
|
874
|
-
|
885
|
+
rescue GraphQL::ExecutionError => ex_err
|
886
|
+
ex_err
|
875
887
|
end
|
876
888
|
yield(inner_obj)
|
877
889
|
end
|
@@ -254,14 +254,14 @@ module GraphQL
|
|
254
254
|
subselections_on_type = selections_on_type
|
255
255
|
if (t = ast_selection.type)
|
256
256
|
# Assuming this is valid, that `t` will be found.
|
257
|
-
on_type = @query.
|
257
|
+
on_type = @query.get_type(t.name).type_class
|
258
258
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
259
259
|
end
|
260
260
|
find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
|
261
261
|
when GraphQL::Language::Nodes::FragmentSpread
|
262
262
|
frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
|
263
263
|
# Again, assuming a valid AST
|
264
|
-
on_type = @query.
|
264
|
+
on_type = @query.get_type(frag_defn.type.name).type_class
|
265
265
|
subselections_on_type = subselections_by_type[on_type] ||= {}
|
266
266
|
find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
|
267
267
|
else
|
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
@queries = queries
|
36
36
|
@queries.each { |q| q.multiplex = self }
|
37
37
|
@context = context
|
38
|
-
@
|
38
|
+
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
|
39
39
|
@tracers = schema.tracers + (context[:tracers] || [])
|
40
40
|
# Support `context: {backtrace: true}`
|
41
41
|
if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
@@ -151,6 +151,9 @@ module GraphQL
|
|
151
151
|
|
152
152
|
result
|
153
153
|
end
|
154
|
+
if query.context.namespace?(:__query_result_extensions__)
|
155
|
+
query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
|
156
|
+
end
|
154
157
|
end
|
155
158
|
|
156
159
|
# use the old `query_execution_strategy` etc to run this query
|
data/lib/graphql/float_type.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::FLOAT_TYPE = GraphQL::Types::Float.graphql_definition
|
2
|
+
GraphQL::FLOAT_TYPE = GraphQL::Types::Float.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/id_type.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::ID_TYPE = GraphQL::Types::ID.graphql_definition
|
2
|
+
GraphQL::ID_TYPE = GraphQL::Types::ID.graphql_definition(silence_deprecation_warning: true)
|
data/lib/graphql/int_type.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
GraphQL::INT_TYPE = GraphQL::Types::Int.graphql_definition
|
2
|
+
GraphQL::INT_TYPE = GraphQL::Types::Int.graphql_definition(silence_deprecation_warning: true)
|
@@ -10,7 +10,7 @@ module GraphQL
|
|
10
10
|
"skipping a field. Directives provide this by describing additional information "\
|
11
11
|
"to the executor."
|
12
12
|
field :name, String, null: false, method: :graphql_name
|
13
|
-
field :description, String
|
13
|
+
field :description, String
|
14
14
|
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
|
15
15
|
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
16
16
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
@@ -3,8 +3,8 @@ module GraphQL
|
|
3
3
|
module Introspection
|
4
4
|
class EntryPoints < Introspection::BaseObject
|
5
5
|
field :__schema, GraphQL::Schema::LateBoundType.new("__Schema"), "This GraphQL schema", null: false
|
6
|
-
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system"
|
7
|
-
argument :name, String
|
6
|
+
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system" do
|
7
|
+
argument :name, String
|
8
8
|
end
|
9
9
|
|
10
10
|
def __schema
|
@@ -7,9 +7,9 @@ module GraphQL
|
|
7
7
|
"placeholder for a string or numeric value. However an Enum value is returned in "\
|
8
8
|
"a JSON response as a string."
|
9
9
|
field :name, String, null: false
|
10
|
-
field :description, String
|
10
|
+
field :description, String
|
11
11
|
field :is_deprecated, Boolean, null: false
|
12
|
-
field :deprecation_reason, String
|
12
|
+
field :deprecation_reason, String
|
13
13
|
|
14
14
|
def name
|
15
15
|
object.graphql_name
|