graphql 2.4.13 → 2.5.11

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/query_complexity.rb +87 -7
  3. data/lib/graphql/backtrace/table.rb +37 -14
  4. data/lib/graphql/current.rb +1 -1
  5. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  6. data/lib/graphql/dashboard/installable.rb +22 -0
  7. data/lib/graphql/dashboard/limiters.rb +93 -0
  8. data/lib/graphql/dashboard/operation_store.rb +199 -0
  9. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  10. data/lib/graphql/dashboard/statics/dashboard.css +27 -0
  11. data/lib/graphql/dashboard/statics/dashboard.js +74 -9
  12. data/lib/graphql/dashboard/subscriptions.rb +96 -0
  13. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  14. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  15. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  16. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
  17. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  18. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  19. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  20. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  21. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  22. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  23. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  24. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  25. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  26. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  27. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +49 -1
  28. data/lib/graphql/dashboard.rb +45 -29
  29. data/lib/graphql/dataloader/active_record_association_source.rb +28 -8
  30. data/lib/graphql/dataloader/active_record_source.rb +26 -5
  31. data/lib/graphql/dataloader/null_dataloader.rb +7 -0
  32. data/lib/graphql/dataloader/source.rb +16 -4
  33. data/lib/graphql/dig.rb +2 -1
  34. data/lib/graphql/execution/interpreter/resolve.rb +3 -3
  35. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +34 -1
  36. data/lib/graphql/execution/interpreter/runtime.rb +163 -59
  37. data/lib/graphql/execution/interpreter.rb +5 -13
  38. data/lib/graphql/execution/multiplex.rb +6 -1
  39. data/lib/graphql/invalid_null_error.rb +15 -2
  40. data/lib/graphql/language/lexer.rb +9 -2
  41. data/lib/graphql/language/nodes.rb +5 -1
  42. data/lib/graphql/language/parser.rb +14 -6
  43. data/lib/graphql/query/context.rb +3 -8
  44. data/lib/graphql/query/partial.rb +179 -0
  45. data/lib/graphql/query.rb +59 -55
  46. data/lib/graphql/schema/addition.rb +3 -1
  47. data/lib/graphql/schema/always_visible.rb +1 -0
  48. data/lib/graphql/schema/argument.rb +9 -3
  49. data/lib/graphql/schema/build_from_definition.rb +96 -47
  50. data/lib/graphql/schema/directive/flagged.rb +2 -0
  51. data/lib/graphql/schema/directive.rb +33 -1
  52. data/lib/graphql/schema/field.rb +23 -1
  53. data/lib/graphql/schema/input_object.rb +38 -30
  54. data/lib/graphql/schema/list.rb +1 -1
  55. data/lib/graphql/schema/member/has_arguments.rb +2 -2
  56. data/lib/graphql/schema/member/has_dataloader.rb +4 -2
  57. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  58. data/lib/graphql/schema/member/has_interfaces.rb +2 -2
  59. data/lib/graphql/schema/member/type_system_helpers.rb +16 -2
  60. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  61. data/lib/graphql/schema/resolver.rb +1 -0
  62. data/lib/graphql/schema/scalar.rb +1 -6
  63. data/lib/graphql/schema/timeout.rb +19 -2
  64. data/lib/graphql/schema/validator/required_validator.rb +15 -6
  65. data/lib/graphql/schema/visibility/migration.rb +2 -2
  66. data/lib/graphql/schema/visibility/profile.rb +107 -21
  67. data/lib/graphql/schema/visibility.rb +41 -29
  68. data/lib/graphql/schema/warden.rb +13 -5
  69. data/lib/graphql/schema.rb +228 -32
  70. data/lib/graphql/static_validation/all_rules.rb +2 -2
  71. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +47 -13
  72. data/lib/graphql/static_validation/rules/fields_will_merge.rb +78 -16
  73. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  74. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  75. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  76. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +6 -2
  77. data/lib/graphql/testing/helpers.rb +5 -2
  78. data/lib/graphql/tracing/active_support_notifications_trace.rb +7 -0
  79. data/lib/graphql/tracing/appoptics_tracing.rb +5 -0
  80. data/lib/graphql/tracing/appsignal_trace.rb +26 -61
  81. data/lib/graphql/tracing/data_dog_trace.rb +41 -164
  82. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  83. data/lib/graphql/tracing/new_relic_trace.rb +34 -164
  84. data/lib/graphql/tracing/notifications_trace.rb +183 -37
  85. data/lib/graphql/tracing/null_trace.rb +1 -1
  86. data/lib/graphql/tracing/perfetto_trace.rb +16 -19
  87. data/lib/graphql/tracing/prometheus_trace.rb +47 -74
  88. data/lib/graphql/tracing/scout_trace.rb +25 -59
  89. data/lib/graphql/tracing/sentry_trace.rb +56 -99
  90. data/lib/graphql/tracing/statsd_trace.rb +24 -47
  91. data/lib/graphql/tracing/trace.rb +0 -17
  92. data/lib/graphql/tracing.rb +1 -0
  93. data/lib/graphql/type_kinds.rb +1 -0
  94. data/lib/graphql/version.rb +1 -1
  95. data/lib/graphql.rb +1 -1
  96. metadata +35 -26
  97. data/lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb +0 -63
  98. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
