graphql 2.3.7 → 2.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +46 -0
  3. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  4. data/lib/generators/graphql/templates/base_resolver.erb +2 -0
  5. data/lib/generators/graphql/type_generator.rb +1 -1
  6. data/lib/graphql/analysis/field_usage.rb +1 -1
  7. data/lib/graphql/analysis/query_complexity.rb +3 -3
  8. data/lib/graphql/analysis/visitor.rb +8 -7
  9. data/lib/graphql/analysis.rb +4 -4
  10. data/lib/graphql/autoload.rb +38 -0
  11. data/lib/graphql/current.rb +52 -0
  12. data/lib/graphql/dataloader/async_dataloader.rb +7 -6
  13. data/lib/graphql/dataloader/source.rb +7 -4
  14. data/lib/graphql/dataloader.rb +40 -19
  15. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  16. data/lib/graphql/execution/interpreter/resolve.rb +13 -9
  17. data/lib/graphql/execution/interpreter/runtime.rb +35 -31
  18. data/lib/graphql/execution/interpreter.rb +6 -4
  19. data/lib/graphql/execution/lookahead.rb +18 -11
  20. data/lib/graphql/introspection/directive_type.rb +1 -1
  21. data/lib/graphql/introspection/entry_points.rb +2 -2
  22. data/lib/graphql/introspection/field_type.rb +1 -1
  23. data/lib/graphql/introspection/schema_type.rb +6 -11
  24. data/lib/graphql/introspection/type_type.rb +5 -5
  25. data/lib/graphql/invalid_null_error.rb +1 -1
  26. data/lib/graphql/language/cache.rb +13 -0
  27. data/lib/graphql/language/comment.rb +18 -0
  28. data/lib/graphql/language/document_from_schema_definition.rb +62 -34
  29. data/lib/graphql/language/lexer.rb +18 -15
  30. data/lib/graphql/language/nodes.rb +24 -16
  31. data/lib/graphql/language/parser.rb +14 -1
  32. data/lib/graphql/language/printer.rb +31 -15
  33. data/lib/graphql/language/sanitized_printer.rb +1 -1
  34. data/lib/graphql/language.rb +6 -6
  35. data/lib/graphql/pagination/connection.rb +1 -1
  36. data/lib/graphql/query/context/scoped_context.rb +1 -1
  37. data/lib/graphql/query/context.rb +13 -6
  38. data/lib/graphql/query/null_context.rb +3 -5
  39. data/lib/graphql/query/variable_validation_error.rb +1 -1
  40. data/lib/graphql/query.rb +72 -18
  41. data/lib/graphql/railtie.rb +7 -0
  42. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  43. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  44. data/lib/graphql/rubocop.rb +2 -0
  45. data/lib/graphql/schema/addition.rb +2 -1
  46. data/lib/graphql/schema/always_visible.rb +6 -2
  47. data/lib/graphql/schema/argument.rb +14 -1
  48. data/lib/graphql/schema/build_from_definition.rb +9 -1
  49. data/lib/graphql/schema/directive/flagged.rb +2 -2
  50. data/lib/graphql/schema/directive.rb +1 -1
  51. data/lib/graphql/schema/enum.rb +71 -23
  52. data/lib/graphql/schema/enum_value.rb +10 -2
  53. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  54. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  55. data/lib/graphql/schema/field.rb +102 -47
  56. data/lib/graphql/schema/field_extension.rb +1 -1
  57. data/lib/graphql/schema/has_single_input_argument.rb +5 -2
  58. data/lib/graphql/schema/input_object.rb +90 -39
  59. data/lib/graphql/schema/interface.rb +22 -5
  60. data/lib/graphql/schema/introspection_system.rb +5 -16
  61. data/lib/graphql/schema/loader.rb +1 -1
  62. data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
  63. data/lib/graphql/schema/member/has_arguments.rb +36 -23
  64. data/lib/graphql/schema/member/has_directives.rb +3 -3
  65. data/lib/graphql/schema/member/has_fields.rb +26 -6
  66. data/lib/graphql/schema/member/has_interfaces.rb +4 -4
  67. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  68. data/lib/graphql/schema/member/has_validators.rb +1 -1
  69. data/lib/graphql/schema/object.rb +8 -0
  70. data/lib/graphql/schema/printer.rb +1 -0
  71. data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
  72. data/lib/graphql/schema/resolver.rb +12 -14
  73. data/lib/graphql/schema/subscription.rb +2 -2
  74. data/lib/graphql/schema/type_expression.rb +2 -2
  75. data/lib/graphql/schema/union.rb +1 -1
  76. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  77. data/lib/graphql/schema/validator/required_validator.rb +28 -4
  78. data/lib/graphql/schema/validator.rb +3 -1
  79. data/lib/graphql/schema/visibility/migration.rb +188 -0
  80. data/lib/graphql/schema/visibility/profile.rb +359 -0
  81. data/lib/graphql/schema/visibility/visit.rb +190 -0
  82. data/lib/graphql/schema/visibility.rb +294 -0
  83. data/lib/graphql/schema/warden.rb +179 -16
  84. data/lib/graphql/schema.rb +348 -94
  85. data/lib/graphql/static_validation/base_visitor.rb +6 -5
  86. data/lib/graphql/static_validation/literal_validator.rb +4 -4
  87. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  88. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  89. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  90. data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
  91. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  92. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  93. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +2 -2
  94. data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
  95. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  96. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  97. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  98. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  99. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  100. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  101. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
  102. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  103. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  104. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  105. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  106. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  107. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  108. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  109. data/lib/graphql/static_validation/validation_context.rb +18 -2
  110. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -2
  111. data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
  112. data/lib/graphql/subscriptions/event.rb +1 -1
  113. data/lib/graphql/subscriptions/serialize.rb +2 -0
  114. data/lib/graphql/subscriptions.rb +6 -4
  115. data/lib/graphql/testing/helpers.rb +10 -6
  116. data/lib/graphql/tracing/notifications_trace.rb +2 -2
  117. data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
  118. data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
  119. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  120. data/lib/graphql/types.rb +18 -11
  121. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  122. data/lib/graphql/version.rb +1 -1
  123. data/lib/graphql.rb +53 -45
  124. metadata +31 -8
  125. data/lib/graphql/language/token.rb +0 -34
  126. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -53,8 +53,7 @@ module GraphQL
