graphql 1.8.3 → 1.8.4
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.
- checksums.yaml +4 -4
- data/lib/graphql.rb +4 -1
- data/lib/graphql/argument.rb +1 -0
- data/lib/graphql/authorization.rb +81 -0
- data/lib/graphql/boolean_type.rb +0 -1
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +2 -1
- data/lib/graphql/execution/execute.rb +34 -10
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/field.rb +7 -1
- data/lib/graphql/float_type.rb +0 -1
- data/lib/graphql/id_type.rb +0 -1
- data/lib/graphql/int_type.rb +0 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/object_type.rb +3 -3
- data/lib/graphql/query.rb +6 -0
- data/lib/graphql/query/arguments.rb +2 -0
- data/lib/graphql/query/context.rb +6 -0
- data/lib/graphql/query/variables.rb +7 -1
- data/lib/graphql/relay/connection_instrumentation.rb +2 -2
- data/lib/graphql/relay/connection_resolve.rb +7 -27
- data/lib/graphql/relay/connection_type.rb +1 -0
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/edges_instrumentation.rb +9 -25
- data/lib/graphql/relay/mutation/instrumentation.rb +1 -2
- data/lib/graphql/relay/mutation/resolve.rb +2 -4
- data/lib/graphql/relay/node.rb +1 -6
- data/lib/graphql/relay/page_info.rb +1 -9
- data/lib/graphql/schema.rb +84 -11
- data/lib/graphql/schema/argument.rb +13 -0
- data/lib/graphql/schema/enum.rb +1 -1
- data/lib/graphql/schema/enum_value.rb +4 -0
- data/lib/graphql/schema/field.rb +44 -11
- data/lib/graphql/schema/interface.rb +20 -0
- data/lib/graphql/schema/introspection_system.rb +1 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +25 -3
- data/lib/graphql/schema/member/instrumentation.rb +15 -17
- data/lib/graphql/schema/mutation.rb +4 -0
- data/lib/graphql/schema/object.rb +33 -0
- data/lib/graphql/schema/possible_types.rb +2 -0
- data/lib/graphql/schema/resolver.rb +10 -0
- data/lib/graphql/schema/traversal.rb +9 -2
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +11 -2
- data/lib/graphql/string_type.rb +0 -1
- data/lib/graphql/types.rb +7 -0
- data/lib/graphql/types/relay.rb +31 -0
- data/lib/graphql/types/relay/base_connection.rb +87 -0
- data/lib/graphql/types/relay/base_edge.rb +51 -0
- data/lib/graphql/types/relay/base_field.rb +22 -0
- data/lib/graphql/types/relay/base_interface.rb +29 -0
- data/lib/graphql/types/relay/base_object.rb +26 -0
- data/lib/graphql/types/relay/node.rb +18 -0
- data/lib/graphql/types/relay/page_info.rb +23 -0
- data/lib/graphql/unauthorized_error.rb +20 -0
- data/lib/graphql/version.rb +1 -1
- data/spec/graphql/authorization_spec.rb +684 -0
- data/spec/graphql/query/variables_spec.rb +20 -0
- data/spec/graphql/relay/connection_instrumentation_spec.rb +1 -1
- data/spec/graphql/schema/resolver_spec.rb +31 -0
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +52 -0
- data/spec/support/dummy/schema.rb +16 -0
- data/spec/support/star_wars/schema.rb +28 -17
- metadata +15 -2
@@ -12,8 +12,7 @@ module GraphQL
|
|
12
12
|
def self.instrument(type, field)
|
13
13
|
if field.mutation.is_a?(GraphQL::Relay::Mutation) || (field.mutation.is_a?(Class) && field.mutation < GraphQL::Schema::RelayClassicMutation)
|
14
14
|
new_resolve = Mutation::Resolve.new(field.mutation, field.resolve_proc)
|
15
|
-
|
16
|
-
field.redefine(resolve: new_resolve, lazy_resolve: new_lazy_resolve)
|
15
|
+
field.redefine(resolve: new_resolve)
|
17
16
|
else
|
18
17
|
field
|
19
18
|
end
|
data/lib/graphql/relay/node.rb
CHANGED
@@ -41,12 +41,7 @@ module GraphQL
|
|
41
41
|
|
42
42
|
# @return [GraphQL::InterfaceType] The interface which all Relay types must implement
|
43
43
|
def self.interface
|
44
|
-
@interface ||= GraphQL::
|
45
|
-
name("Node")
|
46
|
-
description("An object with an ID.")
|
47
|
-
field(:id, types.ID.to_non_null_type, "ID of the object.")
|
48
|
-
default_relay(true)
|
49
|
-
end
|
44
|
+
@interface ||= GraphQL::Types::Relay::Node.graphql_definition
|
50
45
|
end
|
51
46
|
|
52
47
|
# A field resolve for finding objects by IDs
|
@@ -2,14 +2,6 @@
|
|
2
2
|
module GraphQL
|
3
3
|
module Relay
|
4
4
|
# Wrap a Connection and expose its page info
|
5
|
-
PageInfo = GraphQL::
|
6
|
-
name("PageInfo")
|
7
|
-
description("Information about pagination in a connection.")
|
8
|
-
field :hasNextPage, !types.Boolean, "When paginating forwards, are there more items?", property: :has_next_page
|
9
|
-
field :hasPreviousPage, !types.Boolean, "When paginating backwards, are there more items?", property: :has_previous_page
|
10
|
-
field :startCursor, types.String, "When paginating backwards, the cursor to continue.", property: :start_cursor
|
11
|
-
field :endCursor, types.String, "When paginating forwards, the cursor to continue.", property: :end_cursor
|
12
|
-
default_relay true
|
13
|
-
end
|
5
|
+
PageInfo = GraphQL::Types::Relay::PageInfo.graphql_definition
|
14
6
|
end
|
15
7
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -69,6 +69,7 @@ module GraphQL
|
|
69
69
|
# end
|
70
70
|
#
|
71
71
|
class Schema
|
72
|
+
extend Forwardable
|
72
73
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
73
74
|
include GraphQL::Define::InstanceDefinable
|
74
75
|
accepts_definitions \
|
@@ -155,7 +156,7 @@ module GraphQL
|
|
155
156
|
@parse_error_proc = DefaultParseError
|
156
157
|
@instrumenters = Hash.new { |h, k| h[k] = [] }
|
157
158
|
@lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
|
158
|
-
@lazy_methods.set(GraphQL::
|
159
|
+
@lazy_methods.set(GraphQL::Execution::Lazy, :value)
|
159
160
|
@cursor_encoder = Base64Encoder
|
160
161
|
# Default to the built-in execution strategy:
|
161
162
|
@query_execution_strategy = self.class.default_execution_strategy
|
@@ -534,6 +535,10 @@ module GraphQL
|
|
534
535
|
@type_error_proc = new_proc
|
535
536
|
end
|
536
537
|
|
538
|
+
# Can't delegate to `class`
|
539
|
+
alias :_schema_class :class
|
540
|
+
def_delegators :_schema_class, :visible?, :accessible?, :authorized?, :unauthorized_object, :inaccessible_fields
|
541
|
+
|
537
542
|
# A function to call when {#execute} receives an invalid query string
|
538
543
|
#
|
539
544
|
# @see {DefaultParseError} is the default behavior.
|
@@ -647,7 +652,7 @@ module GraphQL
|
|
647
652
|
:static_validator, :introspection_system,
|
648
653
|
:query_analyzers, :middleware, :tracers, :instrumenters,
|
649
654
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
650
|
-
:validate, :multiplex_analyzers, :lazy?, :lazy_method_name,
|
655
|
+
:validate, :multiplex_analyzers, :lazy?, :lazy_method_name, :after_lazy,
|
651
656
|
# Configuration
|
652
657
|
:max_complexity=, :max_depth=,
|
653
658
|
:metadata,
|
@@ -696,6 +701,7 @@ module GraphQL
|
|
696
701
|
schema_defn.cursor_encoder = cursor_encoder
|
697
702
|
schema_defn.tracers.concat(defined_tracers)
|
698
703
|
schema_defn.query_analyzers.concat(defined_query_analyzers)
|
704
|
+
schema_defn.query_analyzers << GraphQL::Authorization::Analyzer
|
699
705
|
schema_defn.middleware.concat(defined_middleware)
|
700
706
|
schema_defn.multiplex_analyzers.concat(defined_multiplex_analyzers)
|
701
707
|
defined_instrumenters.each do |step, insts|
|
@@ -835,6 +841,41 @@ module GraphQL
|
|
835
841
|
raise NotImplementedError, "#{self.name}.id_from_object(object, type, ctx) must be implemented to create global ids (tried to create an id for `#{object.inspect}`)"
|
836
842
|
end
|
837
843
|
|
844
|
+
def visible?(member, context)
|
845
|
+
call_on_type_class(member, :visible?, context, default: true)
|
846
|
+
end
|
847
|
+
|
848
|
+
def accessible?(member, context)
|
849
|
+
call_on_type_class(member, :accessible?, context, default: true)
|
850
|
+
end
|
851
|
+
|
852
|
+
# This hook is called when a client tries to access one or more
|
853
|
+
# fields that fail the `accessible?` check.
|
854
|
+
#
|
855
|
+
# By default, an error is added to the response. Override this hook to
|
856
|
+
# track metrics or return a different error to the client.
|
857
|
+
#
|
858
|
+
# @param error [InaccessibleFieldsError] The analysis error for this check
|
859
|
+
# @return [AnalysisError, nil] Return an error to skip the query
|
860
|
+
def inaccessible_fields(error)
|
861
|
+
error
|
862
|
+
end
|
863
|
+
|
864
|
+
# This hook is called when an object fails an `authorized?` check.
|
865
|
+
# You might report to your bug tracker here, so you can correct
|
866
|
+
# the field resolvers not to return unauthorized objects.
|
867
|
+
#
|
868
|
+
# By default, this hook just replaces the unauthorized object with `nil`.
|
869
|
+
#
|
870
|
+
# If you want to add an error to the `"errors"` key, raise a {GraphQL::ExecutionError}
|
871
|
+
# in this hook.
|
872
|
+
#
|
873
|
+
# @param unauthorized_error [GraphQL::UnauthorizedError]
|
874
|
+
# @return [Object] The returned object will be put in the GraphQL response
|
875
|
+
def unauthorized_object(unauthorized_error)
|
876
|
+
nil
|
877
|
+
end
|
878
|
+
|
838
879
|
def type_error(type_err, ctx)
|
839
880
|
DefaultTypeError.call(type_err, ctx)
|
840
881
|
end
|
@@ -905,6 +946,29 @@ module GraphQL
|
|
905
946
|
def defined_multiplex_analyzers
|
906
947
|
@defined_multiplex_analyzers ||= []
|
907
948
|
end
|
949
|
+
|
950
|
+
# Given this schema member, find the class-based definition object
|
951
|
+
# whose `method_name` should be treated as an application hook
|
952
|
+
# @see {.visible?}
|
953
|
+
# @see {.accessible?}
|
954
|
+
# @see {.authorized?}
|
955
|
+
def call_on_type_class(member, method_name, *args, default:)
|
956
|
+
member = if member.respond_to?(:metadata)
|
957
|
+
member.metadata[:type_class] || member
|
958
|
+
else
|
959
|
+
member
|
960
|
+
end
|
961
|
+
|
962
|
+
if member.respond_to?(:relay_node_type) && (t = member.relay_node_type)
|
963
|
+
member = t
|
964
|
+
end
|
965
|
+
|
966
|
+
if member.respond_to?(method_name)
|
967
|
+
member.public_send(method_name, *args)
|
968
|
+
else
|
969
|
+
default
|
970
|
+
end
|
971
|
+
end
|
908
972
|
end
|
909
973
|
|
910
974
|
|
@@ -923,6 +987,24 @@ module GraphQL
|
|
923
987
|
end
|
924
988
|
end
|
925
989
|
|
990
|
+
# Call the given block at the right time, either:
|
991
|
+
# - Right away, if `value` is not registered with `lazy_resolve`
|
992
|
+
# - After resolving `value`, if it's registered with `lazy_resolve` (eg, `Promise`)
|
993
|
+
# @api private
|
994
|
+
def after_lazy(value)
|
995
|
+
if (lazy_method = lazy_method_name(value))
|
996
|
+
GraphQL::Execution::Lazy.new do
|
997
|
+
result = value.public_send(lazy_method)
|
998
|
+
# The returned result might also be lazy, so check it, too
|
999
|
+
after_lazy(result) do |final_result|
|
1000
|
+
yield(final_result)
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
else
|
1004
|
+
yield(value)
|
1005
|
+
end
|
1006
|
+
end
|
1007
|
+
|
926
1008
|
protected
|
927
1009
|
|
928
1010
|
def rescues?
|
@@ -937,15 +1019,6 @@ module GraphQL
|
|
937
1019
|
|
938
1020
|
private
|
939
1021
|
|
940
|
-
# Wrap Relay-related objects in wrappers
|
941
|
-
# @api private
|
942
|
-
BUILT_IN_INSTRUMENTERS = [
|
943
|
-
GraphQL::Relay::ConnectionInstrumentation,
|
944
|
-
GraphQL::Relay::EdgesInstrumentation,
|
945
|
-
GraphQL::Relay::Mutation::Instrumentation,
|
946
|
-
GraphQL::Schema::Member::Instrumentation,
|
947
|
-
]
|
948
|
-
|
949
1022
|
def rebuild_artifacts
|
950
1023
|
if @rebuilding_artifacts
|
951
1024
|
raise CyclicalDefinitionError, "Part of the schema build process re-triggered the schema build process, causing an infinite loop. Avoid using Schema#types, Schema#possible_types, and Schema#get_field during schema build."
|
@@ -9,6 +9,7 @@ module GraphQL
|
|
9
9
|
|
10
10
|
# @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
|
11
11
|
attr_reader :name
|
12
|
+
alias :graphql_name :name
|
12
13
|
|
13
14
|
# @return [GraphQL::Schema::Field, Class] The field or input object this argument belongs to
|
14
15
|
attr_reader :owner
|
@@ -53,6 +54,18 @@ module GraphQL
|
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
57
|
+
def visible?(context)
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def accessible?(context)
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
def authorized?(obj, ctx)
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
56
69
|
def to_graphql
|
57
70
|
argument = GraphQL::Argument.new
|
58
71
|
argument.name = @name
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -24,7 +24,7 @@ module GraphQL
|
|
24
24
|
|
25
25
|
class << self
|
26
26
|
extend Forwardable
|
27
|
-
def_delegators :graphql_definition, :coerce_isolated_input, :coerce_isolated_result
|
27
|
+
def_delegators :graphql_definition, :coerce_isolated_input, :coerce_isolated_result, :coerce_input, :coerce_result
|
28
28
|
|
29
29
|
# Define a value for this enum
|
30
30
|
# @param graphql_name [String, Symbol] the GraphQL value for this, usually `SCREAMING_CASE`
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -8,7 +8,8 @@ module GraphQL
|
|
8
8
|
include GraphQL::Schema::Member::HasArguments
|
9
9
|
|
10
10
|
# @return [String] the GraphQL name for this field, camelized unless `camelize: false` is provided
|
11
|
-
|
11
|
+
attr_reader :name
|
12
|
+
alias :graphql_name :name
|
12
13
|
|
13
14
|
# @return [String]
|
14
15
|
attr_accessor :description
|
@@ -274,20 +275,52 @@ module GraphQL
|
|
274
275
|
raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: #{$!.message}", $!.backtrace
|
275
276
|
end
|
276
277
|
|
278
|
+
def visible?(context)
|
279
|
+
if @resolver_class
|
280
|
+
@resolver_class.visible?(context)
|
281
|
+
else
|
282
|
+
true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def accessible?(context)
|
287
|
+
if @resolver_class
|
288
|
+
@resolver_class.accessible?(context)
|
289
|
+
else
|
290
|
+
true
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def authorized?(object, context)
|
295
|
+
if @resolver_class
|
296
|
+
@resolver_class.authorized?(object, context)
|
297
|
+
else
|
298
|
+
true
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
277
302
|
# Implement {GraphQL::Field}'s resolve API.
|
278
303
|
#
|
279
304
|
# Eventually, we might hook up field instances to execution in another way. TBD.
|
280
305
|
def resolve_field(obj, args, ctx)
|
281
|
-
|
282
|
-
#
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
306
|
+
ctx.schema.after_lazy(obj) do |after_obj|
|
307
|
+
# First, apply auth ...
|
308
|
+
query_ctx = ctx.query.context
|
309
|
+
inner_obj = after_obj && after_obj.object
|
310
|
+
if authorized?(inner_obj, query_ctx) && arguments.each_value.all? { |a| a.authorized?(inner_obj, query_ctx) }
|
311
|
+
# Then if it passed, resolve the field
|
312
|
+
if @resolve_proc
|
313
|
+
# Might be nil, still want to call the func in that case
|
314
|
+
@resolve_proc.call(inner_obj, args, ctx)
|
315
|
+
elsif @resolver_class
|
316
|
+
singleton_inst = @resolver_class.new(object: inner_obj, context: query_ctx)
|
317
|
+
public_send_field(singleton_inst, args, ctx)
|
318
|
+
else
|
319
|
+
public_send_field(after_obj, args, ctx)
|
320
|
+
end
|
321
|
+
else
|
322
|
+
nil
|
323
|
+
end
|
291
324
|
end
|
292
325
|
end
|
293
326
|
|
@@ -17,6 +17,26 @@ module GraphQL
|
|
17
17
|
self::DefinitionMethods.module_eval(&block)
|
18
18
|
end
|
19
19
|
|
20
|
+
# The interface is visible if any of its possible types are visible
|
21
|
+
def visible?(context)
|
22
|
+
context.schema.possible_types(self).each do |type|
|
23
|
+
if context.schema.visible?(type, context)
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
# The interface is accessible if any of its possible types are accessible
|
31
|
+
def accessible?(context)
|
32
|
+
context.schema.possible_types(self).each do |type|
|
33
|
+
if context.schema.accessible?(type, context)
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
20
40
|
# Here's the tricky part. Make sure behavior keeps making its way down the inheritance chain.
|
21
41
|
def included(child_class)
|
22
42
|
if !child_class.is_a?(Class)
|
@@ -84,7 +84,7 @@ module GraphQL
|
|
84
84
|
if obj.is_a?(GraphQL::Schema::Object)
|
85
85
|
obj = obj.object
|
86
86
|
end
|
87
|
-
wrapped_object = @object_class.
|
87
|
+
wrapped_object = @object_class.authorized_new(obj, query_ctx)
|
88
88
|
@inner_resolve.call(wrapped_object, args, ctx)
|
89
89
|
end
|
90
90
|
end
|
@@ -22,7 +22,7 @@ module GraphQL
|
|
22
22
|
overridden
|
23
23
|
else # Fallback to Ruby constant name
|
24
24
|
raise NotImplementedError, 'Anonymous class should declare an `graphql_name`' if name.nil?
|
25
|
-
|
25
|
+
|
26
26
|
name.split("::").last.sub(/Type\Z/, "")
|
27
27
|
end
|
28
28
|
end
|
@@ -72,12 +72,34 @@ module GraphQL
|
|
72
72
|
raise NotImplementedError
|
73
73
|
end
|
74
74
|
|
75
|
+
alias :unwrap :itself
|
76
|
+
|
75
77
|
def overridden_graphql_name
|
76
78
|
@graphql_name || find_inherited_method(:overridden_graphql_name, nil)
|
77
79
|
end
|
78
80
|
|
79
|
-
def
|
80
|
-
|
81
|
+
def visible?(context)
|
82
|
+
if @mutation
|
83
|
+
@mutation.visible?(context)
|
84
|
+
else
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def accessible?(context)
|
90
|
+
if @mutation
|
91
|
+
@mutation.accessible?(context)
|
92
|
+
else
|
93
|
+
true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def authorized?(object, context)
|
98
|
+
if @mutation
|
99
|
+
@mutation.authorized?(object, context)
|
100
|
+
else
|
101
|
+
true
|
102
|
+
end
|
81
103
|
end
|
82
104
|
|
83
105
|
private
|
@@ -27,7 +27,7 @@ module GraphQL
|
|
27
27
|
# If it has a wrapper, apply it
|
28
28
|
wrapper_class = root_type.metadata[:type_class]
|
29
29
|
if wrapper_class
|
30
|
-
new_root_value = wrapper_class.
|
30
|
+
new_root_value = wrapper_class.authorized_new(query.root_value, query.context)
|
31
31
|
query.root_value = new_root_value
|
32
32
|
end
|
33
33
|
end
|
@@ -72,39 +72,37 @@ module GraphQL
|
|
72
72
|
|
73
73
|
def call(obj, args, ctx)
|
74
74
|
result = @inner_resolve.call(obj, args, ctx)
|
75
|
-
if ctx.schema.lazy?(result)
|
76
|
-
# Wrap it later
|
77
|
-
result
|
78
|
-
elsif ctx.skip == result
|
75
|
+
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || result.is_a?(GraphQL::ExecutionError) || ctx.wrapped_object
|
79
76
|
result
|
80
77
|
else
|
81
|
-
|
78
|
+
ctx.wrapped_object = true
|
79
|
+
proxy_to_depth(result, @list_depth, ctx)
|
82
80
|
end
|
81
|
+
rescue GraphQL::UnauthorizedError => err
|
82
|
+
ctx.schema.unauthorized_object(err)
|
83
83
|
end
|
84
84
|
|
85
85
|
private
|
86
86
|
|
87
|
-
def proxy_to_depth(
|
88
|
-
if
|
89
|
-
|
90
|
-
elsif depth > 0
|
91
|
-
obj.map { |inner_obj| proxy_to_depth(inner_obj, depth - 1, type, ctx) }
|
87
|
+
def proxy_to_depth(inner_obj, depth, ctx)
|
88
|
+
if depth > 0
|
89
|
+
inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
|
92
90
|
else
|
93
|
-
concrete_type = case
|
91
|
+
concrete_type = case @inner_return_type
|
94
92
|
when GraphQL::UnionType, GraphQL::InterfaceType
|
95
|
-
ctx.query.resolve_type(
|
93
|
+
ctx.query.resolve_type(@inner_return_type, inner_obj)
|
96
94
|
when GraphQL::ObjectType
|
97
|
-
|
95
|
+
@inner_return_type
|
98
96
|
else
|
99
|
-
raise "unexpected proxying type #{
|
97
|
+
raise "unexpected proxying type #{@inner_return_type} for #{inner_obj} at #{ctx.owner_type}.#{ctx.field.name}"
|
100
98
|
end
|
101
99
|
|
102
100
|
if concrete_type && (object_class = concrete_type.metadata[:type_class])
|
103
101
|
# use the query-level context here, since it won't be field-specific anyways
|
104
102
|
query_ctx = ctx.query.context
|
105
|
-
object_class.
|
103
|
+
object_class.authorized_new(inner_obj, query_ctx)
|
106
104
|
else
|
107
|
-
|
105
|
+
inner_obj
|
108
106
|
end
|
109
107
|
end
|
110
108
|
end
|