graphql 2.0.32 → 2.1.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/execution/interpreter/runtime.rb +27 -34
  3. data/lib/graphql/language/document_from_schema_definition.rb +6 -16
  4. data/lib/graphql/language/nodes.rb +1 -4
  5. data/lib/graphql/language/printer.rb +233 -145
  6. data/lib/graphql/language/sanitized_printer.rb +14 -21
  7. data/lib/graphql/language/visitor.rb +56 -122
  8. data/lib/graphql/pagination/connection.rb +23 -1
  9. data/lib/graphql/query.rb +2 -19
  10. data/lib/graphql/rake_task.rb +3 -12
  11. data/lib/graphql/schema/argument.rb +5 -3
  12. data/lib/graphql/schema/build_from_definition.rb +7 -8
  13. data/lib/graphql/schema/directive.rb +1 -1
  14. data/lib/graphql/schema/enum_value.rb +1 -1
  15. data/lib/graphql/schema/field/scope_extension.rb +7 -1
  16. data/lib/graphql/schema/field.rb +1 -1
  17. data/lib/graphql/schema/input_object.rb +6 -8
  18. data/lib/graphql/schema/interface.rb +1 -5
  19. data/lib/graphql/schema/member/has_directives.rb +1 -1
  20. data/lib/graphql/schema/member/has_fields.rb +1 -1
  21. data/lib/graphql/schema/member/has_interfaces.rb +1 -1
  22. data/lib/graphql/schema/member/scoped.rb +19 -0
  23. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  24. data/lib/graphql/schema/object.rb +8 -0
  25. data/lib/graphql/schema/printer.rb +8 -7
  26. data/lib/graphql/schema/subscription.rb +11 -4
  27. data/lib/graphql/schema/warden.rb +3 -34
  28. data/lib/graphql/schema.rb +4 -20
  29. data/lib/graphql/static_validation/validation_context.rb +0 -3
  30. data/lib/graphql/static_validation.rb +0 -1
  31. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
  32. data/lib/graphql/subscriptions.rb +11 -6
  33. data/lib/graphql/tracing/appoptics_trace.rb +0 -4
  34. data/lib/graphql/tracing/appsignal_trace.rb +0 -4
  35. data/lib/graphql/tracing/data_dog_trace.rb +34 -25
  36. data/lib/graphql/tracing/data_dog_tracing.rb +21 -7
  37. data/lib/graphql/tracing/notifications_trace.rb +0 -4
  38. data/lib/graphql/tracing/platform_trace.rb +0 -5
  39. data/lib/graphql/tracing/prometheus_trace.rb +0 -4
  40. data/lib/graphql/tracing/scout_trace.rb +0 -3
  41. data/lib/graphql/tracing/statsd_trace.rb +0 -4
  42. data/lib/graphql/types/relay/connection_behaviors.rb +20 -3
  43. data/lib/graphql/types/relay/edge_behaviors.rb +8 -1
  44. data/lib/graphql/version.rb +1 -1
  45. data/lib/graphql.rb +0 -1
  46. metadata +24 -37
  47. data/lib/graphql/filter.rb +0 -59
  48. data/lib/graphql/static_validation/type_stack.rb +0 -216
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c86c6f3920de2d67a9d8b23a2783ec33f15b70571236db184ca9a9e6b459b80b
4
- data.tar.gz: 6f4659f46b99da5c6065ba7084b899253958bdb5627b65f469262898cb38205c
3
+ metadata.gz: 785d064bf9279c1c66291e629607bbfe14f33ea0a8ad3e22549d253116159f81
4
+ data.tar.gz: a66884908e066f99293c3171aa1856977ba01fde58dca3a65a978ef025de8f32
5
5
  SHA512:
6
- metadata.gz: 02bf27d69ec35ecdad618ed18a7731fe7d66cd1b5105fcc7625e7b68f534b31e7e5b6f458ba1efe22b5f6e9e6d819cc696e7cdeba6e80bbfa3259691d9ede441
7
- data.tar.gz: 5b91453bbc8e01a72bcfbe5cef21e7f65704ff1976d945c01291e48667a4a1f36e35f690048ba2a029d5c9f019cfa9c72fa46b2f851b422117de48a4722152ec
6
+ metadata.gz: f27e18f66f871cde5a6aedfea89621e57014c02062736b55aa86ebc4f64bdec83de93dca83c4aaede60c321113f4099efeab362cc3d4a2047d725e5ec2e7d73b
7
+ data.tar.gz: 4071a8921d60279b5ffc3ba11bb653e07596a9a97c0bab783c6a183558ff632996431d365052c27ea571b0b0c3a6a267f3cc10d1d4eff202eec513fc469f094e
@@ -15,10 +15,11 @@ module GraphQL
15
15
  @current_arguments = nil
16
16
  @current_result_name = nil
17
17
  @current_result = nil
18
+ @was_authorized_by_scope_items = nil
18
19
  end
19
20
 
20
21
  attr_accessor :current_result, :current_result_name,
21
- :current_arguments, :current_field, :current_object
22
+ :current_arguments, :current_field, :current_object, :was_authorized_by_scope_items
22
23
  end