53
53
  end
54
54
  end
55
55
  # { Class => Boolean }
56
- @lazy_cache = {}
57
- @lazy_cache.compare_by_identity
56
+ @lazy_cache = {}.compare_by_identity
58
57
  end
59
58
 
60
59
  def final_result
@@ -143,7 +142,7 @@ module GraphQL
143
142
  end
144
143
  else
145
144
  # This is an InlineFragment or a FragmentSpread
146
- 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) }
147
146
  next_selections = {}
148
147
  next_selections[:graphql_directives] = node.directives
149
148
  if selections_to_run
@@ -160,9 +159,9 @@ module GraphQL
160
159
  case node
161
160
  when GraphQL::Language::Nodes::InlineFragment
162
161
  if node.type
163
- type_defn = schema.get_type(node.type.name, context)
162
+ type_defn = query.types.type(node.type.name)
164
163
 
165
- if query.warden.possible_types(type_defn).include?(owner_type)
164
+ if query.types.possible_types(type_defn).include?(owner_type)
166
165
  result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
167
166
  if !result.equal?(next_selections)
168
167
  selections_to_run = result
@@ -177,8 +176,8 @@ module GraphQL
177
176
  end
178
177
  when GraphQL::Language::Nodes::FragmentSpread
179
178
  fragment_def = query.fragments[node.name]
180
- type_defn = query.get_type(fragment_def.type.name)
181
- if query.warden.possible_types(type_defn).include?(owner_type)
179
+ type_defn = query.types.type(fragment_def.type.name)
180
+ if query.types.possible_types(type_defn).include?(owner_type)
182
181
  result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