@@ -1,121 +1,78 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "graphql/tracing/platform_trace"
3
+ require "graphql/tracing/monitor_trace"
4
4
 
5
5
  module GraphQL
6
6
  module Tracing
7
7
  # A tracer for reporting GraphQL-Ruby times to Sentry.
8
+ #
8
9
  # @example Installing the tracer
9
10
  # class MySchema < GraphQL::Schema
10
11
  # trace_with GraphQL::Tracing::SentryTrace
11
12
  # end
13
+ # @see MonitorTrace Configuration Options in the parent module
14
+ SentryTrace = MonitorTrace.create_module("sentry")
12
15
  module SentryTrace
13
- include PlatformTrace
14
-
15
- # @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
16
- # This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
17
- # It can also be specified per-query with `context[:set_sentry_transaction_name]`.
18
- def initialize(set_transaction_name: false, **_rest)
19
- @set_transaction_name = set_transaction_name
20
- super
21
- end
22
-
23
- def execute_query(**data)
24
- set_this_txn_name = data[:query].context[:set_sentry_transaction_name]
25
- if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
26
- Sentry.configure_scope do |scope|
27
- scope.set_transaction_name(transaction_name(data[:query]))
16
+ class SentryMonitor < MonitorTrace::Monitor
17
+ def instrument(keyword, object)
18
+ return yield unless Sentry.initialized?
19
+
20
+ platform_key = name_for(keyword, object)
21
+
22
+ Sentry.with_child_span(op: platform_key, start_timestamp: Sentry.utc_now.to_f) do |span|
23
+ result = yield
24
+ return result unless span
25
+
26
+ span.finish
27
+ if keyword == :execute
28
+ queries = object.queries
29
+ operation_names = queries.map{|q| operation_name(q) }
30
+ span.set_description(operation_names.join(", "))
31
+
32
+ if queries.size == 1
33
+ query = queries.first
34
+ set_this_txn_name = query.context[:set_sentry_transaction_name]
35
+ if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
36
+ Sentry.configure_scope do |scope|
37
+ scope.set_transaction_name(transaction_name(query))
38
+ end
39
+ end
40
+ span.set_data('graphql.document', query.query_string)
41
+ if query.selected_operation_name
42
+ span.set_data('graphql.operation.name', query.selected_operation_name)
43
+ end
44
+ span.set_data('graphql.operation.type', query.selected_operation.operation_type)
45
+ end
46
+ end
47
+
48
+ result
28
49
  end
29
50
  end
30
- instrument_sentry_execution("graphql.execute", "execute_query", data) { super }
31
- end
32
51
 
33
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
52
+ include MonitorTrace::Monitor::GraphQLPrefixNames
34
53
 
