graphql 2.4.3 → 2.4.5

Sign up to get free protection for your applications and to get access to all the features.
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