23
24
 
24
25
  module GraphQLResult
@@ -124,7 +125,7 @@ module GraphQL
124
125
  when GraphQLResultArray
125
126
  # There's no special handling of arrays because currently, there's no way to split the execution
126
127
  # of a list over several concurrent flows.
127
- into_result.set_child_result(key, value)
128
+ next_result.set_child_result(key, value)
128
129
  else
129
130
  # We have to assume that, since this passed the `fields_will_merge` selection,
130
131
  # that the old and new values are the same.
@@ -244,6 +245,7 @@ module GraphQL
244
245
  root_operation = query.selected_operation
245
246
  root_op_type = root_operation.operation_type || "query"
246
247
  root_type = schema.root_type_for_operation(root_op_type)
248
+
247
249
  st = get_current_runtime_state
248
250
  st.current_object = query.root_value
249
251
  st.current_result = @response
@@ -344,26 +346,17 @@ module GraphQL
344
346
  type_defn = schema.get_type(node.type.name, context)
345
347
 
346
348
  if query.warden.possible_types(type_defn).include?(owner_type)
347
- result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
348
- if !result.equal?(next_selections)
349
- selections_to_run = result
350
- end
349
+ gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
351
350
  end
352
351
  else
353
352
  # it's an untyped fragment, definitely continue
354
- result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
355
- if !result.equal?(next_selections)
356
- selections_to_run = result
357
- end
353
+ gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
358
354
  end
359
355
  when GraphQL::Language::Nodes::FragmentSpread
360
356
  fragment_def = query.fragments[node.name]
361
357
  type_defn = query.get_type(fragment_def.type.name)
362
358
  if query.warden.possible_types(type_defn).include?(owner_type)
363
- result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
364
- if !result.equal?(next_selections)
365
- selections_to_run = result
366
- end
359
+ gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
367
360
  end
368
361
  else
369
362
  raise "Invariant: unexpected selection class: #{node.class}"
@@ -435,12 +428,6 @@ module GraphQL
435
428
  end
436
429
  end
437
430
 
438
- return_type = field_defn.type
439
-
440
- # This seems janky, but we need to know
441
- # the field's return type at this path in order
442
- # to propagate `null`
443
- return_type_non_null = return_type.non_null?
444
431
  # Set this before calling `run_with_directives`, so that the directive can have the latest path
445
432
  st = get_current_runtime_state
446
433
  st.current_field = field_defn
@@ -450,26 +437,27 @@ module GraphQL
450
437
  if is_introspection
451
438
  owner_object = field_defn.owner.wrap(owner_object, context)
452
439
  end
453
-
440
+ return_type = field_defn.type
454
441
  total_args_count = field_defn.arguments(context).size
455
442
  if total_args_count == 0
456
443
  resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
457
444
  if field_defn.extras.size == 0
458
445
  evaluate_selection_with_resolved_keyword_args(
459
- NO_ARGS, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type_non_null
446
+ NO_ARGS, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type.non_null?
460
447
  )
461
448
  else
462
- evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type_non_null)
449
+ evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type)
463
450
  end
464
451
  else
465
452
  @query.arguments_cache.dataload_for(ast_node, field_defn, owner_object) do |resolved_arguments|
466
- evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type_non_null)
453
+ evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type)
467
454
  end
468
455
  end
469
456
  end
470
457
 
471
- def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null) # rubocop:disable Metrics/ParameterLists
458
+ def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type) # rubocop:disable Metrics/ParameterLists
472
459
  after_lazy(arguments, field: field_defn, ast_node: ast_node, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result) do |resolved_arguments|
460
+ return_type_non_null = return_type.non_null?
473
461
  if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
