graphql 2.3.7 → 2.4.7

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