183
182
  if !result.equal?(next_selections)
184
183
  selections_to_run = result
@@ -208,22 +207,32 @@ module GraphQL
208
207
  finished_jobs = 0
209
208
  enqueued_jobs = gathered_selections.size
210
209
  gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
211
- @dataloader.append_job {
212
- evaluate_selection(
213
- result_name, field_ast_nodes_or_ast_node, selections_result
214
- )
215
- finished_jobs += 1
216
- if target_result && finished_jobs == enqueued_jobs
217
- selections_result.merge_into(target_result)
218
- end
219
- }
210
+
220
211
  # Field resolution may pause the fiber,
221
212
  # so it wouldn't get to the `Resolve` call that happens below.
222
213
  # So instead trigger a run from this outer context.
223
214
  if selections_result.graphql_is_eager
224
215
  @dataloader.clear_cache
225
- @dataloader.run
226
- @dataloader.clear_cache
216
+ @dataloader.run_isolated {
217
+ evaluate_selection(
218
+ result_name, field_ast_nodes_or_ast_node, selections_result
219
+ )
220
+ finished_jobs += 1
221
+ if target_result && finished_jobs == enqueued_jobs
222
+ selections_result.merge_into(target_result)
223
+ end
224
+ @dataloader.clear_cache
225
+ }
226
+ else
227
+ @dataloader.append_job {
228
+ evaluate_selection(
229
+ result_name, field_ast_nodes_or_ast_node, selections_result
230
+ )
231
+ finished_jobs += 1
232
+ if target_result && finished_jobs == enqueued_jobs
233
+ selections_result.merge_into(target_result)
234
+ end
235
+ }
227
236
  end
228
237
  end
229
238
  selections_result
@@ -245,7 +254,7 @@ module GraphQL
245
254
  end
246
255
  field_name = ast_node.name
247
256
  owner_type = selections_result.graphql_result_type
248
- field_defn = query.warden.get_field(owner_type, field_name)
257
+ field_defn = query.types.field(owner_type, field_name)
249
258
 
250
259
  # Set this before calling `run_with_directives`, so that the directive can have the latest path
251
260
  runtime_state = get_current_runtime_state
@@ -323,7 +332,7 @@ module GraphQL
323
332
  extra_args[extra] = field_defn.fetch_extra(extra, context)
324
333
  end
325
334
  end
326
- if extra_args.any?
335
+ if !extra_args.empty?
327
336
  resolved_arguments = resolved_arguments.merge_extras(extra_args)
328
337
  end
329
338
  resolved_arguments.keyword_arguments
@@ -352,7 +361,7 @@ module GraphQL
352
361
  end
353
362
 
354
363
  field_result = call_method_on_directives(:resolve, object, directives) do
355
- if directives.any?
364
+ if !directives.empty?
356
365
  # This might be executed in a different context; reset this info
357
366
  runtime_state = get_current_runtime_state
358
367
  runtime_state.current_field = field_defn
@@ -516,7 +525,7 @@ module GraphQL
516
525
  end
517
526
  when Array
518
527
  # It's an array full of execution errors; add them all.
519
- if value.any? && value.all?(GraphQL::ExecutionError)
528
+ if !value.empty? && value.all?(GraphQL::ExecutionError)
520
529
  list_type_at_all = (field && (field.type.list?))
521
530
  if selection_result.nil? || !selection_result.graphql_dead
522
531
  value.each_with_index do |error, index|
@@ -579,7 +588,7 @@ module GraphQL
579
588
  resolved_value = value
580
589
  end
581
590
 
582
- possible_types = query.possible_types(current_type)
591
+ possible_types = query.types.possible_types(current_type)
583
592
  if !possible_types.include?(resolved_type)
584
593
  parent_type = field.owner_type
585
594
  err_class = current_type::UnresolvedTypeError
@@ -727,12 +736,7 @@ module GraphQL
727
736
  end
728
737
 
729
738
  def get_current_runtime_state
