graphql 2.3.7 → 2.4.8

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 (152) 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 +9 -5
  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 +52 -6
  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/default_subscription_resolve_extension.rb +12 -10
  113. data/lib/graphql/subscriptions/event.rb +13 -2
  114. data/lib/graphql/subscriptions/serialize.rb +2 -0
  115. data/lib/graphql/subscriptions.rb +6 -4
  116. data/lib/graphql/testing/helpers.rb +10 -6
  117. data/lib/graphql/tracing/active_support_notifications_trace.rb +1 -1
  118. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  119. data/lib/graphql/tracing/appoptics_trace.rb +2 -0
  120. data/lib/graphql/tracing/appoptics_tracing.rb +2 -0
  121. data/lib/graphql/tracing/appsignal_trace.rb +2 -0
  122. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  123. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  124. data/lib/graphql/tracing/data_dog_trace.rb +2 -0
  125. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  126. data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -0
  127. data/lib/graphql/tracing/legacy_trace.rb +4 -61
  128. data/lib/graphql/tracing/new_relic_trace.rb +2 -0
  129. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  130. data/lib/graphql/tracing/notifications_trace.rb +2 -2
  131. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  132. data/lib/graphql/tracing/null_trace.rb +9 -0
  133. data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
  134. data/lib/graphql/tracing/prometheus_trace.rb +5 -0
  135. data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
  136. data/lib/graphql/tracing/scout_trace.rb +2 -0
  137. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  138. data/lib/graphql/tracing/sentry_trace.rb +2 -0
  139. data/lib/graphql/tracing/statsd_trace.rb +2 -0
  140. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  141. data/lib/graphql/tracing/trace.rb +3 -0
  142. data/lib/graphql/tracing.rb +28 -30
  143. data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
  144. data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
  145. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  146. data/lib/graphql/types.rb +18 -11
  147. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  148. data/lib/graphql/version.rb +1 -1
  149. data/lib/graphql.rb +53 -45
  150. metadata +33 -8
  151. data/lib/graphql/language/token.rb +0 -34
  152. data/lib/graphql/schema/invalid_type_error.rb +0 -7
@@ -20,12 +20,22 @@ module GraphQL
20
20
  def after_resolve(value:, context:, object:, arguments:, **rest)
21
21
  if value.is_a?(GraphQL::ExecutionError)
22
22
  value
23
+ elsif @field.resolver&.method_defined?(:subscription_written?) &&
24
+ (subscription_namespace = context.namespace(:subscriptions)) &&
25
+ (subscriptions_by_path = subscription_namespace[:subscriptions])
26
+ (subscription_instance = subscriptions_by_path[context.current_path])
27
+ # If it was already written, don't append this event to be written later
28
+ if !subscription_instance.subscription_written?
29
+ events = context.namespace(:subscriptions)[:events]
30
+ events << subscription_instance.event
31
+ end
32
+ value
23
33
  elsif (events = context.namespace(:subscriptions)[:events])
24
34
  # This is the first execution, so gather an Event
25
35
  # for the backend to register:
26
36
  event = Subscriptions::Event.new(
27
37
  name: field.name,
28
- arguments: arguments_without_field_extras(arguments: arguments),
38
+ arguments: arguments,
29
39
  context: context,
30
40
  field: field,
31
41
  )
@@ -33,7 +43,7 @@ module GraphQL
33
43
  value
34
44
  elsif context.query.subscription_topic == Subscriptions::Event.serialize(
35
45
  field.name,
36
- arguments_without_field_extras(arguments: arguments),
46
+ arguments,
37
47
  field,
38
48
  scope: (field.subscription_scope ? context[field.subscription_scope] : nil),
39
49
  )
@@ -45,14 +55,6 @@ module GraphQL
45
55
  context.skip
46
56
  end
47
57
  end