35
- {
36
- "lex" => "graphql.lex",
37
- "parse" => "graphql.parse",
38
- "validate" => "graphql.validate",
39
- "analyze_query" => "graphql.analyze",
40
- "analyze_multiplex" => "graphql.analyze_multiplex",
41
- "execute_multiplex" => "graphql.execute_multiplex",
42
- "execute_query_lazy" => "graphql.execute"
43
- }.each do |trace_method, platform_key|
44
- module_eval <<-RUBY, __FILE__, __LINE__
45
- def #{trace_method}(**data)
46
- instrument_sentry_execution("#{platform_key}", "#{trace_method}", data) { super }
47
- end
48
- RUBY
49
- end
50
-
51
- # rubocop:enable Development/NoEvalCop
52
-
53
- def platform_execute_field(platform_key, &block)
54
- instrument_sentry_execution(platform_key, "execute_field", &block)
55
- end
56
-
57
- def platform_execute_field_lazy(platform_key, &block)
58
- instrument_sentry_execution(platform_key, "execute_field_lazy", &block)
59
- end
60
-
61
- def platform_authorized(platform_key, &block)
62
- instrument_sentry_execution(platform_key, "authorized", &block)
63
- end
64
-
65
- def platform_authorized_lazy(platform_key, &block)
66
- instrument_sentry_execution(platform_key, "authorized_lazy", &block)
67
- end
68
-
69
- def platform_resolve_type(platform_key, &block)
70
- instrument_sentry_execution(platform_key, "resolve_type", &block)
71
- end
54
+ private
72
55
 
73
- def platform_resolve_type_lazy(platform_key, &block)
74
- instrument_sentry_execution(platform_key, "resolve_type_lazy", &block)
75
- end
76
-
77
- def platform_field_key(field)
78
- "graphql.field.#{field.path}"
79
- end
80
-
81
- def platform_authorized_key(type)
82
- "graphql.authorized.#{type.graphql_name}"
83
- end
84
-
85
- def platform_resolve_type_key(type)
86
- "graphql.resolve_type.#{type.graphql_name}"
87
- end
88
-
89
- private
90
-
91
- def instrument_sentry_execution(platform_key, trace_method, data=nil, &block)
92
- return yield unless Sentry.initialized?
93
-
94
- Sentry.with_child_span(op: platform_key, start_timestamp: Sentry.utc_now.to_f) do |span|
95
- result = yield
96
- return result unless span
97
-
98
- span.finish
99
- if trace_method == "execute_multiplex" && data.key?(:multiplex)
100
- operation_names = data[:multiplex].queries.map{|q| operation_name(q) }
101
- span.set_description(operation_names.join(", "))
102
- elsif trace_method == "execute_query" && data.key?(:query)
103
- span.set_description(operation_name(data[:query]))
104
- span.set_data('graphql.document', data[:query].query_string)
105
- span.set_data('graphql.operation.name', data[:query].selected_operation_name) if data[:query].selected_operation_name
106
- span.set_data('graphql.operation.type', data[:query].selected_operation.operation_type)
56
+ def operation_name(query)
57
+ selected_op = query.selected_operation
58
+ if selected_op
59
+ [selected_op.operation_type, selected_op.name].compact.join(' ')
60
+ else
61
+ 'GraphQL Operation'
107
62
  end
108
-
109
- result
110
63
  end
111
- end
112
64
 
113
- def operation_name(query)
114
- selected_op = query.selected_operation
115
- if selected_op
116
- [selected_op.operation_type, selected_op.name].compact.join(' ')
117
- else
118
- 'GraphQL Operation'
65
+ class Event < MonitorTrace::Monitor::Event
66
+ def start
67
+ if Sentry.initialized? && (@span = Sentry.get_current_scope.get_span)
68
+ span_name = @monitor.name_for(@keyword, @object)
69
+ @span.start_child(op: span_name)
70
+ end
71
+ end
72
+
73
+ def finish
74
+ @span&.finish
75
+ end
119
76
  end
120
77
  end
121
78
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "graphql/tracing/platform_trace"
3
+ require "graphql/tracing/monitor_trace"
4
4
 
5
5
  module GraphQL
6
6
  module Tracing
7
7
  # A tracer for reporting GraphQL-Ruby times to Statsd.
