graphql 2.2.5 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/ast/field_usage.rb +32 -7
- data/lib/graphql/analysis/ast/visitor.rb +8 -0
- data/lib/graphql/analysis/ast.rb +10 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/execution/interpreter/runtime.rb +9 -0
- data/lib/graphql/execution/interpreter.rb +90 -150
- data/lib/graphql/introspection/entry_points.rb +9 -3
- data/lib/graphql/introspection/schema_type.rb +3 -1
- data/lib/graphql/language/document_from_schema_definition.rb +2 -3
- data/lib/graphql/language/lexer.rb +29 -28
- data/lib/graphql/language/nodes.rb +1 -1
- data/lib/graphql/language/parser.rb +12 -8
- data/lib/graphql/language/printer.rb +4 -0
- data/lib/graphql/language.rb +37 -0
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/query/context.rb +30 -33
- data/lib/graphql/query/validation_pipeline.rb +2 -2
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +2 -2
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +3 -1
- data/lib/graphql/schema/field.rb +33 -30
- data/lib/graphql/schema/interface.rb +5 -1
- data/lib/graphql/schema/loader.rb +2 -1
- data/lib/graphql/schema/member/has_arguments.rb +2 -2
- data/lib/graphql/schema/resolver.rb +9 -5
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema.rb +108 -28
- data/lib/graphql/static_validation/literal_validator.rb +1 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -0
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +0 -3
- data/lib/graphql/testing/helpers.rb +8 -4
- data/lib/graphql/tracing/data_dog_trace.rb +21 -34
- data/lib/graphql/tracing/data_dog_tracing.rb +7 -21
- data/lib/graphql/tracing/legacy_hooks_trace.rb +74 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +3 -1
- data/lib/graphql/tracing/sentry_trace.rb +112 -0
- data/lib/graphql/tracing.rb +3 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +3 -2
- metadata +38 -23
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
@@ -121,7 +121,17 @@ module GraphQL
|
|
121
121
|
value
|
122
122
|
end
|
123
123
|
|
124
|
-
|
124
|
+
directives = parse_directives
|
125
|
+
|
126
|
+
defs << Nodes::VariableDefinition.new(
|
127
|
+
pos: loc,
|
128
|
+
name: var_name,
|
129
|
+
type: var_type,
|
130
|
+
default_value: default_value,
|
131
|
+
directives: directives,
|
132
|
+
filename: @filename,
|
133
|
+
source_string: @graphql_str
|
134
|
+
)
|
125
135
|
end
|
126
136
|
expect_token(:RPAREN)
|
127
137
|
defs
|
@@ -729,13 +739,7 @@ module GraphQL
|
|
729
739
|
# token_value works for when the scanner matched something
|
730
740
|
# which is usually fine and it's good for it to be fast at that.
|
731
741
|
def debug_token_value
|
732
|
-
|
733
|
-
Lexer::Punctuation.const_get(token_name)
|
734
|
-
elsif token_name == :ELLIPSIS
|
735
|
-
"..."
|
736
|
-
else
|
737
|
-
@lexer.token_value
|
738
|
-
end
|
742
|
+
@lexer.debug_token_value(token_name)
|
739
743
|
end
|
740
744
|
end
|
741
745
|
end
|
@@ -208,6 +208,10 @@ module GraphQL
|
|
208
208
|
print_string(" = ")
|
209
209
|
print_node(variable_definition.default_value)
|
210
210
|
end
|
211
|
+
variable_definition.directives.each do |dir|
|
212
|
+
print_string(" ")
|
213
|
+
print_directive(dir)
|
214
|
+
end
|
211
215
|
end
|
212
216
|
|
213
217
|
def print_variable_identifier(variable_identifier)
|
data/lib/graphql/language.rb
CHANGED
@@ -12,6 +12,7 @@ require "graphql/language/static_visitor"
|
|
12
12
|
require "graphql/language/token"
|
13
13
|
require "graphql/language/visitor"
|
14
14
|
require "graphql/language/definition_slice"
|
15
|
+
require "strscan"
|
15
16
|
|
16
17
|
module GraphQL
|
17
18
|
module Language
|
@@ -33,5 +34,41 @@ module GraphQL
|
|
33
34
|
JSON.generate(value, quirks_mode: true)
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
# Returns a new string if any single-quoted newlines were escaped.
|
39
|
+
# Otherwise, returns `query_str` unchanged.
|
40
|
+
# @return [String]
|
41
|
+
def self.escape_single_quoted_newlines(query_str)
|
42
|
+
scanner = StringScanner.new(query_str)
|
43
|
+
inside_single_quoted_string = false
|
44
|
+
new_query_str = nil
|
45
|
+
while !scanner.eos?
|
46
|
+
if (match = scanner.scan(/(?:\\"|[^"\n\r]|""")+/m)) && new_query_str
|
47
|
+
new_query_str << match
|
48
|
+
elsif scanner.scan('"')
|
49
|
+
new_query_str && (new_query_str << '"')
|
50
|
+
inside_single_quoted_string = !inside_single_quoted_string
|
51
|
+
elsif scanner.scan("\n")
|
52
|
+
if inside_single_quoted_string
|
53
|
+
new_query_str ||= query_str[0, scanner.pos - 1]
|
54
|
+
new_query_str << '\\n'
|
55
|
+
else
|
56
|
+
new_query_str && (new_query_str << "\n")
|
57
|
+
end
|
58
|
+
elsif scanner.scan("\r")
|
59
|
+
if inside_single_quoted_string
|
60
|
+
new_query_str ||= query_str[0, scanner.pos - 1]
|
61
|
+
new_query_str << '\\r'
|
62
|
+
else
|
63
|
+
new_query_str && (new_query_str << "\r")
|
64
|
+
end
|
65
|
+
elsif scanner.eos?
|
66
|
+
break
|
67
|
+
else
|
68
|
+
raise ArgumentError, "Unmatchable string scanner segment: #{scanner.rest.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
new_query_str || query_str
|
72
|
+
end
|
36
73
|
end
|
37
74
|
end
|
@@ -35,10 +35,10 @@ module GraphQL
|
|
35
35
|
def load_nodes
|
36
36
|
@nodes ||= begin
|
37
37
|
sliced_nodes = if before && after
|
38
|
-
end_idx = index_from_cursor(before)-
|
38
|
+
end_idx = index_from_cursor(before) - 2
|
39
39
|
end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
|
40
40
|
elsif before
|
41
|
-
end_idx = index_from_cursor(before)-2
|
41
|
+
end_idx = index_from_cursor(before) - 2
|
42
42
|
end_idx < 0 ? [] : items[0..end_idx] || []
|
43
43
|
elsif after
|
44
44
|
items[index_from_cursor(after)..-1] || []
|
@@ -56,12 +56,12 @@ module GraphQL
|
|
56
56
|
false
|
57
57
|
end
|
58
58
|
|
59
|
-
@has_next_page = if
|
60
|
-
# There are more items after these items
|
61
|
-
sliced_nodes.count > first
|
62
|
-
elsif before
|
59
|
+
@has_next_page = if before
|
63
60
|
# The original array is longer than the `before` index
|
64
61
|
index_from_cursor(before) < items.length + 1
|
62
|
+
elsif first
|
63
|
+
# There are more items after these items
|
64
|
+
sliced_nodes.count > first
|
65
65
|
else
|
66
66
|
false
|
67
67
|
end
|
@@ -6,36 +6,6 @@ module GraphQL
|
|
6
6
|
# Expose some query-specific info to field resolve functions.
|
7
7
|
# It delegates `[]` to the hash that's passed to `GraphQL::Query#initialize`.
|
8
8
|
class Context
|
9
|
-
module SharedMethods
|
10
|
-
# Return this value to tell the runtime
|
11
|
-
# to exclude this field from the response altogether
|
12
|
-
def skip
|
13
|
-
GraphQL::Execution::SKIP
|
14
|
-
end
|
15
|
-
|
16
|
-
# Add error at query-level.
|
17
|
-
# @param error [GraphQL::ExecutionError] an execution error
|
18
|
-
# @return [void]
|
19
|
-
def add_error(error)
|
20
|
-
if !error.is_a?(ExecutionError)
|
21
|
-
raise TypeError, "expected error to be a ExecutionError, but was #{error.class}"
|
22
|
-
end
|
23
|
-
errors << error
|
24
|
-
nil
|
25
|
-
end
|
26
|
-
|
27
|
-
# @example Print the GraphQL backtrace during field resolution
|
28
|
-
# puts ctx.backtrace
|
29
|
-
#
|
30
|
-
# @return [GraphQL::Backtrace] The backtrace for this point in query execution
|
31
|
-
def backtrace
|
32
|
-
GraphQL::Backtrace.new(self)
|
33
|
-
end
|
34
|
-
|
35
|
-
def execution_errors
|
36
|
-
@execution_errors ||= ExecutionErrors.new(self)
|
37
|
-
end
|
38
|
-
end
|
39
9
|
|
40
10
|
class ExecutionErrors
|
41
11
|
def initialize(ctx)
|
@@ -59,7 +29,6 @@ module GraphQL
|
|
59
29
|
alias :push :add
|
60
30
|
end
|
61
31
|
|
62
|
-
include SharedMethods
|
63
32
|
extend Forwardable
|
64
33
|
|
65
34
|
# @return [Array<GraphQL::ExecutionError>] errors returned during execution
|
@@ -77,11 +46,10 @@ module GraphQL
|
|
77
46
|
# Make a new context which delegates key lookup to `values`
|
78
47
|
# @param query [GraphQL::Query] the query who owns this context
|
79
48
|
# @param values [Hash] A hash of arbitrary values which will be accessible at query-time
|
80
|
-
def initialize(query:, schema: query.schema, values
|
49
|
+
def initialize(query:, schema: query.schema, values:)
|
81
50
|
@query = query
|
82
51
|
@schema = schema
|
83
52
|
@provided_values = values || {}
|
84
|
-
@object = object
|
85
53
|
# Namespaced storage, where user-provided values are in `nil` namespace:
|
86
54
|
@storage = Hash.new { |h, k| h[k] = {} }
|
87
55
|
@storage[nil] = @provided_values
|
@@ -140,6 +108,35 @@ module GraphQL
|
|
140
108
|
end
|
141
109
|
end
|
142
110
|
|
111
|
+
# Return this value to tell the runtime
|
112
|
+
# to exclude this field from the response altogether
|
113
|
+
def skip
|
114
|
+
GraphQL::Execution::SKIP
|
115
|
+
end
|
116
|
+
|
117
|
+
# Add error at query-level.
|
118
|
+
# @param error [GraphQL::ExecutionError] an execution error
|
119
|
+
# @return [void]
|
120
|
+
def add_error(error)
|
121
|
+
if !error.is_a?(ExecutionError)
|
122
|
+
raise TypeError, "expected error to be a ExecutionError, but was #{error.class}"
|
123
|
+
end
|
124
|
+
errors << error
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
128
|
+
# @example Print the GraphQL backtrace during field resolution
|
129
|
+
# puts ctx.backtrace
|
130
|
+
#
|
131
|
+
# @return [GraphQL::Backtrace] The backtrace for this point in query execution
|
132
|
+
def backtrace
|
133
|
+
GraphQL::Backtrace.new(self)
|
134
|
+
end
|
135
|
+
|
136
|
+
def execution_errors
|
137
|
+
@execution_errors ||= ExecutionErrors.new(self)
|
138
|
+
end
|
139
|
+
|
143
140
|
def current_path
|
144
141
|
current_runtime_state = Thread.current[:__graphql_runtime_info]
|
145
142
|
query_runtime_state = current_runtime_state && current_runtime_state[@query]
|
@@ -14,7 +14,7 @@ module GraphQL
|
|
14
14
|
#
|
15
15
|
# @api private
|
16
16
|
class ValidationPipeline
|
17
|
-
attr_reader :max_depth, :max_complexity
|
17
|
+
attr_reader :max_depth, :max_complexity, :validate_timeout_remaining
|
18
18
|
|
19
19
|
def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
|
20
20
|
@validation_errors = []
|
@@ -71,7 +71,7 @@ module GraphQL
|
|
71
71
|
validator = @query.static_validator || @schema.static_validator
|
72
72
|
validation_result = validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
|
73
73
|
@validation_errors.concat(validation_result[:errors])
|
74
|
-
|
74
|
+
@validate_timeout_remaining = validation_result[:remaining_timeout]
|
75
75
|
if @validation_errors.empty?
|
76
76
|
@validation_errors.concat(@query.variables.errors)
|
77
77
|
end
|
@@ -26,7 +26,7 @@ module GraphQL
|
|
26
26
|
# - Then, fall back to the default value from the query string
|
27
27
|
# If it's still nil, raise an error if it's required.
|
28
28
|
variable_type = schema.type_from_ast(ast_variable.type, context: ctx)
|
29
|
-
if variable_type.nil?
|
29
|
+
if variable_type.nil? || !variable_type.unwrap.kind.input?
|
30
30
|
# Pass -- it will get handled by a validator
|
31
31
|
else
|
32
32
|
variable_name = ast_variable.name
|
@@ -80,12 +80,12 @@ module GraphQL
|
|
80
80
|
else
|
81
81
|
val
|
82
82
|
end
|
83
|
-
end
|
83
|
+
end
|
84
84
|
|
85
85
|
def add_max_errors_reached_message
|
86
86
|
message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
|
87
87
|
validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
88
|
-
errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
|
88
|
+
errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
data/lib/graphql/query.rb
CHANGED
@@ -99,7 +99,7 @@ module GraphQL
|
|
99
99
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
100
100
|
variables ||= {}
|
101
101
|
@schema = schema
|
102
|
-
@context = schema.context_class.new(query: self,
|
102
|
+
@context = schema.context_class.new(query: self, values: context)
|
103
103
|
@warden = warden
|
104
104
|
@subscription_topic = subscription_topic
|
105
105
|
@root_value = root_value
|
@@ -317,7 +317,7 @@ module GraphQL
|
|
317
317
|
end
|
318
318
|
|
319
319
|
def_delegators :validation_pipeline, :validation_errors,
|
320
|
-
:analyzers, :ast_analyzers, :max_depth, :max_complexity
|
320
|
+
:analyzers, :ast_analyzers, :max_depth, :max_complexity, :validate_timeout_remaining
|
321
321
|
|
322
322
|
attr_accessor :analysis_errors
|
323
323
|
def valid?
|
@@ -1,18 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'graphql/schema/base_64_bp'
|
4
|
-
|
2
|
+
require "base64"
|
5
3
|
module GraphQL
|
6
4
|
class Schema
|
7
5
|
# @api private
|
8
6
|
module Base64Encoder
|
9
7
|
def self.encode(unencoded_text, nonce: false)
|
10
|
-
|
8
|
+
Base64.urlsafe_encode64(unencoded_text, padding: false)
|
11
9
|
end
|
12
10
|
|
13
11
|
def self.decode(encoded_text, nonce: false)
|
14
12
|
# urlsafe_decode64 is for forward compatibility
|
15
|
-
|
13
|
+
Base64.urlsafe_decode64(encoded_text)
|
16
14
|
rescue ArgumentError
|
17
15
|
raise GraphQL::ExecutionError, "Invalid input: #{encoded_text.inspect}"
|
18
16
|
end
|
@@ -120,10 +120,12 @@ module GraphQL
|
|
120
120
|
|
121
121
|
builder = self
|
122
122
|
|
123
|
+
found_types = types.values
|
123
124
|
schema_class = Class.new(schema_superclass) do
|
124
125
|
begin
|
125
126
|
# Add these first so that there's some chance of resolving late-bound types
|
126
|
-
|
127
|
+
add_type_and_traverse(found_types, root: false)
|
128
|
+
orphan_types(found_types.select { |t| t.respond_to?(:kind) && t.kind.object? })
|
127
129
|
query query_root_type
|
128
130
|
mutation mutation_root_type
|
129
131
|
subscription subscription_root_type
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -471,6 +471,8 @@ module GraphQL
|
|
471
471
|
if arguments[:last] && (max_possible_page_size.nil? || arguments[:last] > max_possible_page_size)
|
472
472
|
max_possible_page_size = arguments[:last]
|
473
473
|
end
|
474
|
+
elsif arguments.is_a?(GraphQL::UnauthorizedError)
|
475
|
+
raise arguments
|
474
476
|
end
|
475
477
|
|
476
478
|
if max_possible_page_size.nil?
|
@@ -483,41 +485,24 @@ module GraphQL
|
|
483
485
|
metadata_complexity = 0
|
484
486
|
lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
|
485
487
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
488
|
+
lookahead.selections.each do |next_lookahead|
|
489
|
+
# this includes `pageInfo`, `nodes` and `edges` and any custom fields
|
490
|
+
# TODO this doesn't support procs yet -- unlikely to need it.
|
491
|
+
metadata_complexity += next_lookahead.field.complexity
|
492
|
+
if next_lookahead.name != :nodes && next_lookahead.name != :edges
|
493
|
+
# subfields, eg, for pageInfo -- assumes no subselections
|
494
|
+
metadata_complexity += next_lookahead.selections.size
|
495
|
+
end
|
493
496
|
end
|
494
497
|
|
495
|
-
nodes_edges_complexity = 0
|
496
|
-
nodes_edges_complexity += 1 if lookahead.selects?(:edges)
|
497
|
-
nodes_edges_complexity += 1 if lookahead.selects?(:nodes)
|
498
|
-
|
499
498
|
# Possible bug: selections on `edges` and `nodes` are _both_ multiplied here. Should they be?
|
500
|
-
items_complexity = child_complexity - metadata_complexity
|
501
|
-
|
502
|
-
|
499
|
+
items_complexity = child_complexity - metadata_complexity
|
500
|
+
subfields_complexity = (max_possible_page_size * items_complexity) + metadata_complexity
|
501
|
+
# Apply this field's own complexity
|
502
|
+
apply_own_complexity_to(subfields_complexity, query, nodes)
|
503
503
|
end
|
504
504
|
else
|
505
|
-
|
506
|
-
case defined_complexity
|
507
|
-
when Proc
|
508
|
-
arguments = query.arguments_for(nodes.first, self)
|
509
|
-
if arguments.is_a?(GraphQL::ExecutionError)
|
510
|
-
return child_complexity
|
511
|
-
elsif arguments.respond_to?(:keyword_arguments)
|
512
|
-
arguments = arguments.keyword_arguments
|
513
|
-
end
|
514
|
-
|
515
|
-
defined_complexity.call(query.context, arguments, child_complexity)
|
516
|
-
when Numeric
|
517
|
-
defined_complexity + child_complexity
|
518
|
-
else
|
519
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{path} (#{inspect})")
|
520
|
-
end
|
505
|
+
apply_own_complexity_to(child_complexity, query, nodes)
|
521
506
|
end
|
522
507
|
end
|
523
508
|
|
@@ -882,6 +867,24 @@ ERR
|
|
882
867
|
yield(obj, args)
|
883
868
|
end
|
884
869
|
end
|
870
|
+
|
871
|
+
def apply_own_complexity_to(child_complexity, query, nodes)
|
872
|
+
case (own_complexity = complexity)
|
873
|
+
when Numeric
|
874
|
+
own_complexity + child_complexity
|
875
|
+
when Proc
|
876
|
+
arguments = query.arguments_for(nodes.first, self)
|
877
|
+
if arguments.is_a?(GraphQL::ExecutionError)
|
878
|
+
return child_complexity
|
879
|
+
elsif arguments.respond_to?(:keyword_arguments)
|
880
|
+
arguments = arguments.keyword_arguments
|
881
|
+
end
|
882
|
+
|
883
|
+
own_complexity.call(query.context, arguments, child_complexity)
|
884
|
+
else
|
885
|
+
raise ArgumentError, "Invalid complexity for #{self.path}: #{own_complexity.inspect}"
|
886
|
+
end
|
887
|
+
end
|
885
888
|
end
|
886
889
|
end
|
887
890
|
end
|
@@ -69,7 +69,11 @@ module GraphQL
|
|
69
69
|
end
|
70
70
|
elsif child_class < GraphQL::Schema::Object
|
71
71
|
# This is being included into an object type, make sure it's using `implements(...)`
|
72
|
-
backtrace_line =
|
72
|
+
backtrace_line = caller_locations(0, 10).find do |location|
|
73
|
+
location.base_label == "implements" &&
|
74
|
+
location.path.end_with?("schema/member/has_interfaces.rb")
|
75
|
+
end
|
76
|
+
|
73
77
|
if !backtrace_line
|
74
78
|
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
75
79
|
end
|
@@ -32,7 +32,8 @@ module GraphQL
|
|
32
32
|
end
|
33
33
|
|
34
34
|
Class.new(GraphQL::Schema) do
|
35
|
-
|
35
|
+
add_type_and_traverse(types.values, root: false)
|
36
|
+
orphan_types(types.values.select { |t| t.kind.object? })
|
36
37
|
directives(directives)
|
37
38
|
description(schema["description"])
|
38
39
|
|
@@ -50,7 +50,7 @@ module GraphQL
|
|
50
50
|
if loads && arg_defn.type.list?
|
51
51
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
52
52
|
def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
|
53
|
-
argument = get_argument("#{arg_defn.graphql_name}")
|
53
|
+
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
54
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
|
@@ -59,7 +59,7 @@ module GraphQL
|
|
59
59
|
elsif loads
|
60
60
|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
61
61
|
def #{method_owner}load_#{arg_defn.keyword}(value, context = nil)
|
62
|
-
argument = get_argument("#{arg_defn.graphql_name}")
|
62
|
+
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
63
63
|
load_application_object(argument, value, context || self.context)
|
64
64
|
end
|
65
65
|
RUBY
|
@@ -166,11 +166,15 @@ module GraphQL
|
|
166
166
|
args.each_value do |argument|
|
167
167
|
arg_keyword = argument.keyword
|
168
168
|
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
169
|
-
|
170
|
-
if
|
171
|
-
return
|
172
|
-
|
173
|
-
|
169
|
+
auth_result = argument.authorized?(self, arg_value, context)
|
170
|
+
if auth_result.is_a?(Array)
|
171
|
+
# only return this second value if the application returned a second value
|
172
|
+
arg_auth, err = auth_result
|
173
|
+
if !arg_auth
|
174
|
+
return arg_auth, err
|
175
|
+
end
|
176
|
+
elsif auth_result == false
|
177
|
+
return auth_result
|
174
178
|
end
|
175
179
|
else
|
176
180
|
true
|