730
- current_state = Thread.current[:__graphql_runtime_info] ||= begin
731
- per_query_state = {}
732
- per_query_state.compare_by_identity
733
- per_query_state
734
- end
735
-
739
+ current_state = Fiber[:__graphql_runtime_info] ||= {}.compare_by_identity
736
740
  current_state[@query] ||= CurrentState.new
737
741
  end
738
742
 
@@ -817,11 +821,11 @@ module GraphQL
817
821
  end
818
822
 
819
823
  def delete_all_interpreter_context
820
- per_query_state = Thread.current[:__graphql_runtime_info]
824
+ per_query_state = Fiber[:__graphql_runtime_info]
821
825
  if per_query_state
822
826
  per_query_state.delete(@query)
823
827
  if per_query_state.size == 0
824
- Thread.current[:__graphql_runtime_info] = nil
828
+ Fiber[:__graphql_runtime_info] = nil
825
829
  end
826
830
  end
827
831
  nil
@@ -34,6 +34,7 @@ module GraphQL
34
34
  end
35
35
 
36
36
  multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
37
+ Fiber[:__graphql_current_multiplex] = multiplex
37
38
  multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
38
39
  schema = multiplex.schema
39
40
  queries = multiplex.queries
@@ -56,7 +57,7 @@ module GraphQL
56
57
  end