8
- # Passing any Statsd client that implements `.time(name) { ... }` will work.
8
+ # Passing any Statsd client that implements `.time(name) { ... }`
9
+ # and `.timing(name, ms)` will work.
9
10
  #
10
11
  # @example Installing this tracer
11
12
  # # eg:
@@ -13,58 +14,34 @@ module GraphQL
13
14
  # class MySchema < GraphQL::Schema
14
15
  # use GraphQL::Tracing::StatsdTrace, statsd: $statsd
15
16
  # end
17
+ StatsdTrace = MonitorTrace.create_module("statsd")
16
18
  module StatsdTrace
17
- include PlatformTrace
19
+ class StatsdMonitor < MonitorTrace::Monitor
20
+ def initialize(statsd:, **_rest)
21
+ @statsd = statsd
22
+ super
23
+ end
18
24
 
19
- # @param statsd [Object] A statsd client
20
- def initialize(statsd:, **rest)
21
- @statsd = statsd
22
- super(**rest)
23
- end
24
-
25
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
25
+ attr_reader :statsd
26
26
 
27
- {
28
- 'lex' => "graphql.lex",
29
- 'parse' => "graphql.parse",
30
- 'validate' => "graphql.validate",
31
- 'analyze_query' => "graphql.analyze_query",
32
- 'analyze_multiplex' => "graphql.analyze_multiplex",
33
- 'execute_multiplex' => "graphql.execute_multiplex",
34
- 'execute_query' => "graphql.execute_query",
35
- 'execute_query_lazy' => "graphql.execute_query_lazy",
36
- }.each do |trace_method, platform_key|
37
- module_eval <<-RUBY, __FILE__, __LINE__
38
- def #{trace_method}(**data)
39
- @statsd.time("#{platform_key}") do
40
- super
41
- end
27
+ def instrument(keyword, object)
28
+ @statsd.time(name_for(keyword, object)) do
29
+ yield
42
30
  end
43
- RUBY
44
- end
45
-
46
- # rubocop:enable Development/NoEvalCop
31
+ end
47
32
 
48
- def platform_execute_field(platform_key, &block)
49
- @statsd.time(platform_key, &block)
50
- end
51
-
52
- def platform_authorized(key, &block)
53
- @statsd.time(key, &block)
54
- end
33
+ include MonitorTrace::Monitor::GraphQLPrefixNames
55
34
 
56
- alias :platform_resolve_type :platform_authorized
57
-
58
- def platform_field_key(field)
59
- "graphql.#{field.path}"
60
- end
61
-
62
- def platform_authorized_key(type)
63
- "graphql.authorized.#{type.graphql_name}"
64
- end
35
+ class Event < MonitorTrace::Monitor::Event
36
+ def start
37
+ @start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
38
+ end
65
39
 
66
- def platform_resolve_type_key(type)
67
- "graphql.resolve_type.#{type.graphql_name}"
40
+ def finish
41
+ elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start_time
42
+ @monitor.statsd.timing(@monitor.name_for(keyword, object), elapsed)
43
+ end
44
+ end
68
45
  end
69
46
  end
70
47
  end
@@ -23,12 +23,6 @@ module GraphQL
23
23
  yield
24
24
  end
25
25
 
26
- # @param query_str [String]
27
- # @return [void]
28
- def begin_parse(query_str); end;
29
- # @param query_str [String]
30
- # @return [void]
31
- def end_parse(query_str); end;
32
26
  # @param query_string [String]
33
27
  # @return [void]
34
28
  def parse(query_string:)
@@ -63,17 +57,6 @@ module GraphQL
63
57
  yield
64
58
  end
65
59
 
66
- # This is the first event in the tracing lifecycle.
67
- # Every Query is technically run _inside_ a {GraphQL::Multiplex}.
68
- # @param multiplex [GraphQL::Execution::Multiplex]
69
- # @return [void]
70
- def begin_execute_multiplex(multiplex); end;
71
-
72
- # This is the last event of the tracing lifecycle.
73
- # @param multiplex [GraphQL::Execution::Multiplex]
74
- # @return [void]
75
- def end_execute_multiplex(multiplex); end;
76
-
77
60
  # This wraps an entire `.execute` call.