48
-
49
- private
50
-
51
- def arguments_without_field_extras(arguments:)
52
- arguments.dup.tap do |event_args|
53
- field.extras.each { |k| event_args.delete(k) }
54
- end
55
- end
56
58
  end
57
59
  end
58
60
  end
@@ -20,7 +20,7 @@ module GraphQL
20
20
 
21
21
  def initialize(name:, arguments:, field: nil, context: nil, scope: nil)
22
22
  @name = name
23
- @arguments = arguments
23
+ @arguments = self.class.arguments_without_field_extras(arguments: arguments, field: field)
24
24
  @context = context
25
25
  field ||= context.field
26
26
  scope_key = field.subscription_scope
@@ -39,6 +39,7 @@ module GraphQL
39
39
  # @return [String] an identifier for this unit of subscription
40
40
  def self.serialize(_name, arguments, field, scope:, context: GraphQL::Query::NullContext.instance)
41
41
  subscription = field.resolver || GraphQL::Schema::Subscription
42
+ arguments = arguments_without_field_extras(field: field, arguments: arguments)
42
43
  normalized_args = stringify_args(field, arguments.to_h, context)
43
44
  subscription.topic_for(arguments: normalized_args, field: field, scope: scope)
44
45
  end
@@ -60,6 +61,16 @@ module GraphQL
60
61
  end
61
62
 
62
63
  class << self
64
+ def arguments_without_field_extras(arguments:, field:)
65
+ if !field.extras.empty?
66
+ arguments = arguments.dup
67
+ field.extras.each do |extra_key|
68
+ arguments.delete(extra_key)
69
+ end
70
+ end
71
+ arguments
72
+ end
73
+
63
74
  private
64
75
 
65
76
  # This method does not support cyclic references in the Hash,
@@ -137,7 +148,7 @@ module GraphQL
137
148
  end
138
149
 
139
150
  def get_arg_definition(arg_owner, arg_name, context)
140
- arg_owner.get_argument(arg_name, context) || arg_owner.arguments(context).each_value.find { |v| v.keyword.to_s == arg_name }
151
+ context.types.argument(arg_owner, arg_name) || context.types.arguments(arg_owner).find { |v| v.keyword.to_s == arg_name }
141
152
  end
142
153
  end
143
154
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require "set"
3
+ require "ostruct"
4
+
3
5
  module GraphQL
4
6
  class Subscriptions
5
7
  # Serialization helpers for passing subscription data around.
@@ -64,12 +64,12 @@ module GraphQL
64
64
  event_name = event_name.to_s
65
65
 
66
66
  # Try with the verbatim input first:
67
- field = @schema.get_field(@schema.subscription, event_name, context)
67
+ field = dummy_query.types.field(@schema.subscription, event_name) # rubocop:disable Development/ContextIsPassedCop
68
68
 
69
69
  if field.nil?
70
70
  # And if it wasn't found, normalize it:
71
71
  normalized_event_name = normalize_name(event_name)
72
- field = @schema.get_field(@schema.subscription, normalized_event_name, context)
72
+ field = dummy_query.types.field(@schema.subscription, normalized_event_name) # rubocop:disable Development/ContextIsPassedCop
73
73
  if field.nil?
74
74
  raise InvalidTriggerError, "No subscription matching trigger: #{event_name} (looked for #{@schema.subscription.graphql_name}.#{normalized_event_name})"
75
75
  end
@@ -250,6 +250,8 @@ module GraphQL
250
250
  def normalize_arguments(event_name, arg_owner, args, context)
251
251
  case arg_owner
252
252
  when GraphQL::Schema::Field, Class
253
+ return args if args.nil?
254
+
253
255
  if arg_owner.is_a?(Class) && !arg_owner.kind.input_object?
254
256
  # it's a type, but not an input object
255
257
  return args
@@ -289,7 +291,7 @@ module GraphQL
289
291
  end
290
292
  end
291
293
 
