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
@@ -4,37 +4,12 @@ require 'set'
4
4
 
5
5
  module GraphQL
6
6
  class Schema
7
- # Restrict access to a {GraphQL::Schema} with a user-defined filter.
7
+ # Restrict access to a {GraphQL::Schema} with a user-defined `visible?` implementations.
8
8
  #
9
9
  # When validating and executing a query, all access to schema members
10
10
  # should go through a warden. If you access the schema directly,
11
11
  # you may show a client something that it shouldn't be allowed to see.
12
12
  #
13
- # @example Hiding private fields
14
- # private_members = -> (member, ctx) { member.metadata[:private] }
15
- # result = Schema.execute(query_string, except: private_members)
16
- #
17
- # @example Custom filter implementation
18
- # # It must respond to `#call(member)`.
19
- # class MissingRequiredFlags
20
- # def initialize(user)
21
- # @user = user
22
- # end
23
- #
24
- # # Return `false` if any required flags are missing
25
- # def call(member, ctx)
26
- # member.metadata[:required_flags].any? do |flag|
27
- # !@user.has_flag?(flag)
28
- # end
29
- # end
30
- # end
31
- #
32
- # # Then, use the custom filter in query:
33
- # missing_required_flags = MissingRequiredFlags.new(current_user)
34
- #
35
- # # This query can only access members which match the user's flags
36
- # result = Schema.execute(query_string, except: missing_required_flags)
37
- #
38
13
  # @api private
39
14
  class Warden
40
15
  def self.from_context(context)
@@ -114,22 +89,16 @@ module GraphQL
114
89
  def interfaces(obj_type); obj_type.interfaces; end
115
90
  end
116
91
 
117
- # @param filter [<#call(member)>] Objects are hidden when `.call(member, ctx)` returns true
118
92
  # @param context [GraphQL::Query::Context]
119
93
  # @param schema [GraphQL::Schema]
120
- def initialize(filter = nil, context:, schema:)
94
+ def initialize(context:, schema:)
121
95
  @schema = schema
122
96
  # Cache these to avoid repeated hits to the inheritance chain when one isn't present
123
97
  @query = @schema.query
124
98
  @mutation = @schema.mutation
125
99
  @subscription = @schema.subscription
126
100
  @context = context
127
- @visibility_cache = if filter
128
- read_through { |m| filter.call(m, context) }
129
- else
130
- read_through { |m| schema.visible?(m, context) }
131
- end
132
-
101
+ @visibility_cache = read_through { |m| schema.visible?(m, context) }
133
102
  @visibility_cache.compare_by_identity
134
103
  # Initialize all ivars to improve object shape consistency:
135
104
  @types = @visible_types = @reachable_types = @visible_parent_fields =
@@ -222,7 +222,7 @@ module GraphQL
222
222
  # @param include_specified_by_url [Boolean] If true, scalar types' `specifiedByUrl:` will be included in the response
223
223
  # @param include_is_one_of [Boolean] If true, `isOneOf: true|false` will be included with input objects
224
224
  # @return [Hash] GraphQL result
