graphql 2.4.3 → 2.4.5
Sign up to get free protection for your applications and to get access to all the features.
- 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 +61 -235
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +162 -26
- data/lib/graphql/schema/warden.rb +4 -4
- data/lib/graphql/schema.rb +33 -12
- 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/static_validation/validation_context.rb +1 -0
- 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 +4 -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
|