78
61
  # @param multiplex [GraphQL::Execution::Multiplex]
79
62
  # @return [void]
@@ -25,6 +25,7 @@ module GraphQL
25
25
  autoload :AppOpticsTrace, "graphql/tracing/appoptics_trace"
26
26
  autoload :AppsignalTrace, "graphql/tracing/appsignal_trace"
27
27
  autoload :DataDogTrace, "graphql/tracing/data_dog_trace"
28
+ autoload :MonitorTrace, "graphql/tracing/monitor_trace"
28
29
  autoload :NewRelicTrace, "graphql/tracing/new_relic_trace"
29
30
  autoload :NotificationsTrace, "graphql/tracing/notifications_trace"
30
31
  autoload :SentryTrace, "graphql/tracing/sentry_trace"
@@ -14,6 +14,7 @@ module GraphQL
14
14
  @leaf = leaf
15
15
  @composite = fields? || abstract?
16
16
  @description = description
17
+ freeze
17
18
  end
18
19
 
19
20
  # Does this TypeKind have multiple possible implementers?
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.4.13"
3
+ VERSION = "2.5.11"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -72,7 +72,7 @@ This is probably a bug in GraphQL-Ruby, please report this error on GitHub: http
72
72
  GraphQL::Language::Lexer.tokenize(graphql_string)
73
73
  end
74
74
 
75
- NOT_CONFIGURED = Object.new
75
+ NOT_CONFIGURED = Object.new.freeze
76
76
  private_constant :NOT_CONFIGURED
77
77
  module EmptyObjects
78
78
  EMPTY_HASH = {}.freeze
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.13
4
+ version: 2.5.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-12 00:00:00.000000000 Z
10
+ date: 2025-07-09 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: base64
@@ -164,7 +164,7 @@ dependencies:
164
164
  - !ruby/object:Gem::Version
165
165
  version: '0'
166
166
  - !ruby/object:Gem::Dependency
167
- name: rake
167
+ name: ostruct
168
168
  requirement: !ruby/object:Gem::Requirement
169
169
  requirements:
170
170
  - - ">="
@@ -178,21 +178,7 @@ dependencies:
178
178
  - !ruby/object:Gem::Version
179
179
  version: '0'
180
180
  - !ruby/object:Gem::Dependency
181
- name: rake-compiler
182
- requirement: !ruby/object:Gem::Requirement
183
- requirements:
184
- - - ">="
185
- - !ruby/object:Gem::Version
186
- version: '0'
187
- type: :development
188
- prerelease: false
189
- version_requirements: !ruby/object:Gem::Requirement
190
- requirements:
191
- - - ">="
192
- - !ruby/object:Gem::Version
193
- version: '0'
194
- - !ruby/object:Gem::Dependency
195
- name: rubocop
181
+ name: rake
196
182
  requirement: !ruby/object:Gem::Requirement
197
183
  requirements:
198
184
  - - ">="
@@ -206,7 +192,7 @@ dependencies:
206
192
  - !ruby/object:Gem::Version
207
193
  version: '0'
208
194
  - !ruby/object:Gem::Dependency
209
- name: simplecov
195
+ name: rake-compiler
210
196
  requirement: !ruby/object:Gem::Requirement
211
197
  requirements:
212
198
  - - ">="
@@ -220,7 +206,7 @@ dependencies:
220
206
  - !ruby/object:Gem::Version
221
207
  version: '0'
222
208
  - !ruby/object:Gem::Dependency
223
- name: simplecov-lcov
209
+ name: rubocop
224
210
  requirement: !ruby/object:Gem::Requirement
225
211
  requirements:
226
212
  - - ">="
@@ -234,7 +220,7 @@ dependencies:
234
220
  - !ruby/object:Gem::Version
235
221
  version: '0'
236
222
  - !ruby/object:Gem::Dependency
237
- name: undercover
223
+ name: simplecov
238
224
  requirement: !ruby/object:Gem::Requirement
239
225
  requirements:
240
226
  - - ">="