474
462
  continue_value(resolved_arguments, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
475
463
  next
@@ -562,7 +550,10 @@ module GraphQL
562
550
  after_lazy(app_result, field: field_defn, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result) do |inner_result|
563
551
  continue_value = continue_value(inner_result, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
564
552
  if HALT != continue_value
565
- continue_field(continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result)
553
+ st = get_current_runtime_state
554
+ was_scoped = st.was_authorized_by_scope_items
555
+ st.was_authorized_by_scope_items = nil
556
+ continue_field(continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result, was_scoped)
566
557
  end
567
558
  end
568
559
  end
@@ -742,7 +733,7 @@ module GraphQL
742
733
  # Location information from `path` and `ast_node`.
743
734
  #
744
735
  # @return [Lazy, Array, Hash, Object] Lazy, Array, and Hash are all traversed to resolve lazy values later
745
- def continue_field(value, owner_type, field, current_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
736
+ def continue_field(value, owner_type, field, current_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result, was_scoped) # rubocop:disable Metrics/ParameterLists
746
737
  if current_type.non_null?
747
738
  current_type = current_type.of_type
748
739
  is_non_null = true
@@ -776,12 +767,12 @@ module GraphQL
776
767
  set_result(selection_result, result_name, nil, false, is_non_null)
777
768
  nil
778
769
  else
779
- continue_field(resolved_value, owner_type, field, resolved_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result)
770
+ continue_field(resolved_value, owner_type, field, resolved_type, ast_node, next_selections, is_non_null, owner_object, arguments, result_name, selection_result, was_scoped)
780
771
  end
781
772
  end
782
773
  when "OBJECT"
783
774
  object_proxy = begin
784
- current_type.wrap(value, context)
775
+ was_scoped ? current_type.wrap_scoped(value, context) : current_type.wrap(value, context)
785
776
  rescue GraphQL::ExecutionError => err
786
777
  err
787
778
  end
@@ -813,7 +804,6 @@ module GraphQL
813
804
  st.current_object = continue_value
814
805
  st.current_result_name = nil
815
806
  st.current_result = this_result
816
-
817
807
  # This is a less-frequent case; use a fast check since it's often not there.
818
808
  if (directives = selections[:graphql_directives])
819
809
  selections.delete(:graphql_directives)
@@ -848,10 +838,10 @@ module GraphQL
848
838
  idx += 1
849
839
  if use_dataloader_job
850
840
  @dataloader.append_job do
851
- resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
841
+ resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped)
852
842
  end
853
843
  else
854
- resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
844
+ resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped)
855
845
  end
856
846
  end
857
847
 
@@ -882,7 +872,7 @@ module GraphQL
882
872
  end
883
873
  end
884
874
 
885
- def resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type) # rubocop:disable Metrics/ParameterLists
875
+ def resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type, was_scoped) # rubocop:disable Metrics/ParameterLists
886
876
  st = get_current_runtime_state
887
877
  st.current_result_name = this_idx
888
878
  st.current_result = response_list
@@ -891,7 +881,7 @@ module GraphQL
891
881
  after_lazy(inner_value, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list) do |inner_inner_value|
892
882
  continue_value = continue_value(inner_inner_value, owner_type, field, inner_type_non_null, ast_node, this_idx, response_list)
893
883
  if HALT != continue_value
894
- continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list)
884
+ continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list, was_scoped)
895
885
  end
896
886
  end
897
887
  end
@@ -971,6 +961,8 @@ module GraphQL
971
961
  def after_lazy(lazy_obj, field:, owner_object:, arguments:, ast_node:, result:, result_name:, eager: false, trace: true, &block)
972
962
  if lazy?(lazy_obj)
973
963
  orig_result = result
964
+ st = get_current_runtime_state
965
+ was_authorized_by_scope_items = st.was_authorized_by_scope_items
974
966
  lazy = GraphQL::Execution::Lazy.new(field: field) do
975
967
  st = get_current_runtime_state
976
968
  st.current_object = owner_object
@@ -978,6 +970,7 @@ module GraphQL
978
970
  st.current_arguments = arguments
979
971
  st.current_result_name = result_name
980
972
  st.current_result = orig_result
973
+ st.was_authorized_by_scope_items = was_authorized_by_scope_items
981
974
  # Wrap the execution of _this_ method with tracing,
982
975
  # but don't wrap the continuation below
983
976
  inner_obj = begin
@@ -14,7 +14,7 @@ module GraphQL
14
14
  # @param include_built_in_directives [Boolean] Whether or not to include built in directives in the AST
15
15
  class DocumentFromSchemaDefinition
16
16
  def initialize(
17
- schema, context: nil, only: nil, except: nil, include_introspection_types: false,
17
+ schema, context: nil, include_introspection_types: false,
18
18
  include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
19
19
  )
20
20
  @schema = schema
@@ -26,21 +26,11 @@ module GraphQL
26
26
 
27
27
  schema_context = schema.context_class.new(query: nil, object: nil, schema: schema, values: context)
28
28
 
29
- @warden = if only || except
30
- filter = GraphQL::Filter
31
- .new(only: only, except: except)
32
- .merge(only: @schema.method(:visible?))
33
- GraphQL::Schema::Warden.new(
34
- filter,
35
- schema: @schema,
36
- context: schema_context,
37
- )
38
- else
39
- @schema.warden_class.new(
40
- schema: @schema,
41
- context: schema_context,
42
- )
43
- end
29
+
30
+ @warden = @schema.warden_class.new(
31
+ schema: @schema,
32
+ context: schema_context,
33
+ )
44
34
 
45
35
  schema_context.warden = @warden
46
36
  end
@@ -138,8 +138,6 @@ module GraphQL
138
138
  end
139
139
 
140
140
  class << self
141
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
142
-
143
141
  # Add a default `#visit_method` and `#children_method_name` using the class name
144
142
  def inherited(child_class)
145
143
  super
@@ -298,7 +296,6 @@ module GraphQL
298
296
  RUBY
299
297
  end
300
298
  end
301
- # rubocop:enable Development/NoEvalCop
302
299
  end
303
300
  end
304
301
 
@@ -538,7 +535,7 @@ module GraphQL
538
535
  # @example Creating a custom string from a document
539
536
  # class VariableScrubber < GraphQL::Language::Printer
540
537
  # def print_argument(arg)
541
- # "#{arg.name}: <HIDDEN>"
538
+ # print_string("#{arg.name}: <HIDDEN>")
542
539
  # end
543
540
  # end
544
541
  #