graphql 2.0.20 → 2.0.22
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.
- checksums.yaml +4 -4
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace.rb +6 -1
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -33
- data/lib/graphql/execution/interpreter/runtime.rb +274 -209
- data/lib/graphql/execution/interpreter.rb +2 -3
- data/lib/graphql/execution/lookahead.rb +1 -1
- data/lib/graphql/filter.rb +8 -2
- data/lib/graphql/language/document_from_schema_definition.rb +37 -17
- data/lib/graphql/language/lexer.rb +5 -3
- data/lib/graphql/language/nodes.rb +2 -2
- data/lib/graphql/language/parser.rb +475 -458
- data/lib/graphql/language/parser.y +5 -1
- data/lib/graphql/pagination/connection.rb +5 -5
- data/lib/graphql/query/context.rb +22 -12
- data/lib/graphql/query/null_context.rb +4 -1
- data/lib/graphql/query.rb +25 -11
- data/lib/graphql/schema/argument.rb +12 -14
- data/lib/graphql/schema/build_from_definition.rb +15 -3
- data/lib/graphql/schema/enum_value.rb +2 -5
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +17 -16
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/member/has_arguments.rb +10 -8
- data/lib/graphql/schema/member/has_directives.rb +4 -6
- data/lib/graphql/schema/member/has_fields.rb +80 -36
- data/lib/graphql/schema/member/has_validators.rb +2 -2
- data/lib/graphql/schema/object.rb +1 -1
- data/lib/graphql/schema/printer.rb +3 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
- data/lib/graphql/schema/resolver.rb +8 -8
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/warden.rb +11 -3
- data/lib/graphql/schema.rb +41 -12
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/tracing/appsignal_trace.rb +6 -0
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/notifications_trace.rb +5 -1
- data/lib/graphql/tracing/platform_trace.rb +21 -19
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +4 -123
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +4 -0
- data/readme.md +1 -1
- metadata +6 -3
@@ -284,7 +284,11 @@ rule
|
|
284
284
|
| directive_definition
|
285
285
|
|
286
286
|
schema_definition:
|
287
|
-
SCHEMA directives_list_opt
|
287
|
+
SCHEMA directives_list_opt operation_type_definition_list_opt { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[2]) }
|
288
|
+
|
289
|
+
operation_type_definition_list_opt:
|
290
|
+
/* none */ { result = {} }
|
291
|
+
| LCURLY operation_type_definition_list RCURLY { result = val[1] }
|
288
292
|
|
289
293
|
operation_type_definition_list:
|
290
294
|
operation_type_definition
|
@@ -58,7 +58,7 @@ module GraphQL
|
|
58
58
|
# @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
|
59
59
|
# @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
|
60
60
|
# @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
|
61
|
-
def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size:
|
61
|
+
def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil)
|
62
62
|
@items = items
|
63
63
|
@parent = parent
|
64
64
|
@context = context
|
@@ -71,14 +71,14 @@ module GraphQL
|
|
71
71
|
@edge_class = edge_class || self.class::Edge
|
72
72
|
# This is only true if the object was _initialized_ with an override
|
73
73
|
# or if one is assigned later.
|
74
|
-
@has_max_page_size_override = max_page_size !=
|
75
|
-
@max_page_size = if max_page_size ==
|
74
|
+
@has_max_page_size_override = max_page_size != NOT_CONFIGURED
|
75
|
+
@max_page_size = if max_page_size == NOT_CONFIGURED
|
76
76
|
nil
|
77
77
|
else
|
78
78
|
max_page_size
|
79
79
|
end
|
80
|
-
@has_default_page_size_override = default_page_size !=
|
81
|
-
@default_page_size = if default_page_size ==
|
80
|
+
@has_default_page_size_override = default_page_size != NOT_CONFIGURED
|
81
|
+
@default_page_size = if default_page_size == NOT_CONFIGURED
|
82
82
|
nil
|
83
83
|
else
|
84
84
|
default_page_size
|
@@ -91,8 +91,8 @@ module GraphQL
|
|
91
91
|
end
|
92
92
|
|
93
93
|
class ScopedContext
|
94
|
-
NO_PATH =
|
95
|
-
NO_CONTEXT =
|
94
|
+
NO_PATH = GraphQL::EmptyObjects::EMPTY_ARRAY
|
95
|
+
NO_CONTEXT = GraphQL::EmptyObjects::EMPTY_HASH
|
96
96
|
|
97
97
|
def initialize(query_context)
|
98
98
|
@query_context = query_context
|
@@ -226,8 +226,9 @@ module GraphQL
|
|
226
226
|
if key == :current_path
|
227
227
|
current_path
|
228
228
|
else
|
229
|
-
|
230
|
-
|
229
|
+
(current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
|
230
|
+
(query_runtime_state = current_runtime_state[@query]) &&
|
231
|
+
(query_runtime_state.public_send(key))
|
231
232
|
end
|
232
233
|
else
|
233
234
|
# not found
|
@@ -236,11 +237,13 @@ module GraphQL
|
|
236
237
|
end
|
237
238
|
|
238
239
|
def current_path
|
239
|
-
|
240
|
-
|
241
|
-
|
240
|
+
current_runtime_state = Thread.current[:__graphql_runtime_info]
|
241
|
+
query_runtime_state = current_runtime_state && current_runtime_state[@query]
|
242
|
+
|
243
|
+
path = query_runtime_state &&
|
244
|
+
(result = query_runtime_state.current_result) &&
|
242
245
|
(result.path)
|
243
|
-
if path && (rn =
|
246
|
+
if path && (rn = query_runtime_state.current_result_name)
|
244
247
|
path = path.dup
|
245
248
|
path.push(rn)
|
246
249
|
end
|
@@ -259,8 +262,9 @@ module GraphQL
|
|
259
262
|
|
260
263
|
def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
|
261
264
|
if RUNTIME_METADATA_KEYS.include?(key)
|
262
|
-
(
|
263
|
-
|
265
|
+
(runtime = Thread.current[:__graphql_runtime_info]) &&
|
266
|
+
(query_runtime_state = runtime[@query]) &&
|
267
|
+
(query_runtime_state.public_send(key))
|
264
268
|
elsif @scoped_context.key?(key)
|
265
269
|
scoped_context[key]
|
266
270
|
elsif @provided_values.key?(key)
|
@@ -276,8 +280,14 @@ module GraphQL
|
|
276
280
|
|
277
281
|
def dig(key, *other_keys)
|
278
282
|
if RUNTIME_METADATA_KEYS.include?(key)
|
279
|
-
(
|
280
|
-
|
283
|
+
(current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
|
284
|
+
(query_runtime_state = current_runtime_state[@query]) &&
|
285
|
+
(obj = query_runtime_state.public_send(key)) &&
|
286
|
+
if other_keys.empty?
|
287
|
+
obj
|
288
|
+
else
|
289
|
+
obj.dig(*other_keys)
|
290
|
+
end
|
281
291
|
elsif @scoped_context.key?(key)
|
282
292
|
@scoped_context.dig(key, *other_keys)
|
283
293
|
else
|
@@ -12,6 +12,9 @@ module GraphQL
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class NullQuery
|
15
|
+
def after_lazy(value)
|
16
|
+
yield(value)
|
17
|
+
end
|
15
18
|
end
|
16
19
|
|
17
20
|
class NullSchema < GraphQL::Schema
|
@@ -24,7 +27,7 @@ module GraphQL
|
|
24
27
|
@dataloader = GraphQL::Dataloader::NullDataloader.new
|
25
28
|
@schema = NullSchema
|
26
29
|
@warden = NullWarden.new(
|
27
|
-
GraphQL::Filter.new,
|
30
|
+
GraphQL::Filter.new(silence_deprecation_warning: true),
|
28
31
|
context: self,
|
29
32
|
schema: @schema,
|
30
33
|
)
|
data/lib/graphql/query.rb
CHANGED
@@ -87,7 +87,9 @@ module GraphQL
|
|
87
87
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
88
88
|
variables ||= {}
|
89
89
|
@schema = schema
|
90
|
-
|
90
|
+
if only || except
|
91
|
+
merge_filters(except: except, only: only)
|
92
|
+
end
|
91
93
|
@context = schema.context_class.new(query: self, object: root_value, values: context)
|
92
94
|
@warden = warden
|
93
95
|
@subscription_topic = subscription_topic
|
@@ -100,12 +102,16 @@ module GraphQL
|
|
100
102
|
|
101
103
|
# Support `ctx[:backtrace] = true` for wrapping backtraces
|
102
104
|
if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
103
|
-
|
104
|
-
|
105
|
+
if schema.trace_class <= GraphQL::Tracing::LegacyTrace
|
106
|
+
context_tracers += [GraphQL::Backtrace::Tracer]
|
107
|
+
@tracers << GraphQL::Backtrace::Tracer
|
108
|
+
elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
|
109
|
+
raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
|
110
|
+
end
|
105
111
|
end
|
106
112
|
|
107
113
|
if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
|
108
|
-
raise ArgumentError, "context[:tracers]
|
114
|
+
raise ArgumentError, "context[:tracers] are not supported without `trace_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
|
109
115
|
end
|
110
116
|
|
111
117
|
|
@@ -147,11 +153,6 @@ module GraphQL
|
|
147
153
|
|
148
154
|
@result_values = nil
|
149
155
|
@executed = false
|
150
|
-
|
151
|
-
# TODO add a general way to define schema-level filters
|
152
|
-
if @schema.respond_to?(:visible?)
|
153
|
-
merge_filters(only: @schema.method(:visible?))
|
154
|
-
end
|
155
156
|
end
|
156
157
|
|
157
158
|
# If a document was provided to `GraphQL::Schema#execute` instead of the raw query string, we will need to get it from the document
|
@@ -318,8 +319,8 @@ module GraphQL
|
|
318
319
|
# @param value [Object] Any runtime value
|
319
320
|
# @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
|
320
321
|
# @see {#possible_types} to apply filtering from `only` / `except`
|
321
|
-
def resolve_type(abstract_type, value =
|
322
|
-
if value.is_a?(Symbol) && value ==
|
322
|
+
def resolve_type(abstract_type, value = NOT_CONFIGURED)
|
323
|
+
if value.is_a?(Symbol) && value == NOT_CONFIGURED
|
323
324
|
# Old method signature
|
324
325
|
value = abstract_type
|
325
326
|
abstract_type = nil
|
@@ -343,6 +344,7 @@ module GraphQL
|
|
343
344
|
if @prepared_ast
|
344
345
|
raise "Can't add filters after preparing the query"
|
345
346
|
else
|
347
|
+
@filter ||= @schema.default_filter
|
346
348
|
@filter = @filter.merge(only: only, except: except)
|
347
349
|
end
|
348
350
|
nil
|
@@ -357,6 +359,18 @@ module GraphQL
|
|
357
359
|
schema.handle_or_reraise(context, err)
|
358
360
|
end
|
359
361
|
|
362
|
+
def after_lazy(value, &block)
|
363
|
+
if !defined?(@runtime_instance)
|
364
|
+
@runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
|
365
|
+
end
|
366
|
+
|
367
|
+
if @runtime_instance
|
368
|
+
@runtime_instance.minimal_after_lazy(value, &block)
|
369
|
+
else
|
370
|
+
@schema.after_lazy(value, &block)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
360
374
|
private
|
361
375
|
|
362
376
|
def find_operation(operations, operation_name)
|
@@ -7,9 +7,7 @@ module GraphQL
|
|
7
7
|
include GraphQL::Schema::Member::HasDirectives
|
8
8
|
include GraphQL::Schema::Member::HasDeprecationReason
|
9
9
|
include GraphQL::Schema::Member::HasValidators
|
10
|
-
include GraphQL::
|
11
|
-
|
12
|
-
NO_DEFAULT = :__no_default__
|
10
|
+
include GraphQL::EmptyObjects
|
13
11
|
|
14
12
|
# @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
|
15
13
|
attr_reader :name
|
@@ -20,8 +18,8 @@ module GraphQL
|
|
20
18
|
|
21
19
|
# @param new_prepare [Method, Proc]
|
22
20
|
# @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
|
23
|
-
def prepare(new_prepare =
|
24
|
-
if new_prepare !=
|
21
|
+
def prepare(new_prepare = NOT_CONFIGURED)
|
22
|
+
if new_prepare != NOT_CONFIGURED
|
25
23
|
@prepare = new_prepare
|
26
24
|
end
|
27
25
|
@prepare
|
@@ -52,7 +50,7 @@ module GraphQL
|
|
52
50
|
# @param deprecation_reason [String]
|
53
51
|
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
54
52
|
# @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
|
55
|
-
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value:
|
53
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
56
54
|
arg_name ||= name
|
57
55
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
58
56
|
@type_expr = type_expr || type
|
@@ -104,8 +102,8 @@ module GraphQL
|
|
104
102
|
|
105
103
|
# @param default_value [Object] The value to use when the client doesn't provide one
|
106
104
|
# @return [Object] the value used when the client doesn't provide a value for this argument
|
107
|
-
def default_value(new_default_value =
|
108
|
-
if new_default_value !=
|
105
|
+
def default_value(new_default_value = NOT_CONFIGURED)
|
106
|
+
if new_default_value != NOT_CONFIGURED
|
109
107
|
@default_value = new_default_value
|
110
108
|
end
|
111
109
|
@default_value
|
@@ -113,7 +111,7 @@ module GraphQL
|
|
113
111
|
|
114
112
|
# @return [Boolean] True if this argument has a default value
|
115
113
|
def default_value?
|
116
|
-
@default_value !=
|
114
|
+
@default_value != NOT_CONFIGURED
|
117
115
|
end
|
118
116
|
|
119
117
|
def replace_null_with_default?
|
@@ -200,8 +198,8 @@ module GraphQL
|
|
200
198
|
|
201
199
|
def statically_coercible?
|
202
200
|
return @statically_coercible if defined?(@statically_coercible)
|
203
|
-
|
204
|
-
@statically_coercible =
|
201
|
+
requires_parent_object = @prepare.is_a?(String) || @prepare.is_a?(Symbol) || @own_validators
|
202
|
+
@statically_coercible = !requires_parent_object
|
205
203
|
end
|
206
204
|
|
207
205
|
# Apply the {prepare} configuration to `value`, using methods from `obj`.
|
@@ -266,7 +264,7 @@ module GraphQL
|
|
266
264
|
|
267
265
|
# If this isn't lazy, then the block returns eagerly and assigns the result here
|
268
266
|
# If it _is_ lazy, then we write the lazy to the hash, then update it later
|
269
|
-
argument_values[arg_key] = context.
|
267
|
+
argument_values[arg_key] = context.query.after_lazy(coerced_value) do |resolved_coerced_value|
|
270
268
|
owner.validate_directive_argument(self, resolved_coerced_value)
|
271
269
|
prepared_value = begin
|
272
270
|
prepare_value(parent_object, resolved_coerced_value, context: context)
|
@@ -283,7 +281,7 @@ module GraphQL
|
|
283
281
|
end
|
284
282
|
|
285
283
|
maybe_loaded_value = loaded_value || prepared_value
|
286
|
-
context.
|
284
|
+
context.query.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
|
287
285
|
# TODO code smell to access such a deeply-nested constant in a distant module
|
288
286
|
argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
|
289
287
|
value: resolved_loaded_value,
|
@@ -305,7 +303,7 @@ module GraphQL
|
|
305
303
|
else
|
306
304
|
load_method_owner.public_send(arg_load_method, coerced_value)
|
307
305
|
end
|
308
|
-
context.
|
306
|
+
context.query.after_lazy(custom_loaded_value) do |custom_value|
|
309
307
|
if loads
|
310
308
|
if type.list?
|
311
309
|
loaded_values = custom_value.each_with_index.map { |custom_val, idx|
|
@@ -21,6 +21,7 @@ module GraphQL
|
|
21
21
|
|
22
22
|
# @api private
|
23
23
|
module Builder
|
24
|
+
include GraphQL::EmptyObjects
|
24
25
|
extend self
|
25
26
|
|
26
27
|
def build(schema_superclass, document, default_resolve:, using: {}, relay:)
|
@@ -99,6 +100,16 @@ module GraphQL
|
|
99
100
|
raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
|
100
101
|
subscription_root_type = types[schema_definition.subscription]
|
101
102
|
end
|
103
|
+
|
104
|
+
if schema_definition.query.nil? &&
|
105
|
+
schema_definition.mutation.nil? &&
|
106
|
+
schema_definition.subscription.nil?
|
107
|
+
# This schema may have been given with directives only,
|
108
|
+
# check for defaults:
|
109
|
+
query_root_type = types['Query']
|
110
|
+
mutation_root_type = types['Mutation']
|
111
|
+
subscription_root_type = types['Subscription']
|
112
|
+
end
|
102
113
|
else
|
103
114
|
query_root_type = types['Query']
|
104
115
|
mutation_root_type = types['Mutation']
|
@@ -107,6 +118,8 @@ module GraphQL
|
|
107
118
|
|
108
119
|
raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
|
109
120
|
|
121
|
+
builder = self
|
122
|
+
|
110
123
|
schema_class = Class.new(schema_superclass) do
|
111
124
|
begin
|
112
125
|
# Add these first so that there's some chance of resolving late-bound types
|
@@ -134,6 +147,7 @@ module GraphQL
|
|
134
147
|
|
135
148
|
if schema_definition
|
136
149
|
ast_node(schema_definition)
|
150
|
+
builder.build_directives(self, schema_definition, type_resolver)
|
137
151
|
end
|
138
152
|
|
139
153
|
using.each do |plugin, options|
|
@@ -361,8 +375,6 @@ module GraphQL
|
|
361
375
|
end
|
362
376
|
end
|
363
377
|
|
364
|
-
NO_DEFAULT_VALUE = {}.freeze
|
365
|
-
|
366
378
|
def build_arguments(type_class, arguments, type_resolver)
|
367
379
|
builder = self
|
368
380
|
|
@@ -370,7 +382,7 @@ module GraphQL
|
|
370
382
|
default_value_kwargs = if !argument_defn.default_value.nil?
|
371
383
|
{ default_value: builder.build_default_value(argument_defn.default_value) }
|
372
384
|
else
|
373
|
-
|
385
|
+
EMPTY_HASH
|
374
386
|
end
|
375
387
|
|
376
388
|
type_class.argument(
|
@@ -25,19 +25,16 @@ module GraphQL
|
|
25
25
|
include GraphQL::Schema::Member::HasDirectives
|
26
26
|
include GraphQL::Schema::Member::HasDeprecationReason
|
27
27
|
|
28
|
-
UNDEFINED_VALUE = Object.new.freeze
|
29
|
-
private_constant :UNDEFINED_VALUE
|
30
|
-
|
31
28
|
attr_reader :graphql_name
|
32
29
|
|
33
30
|
# @return [Class] The enum type that owns this value
|
34
31
|
attr_reader :owner
|
35
32
|
|
36
|
-
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value:
|
33
|
+
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
|
37
34
|
@graphql_name = graphql_name.to_s
|
38
35
|
GraphQL::NameValidator.validate!(@graphql_name)
|
39
36
|
@description = desc || description
|
40
|
-
@value = value
|
37
|
+
@value = value == NOT_CONFIGURED ? @graphql_name : value
|
41
38
|
if deprecation_reason
|
42
39
|
self.deprecation_reason = deprecation_reason
|
43
40
|
end
|
@@ -26,7 +26,7 @@ module GraphQL
|
|
26
26
|
# rename some inputs to avoid conflicts inside the block
|
27
27
|
maybe_lazy = value
|
28
28
|
value = nil
|
29
|
-
context.
|
29
|
+
context.query.after_lazy(maybe_lazy) do |resolved_value|
|
30
30
|
value = resolved_value
|
31
31
|
if value.is_a? GraphQL::ExecutionError
|
32
32
|
# This isn't even going to work because context doesn't have ast_node anymore
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -11,7 +11,7 @@ module GraphQL
|
|
11
11
|
include GraphQL::Schema::Member::HasPath
|
12
12
|
include GraphQL::Schema::Member::HasValidators
|
13
13
|
extend GraphQL::Schema::FindInheritedValue
|
14
|
-
include GraphQL::
|
14
|
+
include GraphQL::EmptyObjects
|
15
15
|
include GraphQL::Schema::Member::HasDirectives
|
16
16
|
include GraphQL::Schema::Member::HasDeprecationReason
|
17
17
|
|
@@ -219,7 +219,7 @@ module GraphQL
|
|
219
219
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
220
220
|
# @param validates [Array<Hash>] Configurations for validating this field
|
221
221
|
# @fallback_value [Object] A fallback value if the method is not defined
|
222
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value:
|
222
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, &definition_block)
|
223
223
|
if name.nil?
|
224
224
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
225
225
|
end
|
@@ -235,7 +235,7 @@ module GraphQL
|
|
235
235
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
236
236
|
|
237
237
|
@description = description
|
238
|
-
@type = @owner_type = @own_validators = @own_directives = @own_arguments = nil # these will be prepared later if necessary
|
238
|
+
@type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
|
239
239
|
|
240
240
|
self.deprecation_reason = deprecation_reason
|
241
241
|
|
@@ -608,15 +608,16 @@ module GraphQL
|
|
608
608
|
# The resolver _instance_ will check itself during `resolve()`
|
609
609
|
@resolver_class.authorized?(object, context)
|
610
610
|
else
|
611
|
-
if (arg_values = context[:current_arguments])
|
612
|
-
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
613
|
-
using_arg_values = true
|
614
|
-
arg_values = arg_values.argument_values
|
615
|
-
else
|
616
|
-
arg_values = args
|
617
|
-
using_arg_values = false
|
618
|
-
end
|
619
611
|
if args.size > 0
|
612
|
+
if (arg_values = context[:current_arguments])
|
613
|
+
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
614
|
+
using_arg_values = true
|
615
|
+
arg_values = arg_values.argument_values
|
616
|
+
else
|
617
|
+
arg_values = args
|
618
|
+
using_arg_values = false
|
619
|
+
end
|
620
|
+
|
620
621
|
args = context.warden.arguments(self)
|
621
622
|
args.each do |arg|
|
622
623
|
arg_key = arg.keyword
|
@@ -660,7 +661,7 @@ module GraphQL
|
|
660
661
|
|
661
662
|
Schema::Validator.validate!(validators, application_object, query_ctx, args)
|
662
663
|
|
663
|
-
query_ctx.
|
664
|
+
query_ctx.query.after_lazy(self.authorized?(application_object, args, query_ctx)) do |is_authorized|
|
664
665
|
if is_authorized
|
665
666
|
with_extensions(object, args, query_ctx) do |obj, ruby_kwargs|
|
666
667
|
method_args = ruby_kwargs
|
@@ -684,7 +685,7 @@ module GraphQL
|
|
684
685
|
if hash_value == false
|
685
686
|
hash_value
|
686
687
|
else
|
687
|
-
hash_value || (@fallback_value !=
|
688
|
+
hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
|
688
689
|
end
|
689
690
|
elsif obj.respond_to?(resolver_method)
|
690
691
|
method_to_call = resolver_method
|
@@ -702,7 +703,7 @@ module GraphQL
|
|
702
703
|
inner_object[@method_sym]
|
703
704
|
elsif inner_object.key?(@method_str)
|
704
705
|
inner_object[@method_str]
|
705
|
-
elsif @fallback_value !=
|
706
|
+
elsif @fallback_value != NOT_CONFIGURED
|
706
707
|
@fallback_value
|
707
708
|
else
|
708
709
|
nil
|
@@ -715,7 +716,7 @@ module GraphQL
|
|
715
716
|
else
|
716
717
|
inner_object.public_send(@method_sym)
|
717
718
|
end
|
718
|
-
elsif @fallback_value !=
|
719
|
+
elsif @fallback_value != NOT_CONFIGURED
|
719
720
|
@fallback_value
|
720
721
|
else
|
721
722
|
raise <<-ERR
|
@@ -832,7 +833,7 @@ ERR
|
|
832
833
|
extended_args = extended[:args]
|
833
834
|
memos = extended[:memos] || EMPTY_HASH
|
834
835
|
|
835
|
-
ctx.
|
836
|
+
ctx.query.after_lazy(value) do |resolved_value|
|
836
837
|
idx = 0
|
837
838
|
@extensions.each do |ext|
|
838
839
|
memo = memos[idx]
|
@@ -71,14 +71,11 @@ module GraphQL
|
|
71
71
|
elsif inherited_extras
|
72
72
|
inherited_extras
|
73
73
|
else
|
74
|
-
|
74
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
NO_EXTRAS = [].freeze
|
80
|
-
private_constant :NO_EXTRAS
|
81
|
-
|
82
79
|
# Called when this extension is attached to a field.
|
83
80
|
# The field definition may be extended during this method.
|
84
81
|
# @return [void]
|
@@ -2,17 +2,12 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
module FindInheritedValue
|
5
|
-
module EmptyObjects
|
6
|
-
EMPTY_HASH = {}.freeze
|
7
|
-
EMPTY_ARRAY = [].freeze
|
8
|
-
end
|
9
|
-
|
10
5
|
def self.extended(child_cls)
|
11
|
-
child_cls.singleton_class.include(EmptyObjects)
|
6
|
+
child_cls.singleton_class.include(GraphQL::EmptyObjects)
|
12
7
|
end
|
13
8
|
|
14
9
|
def self.included(child_cls)
|
15
|
-
child_cls.include(EmptyObjects)
|
10
|
+
child_cls.include(GraphQL::EmptyObjects)
|
16
11
|
end
|
17
12
|
|
18
13
|
private
|
@@ -211,7 +211,7 @@ module GraphQL
|
|
211
211
|
|
212
212
|
arguments = coerce_arguments(nil, value, ctx)
|
213
213
|
|
214
|
-
ctx.
|
214
|
+
ctx.query.after_lazy(arguments) do |resolved_arguments|
|
215
215
|
if resolved_arguments.is_a?(GraphQL::Error)
|
216
216
|
raise resolved_arguments
|
217
217
|
else
|
@@ -51,7 +51,7 @@ module GraphQL
|
|
51
51
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
52
52
|
def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
|
53
53
|
argument = get_argument("#{arg_defn.graphql_name}")
|
54
|
-
(context || self.context).
|
54
|
+
(context || self.context).query.after_lazy(values) do |values2|
|
55
55
|
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, value, context || self.context) })
|
56
56
|
end
|
57
57
|
end
|
@@ -320,9 +320,11 @@ module GraphQL
|
|
320
320
|
end
|
321
321
|
|
322
322
|
def arguments_statically_coercible?
|
323
|
-
|
324
|
-
|
325
|
-
|
323
|
+
if defined?(@arguments_statically_coercible) && !@arguments_statically_coercible.nil?
|
324
|
+
@arguments_statically_coercible
|
325
|
+
else
|
326
|
+
@arguments_statically_coercible = all_argument_definitions.all?(&:statically_coercible?)
|
327
|
+
end
|
326
328
|
end
|
327
329
|
|
328
330
|
module ArgumentClassAccessor
|
@@ -363,7 +365,7 @@ module GraphQL
|
|
363
365
|
end
|
364
366
|
|
365
367
|
def authorize_application_object(argument, id, context, loaded_application_object)
|
366
|
-
context.
|
368
|
+
context.query.after_lazy(loaded_application_object) do |application_object|
|
367
369
|
if application_object.nil?
|
368
370
|
err = GraphQL::LoadApplicationObjectFailedError.new(argument: argument, id: id, object: application_object)
|
369
371
|
load_application_object_failed(err)
|
@@ -371,7 +373,7 @@ module GraphQL
|
|
371
373
|
# Double-check that the located object is actually of this type
|
372
374
|
# (Don't want to allow arbitrary access to objects this way)
|
373
375
|
maybe_lazy_resolve_type = context.schema.resolve_type(argument.loads, application_object, context)
|
374
|
-
context.
|
376
|
+
context.query.after_lazy(maybe_lazy_resolve_type) do |resolve_type_result|
|
375
377
|
if resolve_type_result.is_a?(Array) && resolve_type_result.size == 2
|
376
378
|
application_object_type, application_object = resolve_type_result
|
377
379
|
else
|
@@ -386,7 +388,7 @@ module GraphQL
|
|
386
388
|
# This object was loaded successfully
|
387
389
|
# and resolved to the right type,
|
388
390
|
# now apply the `.authorized?` class method if there is one
|
389
|
-
context.
|
391
|
+
context.query.after_lazy(application_object_type.authorized?(application_object, context)) do |authed|
|
390
392
|
if authed
|
391
393
|
application_object
|
392
394
|
else
|
@@ -413,7 +415,7 @@ module GraphQL
|
|
413
415
|
end
|
414
416
|
end
|
415
417
|
|
416
|
-
NO_ARGUMENTS =
|
418
|
+
NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
|
417
419
|
def own_arguments
|
418
420
|
@own_arguments || NO_ARGUMENTS
|
419
421
|
end
|
@@ -33,8 +33,6 @@ module GraphQL
|
|
33
33
|
nil
|
34
34
|
end
|
35
35
|
|
36
|
-
NO_DIRECTIVES = [].freeze
|
37
|
-
|
38
36
|
def directives
|
39
37
|
HasDirectives.get_directives(self, @own_directives, :directives)
|
40
38
|
end
|
@@ -55,7 +53,7 @@ module GraphQL
|
|
55
53
|
inherited_directives = if schema_member.superclass.respond_to?(directives_method)
|
56
54
|
get_directives(schema_member.superclass, schema_member.superclass.public_send(directives_method), directives_method)
|
57
55
|
else
|
58
|
-
|
56
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
59
57
|
end
|
60
58
|
if inherited_directives.any? && directives
|
61
59
|
dirs = []
|
@@ -67,7 +65,7 @@ module GraphQL
|
|
67
65
|
elsif inherited_directives.any?
|
68
66
|
inherited_directives
|
69
67
|
else
|
70
|
-
|
68
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
71
69
|
end
|
72
70
|
when Module
|
73
71
|
dirs = nil
|
@@ -82,9 +80,9 @@ module GraphQL
|
|
82
80
|
dirs ||= []
|
83
81
|
merge_directives(dirs, directives)
|
84
82
|
end
|
85
|
-
dirs ||
|
83
|
+
dirs || GraphQL::EmptyObjects::EMPTY_ARRAY
|
86
84
|
when HasDirectives
|
87
|
-
directives ||
|
85
|
+
directives || GraphQL::EmptyObjects::EMPTY_ARRAY
|
88
86
|
else
|
89
87
|
raise "Invariant: how could #{schema_member} not be a Class, Module, or instance of HasDirectives?"
|
90
88
|
end
|