57
58
  multiplex.dataloader.append_job {
58
59
  operation = query.selected_operation
59
- result = if operation.nil? || !query.valid? || query.context.errors.any?
60
+ result = if operation.nil? || !query.valid? || !query.context.errors.empty?
60
61
  NO_OPERATION
61
62
  else
62
63
  begin
@@ -99,12 +100,12 @@ module GraphQL
99
100
  # Then, find all errors and assign the result to the query object
100
101
  results.each_with_index do |data_result, idx|
101
102
  query = queries[idx]
102
- if (events = query.context.namespace(:subscriptions)[:events]) && events.any?
103
+ if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
103
104
  schema.subscriptions.write_subscription(query, events)
104
105
  end
105
106
  # Assign the result so that it can be accessed in instrumentation
106
107
  query.result_values = if data_result.equal?(NO_OPERATION)
107
- if !query.valid? || query.context.errors.any?
108
+ if !query.valid? || !query.context.errors.empty?
108
109
  # A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
109
110
  { "errors" => query.static_errors.map(&:to_h) }
110
111
  else
@@ -113,7 +114,7 @@ module GraphQL
113
114
  else
114
115
  result = {}
115
116
 
116
- if query.context.errors.any?
117
+ if !query.context.errors.empty?
117
118
  error_result = query.context.errors.map(&:to_h)
118
119
  result["errors"] = error_result
119
120
  end
@@ -136,6 +137,7 @@ module GraphQL
136
137
  queries.map { |q| q.result_values ||= {} }
137
138
  raise
138
139
  ensure
140
+ Fiber[:__graphql_current_multiplex] = nil
139
141
  queries.map { |query|
140
142
  runtime = query.context.namespace(:interpreter_runtime)[:runtime]
141
143
  if runtime
@@ -56,7 +56,14 @@ module GraphQL
56
56
  else
57
57
  @arguments = if @field
58
58
  @query.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
59
- args.is_a?(Execution::Interpreter::Arguments) ? args.keyword_arguments : args
59
+ case args
60
+ when Execution::Interpreter::Arguments
61
+ args.keyword_arguments
62
+ when GraphQL::ExecutionError
63
+ EmptyObjects::EMPTY_HASH
64
+ else
65
+ args
66
+ end
60
67
  end
61
68
  else
62
69
  nil
@@ -108,16 +115,16 @@ module GraphQL
108
115
  def selection(field_name, selected_type: @selected_type, arguments: nil)
109
116
  next_field_defn = case field_name
110
117
  when String
111
- @query.get_field(selected_type, field_name)
118
+ @query.types.field(selected_type, field_name)
112
119
  when Symbol
113
120
  # Try to avoid the `.to_s` below, if possible
114
121
  all_fields = if selected_type.kind.fields?
115
- @query.warden.fields(selected_type)
122
+ @query.types.fields(selected_type)
116
123
  else
117
124
  # Handle unions by checking possible
118
- @query.warden
125
+ @query.types
119
126
  .possible_types(selected_type)
120
- .map { |t| @query.warden.fields(t) }
127
+ .map { |t| @query.types.fields(t) }
121
128
  .tap(&:flatten!)
122
129
  end
123
130
 
@@ -128,7 +135,7 @@ module GraphQL
128
135
  # Symbol#name is only present on 3.0+
129
136
  sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
130
137
  guessed_name = Schema::Member::BuildType.camelize(sym_s)
131
- @query.get_field(selected_type, guessed_name)
138
+ @query.types.field(selected_type, guessed_name)
132
139
  end
133
140
  end
134
141
  lookahead_for_selection(next_field_defn, selected_type, arguments)
@@ -144,7 +151,7 @@ module GraphQL
144
151
  alias_node = lookup_alias_node(ast_nodes, alias_name)
145
152
  return NULL_LOOKAHEAD unless alias_node
146
153
 
147
- next_field_defn = @query.get_field(selected_type, alias_node.name)
154
+ next_field_defn = @query.types.field(selected_type, alias_node.name)
148
155
 
149
156
  alias_arguments = @query.arguments_for(alias_node, next_field_defn)
150
157
  if alias_arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments)
@@ -183,7 +190,7 @@ module GraphQL
183
190
 
184
191
  subselections_by_type.each do |type, ast_nodes_by_response_key|
185
192
  ast_nodes_by_response_key.each do |response_key, ast_nodes|
186
- field_defn = @query.get_field(type, ast_nodes.first.name)
193
+ field_defn = @query.types.field(type, ast_nodes.first.name)
187
194
  lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
188
195
  subselections.push(lookahead)
189
196
  end
@@ -266,7 +273,7 @@ module GraphQL
266
273
  elsif arguments.nil? || arguments.empty?
267
274
  selections_on_type[response_key] = [ast_selection]
268
275
  else
269
- field_defn = @query.get_field(selected_type, ast_selection.name)
276
+ field_defn = @query.types.field(selected_type, ast_selection.name)
270
277
  if arguments_match?(arguments, field_defn, ast_selection)
271
278
  selections_on_type[response_key] = [ast_selection]
272
279
  end
@@ -276,14 +283,14 @@ module GraphQL
276
283
  subselections_on_type = selections_on_type
277
284
  if (t = ast_selection.type)
278
285
  # Assuming this is valid, that `t` will be found.
279
- on_type = @query.get_type(t.name)
286
+ on_type = @query.types.type(t.name)
280
287
  subselections_on_type = subselections_by_type[on_type] ||= {}
281
288
  end
282
289
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
283
290
  when GraphQL::Language::Nodes::FragmentSpread
284
291
  frag_defn = lookup_fragment(ast_selection)
285
292
  # Again, assuming a valid AST
286
- on_type = @query.get_type(frag_defn.type.name)
293
+ on_type = @query.types.type(frag_defn.type.name)
287
294
  subselections_on_type = subselections_by_type[on_type] ||= {}
288
295
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
289
296
  else
@@ -22,7 +22,7 @@ module GraphQL
22
22
  field :is_repeatable, Boolean, method: :repeatable?
23
23
 
24
24
  def args(include_deprecated:)
25
- args = @context.warden.arguments(@object)
25
+ args = @context.types.arguments(@object)
26
26
  args = args.reject(&:deprecation_reason) unless include_deprecated
27
27
  args
28
28
  end
@@ -15,8 +15,8 @@ module GraphQL
15
15
  end
16
16
 
17
17
  def __type(name:)
18
- if context.warden.reachable_type?(name)
19
- context.warden.get_type(name)
18
+ if context.types.reachable_type?(name) && (type = context.types.type(name))
19
+ type
20
20
  elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })
21
21
  type
22
22
  else
@@ -19,7 +19,7 @@ module GraphQL
19
19
  end