@@ -248,7 +234,7 @@ dependencies:
248
234
  - !ruby/object:Gem::Version
249
235
  version: '0'
250
236
  - !ruby/object:Gem::Dependency
251
- name: pronto
237
+ name: simplecov-lcov
252
238
  requirement: !ruby/object:Gem::Requirement
253
239
  requirements:
254
240
  - - ">="
@@ -262,7 +248,7 @@ dependencies:
262
248
  - !ruby/object:Gem::Version
263
249
  version: '0'
264
250
  - !ruby/object:Gem::Dependency
265
- name: pronto-undercover
251
+ name: undercover
266
252
  requirement: !ruby/object:Gem::Requirement
267
253
  requirements:
268
254
  - - ">="
@@ -460,14 +446,33 @@ files:
460
446
  - lib/graphql/coercion_error.rb
461
447
  - lib/graphql/current.rb
462
448
  - lib/graphql/dashboard.rb
449
+ - lib/graphql/dashboard/detailed_traces.rb
450
+ - lib/graphql/dashboard/installable.rb
451
+ - lib/graphql/dashboard/limiters.rb
452
+ - lib/graphql/dashboard/operation_store.rb
463
453
  - lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css
464
454
  - lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js
455
+ - lib/graphql/dashboard/statics/charts.min.css
465
456
  - lib/graphql/dashboard/statics/dashboard.css
466
457
  - lib/graphql/dashboard/statics/dashboard.js
467
458
  - lib/graphql/dashboard/statics/header-icon.png
468
459
  - lib/graphql/dashboard/statics/icon.png
460
+ - lib/graphql/dashboard/subscriptions.rb
461
+ - lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb
469
462
  - lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb
470
- - lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb
463
+ - lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb
464
+ - lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb
465
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb
466
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb
467
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb
468
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb
469
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb
470
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb
471
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb
472
+ - lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb
473
+ - lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb
474
+ - lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb
475
+ - lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb
471
476
  - lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb
472
477
  - lib/graphql/dataloader.rb
473
478
  - lib/graphql/dataloader/active_record_association_source.rb
@@ -545,6 +550,7 @@ files:
545
550
  - lib/graphql/query/fingerprint.rb
546
551
  - lib/graphql/query/input_validation_result.rb
547
552
  - lib/graphql/query/null_context.rb
553
+ - lib/graphql/query/partial.rb
548
554
  - lib/graphql/query/result.rb
549
555
  - lib/graphql/query/validation_pipeline.rb
550
556
  - lib/graphql/query/variable_validation_error.rb
@@ -616,6 +622,7 @@ files:
616
622
  - lib/graphql/schema/non_null.rb
617
623
  - lib/graphql/schema/object.rb
618
624
  - lib/graphql/schema/printer.rb
625
+ - lib/graphql/schema/ractor_shareable.rb
619
626
  - lib/graphql/schema/relay_classic_mutation.rb
620
627
  - lib/graphql/schema/resolver.rb
621
628
  - lib/graphql/schema/resolver/has_payload_type.rb
@@ -685,6 +692,7 @@ files:
685
692
  - lib/graphql/static_validation/rules/mutation_root_exists_error.rb
686
693
  - lib/graphql/static_validation/rules/no_definitions_are_present.rb
687
694
  - lib/graphql/static_validation/rules/no_definitions_are_present_error.rb
695
+ - lib/graphql/static_validation/rules/not_single_subscription_error.rb
688
696
  - lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb
689
697
  - lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb
690
698
  - lib/graphql/static_validation/rules/operation_names_are_valid.rb
@@ -695,7 +703,7 @@ files:
695
703
  - lib/graphql/static_validation/rules/required_arguments_are_present_error.rb
696
704
  - lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb
697
705
  - lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb
698
- - lib/graphql/static_validation/rules/subscription_root_exists.rb
706
+ - lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb
699
707
  - lib/graphql/static_validation/rules/subscription_root_exists_error.rb
700
708
  - lib/graphql/static_validation/rules/unique_directives_per_location.rb
701
709
  - lib/graphql/static_validation/rules/unique_directives_per_location_error.rb