225
- def as_json(only: nil, except: nil, context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
225
+ def as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
226
226
  introspection_query = Introspection.query(
227
227
  include_deprecated_args: include_deprecated_args,
228
228
  include_schema_description: include_schema_description,
@@ -231,16 +231,14 @@ module GraphQL
231
231
  include_specified_by_url: include_specified_by_url,
232
232
  )
233
233
 
234
- execute(introspection_query, only: only, except: except, context: context).to_h
234
+ execute(introspection_query, context: context).to_h
235
235
  end
236
236
 
237
237
  # Return the GraphQL IDL for the schema
238
238
  # @param context [Hash]
239
- # @param only [<#call(member, ctx)>]
240
- # @param except [<#call(member, ctx)>]
241
239
  # @return [String]
242
- def to_definition(only: nil, except: nil, context: {})
243
- GraphQL::Schema::Printer.print_schema(self, only: only, except: except, context: context)
240
+ def to_definition(context: {})
241
+ GraphQL::Schema::Printer.print_schema(self, context: context)
244
242
  end
245
243
 
246
244
  # Return the GraphQL::Language::Document IDL AST for the schema
@@ -268,20 +266,6 @@ module GraphQL
268
266
  @find_cache[path] ||= @finder.find(path)
269
267
  end
270
268
 
271
- def default_filter
272
- GraphQL::Filter.new(except: default_mask)
273
- end
274
-
275
- def default_mask(new_mask = nil)
276
- if new_mask
277
- line = caller(2, 10).find { |l| !l.include?("lib/graphql") }
278
- GraphQL::Deprecation.warn("GraphQL::Filter and Schema.mask are deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).\n #{line}")
279
- @own_default_mask = new_mask
280
- else
281
- @own_default_mask || find_inherited_value(:default_mask, Schema::NullMask)
282
- end
283
- end
284
-
285
269
  def static_validator
286
270
  GraphQL::StaticValidation::Validator.new(schema: self)
287
271
  end
@@ -8,9 +8,6 @@ module GraphQL
8
8
  # It provides access to the schema & fragments which validators may read from.
9
9
  #
10
10
  # It holds a list of errors which each validator may add to.
11
- #
12
- # It also provides limited access to the {TypeStack} instance,
13
- # which tracks state as you climb in and out of different fields.
14
11
  class ValidationContext
15
12
  extend Forwardable
16
13
 
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/static_validation/error"
3
3
  require "graphql/static_validation/definition_dependencies"
4
- require "graphql/static_validation/type_stack"
5
4
  require "graphql/static_validation/validator"
6
5
  require "graphql/static_validation/validation_context"
7
6
  require "graphql/static_validation/validation_timeout_error"
@@ -124,7 +124,8 @@ module GraphQL
124
124
  # This subscription was re-evaluated.
125
125
  # Send it to the specific stream where this client was waiting.
126
126
  def deliver(subscription_id, result)
127
- payload = { result: result.to_h, more: true }
127
+ has_more = !result.context.namespace(:subscriptions)[:final_update]
128
+ payload = { result: result.to_h, more: has_more }
128
129
  @action_cable.server.broadcast(stream_subscription_name(subscription_id), payload)
129
130
  end
130
131
 
@@ -125,10 +125,10 @@ module GraphQL
125
125
  variables: variables,
126
126
  root_value: object,
127
127
  }
128
-
128
+
129
129
  # merge event's and query's context together
130
130
  context.merge!(event.context) unless event.context.nil? || context.nil?
131
-
131
+
132
132
  execute_options[:validate] = validate_update?(**execute_options)
133
133
  result = @schema.execute(**execute_options)
134
134
  subscriptions_context = result.context.namespace(:subscriptions)
@@ -136,11 +136,9 @@ module GraphQL
136
136
  result = nil
137
137
  end
138
138
 
139
- unsubscribed = subscriptions_context[:unsubscribed]
140
-
141
- if unsubscribed
139
+ if subscriptions_context[:unsubscribed] && !subscriptions_context[:final_update]
142
140
  # `unsubscribe` was called, clean up on our side
143
- # TODO also send `{more: false}` to client?
141
+ # The transport should also send `{more: false}` to client
144
142
  delete_subscription(subscription_id)
145
143
  result = nil
146
144
  end
@@ -164,7 +162,14 @@ module GraphQL
164
162
  res = execute_update(subscription_id, event, object)
165
163
  if !res.nil?
166
164
  deliver(subscription_id, res)
165
+
166
+ if res.context.namespace(:subscriptions)[:unsubscribed]
167
+ # `unsubscribe` was called, clean up on our side
168
+ # The transport should also send `{more: false}` to client
169
+ delete_subscription(subscription_id)
170
+ end
167
171
  end
172
+
168
173
  end
169
174
 
170
175
  # Event `event` occurred on `object`,
@@ -28,8 +28,6 @@ module GraphQL
28
28
  Gem::Version.new('1.0.0')
29
29
  end
30
30
 