292
- if missing_arg_names.any?
294
+ if !missing_arg_names.empty?
293
295
  arg_owner_name = if arg_owner.is_a?(GraphQL::Schema::Field)
294
296
  arg_owner.path
295
297
  elsif arg_owner.is_a?(Class)
@@ -302,7 +304,7 @@ module GraphQL
302
304
 
303
305
  normalized_args
304
306
  when GraphQL::Schema::List
305
- args.map { |a| normalize_arguments(event_name, arg_owner.of_type, a, context) }
307
+ args&.map { |a| normalize_arguments(event_name, arg_owner.of_type, a, context) }
306
308
  when GraphQL::Schema::NonNull
307
309
  normalize_arguments(event_name, arg_owner.of_type, args, context)
308
310
  else
@@ -43,7 +43,7 @@ module GraphQL
43
43
  type_name, *field_names = field_path.split(".")
44
44
  dummy_query = GraphQL::Query.new(schema, "{ __typename }", context: context)
45
45
  query_context = dummy_query.context
46
- object_type = dummy_query.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
46
+ object_type = dummy_query.types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
47
47
  if object_type
48
48
  graphql_result = object
49
49
  field_names.each do |field_name|
@@ -52,12 +52,13 @@ module GraphQL
52
52
  if graphql_result.nil?
53
53
  return nil
54
54
  end
55
- visible_field = dummy_query.get_field(object_type, field_name)
55
+ visible_field = dummy_query.types.field(object_type, field_name) # rubocop:disable Development/ContextIsPassedCop
56
56
  if visible_field
57
57
  dummy_query.context.dataloader.run_isolated {
58
+ query_context[:current_field] = visible_field
58
59
  field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
59
60
  field_args = schema.sync_lazy(field_args)
60
- if visible_field.extras.any?
61
+ if !visible_field.extras.empty?
61
62
  extra_args = {}
62
63
  visible_field.extras.each do |extra|
63
64
  extra_args[extra] = case extra
@@ -90,10 +91,13 @@ module GraphQL
90
91
  end
91
92
  end
92
93
  graphql_result
93
- elsif schema.has_defined_type?(type_name)
94
- raise TypeNotVisibleError.new(type_name: type_name)
95
94
  else
96
- raise TypeNotDefinedError.new(type_name: type_name)
95
+ unfiltered_type = schema.use_visibility_profile? ? schema.visibility.get_type(type_name) : schema.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
96
+ if unfiltered_type
97
+ raise TypeNotVisibleError.new(type_name: type_name)
98
+ else
99
+ raise TypeNotDefinedError.new(type_name: type_name)
100
+ end
97
101
  end
98
102
  end
99
103
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql/tracing/notifications_trace'
3
+ require "graphql/tracing/notifications_trace"
4
4
 
5
5
  module GraphQL
6
6
  module Tracing
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql/tracing/notifications_tracing'
3
+ require "graphql/tracing/notifications_tracing"
4
4
 
5
5
  module GraphQL
6
6
  module Tracing
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module AppsignalTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class AppsignalTracing < PlatformTracing
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module Tracing
5
+ # This trace class calls legacy-style tracer with payload hashes.
6
+ # New-style `trace_with` modules significantly reduce the overhead of tracing,
7
+ # but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
8
+ module CallLegacyTracers
9
+ def lex(query_string:)
10
+ (@multiplex || @query).trace("lex", { query_string: query_string }) { super }
11
+ end
12
+
13
+ def parse(query_string:)
14
+ (@multiplex || @query).trace("parse", { query_string: query_string }) { super }
15
+ end
16
+
17
+ def validate(query:, validate:)
18
+ query.trace("validate", { validate: validate, query: query }) { super }
19
+ end
20
+
21
+ def analyze_multiplex(multiplex:)
22
+ multiplex.trace("analyze_multiplex", { multiplex: multiplex }) { super }
23
+ end
24
+
25
+ def analyze_query(query:)
26
+ query.trace("analyze_query", { query: query }) { super }
27
+ end
28
+
29
+ def execute_multiplex(multiplex:)
30
+ multiplex.trace("execute_multiplex", { multiplex: multiplex }) { super }
31
+ end
32
+
33
+ def execute_query(query:)
34
+ query.trace("execute_query", { query: query }) { super }
35
+ end
36
+
37
+ def execute_query_lazy(query:, multiplex:)
38
+ multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }) { super }
39
+ end
40
+
41
+ def execute_field(field:, query:, ast_node:, arguments:, object:)
42
+ query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
43
+ end
44
+
45
+ def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
46
+ query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
47
+ end
48
+
49
+ def authorized(query:, type:, object:)
50
+ query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
51
+ end
52
+
53
+ def authorized_lazy(query:, type:, object:)
54
+ query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
55
+ end
56
+
57
+ def resolve_type(query:, type:, object:)
58
+ query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
59
+ end
60
+
61
+ def resolve_type_lazy(query:, type:, object:)
62
+ query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module DataDogTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class DataDogTracing < PlatformTracing
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module GraphQL
3
4
  module Tracing