20
20
 
21
21
  def args(include_deprecated:)
22
- args = @context.warden.arguments(@object)
22
+ args = @context.types.arguments(@object)
23
23
  args = args.reject(&:deprecation_reason) unless include_deprecated
24
24
  args
25
25
  end
@@ -20,31 +20,26 @@ module GraphQL
20
20
  end
21
21
 
22
22
  def types
23
- types = context.warden.reachable_types + context.schema.extra_types
23
+ query_types = context.types.all_types
24
+ types = query_types + context.schema.extra_types
24
25
  types.sort_by!(&:graphql_name)
25
26
  types
26
27
  end
27
28
 
28
29
  def query_type
29
- permitted_root_type("query")
30
+ @context.types.query_root
30
31
  end
31
32
 
32
33
  def mutation_type
33
- permitted_root_type("mutation")
34
+ @context.types.mutation_root
34
35
  end
35
36
 
36
37
  def subscription_type
37
- permitted_root_type("subscription")
38
+ @context.types.subscription_root
38
39
  end
39
40
 
40
41
  def directives
41
- @context.warden.directives
42
- end
43
-
44
- private
45
-
46
- def permitted_root_type(op_type)
47
- @context.warden.root_type_for_operation(op_type)
42
+ @context.types.directives.sort_by(&:graphql_name)
48
43
  end
49
44
  end
50
45
  end
@@ -52,7 +52,7 @@ module GraphQL
52
52
  if !@object.kind.enum?
53
53
  nil
54
54
  else
55
- enum_values = @context.warden.enum_values(@object)
55
+ enum_values = @context.types.enum_values(@object)
56
56
 
57
57
  if !include_deprecated
58
58
  enum_values = enum_values.select {|f| !f.deprecation_reason }
@@ -64,7 +64,7 @@ module GraphQL
64
64
 
65
65
  def interfaces
66
66
  if @object.kind.object? || @object.kind.interface?
67
- @context.warden.interfaces(@object).sort_by(&:graphql_name)
67
+ @context.types.interfaces(@object).sort_by(&:graphql_name)
68
68
  else
69
69
  nil
70
70
  end
@@ -72,7 +72,7 @@ module GraphQL
72
72
 
73
73
  def input_fields(include_deprecated:)
74
74
  if @object.kind.input_object?
75
- args = @context.warden.arguments(@object)
75
+ args = @context.types.arguments(@object)
76
76
  args = args.reject(&:deprecation_reason) unless include_deprecated
77
77
  args
78
78
  else
@@ -82,7 +82,7 @@ module GraphQL
82
82
 
83
83
  def possible_types
84
84
  if @object.kind.abstract?
85
- @context.warden.possible_types(@object).sort_by(&:graphql_name)
85
+ @context.types.possible_types(@object).sort_by(&:graphql_name)
86
86
  else
87
87
  nil
88
88
  end
@@ -92,7 +92,7 @@ module GraphQL
92
92
  if !@object.kind.fields?
93
93
  nil
94
94
  else
95
- fields = @context.warden.fields(@object)
95
+ fields = @context.types.fields(@object)
96
96
  if !include_deprecated
97
97
  fields = fields.select {|f| !f.deprecation_reason }
98
98
  end
@@ -39,7 +39,7 @@ module GraphQL
39
39
  end
40
40
 
41
41
  def inspect
42
- if (name.nil? || parent_class.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
42
+ if (name.nil? || parent_class&.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
43
43
  "#{mutation.inspect}::#{parent_class.graphql_name}::InvalidNullError"
44
44
  else
45
45
  super
@@ -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
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Language
4
+ module Comment
5
+ def self.print(str, indent: '')
6
+ lines = str.split("\n").map do |line|
7
+ comment_str = "".dup
8
+ comment_str << indent
9
+ comment_str << "# "
10
+ comment_str << line
11
+ comment_str.rstrip
12
+ end
13
+
14
+ lines.join("\n") + "\n"
15
+ end
16
+ end
17
+ end
18
+ end