31
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
32
-
33
31
  [
34
32
  'lex',
35
33
  'parse',
@@ -57,8 +55,6 @@ module GraphQL
57
55
  RUBY
58
56
  end
59
57
 
60
- # rubocop:enable Development/NoEvalCop
61
-
62
58
  def execute_field(query:, field:, ast_node:, arguments:, object:)
63
59
  return_type = field.type.unwrap
64
60
  trace_field = if return_type.kind.scalar? || return_type.kind.enum?
@@ -13,8 +13,6 @@ module GraphQL
13
13
  super
14
14
  end
15
15
 
16
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
17
-
18
16
  {
19
17
  "lex" => "lex.graphql",
20
18
  "parse" => "parse.graphql",
@@ -45,8 +43,6 @@ module GraphQL
45
43
  RUBY
46
44
  end
47
45
 
48
- # rubocop:enable Development/NoEvalCop
49
-
50
46
  def platform_execute_field(platform_key)
51
47
  Appsignal.instrument(platform_key) do
52
48
  yield
@@ -3,25 +3,25 @@
3
3
  module GraphQL
4
4
  module Tracing
5
5
  module DataDogTrace
6
- # @param tracer [#trace] Deprecated
7
6
  # @param analytics_enabled [Boolean] Deprecated
8
7
  # @param analytics_sample_rate [Float] Deprecated
9
- def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service: nil, **rest)
8
+ def initialize(tracer: nil, analytics_enabled: false, analytics_sample_rate: 1.0, service: "ruby-graphql", **rest)
10
9
  if tracer.nil?
11
10
  tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
12
11
  end
13
12
  @tracer = tracer
14
13
 
15
- @analytics_enabled = analytics_enabled
16
- @analytics_sample_rate = analytics_sample_rate
14
+ analytics_available = defined?(Datadog::Contrib::Analytics) \
15
+ && Datadog::Contrib::Analytics.respond_to?(:enabled?) \
16
+ && Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
17
17
 
18
+ @analytics_enabled = analytics_available && Datadog::Contrib::Analytics.enabled?(analytics_enabled)
19
+ @analytics_sample_rate = analytics_sample_rate
18
20
  @service_name = service
19
21
  @has_prepare_span = respond_to?(:prepare_span)
20
22
  super
21
23
  end
22
24
 
23
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
24
-
25
25
  {
26
26
  'lex' => 'lex.graphql',
27
27
  'parse' => 'parse.graphql',
@@ -34,9 +34,12 @@ module GraphQL
34
34
  }.each do |trace_method, trace_key|
35
35
  module_eval <<-RUBY, __FILE__, __LINE__
36
36
  def #{trace_method}(**data)
37
- @tracer.trace("#{trace_key}", service: @service_name, type: 'custom') do |span|
38
- span.set_tag('component', 'graphql')
39
- span.set_tag('operation', '#{trace_method}')
37
+ @tracer.trace("#{trace_key}", service: @service_name) do |span|
38
+ span.span_type = 'custom'
39
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
40
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
41
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, '#{trace_method}')
42
+ end
40
43
 
41
44
  #{
42
45
  if trace_method == 'execute_multiplex'
@@ -51,8 +54,10 @@ module GraphQL
51
54
  end
52
55
  span.resource = resource if resource
53
56
 
54
- # [Deprecated] will be removed in the future
55
- span.set_metric('_dd1.sr.eausr', @analytics_sample_rate) if @analytics_enabled
57
+ # For top span of query, set the analytics sample rate tag, if available.
58
+ if @analytics_enabled
59
+ Datadog::Contrib::Analytics.set_sample_rate(span, @analytics_sample_rate)
60
+ end
56
61
  RUBY
57
62
  elsif trace_method == 'execute_query'
58
63
  <<-RUBY
@@ -71,8 +76,6 @@ module GraphQL
71
76
  RUBY
72
77
  end
73
78
 
74
- # rubocop:enable Development/NoEvalCop
75
-
76
79
  def execute_field_span(span_key, query, field, ast_node, arguments, object)
77
80
  return_type = field.type.unwrap
78
81
  trace_field = if return_type.kind.scalar? || return_type.kind.enum?
@@ -86,10 +89,12 @@ module GraphQL
86
89
  nil
87
90
  end
88
91
  if platform_key && trace_field
89
- @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
90
- span.set_tag('component', 'graphql')
91
- span.set_tag('operation', span_key)
92
-
92
+ @tracer.trace(platform_key, service: @service_name) do |span|
93
+ span.span_type = 'custom'
94
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
95
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
96
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
97
+ end
93
98
  if @has_prepare_span
94
99
  prepare_span_data = { query: query, field: field, ast_node: ast_node, arguments: arguments, object: object }
95
100
  prepare_span(span_key, prepare_span_data, span)
@@ -120,10 +125,12 @@ module GraphQL
120
125
 
121
126
  def authorized_span(span_key, object, type, query)
122
127
  platform_key = @platform_key_cache[DataDogTrace].platform_authorized_key_cache[type]
123
- @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
124
- span.set_tag('component', 'graphql')
125
- span.set_tag('operation', span_key)
126
-
128
+ @tracer.trace(platform_key, service: @service_name) do |span|
129
+ span.span_type = 'custom'
130
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
131
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
132
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
133
+ end
127
134
  if @has_prepare_span
128
135
  prepare_span(span_key, {object: object, type: type, query: query}, span)
129
136
  end
@@ -151,10 +158,12 @@ module GraphQL
151
158
 
