graphql 2.4.3 → 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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/visitor.rb +1 -1
  3. data/lib/graphql/analysis.rb +3 -3
  4. data/lib/graphql/autoload.rb +37 -0
  5. data/lib/graphql/current.rb +1 -1
  6. data/lib/graphql/dataloader/async_dataloader.rb +4 -4
  7. data/lib/graphql/dataloader/source.rb +1 -1
  8. data/lib/graphql/dataloader.rb +6 -9
  9. data/lib/graphql/execution/interpreter/resolve.rb +3 -3
  10. data/lib/graphql/execution/interpreter/runtime.rb +7 -7
  11. data/lib/graphql/execution/interpreter.rb +4 -4
  12. data/lib/graphql/language/cache.rb +13 -0
  13. data/lib/graphql/language/document_from_schema_definition.rb +8 -7
  14. data/lib/graphql/language/lexer.rb +4 -1
  15. data/lib/graphql/language/printer.rb +8 -8
  16. data/lib/graphql/pagination/connection.rb +1 -1
  17. data/lib/graphql/query/context/scoped_context.rb +1 -1
  18. data/lib/graphql/query/context.rb +6 -5
  19. data/lib/graphql/query/variable_validation_error.rb +1 -1
  20. data/lib/graphql/query.rb +12 -10
  21. data/lib/graphql/railtie.rb +7 -0
  22. data/lib/graphql/schema/addition.rb +1 -1
  23. data/lib/graphql/schema/directive/flagged.rb +1 -1
  24. data/lib/graphql/schema/directive.rb +1 -1
  25. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  26. data/lib/graphql/schema/field.rb +10 -10
  27. data/lib/graphql/schema/field_extension.rb +1 -1
  28. data/lib/graphql/schema/has_single_input_argument.rb +3 -1
  29. data/lib/graphql/schema/input_object.rb +64 -27
  30. data/lib/graphql/schema/interface.rb +1 -1
  31. data/lib/graphql/schema/loader.rb +1 -1
  32. data/lib/graphql/schema/member/has_arguments.rb +12 -12
  33. data/lib/graphql/schema/member/has_directives.rb +3 -3
  34. data/lib/graphql/schema/member/has_fields.rb +18 -0
  35. data/lib/graphql/schema/member/has_interfaces.rb +4 -4
  36. data/lib/graphql/schema/member/has_validators.rb +1 -1
  37. data/lib/graphql/schema/object.rb +8 -0
  38. data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
  39. data/lib/graphql/schema/resolver.rb +5 -5
  40. data/lib/graphql/schema/subscription.rb +2 -2
  41. data/lib/graphql/schema/union.rb +1 -1
  42. data/lib/graphql/schema/validator.rb +1 -1
  43. data/lib/graphql/schema/visibility/profile.rb +61 -235
  44. data/lib/graphql/schema/visibility/visit.rb +190 -0
  45. data/lib/graphql/schema/visibility.rb +162 -26
  46. data/lib/graphql/schema/warden.rb +4 -4
  47. data/lib/graphql/schema.rb +33 -12
  48. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  49. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
  50. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  51. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
  52. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  53. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  54. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
  55. data/lib/graphql/static_validation/validation_context.rb +1 -0
  56. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
  57. data/lib/graphql/subscriptions.rb +1 -1
  58. data/lib/graphql/testing/helpers.rb +2 -2
  59. data/lib/graphql/types/relay/connection_behaviors.rb +2 -2
  60. data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
  61. data/lib/graphql/types.rb +18 -11
  62. data/lib/graphql/version.rb +1 -1
  63. data/lib/graphql.rb +80 -47
  64. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0dcc846071132cf2d084ff65347dab7c97d0b25b60c1cdb6dfcbe37c55f278e9
4
- data.tar.gz: afc95cb5ba89e33974b8b38616bc36c14dcbfd3c9f121b8e65437e7cfc390770
3
+ metadata.gz: 576505327425ece2720724b18acb06b712d9574f18bbde7f43242a3288046966
4
+ data.tar.gz: 6b67a9aac34abf8e340c8fcdba329ff7e64357f9ade833d909244ec2683c4174
5
5
  SHA512:
6
- metadata.gz: d1b6ad8fba792ca671246b2d6531f981a2c184adde3e4efc7522a7f38ea659c563dadd50ee208ab406f0ce4c37fc6625c2d59e020b0334cdefd8ea7f5d5eed8a
7
- data.tar.gz: 74c1156b7b407b2d687cc74886198d9f2705d7d82e3672e5d5b9b61f2811fa53dfe7b2bdb61ac0dae8e5e83242415ff7d7d1f6e2721f77b90dcda61dff88c815
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.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
267
+ !dir.empty? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
268
268
  end
269
269
 
270
270
  def on_fragment_with_type(node)
@@ -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.any?
58
+ if !analyzers_to_run.empty?
59
59
 
60
60
  analyzers_to_run.select!(&:visit?)
61
- if analyzers_to_run.any?
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.any?
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
@@ -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
- Thread.current[:__graphql_runtime_info]&.values&.first&.current_field
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 = Thread.current[:graphql_dataloader_next_tick])
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.any?
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.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) }
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
- Thread.current[:graphql_dataloader_next_tick] = condition
81
+ Fiber[:graphql_dataloader_next_tick] = condition
82
82
  pending_sources.each(&:run_pending_keys)
83
83
  cleanup_fiber
84
84
  end
@@ -73,7 +73,7 @@ module GraphQL
73
73
  end
74
74
  }
75
75
 
76
- if pending_keys.any?
76
+ if !pending_keys.empty?
77
77
  sync(pending_keys)
78
78
  end
79
79
 
@@ -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
- # This variable should be fresh in each new fiber
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.any?
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.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) })
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.any?
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.any?
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 @pending_jobs.any?
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.any?
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.any?
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.any?
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 @runtime_directive_names.any? && node.directives.any? { |d| @runtime_directive_names.include?(d.name) }
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.any?
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.any?
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.any? && value.all?(GraphQL::ExecutionError)
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 = Thread.current[:__graphql_runtime_info] ||= {}.compare_by_identity
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 = Thread.current[:__graphql_runtime_info]
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
- Thread.current[:__graphql_runtime_info] = nil
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.any?
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.any?
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.any?
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.any?
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.any?
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.any?
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).any?
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
- dirs = if !member.respond_to?(directives_method) || member.directives.empty?
349
+ if !member.respond_to?(directives_method) || member.directives.empty?
350
350
  EmptyObjects::EMPTY_ARRAY
351
351
  else
352
- member.public_send(directives_method).map do |dir|
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
- dirs
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
- raise_parse_error("Expected a number, but it was malformed (#{@string[@pos].inspect})")
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.any?
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.any?
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.any?
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.any?
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.any?
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.any?
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.any?
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.any?
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 = Thread.current[:__graphql_runtime_info]) &&
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
@@ -60,7 +60,7 @@ module GraphQL
60
60
  each_present_path_ctx do |path_ctx|
61
61
  if path_ctx.key?(key)
62
62
  found_value = path_ctx[key]
63
- if other_keys.any?
63
+ if !other_keys.empty?
64
64
  return found_value.dig(*other_keys)
65
65
  else
66
66
  return found_value
@@ -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 = Thread.current[:__graphql_runtime_info]) &&
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 = Thread.current[:__graphql_runtime_info]
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 = Thread.current[:__graphql_runtime_info]) &&
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 = Thread.current[:__graphql_runtime_info]) &&
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"
@@ -10,7 +10,7 @@ module GraphQL
10
10
 
11
11
  msg ||= "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
12
12
 
13
- if problem_fields.any?
13
+ if !problem_fields.empty?
14
14
  msg += " for #{problem_fields.join(", ")}"
15
15
  end
16
16
 
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.any? && !(schema.trace_class <= GraphQL::Tracing::CallLegacyTracers)
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 @operations.any?
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)
@@ -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
@@ -40,7 +40,7 @@ module GraphQL
40
40
  end
41
41
 
42
42
  def add_directives_from(owner)
43
- if (dir_instances = owner.directives).any?
43
+ if !(dir_instances = owner.directives).empty?
44
44
  dirs = dir_instances.map(&:class)
45
45
  @directives.merge(dirs)
46
46
  add_type_and_traverse(dirs)
@@ -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.any? && super
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.any?
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 = Thread.current[:__graphql_runtime_info]) &&
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