4
5
  module LegacyHooksTrace
@@ -1,67 +1,10 @@
1
1
  # frozen_string_literal: true
2
- module GraphQL
3
- module Tracing
4
- # This trace class calls legacy-style tracer with payload hashes.
5
- # New-style `trace_with` modules significantly reduce the overhead of tracing,
6
- # but that advantage is lost when legacy-style tracers are also used (since the payload hashes are still constructed).
7
- module CallLegacyTracers
8
- def lex(query_string:)
9
- (@multiplex || @query).trace("lex", { query_string: query_string }) { super }
10
- end
11
-
12
- def parse(query_string:)
13
- (@multiplex || @query).trace("parse", { query_string: query_string }) { super }
14
- end
15
-
16
- def validate(query:, validate:)
17
- query.trace("validate", { validate: validate, query: query }) { super }
18
- end
19
-
20
- def analyze_multiplex(multiplex:)
21
- multiplex.trace("analyze_multiplex", { multiplex: multiplex }) { super }
22
- end
23
-
24
- def analyze_query(query:)
25
- query.trace("analyze_query", { query: query }) { super }
26
- end
27
-
28
- def execute_multiplex(multiplex:)
29
- multiplex.trace("execute_multiplex", { multiplex: multiplex }) { super }
30
- end
31
-
32
- def execute_query(query:)
33
- query.trace("execute_query", { query: query }) { super }
34
- end
35
-
36
- def execute_query_lazy(query:, multiplex:)
37
- multiplex.trace("execute_query_lazy", { multiplex: multiplex, query: query }) { super }
38
- end
39
2
 
