graphql 2.4.4 → 2.4.5
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.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/visitor.rb +1 -1
- data/lib/graphql/analysis.rb +3 -3
- data/lib/graphql/autoload.rb +37 -0
- data/lib/graphql/current.rb +1 -1
- data/lib/graphql/dataloader/async_dataloader.rb +4 -4
- data/lib/graphql/dataloader/source.rb +1 -1
- data/lib/graphql/dataloader.rb +6 -9
- data/lib/graphql/execution/interpreter/resolve.rb +3 -3
- data/lib/graphql/execution/interpreter/runtime.rb +7 -7
- data/lib/graphql/execution/interpreter.rb +4 -4
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/document_from_schema_definition.rb +8 -7
- data/lib/graphql/language/lexer.rb +4 -1
- data/lib/graphql/language/printer.rb +8 -8
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +6 -5
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +12 -10
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/schema/addition.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +1 -1
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +10 -10
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +3 -1
- data/lib/graphql/schema/input_object.rb +64 -27
- data/lib/graphql/schema/interface.rb +1 -1
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/member/has_arguments.rb +12 -12
- data/lib/graphql/schema/member/has_directives.rb +3 -3
- data/lib/graphql/schema/member/has_fields.rb +18 -0
- data/lib/graphql/schema/member/has_interfaces.rb +4 -4
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/object.rb +8 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +5 -5
- data/lib/graphql/schema/subscription.rb +2 -2
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/visibility/profile.rb +4 -2
- data/lib/graphql/schema/visibility/visit.rb +2 -2
- data/lib/graphql/schema/visibility.rb +33 -19
- data/lib/graphql/schema/warden.rb +4 -4
- data/lib/graphql/schema.rb +15 -9
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
- data/lib/graphql/subscriptions.rb +1 -1
- data/lib/graphql/testing/helpers.rb +2 -2
- data/lib/graphql/types/relay/connection_behaviors.rb +2 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +80 -47
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 576505327425ece2720724b18acb06b712d9574f18bbde7f43242a3288046966
|
4
|
+
data.tar.gz: 6b67a9aac34abf8e340c8fcdba329ff7e64357f9ade833d909244ec2683c4174
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 394b8ba06f32a1a983b5cb41cf322c361fb05fe68b9dd5946e5d0eb846923fc03edf9674935767a0a06737ccad300a790439a160e0499f82ed0f6ff5223a675d
|
7
|
+
data.tar.gz: 0410a99ab8efe22a1d130b93d08a12d2a3e989974a50af65416ea4979023826bd829da64d1eeb6d4b9dd75d552547a80e26f100f14a7c107acc0740339044430
|
@@ -264,7 +264,7 @@ module GraphQL
|
|
264
264
|
|
265
265
|
def skip?(ast_node)
|
266
266
|
dir = ast_node.directives
|
267
|
-
dir.
|
267
|
+
!dir.empty? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
|
268
268
|
end
|
269
269
|
|
270
270
|
def on_fragment_with_type(node)
|
data/lib/graphql/analysis.rb
CHANGED
@@ -55,10 +55,10 @@ module GraphQL
|
|
55
55
|
.tap { _1.select!(&:analyze?) }
|
56
56
|
|
57
57
|
analyzers_to_run = query_analyzers + multiplex_analyzers
|
58
|
-
if analyzers_to_run.
|
58
|
+
if !analyzers_to_run.empty?
|
59
59
|
|
60
60
|
analyzers_to_run.select!(&:visit?)
|
61
|
-
if analyzers_to_run.
|
61
|
+
if !analyzers_to_run.empty?
|
62
62
|
visitor = GraphQL::Analysis::Visitor.new(
|
63
63
|
query: query,
|
64
64
|
analyzers: analyzers_to_run
|
@@ -69,7 +69,7 @@ module GraphQL
|
|
69
69
|
visitor.visit
|
70
70
|
end
|
71
71
|
|
72
|
-
if visitor.rescued_errors.
|
72
|
+
if !visitor.rescued_errors.empty?
|
73
73
|
return visitor.rescued_errors
|
74
74
|
end
|
75
75
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Autoload
|
5
|
+
# Register a constant named `const_name` to be loaded from `path`.
|
6
|
+
# This is like `Kernel#autoload` but it tracks the constants so they can be eager-loaded with {#eager_load!}
|
7
|
+
# @param const_name [Symbol]
|
8
|
+
# @param path [String]
|
9
|
+
# @return [void]
|
10
|
+
def autoload(const_name, path)
|
11
|
+
@_eagerloaded_constants ||= []
|
12
|
+
@_eagerloaded_constants << const_name
|
13
|
+
|
14
|
+
super const_name, path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Call this to load this constant's `autoload` dependents and continue calling recursively
|
18
|
+
# @return [void]
|
19
|
+
def eager_load!
|
20
|
+
@_eager_loading = true
|
21
|
+
if @_eagerloaded_constants
|
22
|
+
@_eagerloaded_constants.each { |const_name| const_get(const_name) }
|
23
|
+
@_eagerloaded_constants = nil
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
ensure
|
27
|
+
@_eager_loading = false
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# @return [Boolean] `true` if GraphQL-Ruby is currently eager-loading its constants
|
33
|
+
def eager_loading?
|
34
|
+
@_eager_loading ||= false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/graphql/current.rb
CHANGED
@@ -41,7 +41,7 @@ module GraphQL
|
|
41
41
|
# @see GraphQL::Field#path for a string identifying this field
|
42
42
|
# @return [GraphQL::Field, nil] The currently-running field, if there is one.
|
43
43
|
def self.field
|
44
|
-
|
44
|
+
Fiber[:__graphql_runtime_info]&.values&.first&.current_field
|
45
45
|
end
|
46
46
|
|
47
47
|
# @return [Class, nil] The currently-running {Dataloader::Source} class, if there is one.
|
@@ -3,7 +3,7 @@ module GraphQL
|
|
3
3
|
class Dataloader
|
4
4
|
class AsyncDataloader < Dataloader
|
5
5
|
def yield
|
6
|
-
if (condition =
|
6
|
+
if (condition = Fiber[:graphql_dataloader_next_tick])
|
7
7
|
condition.wait
|
8
8
|
else
|
9
9
|
Fiber.yield
|
@@ -20,7 +20,7 @@ module GraphQL
|
|
20
20
|
first_pass = true
|
21
21
|
sources_condition = Async::Condition.new
|
22
22
|
manager = spawn_fiber do
|
23
|
-
while first_pass || job_fibers.
|
23
|
+
while first_pass || !job_fibers.empty?
|
24
24
|
first_pass = false
|
25
25
|
fiber_vars = get_fiber_variables
|
26
26
|
|
@@ -37,7 +37,7 @@ module GraphQL
|
|
37
37
|
|
38
38
|
Sync do |root_task|
|
39
39
|
set_fiber_variables(fiber_vars)
|
40
|
-
while source_tasks.
|
40
|
+
while !source_tasks.empty? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) }
|
41
41
|
while (task = (source_tasks.shift || (((job_fibers.size + next_job_fibers.size + source_tasks.size + next_source_tasks.size) < total_fiber_limit) && spawn_source_task(root_task, sources_condition))))
|
42
42
|
if task.alive?
|
43
43
|
root_task.yield # give the source task a chance to run
|
@@ -78,7 +78,7 @@ module GraphQL
|
|
78
78
|
fiber_vars = get_fiber_variables
|
79
79
|
parent_task.async do
|
80
80
|
set_fiber_variables(fiber_vars)
|
81
|
-
|
81
|
+
Fiber[:graphql_dataloader_next_tick] = condition
|
82
82
|
pending_sources.each(&:run_pending_keys)
|
83
83
|
cleanup_fiber
|
84
84
|
end
|
data/lib/graphql/dataloader.rb
CHANGED
@@ -78,10 +78,7 @@ module GraphQL
|
|
78
78
|
def get_fiber_variables
|
79
79
|
fiber_vars = {}
|
80
80
|
Thread.current.keys.each do |fiber_var_key|
|
81
|
-
|
82
|
-
if fiber_var_key != :__graphql_runtime_info
|
83
|
-
fiber_vars[fiber_var_key] = Thread.current[fiber_var_key]
|
84
|
-
end
|
81
|
+
fiber_vars[fiber_var_key] = Thread.current[fiber_var_key]
|
85
82
|
end
|
86
83
|
fiber_vars
|
87
84
|
end
|
@@ -194,7 +191,7 @@ module GraphQL
|
|
194
191
|
next_source_fibers = []
|
195
192
|
first_pass = true
|
196
193
|
manager = spawn_fiber do
|
197
|
-
while first_pass || job_fibers.
|
194
|
+
while first_pass || !job_fibers.empty?
|
198
195
|
first_pass = false
|
199
196
|
|
200
197
|
while (f = (job_fibers.shift || (((next_job_fibers.size + job_fibers.size) < jobs_fiber_limit) && spawn_job_fiber)))
|
@@ -207,7 +204,7 @@ module GraphQL
|
|
207
204
|
end
|
208
205
|
join_queues(job_fibers, next_job_fibers)
|
209
206
|
|
210
|
-
while (source_fibers.
|
207
|
+
while (!source_fibers.empty? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) })
|
211
208
|
while (f = source_fibers.shift || (((job_fibers.size + source_fibers.size + next_source_fibers.size + next_job_fibers.size) < total_fiber_limit) && spawn_source_fiber))
|
212
209
|
if f.alive?
|
213
210
|
finished = run_fiber(f)
|
@@ -227,10 +224,10 @@ module GraphQL
|
|
227
224
|
raise "Invariant: Manager fiber didn't terminate properly."
|
228
225
|
end
|
229
226
|
|
230
|
-
if job_fibers.
|
227
|
+
if !job_fibers.empty?
|
231
228
|
raise "Invariant: job fibers should have exited but #{job_fibers.size} remained"
|
232
229
|
end
|
233
|
-
if source_fibers.
|
230
|
+
if !source_fibers.empty?
|
234
231
|
raise "Invariant: source fibers should have exited but #{source_fibers.size} remained"
|
235
232
|
end
|
236
233
|
rescue UncaughtThrowError => e
|
@@ -270,7 +267,7 @@ module GraphQL
|
|
270
267
|
end
|
271
268
|
|
272
269
|
def spawn_job_fiber
|
273
|
-
if
|
270
|
+
if !@pending_jobs.empty?
|
274
271
|
spawn_fiber do
|
275
272
|
while job = @pending_jobs.shift
|
276
273
|
job.call
|
@@ -22,7 +22,7 @@ module GraphQL
|
|
22
22
|
|
23
23
|
if smallest_depth
|
24
24
|
lazies = lazies_at_depth.delete(smallest_depth)
|
25
|
-
if lazies.
|
25
|
+
if !lazies.empty?
|
26
26
|
dataloader.append_job {
|
27
27
|
lazies.each(&:value) # resolve these Lazy instances
|
28
28
|
}
|
@@ -55,7 +55,7 @@ module GraphQL
|
|
55
55
|
# these approaches.
|
56
56
|
dataloader.run
|
57
57
|
next_results = []
|
58
|
-
while results.
|
58
|
+
while !results.empty?
|
59
59
|
result_value = results.shift
|
60
60
|
if result_value.is_a?(Runtime::GraphQLResultHash) || result_value.is_a?(Hash)
|
61
61
|
results.concat(result_value.values)
|
@@ -81,7 +81,7 @@ module GraphQL
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
if next_results.
|
84
|
+
if !next_results.empty?
|
85
85
|
# Any pending data loader jobs may populate the
|
86
86
|
# resutl arrays or result hashes accumulated in
|
87
87
|
# `next_results``. Run those **to completion**
|
@@ -142,7 +142,7 @@ module GraphQL
|
|
142
142
|
end
|
143
143
|
else
|
144
144
|
# This is an InlineFragment or a FragmentSpread
|
145
|
-
if
|
145
|
+
if !@runtime_directive_names.empty? && node.directives.any? { |d| @runtime_directive_names.include?(d.name) }
|
146
146
|
next_selections = {}
|
147
147
|
next_selections[:graphql_directives] = node.directives
|
148
148
|
if selections_to_run
|
@@ -332,7 +332,7 @@ module GraphQL
|
|
332
332
|
extra_args[extra] = field_defn.fetch_extra(extra, context)
|
333
333
|
end
|
334
334
|
end
|
335
|
-
if extra_args.
|
335
|
+
if !extra_args.empty?
|
336
336
|
resolved_arguments = resolved_arguments.merge_extras(extra_args)
|
337
337
|
end
|
338
338
|
resolved_arguments.keyword_arguments
|
@@ -361,7 +361,7 @@ module GraphQL
|
|
361
361
|
end
|
362
362
|
|
363
363
|
field_result = call_method_on_directives(:resolve, object, directives) do
|
364
|
-
if directives.
|
364
|
+
if !directives.empty?
|
365
365
|
# This might be executed in a different context; reset this info
|
366
366
|
runtime_state = get_current_runtime_state
|
367
367
|
runtime_state.current_field = field_defn
|
@@ -525,7 +525,7 @@ module GraphQL
|
|
525
525
|
end
|
526
526
|
when Array
|
527
527
|
# It's an array full of execution errors; add them all.
|
528
|
-
if value.
|
528
|
+
if !value.empty? && value.all?(GraphQL::ExecutionError)
|
529
529
|
list_type_at_all = (field && (field.type.list?))
|
530
530
|
if selection_result.nil? || !selection_result.graphql_dead
|
531
531
|
value.each_with_index do |error, index|
|
@@ -736,7 +736,7 @@ module GraphQL
|
|
736
736
|
end
|
737
737
|
|
738
738
|
def get_current_runtime_state
|
739
|
-
current_state =
|
739
|
+
current_state = Fiber[:__graphql_runtime_info] ||= {}.compare_by_identity
|
740
740
|
current_state[@query] ||= CurrentState.new
|
741
741
|
end
|
742
742
|
|
@@ -821,11 +821,11 @@ module GraphQL
|
|
821
821
|
end
|
822
822
|
|
823
823
|
def delete_all_interpreter_context
|
824
|
-
per_query_state =
|
824
|
+
per_query_state = Fiber[:__graphql_runtime_info]
|
825
825
|
if per_query_state
|
826
826
|
per_query_state.delete(@query)
|
827
827
|
if per_query_state.size == 0
|
828
|
-
|
828
|
+
Fiber[:__graphql_runtime_info] = nil
|
829
829
|
end
|
830
830
|
end
|
831
831
|
nil
|
@@ -57,7 +57,7 @@ module GraphQL
|
|
57
57
|
end
|
58
58
|
multiplex.dataloader.append_job {
|
59
59
|
operation = query.selected_operation
|
60
|
-
result = if operation.nil? || !query.valid? || query.context.errors.
|
60
|
+
result = if operation.nil? || !query.valid? || !query.context.errors.empty?
|
61
61
|
NO_OPERATION
|
62
62
|
else
|
63
63
|
begin
|
@@ -100,12 +100,12 @@ module GraphQL
|
|
100
100
|
# Then, find all errors and assign the result to the query object
|
101
101
|
results.each_with_index do |data_result, idx|
|
102
102
|
query = queries[idx]
|
103
|
-
if (events = query.context.namespace(:subscriptions)[:events]) && events.
|
103
|
+
if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
|
104
104
|
schema.subscriptions.write_subscription(query, events)
|
105
105
|
end
|
106
106
|
# Assign the result so that it can be accessed in instrumentation
|
107
107
|
query.result_values = if data_result.equal?(NO_OPERATION)
|
108
|
-
if !query.valid? || query.context.errors.
|
108
|
+
if !query.valid? || !query.context.errors.empty?
|
109
109
|
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
110
110
|
{ "errors" => query.static_errors.map(&:to_h) }
|
111
111
|
else
|
@@ -114,7 +114,7 @@ module GraphQL
|
|
114
114
|
else
|
115
115
|
result = {}
|
116
116
|
|
117
|
-
if query.context.errors.
|
117
|
+
if !query.context.errors.empty?
|
118
118
|
error_result = query.context.errors.map(&:to_h)
|
119
119
|
result["errors"] = error_result
|
120
120
|
end
|
@@ -5,12 +5,25 @@ require 'digest/sha2'
|
|
5
5
|
|
6
6
|
module GraphQL
|
7
7
|
module Language
|
8
|
+
# This cache is used by {GraphQL::Language::Parser.parse_file} when it's enabled.
|
9
|
+
#
|
10
|
+
# With Rails, parser caching may enabled by setting `config.graphql.parser_cache = true` in your Rails application.
|
11
|
+
#
|
12
|
+
# The cache may be manually built by assigning `GraphQL::Language::Parser.cache = GraphQL::Language::Cache.new("some_dir")`.
|
13
|
+
# This will create a directory (`tmp/cache/graphql` by default) that stores a cache of parsed files.
|
14
|
+
#
|
15
|
+
# Much like [bootsnap](https://github.com/Shopify/bootsnap), the parser cache needs to be cleaned up manually.
|
16
|
+
# You will need to clear the cache directory for each new deployment of your application.
|
17
|
+
# Also note that the parser cache will grow as your schema is loaded, so the cache directory must be writable.
|
18
|
+
#
|
19
|
+
# @see GraphQL::Railtie for simple Rails integration
|
8
20
|
class Cache
|
9
21
|
def initialize(path)
|
10
22
|
@path = path
|
11
23
|
end
|
12
24
|
|
13
25
|
DIGEST = Digest::SHA256.new << GraphQL::VERSION
|
26
|
+
|
14
27
|
def fetch(filename)
|
15
28
|
hash = DIGEST.dup << filename
|
16
29
|
begin
|
@@ -52,7 +52,7 @@ module GraphQL
|
|
52
52
|
|
53
53
|
def build_object_type_node(object_type)
|
54
54
|
ints = @types.interfaces(object_type)
|
55
|
-
if ints.
|
55
|
+
if !ints.empty?
|
56
56
|
ints.sort_by!(&:graphql_name)
|
57
57
|
ints.map! { |iface| build_type_name_node(iface) }
|
58
58
|
end
|
@@ -247,7 +247,7 @@ module GraphQL
|
|
247
247
|
end
|
248
248
|
|
249
249
|
def build_argument_nodes(arguments)
|
250
|
-
if arguments.
|
250
|
+
if !arguments.empty?
|
251
251
|
nodes = arguments.map { |arg| build_argument_node(arg) }
|
252
252
|
nodes.sort_by!(&:name)
|
253
253
|
nodes
|
@@ -271,7 +271,7 @@ module GraphQL
|
|
271
271
|
all_types = @types.all_types
|
272
272
|
type_nodes = build_type_definition_nodes(all_types)
|
273
273
|
|
274
|
-
if (ex_t = schema.extra_types).
|
274
|
+
if !(ex_t = schema.extra_types).empty?
|
275
275
|
dummy_query = Class.new(GraphQL::Schema::Object) do
|
276
276
|
graphql_name "DummyQuery"
|
277
277
|
(all_types + ex_t).each_with_index do |type, idx|
|
@@ -346,10 +346,11 @@ module GraphQL
|
|
346
346
|
end
|
347
347
|
|
348
348
|
def definition_directives(member, directives_method)
|
349
|
-
|
349
|
+
if !member.respond_to?(directives_method) || member.directives.empty?
|
350
350
|
EmptyObjects::EMPTY_ARRAY
|
351
351
|
else
|
352
|
-
member.public_send(directives_method).
|
352
|
+
visible_directives = member.public_send(directives_method).select { |dir| @types.directive_exists?(dir.graphql_name) }
|
353
|
+
visible_directives.map! do |dir|
|
353
354
|
args = []
|
354
355
|
dir.arguments.argument_values.each_value do |arg_value| # rubocop:disable Development/ContextIsPassedCop -- directive instance method
|
355
356
|
arg_defn = arg_value.definition
|
@@ -373,9 +374,9 @@ module GraphQL
|
|
373
374
|
arguments: args
|
374
375
|
)
|
375
376
|
end
|
376
|
-
end
|
377
377
|
|
378
|
-
|
378
|
+
visible_directives
|
379
|
+
end
|
379
380
|
end
|
380
381
|
|
381
382
|
attr_reader :schema, :always_include_schema,
|
@@ -72,7 +72,10 @@ module GraphQL
|
|
72
72
|
# Check for a matched decimal:
|
73
73
|
@scanner[1] ? :FLOAT : :INT
|
74
74
|
else
|
75
|
-
|
75
|
+
# Attempt to find the part after the `-`
|
76
|
+
value = @scanner.scan(/-\s?[a-z0-9]*/i)
|
77
|
+
invalid_byte_for_number_error_message = "Expected type 'number', but it was malformed#{value.nil? ? "" : ": #{value.inspect}"}."
|
78
|
+
raise_parse_error(invalid_byte_for_number_error_message)
|
76
79
|
end
|
77
80
|
when ByteFor::ELLIPSIS
|
78
81
|
if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46
|
@@ -92,7 +92,7 @@ module GraphQL
|
|
92
92
|
print_string("@")
|
93
93
|
print_string(directive.name)
|
94
94
|
|
95
|
-
if directive.arguments.
|
95
|
+
if !directive.arguments.empty?
|
96
96
|
print_string("(")
|
97
97
|
directive.arguments.each_with_index do |a, i|
|
98
98
|
print_argument(a)
|
@@ -117,7 +117,7 @@ module GraphQL
|
|
117
117
|
print_string(": ")
|
118
118
|
end
|
119
119
|
print_string(field.name)
|
120
|
-
if field.arguments.
|
120
|
+
if !field.arguments.empty?
|
121
121
|
print_string("(")
|
122
122
|
field.arguments.each_with_index do |a, i|
|
123
123
|
print_argument(a)
|
@@ -182,7 +182,7 @@ module GraphQL
|
|
182
182
|
print_string(operation_definition.name)
|
183
183
|
end
|
184
184
|
|
185
|
-
if operation_definition.variables.
|
185
|
+
if !operation_definition.variables.empty?
|
186
186
|
print_string("(")
|
187
187
|
operation_definition.variables.each_with_index do |v, i|
|
188
188
|
print_variable_definition(v)
|
@@ -230,7 +230,7 @@ module GraphQL
|
|
230
230
|
|
231
231
|
extension ? print_string("extend schema") : print_string("schema")
|
232
232
|
|
233
|
-
if schema.directives.
|
233
|
+
if !schema.directives.empty?
|
234
234
|
schema.directives.each do |dir|
|
235
235
|
print_string("\n ")
|
236
236
|
print_node(dir)
|
@@ -332,7 +332,7 @@ module GraphQL
|
|
332
332
|
extension ? print_string("extend ") : print_description_and_comment(interface_type)
|
333
333
|
print_string("interface ")
|
334
334
|
print_string(interface_type.name)
|
335
|
-
print_implements(interface_type) if interface_type.interfaces.
|
335
|
+
print_implements(interface_type) if !interface_type.interfaces.empty?
|
336
336
|
print_directives(interface_type.directives)
|
337
337
|
print_field_definitions(interface_type.fields)
|
338
338
|
end
|
@@ -342,7 +342,7 @@ module GraphQL
|
|
342
342
|
print_string("union ")
|
343
343
|
print_string(union_type.name)
|
344
344
|
print_directives(union_type.directives)
|
345
|
-
if union_type.types.
|
345
|
+
if !union_type.types.empty?
|
346
346
|
print_string(" = ")
|
347
347
|
i = 0
|
348
348
|
union_type.types.each do |t|
|
@@ -360,7 +360,7 @@ module GraphQL
|
|
360
360
|
print_string("enum ")
|
361
361
|
print_string(enum_type.name)
|
362
362
|
print_directives(enum_type.directives)
|
363
|
-
if enum_type.values.
|
363
|
+
if !enum_type.values.empty?
|
364
364
|
print_string(" {\n")
|
365
365
|
enum_type.values.each.with_index do |value, i|
|
366
366
|
print_description(value, indent: " ", first_in_block: i == 0)
|
@@ -401,7 +401,7 @@ module GraphQL
|
|
401
401
|
print_string("directive @")
|
402
402
|
print_string(directive.name)
|
403
403
|
|
404
|
-
if directive.arguments.
|
404
|
+
if !directive.arguments.empty?
|
405
405
|
print_arguments(directive.arguments)
|
406
406
|
end
|
407
407
|
|
@@ -223,7 +223,7 @@ module GraphQL
|
|
223
223
|
|
224
224
|
def detect_was_authorized_by_scope_items
|
225
225
|
if @context &&
|
226
|
-
(current_runtime_state =
|
226
|
+
(current_runtime_state = Fiber[:__graphql_runtime_info]) &&
|
227
227
|
(query_runtime_state = current_runtime_state[@context.query])
|
228
228
|
query_runtime_state.was_authorized_by_scope_items
|
229
229
|
else
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "graphql/query/context/scoped_context"
|
3
2
|
|
4
3
|
module GraphQL
|
5
4
|
class Query
|
@@ -104,7 +103,7 @@ module GraphQL
|
|
104
103
|
if key == :current_path
|
105
104
|
current_path
|
106
105
|
else
|
107
|
-
(current_runtime_state =
|
106
|
+
(current_runtime_state = Fiber[:__graphql_runtime_info]) &&
|
108
107
|
(query_runtime_state = current_runtime_state[@query]) &&
|
109
108
|
(query_runtime_state.public_send(key))
|
110
109
|
end
|
@@ -144,7 +143,7 @@ module GraphQL
|
|
144
143
|
end
|
145
144
|
|
146
145
|
def current_path
|
147
|
-
current_runtime_state =
|
146
|
+
current_runtime_state = Fiber[:__graphql_runtime_info]
|
148
147
|
query_runtime_state = current_runtime_state && current_runtime_state[@query]
|
149
148
|
|
150
149
|
path = query_runtime_state &&
|
@@ -169,7 +168,7 @@ module GraphQL
|
|
169
168
|
|
170
169
|
def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
|
171
170
|
if RUNTIME_METADATA_KEYS.include?(key)
|
172
|
-
(runtime =
|
171
|
+
(runtime = Fiber[:__graphql_runtime_info]) &&
|
173
172
|
(query_runtime_state = runtime[@query]) &&
|
174
173
|
(query_runtime_state.public_send(key))
|
175
174
|
elsif @scoped_context.key?(key)
|
@@ -187,7 +186,7 @@ module GraphQL
|
|
187
186
|
|
188
187
|
def dig(key, *other_keys)
|
189
188
|
if RUNTIME_METADATA_KEYS.include?(key)
|
190
|
-
(current_runtime_state =
|
189
|
+
(current_runtime_state = Fiber[:__graphql_runtime_info]) &&
|
191
190
|
(query_runtime_state = current_runtime_state[@query]) &&
|
192
191
|
(obj = query_runtime_state.public_send(key)) &&
|
193
192
|
if other_keys.empty?
|
@@ -289,3 +288,5 @@ module GraphQL
|
|
289
288
|
end
|
290
289
|
end
|
291
290
|
end
|
291
|
+
|
292
|
+
require "graphql/query/context/scoped_context"
|
data/lib/graphql/query.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "graphql/query/context"
|
3
|
-
require "graphql/query/fingerprint"
|
4
|
-
require "graphql/query/null_context"
|
5
|
-
require "graphql/query/result"
|
6
|
-
require "graphql/query/variables"
|
7
|
-
require "graphql/query/input_validation_result"
|
8
|
-
require "graphql/query/variable_validation_error"
|
9
|
-
require "graphql/query/validation_pipeline"
|
10
2
|
|
11
3
|
module GraphQL
|
12
4
|
# A combination of query string and {Schema} instance which can be reduced to a {#result}.
|
13
5
|
class Query
|
6
|
+
extend Autoload
|
14
7
|
include Tracing::Traceable
|
15
8
|
extend Forwardable
|
16
9
|
|
10
|
+
autoload :Context, "graphql/query/context"
|
11
|
+
autoload :Fingerprint, "graphql/query/fingerprint"
|
12
|
+
autoload :NullContext, "graphql/query/null_context"
|
13
|
+
autoload :Result, "graphql/query/result"
|
14
|
+
autoload :Variables, "graphql/query/variables"
|
15
|
+
autoload :InputValidationResult, "graphql/query/input_validation_result"
|
16
|
+
autoload :VariableValidationError, "graphql/query/variable_validation_error"
|
17
|
+
autoload :ValidationPipeline, "graphql/query/validation_pipeline"
|
18
|
+
|
17
19
|
class OperationNameMissingError < GraphQL::ExecutionError
|
18
20
|
def initialize(name)
|
19
21
|
msg = if name.nil?
|
@@ -133,7 +135,7 @@ module GraphQL
|
|
133
135
|
end
|
134
136
|
end
|
135
137
|
|
136
|
-
if context_tracers.
|
138
|
+
if !context_tracers.empty? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
|
137
139
|
raise ArgumentError, "context[:tracers] are not supported without `trace_with(GraphQL::Tracing::CallLegacyTracers)` in the schema configuration, please add it."
|
138
140
|
end
|
139
141
|
|
@@ -479,7 +481,7 @@ module GraphQL
|
|
479
481
|
@mutation = false
|
480
482
|
@subscription = false
|
481
483
|
operation_name_error = nil
|
482
|
-
if
|
484
|
+
if !@operations.empty?
|
483
485
|
@selected_operation = find_operation(@operations, @operation_name)
|
484
486
|
if @selected_operation.nil?
|
485
487
|
operation_name_error = GraphQL::Query::OperationNameMissingError.new(@operation_name)
|
data/lib/graphql/railtie.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module GraphQL
|
4
|
+
# Support {GraphQL::Parser::Cache}
|
5
|
+
#
|
6
|
+
# @example Enable the parser cache with default directory
|
7
|
+
#
|
8
|
+
# config.graphql.parser_cache = true
|
9
|
+
#
|
4
10
|
class Railtie < Rails::Railtie
|
5
11
|
config.graphql = ActiveSupport::OrderedOptions.new
|
6
12
|
config.graphql.parser_cache = false
|
13
|
+
config.eager_load_namespaces << GraphQL
|
7
14
|
|
8
15
|
initializer("graphql.cache") do |app|
|
9
16
|
if config.graphql.parser_cache
|
@@ -45,7 +45,7 @@ module GraphQL
|
|
45
45
|
def visible?(context)
|
46
46
|
if dir = self.directives.find { |d| d.is_a?(Flagged) }
|
47
47
|
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
48
|
-
relevant_flags && relevant_flags.
|
48
|
+
relevant_flags && !relevant_flags.empty? && super
|
49
49
|
else
|
50
50
|
super
|
51
51
|
end
|
@@ -29,7 +29,7 @@ module GraphQL
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def locations(*new_locations)
|
32
|
-
if new_locations.
|
32
|
+
if !new_locations.empty?
|
33
33
|
new_locations.each do |new_loc|
|
34
34
|
if !LOCATIONS.include?(new_loc.to_sym)
|
35
35
|
raise ArgumentError, "#{self} (#{self.graphql_name}) has an invalid directive location: `locations #{new_loc}` "
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
if ret_type.respond_to?(:scope_items)
|
13
13
|
scoped_items = ret_type.scope_items(value, context)
|
14
14
|
if !scoped_items.equal?(value) && !ret_type.reauthorize_scoped_objects
|
15
|
-
if (current_runtime_state =
|
15
|
+
if (current_runtime_state = Fiber[:__graphql_runtime_info]) &&
|
16
16
|
(query_runtime_state = current_runtime_state[context.query])
|
17
17
|
query_runtime_state.was_authorized_by_scope_items = true
|
18
18
|
end
|