@@ -736,6 +744,7 @@ files:
736
744
  - lib/graphql/tracing/detailed_trace/redis_backend.rb
737
745
  - lib/graphql/tracing/legacy_hooks_trace.rb
738
746
  - lib/graphql/tracing/legacy_trace.rb
747
+ - lib/graphql/tracing/monitor_trace.rb
739
748
  - lib/graphql/tracing/new_relic_trace.rb
740
749
  - lib/graphql/tracing/new_relic_tracing.rb
741
750
  - lib/graphql/tracing/notifications_trace.rb
@@ -808,7 +817,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
808
817
  - !ruby/object:Gem::Version
809
818
  version: '0'
810
819
  requirements: []
811
- rubygems_version: 3.6.3
820
+ rubygems_version: 3.6.8
812
821
  specification_version: 4
813
822
  summary: A GraphQL language and runtime for Ruby
814
823
  test_files: []
@@ -1,63 +0,0 @@
1
- <% content_for(:title, "Profiles") %>
2
- <div class="row">
3
- <div class="col">
4
- <h1>Detailed Profiles</h1>
5
- </div>
6
- </div>
7
- <% if !@detailed_trace_installed %>
8
- <div class="row">
9
- <div class="col-md col-lg-6 mx-auto">
10
- <div class="card mt-4">
11
- <div class="card-body">
12
- <div class="card-title">
13
- <h3>
14
- Traces aren't installed yet
15
- </h3>
16
- </div>
17
- <p class="card-text">
18
- GraphQL-Ruby can instrument production traffic and save tracing artifacts here for later review.
19
- </p>
20
- <p class="card-text">
21
- Read more in <%= link_to "the tracing docs", "https://graphql-ruby.org/queries/tracing#detailed-traces" %>.
22
- </p>
23
- </div>
24
- </div>
25
- </div>
26
- </div>
27
- <% else %>
28
- <div class="row">
29
- <div class="col">
30
- <table class="table table-striped">
31
- <thead>
32
- <tr>
33
- <th>Operation</th>
34
- <th>Duration (ms) </th>
35
- <th>Timestamp</th>
36
- <th>Open in Perfetto UI</th>
37
- </tr>
38
- </thead>
39
- <tbody>
40
- <% if @traces.empty? %>
41
- <tr>
42
- <td colspan="4" class="text-center">
43
- <em>No traces saved yet. Read about saving traces <%= link_to "in the docs", "https://graphql-ruby.org/queries/tracing#detailed-profiles" %>.</em>
44
- </td>
45
- </tr>
46
- <% end %>
47
- <% @traces.each do |trace| %>
48
- <tr>
49
- <td><%= trace.operation_name %></td>
50
- <td><%= trace.duration_ms.round(2) %></td>
51
- <td><%= Time.at(trace.begin_ms / 1000.0).strftime("%Y-%m-%d %H:%M:%S.%L") %></td>
52
- <td><%= link_to "View ↗", "#", data: { perfetto_open: trace.operation_name, perfetto_path: "#{graphql_dashboard.traces_path}/#{trace.id}" } %></td>
53
- <td><%= link_to "Delete", "#", data: { perfetto_delete: "#{graphql_dashboard.traces_path}/#{trace.id}" }, class: "text-danger" %></td>
54
- </tr>
55
- <% end %>
56
- </tbody>
57
- </table>
58
- <% if @last && @traces.size >= @last %>
59
- <%= link_to("Previous >", graphql_dashboard.traces_path(last: @last, before: @traces.last.begin_ms), class: "btn btn-outline-primary") %>
60
- <% end %>
61
- </div>
62
- </div>
63
- <% end %>
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module StaticValidation
4
- module SubscriptionRootExists
5
- def on_operation_definition(node, _parent)
6
- if node.operation_type == "subscription" && context.types.subscription_root.nil?
7
- add_error(GraphQL::StaticValidation::SubscriptionRootExistsError.new(
8
- 'Schema is not configured for subscriptions',
9
- nodes: node
10
- ))
11
- else
12
- super
13
- end
14
- end
15
- end
16
- end
17
- end