40
- def execute_field(field:, query:, ast_node:, arguments:, object:)
41
- query.trace("execute_field", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
42
- end
43
-
44
- def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
45
- query.trace("execute_field_lazy", { field: field, query: query, ast_node: ast_node, arguments: arguments, object: object, owner: field.owner, path: query.context[:current_path] }) { super }
46
- end
47
-
48
- def authorized(query:, type:, object:)
49
- query.trace("authorized", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
50
- end
51
-
52
- def authorized_lazy(query:, type:, object:)
53
- query.trace("authorized_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
54
- end
55
-
56
- def resolve_type(query:, type:, object:)
57
- query.trace("resolve_type", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
58
- end
59
-
60
- def resolve_type_lazy(query:, type:, object:)
61
- query.trace("resolve_type_lazy", { context: query.context, type: type, object: object, path: query.context[:current_path] }) { super }
62
- end
63
- end
3
+ require "graphql/tracing/trace"
4
+ require "graphql/tracing/call_legacy_tracers"
64
5
 
6
+ module GraphQL
7
+ module Tracing
65
8
  class LegacyTrace < Trace
66
9
  include CallLegacyTracers
67
10
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module NewRelicTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class NewRelicTracing < PlatformTracing
@@ -33,8 +33,8 @@ module GraphQL
33
33
  "resolve_type_lazy" => "resolve_type.graphql",
34
34
  }.each do |trace_method, platform_key|
35
35
  module_eval <<-RUBY, __FILE__, __LINE__
36
- def #{trace_method}(**metadata, &blk)
37
- @notifications_engine.instrument("#{platform_key}", metadata, &blk)
36
+ def #{trace_method}(**metadata, &block)
37
+ @notifications_engine.instrument("#{platform_key}", metadata) { super(**metadata, &block) }
38
38
  end
39
39
  RUBY
40
40
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  # This implementation forwards events to a notification handler (i.e.
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphql/tracing/trace"
4
+
5
+ module GraphQL
6
+ module Tracing
7
+ NullTrace = Trace.new
8
+ end
9
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module PrometheusTrace
@@ -1,8 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module PrometheusTrace
8
+ if defined?(PrometheusExporter::Server)
9
+ autoload :GraphQLCollector, "graphql/tracing/prometheus_trace/graphql_collector"
10
+ end
6
11
  include PlatformTrace
7
12
 
8
13
  def initialize(client: PrometheusExporter::Client.default, keys_whitelist: ["execute_field", "execute_field_lazy"], collector_type: "graphql", **rest)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class PrometheusTracing < PlatformTracing
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module ScoutTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class ScoutTracing < PlatformTracing
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module SentryTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_trace"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  module StatsdTrace
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "graphql/tracing/platform_tracing"
4
+
3
5
  module GraphQL
4
6
  module Tracing
5
7
  class StatsdTracing < PlatformTracing
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
3
+ require "graphql/tracing"
4
+
2
5
  module GraphQL
3
6
  module Tracing
4
7
  # This is the base class for a `trace` instance whose methods are called during query execution.
@@ -1,38 +1,36 @@
1
1
  # frozen_string_literal: true
2
- require "graphql/tracing/trace"
3
- require "graphql/tracing/legacy_trace"
4
- require "graphql/tracing/legacy_hooks_trace"
5
2
 
6
- # Legacy tracing:
7
- require "graphql/tracing/active_support_notifications_tracing"
8
- require "graphql/tracing/platform_tracing"
9
- require "graphql/tracing/appoptics_tracing"
10
- require "graphql/tracing/appsignal_tracing"
11
- require "graphql/tracing/data_dog_tracing"
12
- require "graphql/tracing/new_relic_tracing"
13
- require "graphql/tracing/scout_tracing"
14
- require "graphql/tracing/statsd_tracing"
15
- require "graphql/tracing/prometheus_tracing"
16
-
17
- # New Tracing:
18
- require "graphql/tracing/active_support_notifications_trace"
19
- require "graphql/tracing/platform_trace"
20
- require "graphql/tracing/appoptics_trace"
21
- require "graphql/tracing/appsignal_trace"
22
- require "graphql/tracing/data_dog_trace"
23
- require "graphql/tracing/new_relic_trace"
24
- require "graphql/tracing/notifications_trace"
25
- require "graphql/tracing/sentry_trace"
26
- require "graphql/tracing/scout_trace"
27
- require "graphql/tracing/statsd_trace"
28
- require "graphql/tracing/prometheus_trace"
29
- if defined?(PrometheusExporter::Server)
30
- require "graphql/tracing/prometheus_trace/graphql_collector"
31
- end
32
3
 
33
4
  module GraphQL
34
5
  module Tracing
35
- NullTrace = Trace.new
6
+ autoload :Trace, "graphql/tracing/trace"
7
+ autoload :CallLegacyTracers, "graphql/tracing/call_legacy_tracers"
8
+ autoload :LegacyTrace, "graphql/tracing/legacy_trace"
9
+ autoload :LegacyHooksTrace, "graphql/tracing/legacy_hooks_trace"
10
+ autoload :NullTrace, "graphql/tracing/null_trace"
11
+
12
+ autoload :ActiveSupportNotificationsTracing, "graphql/tracing/active_support_notifications_tracing"
13
+ autoload :PlatformTracing, "graphql/tracing/platform_tracing"
14
+ autoload :AppOpticsTracing, "graphql/tracing/appoptics_tracing"
15
+ autoload :AppsignalTracing, "graphql/tracing/appsignal_tracing"
16
+ autoload :DataDogTracing, "graphql/tracing/data_dog_tracing"
17
+ autoload :NewRelicTracing, "graphql/tracing/new_relic_tracing"
18
+ autoload :NotificationsTracing, "graphql/tracing/notifications_tracing"
19
+ autoload :ScoutTracing, "graphql/tracing/scout_tracing"
20
+ autoload :StatsdTracing, "graphql/tracing/statsd_tracing"
21
+ autoload :PrometheusTracing, "graphql/tracing/prometheus_tracing"
22
+
23
+ autoload :ActiveSupportNotificationsTrace, "graphql/tracing/active_support_notifications_trace"
24
+ autoload :PlatformTrace, "graphql/tracing/platform_trace"
25
+ autoload :AppOpticsTrace, "graphql/tracing/appoptics_trace"
26
+ autoload :AppsignalTrace, "graphql/tracing/appsignal_trace"
27
+ autoload :DataDogTrace, "graphql/tracing/data_dog_trace"
28
+ autoload :NewRelicTrace, "graphql/tracing/new_relic_trace"
29
+ autoload :NotificationsTrace, "graphql/tracing/notifications_trace"
30
+ autoload :SentryTrace, "graphql/tracing/sentry_trace"
31
+ autoload :ScoutTrace, "graphql/tracing/scout_trace"
32
+ autoload :StatsdTrace, "graphql/tracing/statsd_trace"
33
+ autoload :PrometheusTrace, "graphql/tracing/prometheus_trace"
36
34
 
37
35
  # Objects may include traceable to gain a `.trace(...)` method.
38
36
  # The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
@@ -18,6 +18,7 @@ module GraphQL
18
18
  self.node_type = nil
19
19
  self.edge_class = nil
20
20
  }
21
+ child_class.default_broadcastable(nil)
21
22
  add_page_info_field(child_class)
22
23
  end
23
24
 
@@ -31,12 +32,21 @@ module GraphQL
31
32
  child_class.edge_type = nil
32
33
  child_class.node_type = nil
33
34
  child_class.edge_class = nil
35
+ child_class.default_broadcastable(default_broadcastable?)
34
36
  end
35
37
 
36
38
  def default_relay?
37
39
  true
38
40
  end
39
41
 
42
+ def default_broadcastable?
43
+ @default_broadcastable
44
+ end
45
+
46
+ def default_broadcastable(new_value)
47
+ @default_broadcastable = new_value
48
+ end
49
+
40
50
  # @return [Class]
41
51
  attr_reader :node_type
42
52
 
@@ -186,7 +196,7 @@ module GraphQL
186
196
  def edges
187
197
  # Assume that whatever authorization needed to happen
188
198
  # already happened at the connection level.
189
- current_runtime_state = Thread.current[:__graphql_runtime_info]
199
+ current_runtime_state = Fiber[:__graphql_runtime_info]
190
200
  query_runtime_state = current_runtime_state[context.query]
191
201
  query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
192
202
  @object.edges
@@ -195,7 +205,7 @@ module GraphQL
195
205
  def nodes
196
206
  # Assume that whatever authorization needed to happen
197
207
  # already happened at the connection level.
198
- current_runtime_state = Thread.current[:__graphql_runtime_info]
208
+ current_runtime_state = Fiber[:__graphql_runtime_info]
199
209
  query_runtime_state = current_runtime_state[context.query]
200
210
  query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
201
211
  @object.nodes