152
159
  def resolve_type_span(span_key, object, type, query)
153
160
  platform_key = @platform_key_cache[DataDogTrace].platform_resolve_type_key_cache[type]
154
- @tracer.trace(platform_key, service: @service_name, type: 'custom') do |span|
155
- span.set_tag('component', 'graphql')
156
- span.set_tag('operation', span_key)
157
-
161
+ @tracer.trace(platform_key, service: @service_name) do |span|
162
+ span.span_type = 'custom'
163
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
164
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
165
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, span_key)
166
+ end
158
167
  if @has_prepare_span
159
168
  prepare_span(span_key, {object: object, type: type, query: query}, span)
160
169
  end
@@ -15,9 +15,12 @@ module GraphQL
15
15
  }
16
16
 
17
17
  def platform_trace(platform_key, key, data)
18
- tracer.trace(platform_key, service: options[:service], type: 'custom') do |span|
19
- span.set_tag('component', 'graphql')
20
- span.set_tag('operation', key)
18
+ tracer.trace(platform_key, service: service_name) do |span|
19
+ span.span_type = 'custom'
20
+ if defined?(Datadog::Tracing::Metadata::Ext) # Introduced in ddtrace 1.0
21
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT, 'graphql')
22
+ span.set_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION, key)
23
+ end
21
24
 
22
25
  if key == 'execute_multiplex'
23
26
  operations = data[:multiplex].queries.map(&:selected_operation_name).join(', ')
@@ -30,8 +33,10 @@ module GraphQL
30
33
  end
31
34
  span.resource = resource if resource
32
35
 
33
- # [Deprecated] will be removed in the future
34
- span.set_metric('_dd1.sr.eausr', analytics_sample_rate) if analytics_enabled?
36
+ # For top span of query, set the analytics sample rate tag, if available.
37
+ if analytics_enabled?
38
+ Datadog::Contrib::Analytics.set_sample_rate(span, analytics_sample_rate)
39
+ end
35
40
  end
36
41
 
37
42
  if key == 'execute_query'
@@ -46,6 +51,10 @@ module GraphQL
46
51
  end
47
52
  end
48
53
 
54
+ def service_name
55
+ options.fetch(:service, 'ruby-graphql')
56
+ end
57
+
49
58
  # Implement this method in a subclass to apply custom tags to datadog spans
50
59
  # @param key [String] The event being traced
51
60
  # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
@@ -56,13 +65,18 @@ module GraphQL
56
65
  def tracer
57
66
  default_tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
58
67
 
59
- # [Deprecated] options[:tracer] will be removed in the future
60
68
  options.fetch(:tracer, default_tracer)
61
69
  end
62
70
 
71
+ def analytics_available?
72
+ defined?(Datadog::Contrib::Analytics) \
73
+ && Datadog::Contrib::Analytics.respond_to?(:enabled?) \
74
+ && Datadog::Contrib::Analytics.respond_to?(:set_sample_rate)
75
+ end
76
+
63
77
  def analytics_enabled?
64
78
  # [Deprecated] options[:analytics_enabled] will be removed in the future
65
- options.fetch(:analytics_enabled, false)
79
+ analytics_available? && Datadog::Contrib::Analytics.enabled?(options.fetch(:analytics_enabled, false))
66
80
  end
67
81
 
68
82
  def analytics_sample_rate
@@ -16,8 +16,6 @@ module GraphQL
16
16
  super
17
17
  end
18
18
 
19
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
20
-
21
19
  {
22
20
  "lex" => "lex.graphql",
23
21
  "parse" => "parse.graphql",
@@ -41,8 +39,6 @@ module GraphQL
41
39
  RUBY
42
40
  end
43
41
 
44
- # rubocop:enable Development/NoEvalCop
45
-
46
42
  include PlatformTrace
47
43
  end
48
44
  end
@@ -39,9 +39,6 @@ module GraphQL
39
39
  include(BaseKeyCache)
40
40
  }
41
41
  child_class.const_set(:KeyCache, key_methods_class)
42
-
43
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
44
-
45
42
  [:execute_field, :execute_field_lazy].each do |field_trace_method|
46
43
  if !child_class.method_defined?(field_trace_method)
47
44
  child_class.module_eval <<-RUBY, __FILE__, __LINE__
@@ -94,8 +91,6 @@ module GraphQL
94
91
  end
95
92
  RUBY
96
93
  end
97
-
98
- # rubocop:enable Development/NoEvalCop
99
94
  end
100
95
  end
101
96
 
@@ -13,8 +13,6 @@ module GraphQL
13
13
  super(**rest)
14
14
  end
15
15
 
16
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
17
-
18
16
  {
19
17
  'lex' => "graphql.lex",
20
18
  'parse' => "graphql.parse",
@@ -32,8 +30,6 @@ module GraphQL
32
30
  RUBY
33
31
  end
34
32
 
35
- # rubocop:enable Development/NoEvalCop
36
-
37
33
  def platform_execute_field(platform_key, &block)
38
34
  instrument_execution(platform_key, "execute_field", &block)
39
35
  end
@@ -16,8 +16,6 @@ module GraphQL
16
16
  super
17
17
  end
18
18
 
19
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
20
-
21
19
  {
22
20
  "lex" => "lex.graphql",
23
21
  "parse" => "parse.graphql",
@@ -47,7 +45,6 @@ module GraphQL
47
45
  end
48
46
  RUBY
49
47
  end
50
- # rubocop:enable Development/NoEvalCop
51
48
 
52
49
  def platform_execute_field(platform_key, &block)
53
50
  self.class.instrument("GraphQL", platform_key, INSTRUMENT_OPTS, &block)
@@ -11,8 +11,6 @@ module GraphQL
11
11
  super(**rest)
12
12
  end
13
13
 
14
- # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
15
-
16
14
  {
17
15
  'lex' => "graphql.lex",
18
16
  'parse' => "graphql.parse",
@@ -32,8 +30,6 @@ module GraphQL
32
30
  RUBY
33
31
  end
34
32
 
35
- # rubocop:enable Development/NoEvalCop
36
-
37
33
  def platform_execute_field(platform_key, &block)
38
34
  @statsd.time(platform_key, &block)
39
35
  end
@@ -13,7 +13,7 @@ module GraphQL
13
13
  child_class.node_nullable(true)
14
14
  child_class.edges_nullable(true)
15
15
  child_class.edge_nullable(true)
16
- child_class.module_exec {
16
+ child_class.module_eval {
17
17
  self.edge_type = nil
18
18
  self.node_type = nil
19
19
  self.edge_class = nil
@@ -67,9 +67,8 @@ module GraphQL
67
67
  type: [edge_type_class, null: edge_nullable],
68
68
  null: edges_nullable,
69
69
  description: "A list of edges.",
70
+ scope: false, # Assume that the connection was already scoped.
70
71
  connection: false,
71
- # Assume that the connection was scoped before this step:
72
- scope: false,
73
72
  }
74
73
 
75
74
  if field_options
@@ -170,6 +169,24 @@ module GraphQL
170
169
  obj_type.field :page_info, GraphQL::Types::Relay::PageInfo, null: false, description: "Information to aid in pagination."
171
170
  end
172
171
  end
172
+
173
+ def edges
174
+ # Assume that whatever authorization needed to happen
175
+ # already happened at the connection level.
176
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
177
+ query_runtime_state = current_runtime_state[context.query]
178
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
179
+ @object.edges
180
+ end
181
+
182
+ def nodes
183
+ # Assume that whatever authorization needed to happen
184
+ # already happened at the connection level.
185
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
186
+ query_runtime_state = current_runtime_state[context.query]
187
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
188
+ @object.nodes
189
+ end
173
190
  end
174
191
  end
175
192
  end
@@ -8,10 +8,17 @@ module GraphQL
8
8
  child_class.description("An edge in a connection.")
9
9
  child_class.field(:cursor, String, null: false, description: "A cursor for use in pagination.")
10
10
  child_class.extend(ClassMethods)
11
- child_class.class_exec { self.node_type = nil }
11
+ child_class.class_eval { self.node_type = nil }
12
12
  child_class.node_nullable(true)
13
13
  end
14
14
 
15
+ def node
16
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
17
+ query_runtime_state = current_runtime_state[context.query]
18
+ query_runtime_state.was_authorized_by_scope_items = @object.was_authorized_by_scope_items?
19
+ @object.node
20
+ end
21
+
15
22
  module ClassMethods
16
23
  def inherited(child_class)
17
24
  super
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.32"
3
+ VERSION = "2.1.0"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -103,7 +103,6 @@ require "graphql/schema"
103
103
  require "graphql/query"
104
104
  require "graphql/types"
105
105
  require "graphql/dataloader"
106
- require "graphql/filter"
107
106
  require "graphql/static_validation"
108
107
  require "graphql/execution"
109
108
  require "graphql/schema/built_in_types"