graphql 1.9.21 → 1.10.0.pre1
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/generators/graphql/core.rb +0 -1
- data/lib/generators/graphql/install_generator.rb +0 -1
- data/lib/generators/graphql/mutation_generator.rb +1 -1
- data/lib/generators/graphql/templates/base_field.erb +4 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +0 -5
- data/lib/generators/graphql/templates/mutation.erb +1 -1
- data/lib/generators/graphql/templates/schema.erb +1 -1
- data/lib/graphql.rb +1 -11
- data/lib/graphql/analysis/ast.rb +2 -2
- data/lib/graphql/analysis/ast/analyzer.rb +4 -23
- data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
- data/lib/graphql/analysis/ast/max_query_depth.rb +3 -7
- data/lib/graphql/analysis/ast/query_complexity.rb +2 -2
- data/lib/graphql/argument.rb +6 -2
- data/lib/graphql/backtrace/table.rb +10 -2
- data/lib/graphql/base_type.rb +5 -1
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
- data/lib/graphql/define/assign_object_field.rb +2 -2
- data/lib/graphql/define/defined_object_proxy.rb +0 -3
- data/lib/graphql/define/instance_definable.rb +3 -14
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/directive_checks.rb +2 -2
- data/lib/graphql/execution/errors.rb +14 -15
- data/lib/graphql/execution/execute.rb +1 -1
- data/lib/graphql/execution/interpreter/runtime.rb +17 -39
- data/lib/graphql/execution/multiplex.rb +3 -3
- data/lib/graphql/field.rb +8 -0
- data/lib/graphql/filter.rb +1 -1
- data/lib/graphql/function.rb +1 -1
- data/lib/graphql/input_object_type.rb +1 -2
- data/lib/graphql/introspection/entry_points.rb +1 -2
- data/lib/graphql/introspection/input_value_type.rb +27 -9
- data/lib/graphql/introspection/schema_type.rb +1 -2
- data/lib/graphql/language/block_string.rb +2 -2
- data/lib/graphql/language/document_from_schema_definition.rb +5 -11
- data/lib/graphql/language/lexer.rb +48 -49
- data/lib/graphql/language/lexer.rl +48 -49
- data/lib/graphql/language/nodes.rb +11 -14
- data/lib/graphql/language/parser.rb +645 -650
- data/lib/graphql/language/parser.y +7 -8
- data/lib/graphql/language/token.rb +1 -1
- data/lib/graphql/non_null_type.rb +0 -10
- data/lib/graphql/pagination.rb +6 -0
- data/lib/graphql/pagination/active_record_relation_connection.rb +35 -0
- data/lib/graphql/pagination/array_connection.rb +78 -0
- data/lib/graphql/pagination/connection.rb +150 -0
- data/lib/graphql/pagination/connections.rb +103 -0
- data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
- data/lib/graphql/pagination/relation_connection.rb +157 -0
- data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
- data/lib/graphql/query.rb +1 -7
- data/lib/graphql/query/arguments.rb +3 -9
- data/lib/graphql/query/context.rb +9 -31
- data/lib/graphql/query/literal_input.rb +29 -10
- data/lib/graphql/query/null_context.rb +0 -4
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query/variables.rb +2 -4
- data/lib/graphql/relay/base_connection.rb +7 -3
- data/lib/graphql/relay/edges_instrumentation.rb +1 -1
- data/lib/graphql/relay/node.rb +2 -2
- data/lib/graphql/relay/relation_connection.rb +5 -9
- data/lib/graphql/schema.rb +27 -68
- data/lib/graphql/schema/argument.rb +31 -5
- data/lib/graphql/schema/base_64_bp.rb +2 -3
- data/lib/graphql/schema/build_from_definition.rb +113 -179
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +10 -4
- data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
- data/lib/graphql/schema/directive.rb +6 -7
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/enum.rb +1 -0
- data/lib/graphql/schema/enum_value.rb +4 -1
- data/lib/graphql/schema/field.rb +37 -39
- data/lib/graphql/schema/field/connection_extension.rb +11 -1
- data/lib/graphql/schema/input_object.rb +2 -5
- data/lib/graphql/schema/interface.rb +2 -0
- data/lib/graphql/schema/introspection_system.rb +1 -4
- data/lib/graphql/schema/loader.rb +6 -12
- data/lib/graphql/schema/member.rb +2 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +2 -2
- data/lib/graphql/schema/member/build_type.rb +4 -0
- data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
- data/lib/graphql/schema/member/has_ast_node.rb +17 -0
- data/lib/graphql/schema/member/has_fields.rb +10 -16
- data/lib/graphql/schema/member/instrumentation.rb +1 -6
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema/mutation.rb +1 -1
- data/lib/graphql/schema/object.rb +5 -6
- data/lib/graphql/schema/possible_types.rb +3 -3
- data/lib/graphql/schema/printer.rb +1 -3
- data/lib/graphql/schema/relay_classic_mutation.rb +2 -6
- data/lib/graphql/schema/resolver.rb +5 -35
- data/lib/graphql/schema/scalar.rb +1 -0
- data/lib/graphql/schema/subscription.rb +6 -6
- data/lib/graphql/schema/timeout_middleware.rb +2 -3
- data/lib/graphql/schema/type_expression.rb +27 -17
- data/lib/graphql/schema/union.rb +7 -26
- data/lib/graphql/schema/validation.rb +1 -17
- data/lib/graphql/schema/warden.rb +3 -77
- data/lib/graphql/schema/wrapper.rb +1 -1
- data/lib/graphql/static_validation/definition_dependencies.rb +12 -21
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +9 -4
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +10 -7
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -3
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -1
- data/lib/graphql/subscriptions.rb +7 -7
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -2
- data/lib/graphql/subscriptions/event.rb +5 -19
- data/lib/graphql/subscriptions/instrumentation.rb +9 -4
- data/lib/graphql/subscriptions/subscription_root.rb +2 -10
- data/lib/graphql/tracing/skylight_tracing.rb +0 -1
- data/lib/graphql/types/int.rb +1 -1
- data/lib/graphql/types/relay/base_connection.rb +3 -1
- data/lib/graphql/union_type.rb +23 -58
- data/lib/graphql/upgrader/member.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- metadata +20 -13
- data/lib/generators/graphql/templates/base_mutation.erb +0 -8
- data/lib/graphql/schema/type_membership.rb +0 -34
@@ -1,5 +1,4 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
2
|
module GraphQL
|
4
3
|
class Schema
|
5
4
|
class Member
|
@@ -7,11 +6,11 @@ module GraphQL
|
|
7
6
|
module HasFields
|
8
7
|
# Add a field to this object or interface with the given definition
|
9
8
|
# @see {GraphQL::Schema::Field#initialize} for method signature
|
10
|
-
# @return [
|
9
|
+
# @return [GraphQL::Schema::Field]
|
11
10
|
def field(*args, **kwargs, &block)
|
12
11
|
field_defn = field_class.from_options(*args, owner: self, **kwargs, &block)
|
13
12
|
add_field(field_defn)
|
14
|
-
|
13
|
+
field_defn
|
15
14
|
end
|
16
15
|
|
17
16
|
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
@@ -39,28 +38,23 @@ module GraphQL
|
|
39
38
|
end
|
40
39
|
end
|
41
40
|
|
42
|
-
# A list of Ruby keywords.
|
43
|
-
#
|
44
|
-
# @api private
|
45
|
-
RUBY_KEYWORDS = [:class, :module, :def, :undef, :begin, :rescue, :ensure, :end, :if, :unless, :then, :elsif, :else, :case, :when, :while, :until, :for, :break, :next, :redo, :retry, :in, :do, :return, :yield, :super, :self, :nil, :true, :false, :and, :or, :not, :alias, :defined?, :BEGIN, :END, :__LINE__, :__FILE__]
|
46
|
-
|
47
|
-
# A list of GraphQL-Ruby keywords.
|
48
|
-
#
|
49
|
-
# @api private
|
50
|
-
GRAPHQL_RUBY_KEYWORDS = [:context, :object, :method]
|
51
|
-
|
52
41
|
# A list of field names that we should advise users to pick a different
|
53
42
|
# resolve method name.
|
54
43
|
#
|
55
44
|
# @api private
|
56
|
-
CONFLICT_FIELD_NAMES = Set.new(
|
45
|
+
CONFLICT_FIELD_NAMES = Set.new([
|
46
|
+
# GraphQL-Ruby conflicts
|
47
|
+
:context, :object,
|
48
|
+
# Ruby built-ins conflicts
|
49
|
+
:method, :class
|
50
|
+
])
|
57
51
|
|
58
52
|
# Register this field with the class, overriding a previous one if needed.
|
59
53
|
# @param field_defn [GraphQL::Schema::Field]
|
60
54
|
# @return [void]
|
61
55
|
def add_field(field_defn)
|
62
|
-
if CONFLICT_FIELD_NAMES.include?(field_defn.
|
63
|
-
warn "#{self.graphql_name}'s `field :#{field_defn.
|
56
|
+
if CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) && field_defn.original_name == field_defn.resolver_method && field_defn.method_conflict_warning?
|
57
|
+
warn "#{self.graphql_name}'s `field :#{field_defn.name}` conflicts with a built-in method, use `resolver_method:` to pick a different resolver method for this field (for example, `resolver_method: :resolve_#{field_defn.resolver_method}` and `def resolve_#{field_defn.resolver_method}`). Or use `method_conflict_warning: false` to suppress this warning."
|
64
58
|
end
|
65
59
|
own_fields[field_defn.name] = field_defn
|
66
60
|
nil
|
@@ -78,7 +78,7 @@ module GraphQL
|
|
78
78
|
|
79
79
|
def call(obj, args, ctx)
|
80
80
|
result = @inner_resolve.call(obj, args, ctx)
|
81
|
-
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? ||
|
81
|
+
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || result.is_a?(GraphQL::ExecutionError) || ctx.wrapped_object
|
82
82
|
result
|
83
83
|
else
|
84
84
|
ctx.wrapped_object = true
|
@@ -88,11 +88,6 @@ module GraphQL
|
|
88
88
|
|
89
89
|
private
|
90
90
|
|
91
|
-
def execution_errors?(result)
|
92
|
-
result.is_a?(GraphQL::ExecutionError) ||
|
93
|
-
(result.is_a?(Array) && result.any? && result.all? { |v| v.is_a?(GraphQL::ExecutionError) })
|
94
|
-
end
|
95
|
-
|
96
91
|
def proxy_to_depth(inner_obj, depth, ctx)
|
97
92
|
if depth > 0
|
98
93
|
inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
|
@@ -64,7 +64,7 @@ module GraphQL
|
|
64
64
|
|
65
65
|
class << self
|
66
66
|
# Override this method to handle legacy-style usages of `MyMutation.field`
|
67
|
-
def field(*args,
|
67
|
+
def field(*args, &block)
|
68
68
|
if args.empty?
|
69
69
|
raise ArgumentError, "#{name}.field is used for adding fields to this mutation. Use `mutation: #{name}` to attach this mutation instead."
|
70
70
|
else
|
@@ -35,12 +35,10 @@ module GraphQL
|
|
35
35
|
# @return [GraphQL::Schema::Object, GraphQL::Execution::Lazy]
|
36
36
|
# @raise [GraphQL::UnauthorizedError] if the user-provided hook returns `false`
|
37
37
|
def authorized_new(object, context)
|
38
|
-
auth_val =
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
context.schema.unauthorized_object(err)
|
43
|
-
end
|
38
|
+
auth_val = begin
|
39
|
+
authorized?(object, context)
|
40
|
+
rescue GraphQL::UnauthorizedError => err
|
41
|
+
context.schema.unauthorized_object(err)
|
44
42
|
end
|
45
43
|
|
46
44
|
context.schema.after_lazy(auth_val) do |is_authorized|
|
@@ -120,6 +118,7 @@ module GraphQL
|
|
120
118
|
obj_type.interfaces = interfaces
|
121
119
|
obj_type.introspection = introspection
|
122
120
|
obj_type.mutation = mutation
|
121
|
+
obj_type.ast_node = ast_node
|
123
122
|
fields.each do |field_name, field_inst|
|
124
123
|
field_defn = field_inst.to_graphql
|
125
124
|
obj_type.fields[field_defn.name] = field_defn
|
@@ -20,12 +20,12 @@ module GraphQL
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def possible_types(type_defn
|
23
|
+
def possible_types(type_defn)
|
24
24
|
case type_defn
|
25
25
|
when Module
|
26
|
-
possible_types(type_defn.graphql_definition
|
26
|
+
possible_types(type_defn.graphql_definition)
|
27
27
|
when GraphQL::UnionType
|
28
|
-
type_defn.possible_types
|
28
|
+
type_defn.possible_types
|
29
29
|
when GraphQL::InterfaceType
|
30
30
|
@interface_implementers[type_defn]
|
31
31
|
when GraphQL::BaseType
|
@@ -60,9 +60,7 @@ module GraphQL
|
|
60
60
|
|
61
61
|
# Return the GraphQL schema string for the introspection type system
|
62
62
|
def self.print_introspection_schema
|
63
|
-
query_root = ObjectType.define(name: "Root")
|
64
|
-
field :throwaway_field, types.String
|
65
|
-
end
|
63
|
+
query_root = ObjectType.define(name: "Root")
|
66
64
|
schema = GraphQL::Schema.define(query: query_root)
|
67
65
|
|
68
66
|
introspection_schema_ast = GraphQL::Language::DocumentFromSchemaDefinition.new(
|
@@ -33,13 +33,9 @@ module GraphQL
|
|
33
33
|
# But when using the interpreter, no instrumenters are applied.
|
34
34
|
if context.interpreter?
|
35
35
|
input = inputs[:input].to_kwargs
|
36
|
-
|
37
|
-
new_extras = field ? field.extras : []
|
38
|
-
all_extras = self.class.extras + new_extras
|
39
|
-
|
40
36
|
# Transfer these from the top-level hash to the
|
41
37
|
# shortcutted `input:` object
|
42
|
-
|
38
|
+
self.class.extras.each do |ext|
|
43
39
|
# It's possible that the `extra` was not passed along by this point,
|
44
40
|
# don't re-add it if it wasn't given here.
|
45
41
|
if inputs.key?(ext)
|
@@ -61,7 +57,7 @@ module GraphQL
|
|
61
57
|
end
|
62
58
|
|
63
59
|
return_value = if input_kwargs.any?
|
64
|
-
super(
|
60
|
+
super(input_kwargs)
|
65
61
|
else
|
66
62
|
super()
|
67
63
|
end
|
@@ -29,11 +29,9 @@ module GraphQL
|
|
29
29
|
|
30
30
|
# @param object [Object] the initialize object, pass to {Query.initialize} as `root_value`
|
31
31
|
# @param context [GraphQL::Query::Context]
|
32
|
-
|
33
|
-
def initialize(object:, context:, field:)
|
32
|
+
def initialize(object:, context:)
|
34
33
|
@object = object
|
35
34
|
@context = context
|
36
|
-
@field = field
|
37
35
|
# Since this hash is constantly rebuilt, cache it for this call
|
38
36
|
@arguments_by_keyword = {}
|
39
37
|
self.class.arguments.each do |name, arg|
|
@@ -48,9 +46,6 @@ module GraphQL
|
|
48
46
|
# @return [GraphQL::Query::Context]
|
49
47
|
attr_reader :context
|
50
48
|
|
51
|
-
# @return [GraphQL::Schema::Field]
|
52
|
-
attr_reader :field
|
53
|
-
|
54
49
|
# This method is _actually_ called by the runtime,
|
55
50
|
# it does some preparation and then eventually calls
|
56
51
|
# the user-defined `#resolve` method.
|
@@ -76,7 +71,7 @@ module GraphQL
|
|
76
71
|
context.schema.after_lazy(load_arguments_val) do |loaded_args|
|
77
72
|
# Then call `authorized?`, which may raise or may return a lazy object
|
78
73
|
authorized_val = if loaded_args.any?
|
79
|
-
authorized?(
|
74
|
+
authorized?(loaded_args)
|
80
75
|
else
|
81
76
|
authorized?
|
82
77
|
end
|
@@ -108,7 +103,7 @@ module GraphQL
|
|
108
103
|
# Do the work. Everything happens here.
|
109
104
|
# @return [Object] An object corresponding to the return type
|
110
105
|
def resolve(**args)
|
111
|
-
raise
|
106
|
+
raise NotImplementedError, "#{self.class.name}#resolve should execute the field's logic"
|
112
107
|
end
|
113
108
|
|
114
109
|
# Called before arguments are prepared.
|
@@ -135,20 +130,8 @@ module GraphQL
|
|
135
130
|
def authorized?(**inputs)
|
136
131
|
self.class.arguments.each_value do |argument|
|
137
132
|
arg_keyword = argument.keyword
|
138
|
-
if inputs.key?(arg_keyword) && !(
|
139
|
-
|
140
|
-
# If this argument resulted in an object being loaded,
|
141
|
-
# then authorize this loaded object with its own policy.
|
142
|
-
#
|
143
|
-
# But if this argument was "just" a plain argument, like
|
144
|
-
# a boolean, then authorize it based on the mutation.
|
145
|
-
authorization_value = if loads_type
|
146
|
-
value
|
147
|
-
else
|
148
|
-
self
|
149
|
-
end
|
150
|
-
|
151
|
-
arg_auth, err = argument.authorized?(authorization_value, context)
|
133
|
+
if inputs.key?(arg_keyword) && !(arg_value = inputs[arg_keyword]).nil? && (arg_value != argument.default_value)
|
134
|
+
arg_auth, err = argument.authorized?(self, arg_value, context)
|
152
135
|
if !arg_auth
|
153
136
|
return arg_auth, err
|
154
137
|
else
|
@@ -272,7 +255,6 @@ module GraphQL
|
|
272
255
|
arguments: arguments,
|
273
256
|
null: null,
|
274
257
|
complexity: complexity,
|
275
|
-
extensions: extensions,
|
276
258
|
}
|
277
259
|
end
|
278
260
|
|
@@ -326,18 +308,6 @@ module GraphQL
|
|
326
308
|
inherited_lookups.merge(own_arguments_loads_as_type)
|
327
309
|
end
|
328
310
|
|
329
|
-
# Registers new extension
|
330
|
-
# @param extension [Class] Extension class
|
331
|
-
# @param options [Hash] Optional extension options
|
332
|
-
def extension(extension, **options)
|
333
|
-
extensions << {extension => options}
|
334
|
-
end
|
335
|
-
|
336
|
-
# @api private
|
337
|
-
def extensions
|
338
|
-
@extensions ||= []
|
339
|
-
end
|
340
|
-
|
341
311
|
private
|
342
312
|
|
343
313
|
def own_arguments_loads_as_type
|
@@ -29,7 +29,7 @@ module GraphQL
|
|
29
29
|
# propagate null.
|
30
30
|
null false
|
31
31
|
|
32
|
-
def initialize(object:, context
|
32
|
+
def initialize(object:, context:)
|
33
33
|
super
|
34
34
|
# Figure out whether this is an update or an initial subscription
|
35
35
|
@mode = context.query.subscription_update? ? :update : :subscribe
|
@@ -39,12 +39,12 @@ module GraphQL
|
|
39
39
|
def resolve(**args)
|
40
40
|
# Dispatch based on `@mode`, which will raise a `NoMethodError` if we ever
|
41
41
|
# have an unexpected `@mode`
|
42
|
-
public_send("resolve_#{@mode}",
|
42
|
+
public_send("resolve_#{@mode}", args)
|
43
43
|
end
|
44
44
|
|
45
45
|
# Wrap the user-defined `#subscribe` hook
|
46
|
-
def resolve_subscribe(
|
47
|
-
ret_val = args.any? ? subscribe(
|
46
|
+
def resolve_subscribe(args)
|
47
|
+
ret_val = args.any? ? subscribe(args) : subscribe
|
48
48
|
if ret_val == :no_response
|
49
49
|
context.skip
|
50
50
|
else
|
@@ -62,8 +62,8 @@ module GraphQL
|
|
62
62
|
end
|
63
63
|
|
64
64
|
# Wrap the user-provided `#update` hook
|
65
|
-
def resolve_update(
|
66
|
-
ret_val = args.any? ? update(
|
65
|
+
def resolve_update(args)
|
66
|
+
ret_val = args.any? ? update(args) : update
|
67
67
|
if ret_val == :no_update
|
68
68
|
raise NoUpdateError
|
69
69
|
else
|
@@ -35,10 +35,9 @@ module GraphQL
|
|
35
35
|
|
36
36
|
def call(parent_type, parent_object, field_definition, field_args, query_context)
|
37
37
|
ns = query_context.namespace(self.class)
|
38
|
-
|
39
|
-
timeout_at = ns[:timeout_at] ||= now + @max_seconds
|
38
|
+
timeout_at = ns[:timeout_at] ||= Time.now + @max_seconds
|
40
39
|
|
41
|
-
if timeout_at < now
|
40
|
+
if timeout_at < Time.now
|
42
41
|
on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
|
43
42
|
else
|
44
43
|
yield
|
@@ -9,25 +9,35 @@ module GraphQL
|
|
9
9
|
# @param ast_node [GraphQL::Language::Nodes::AbstractNode]
|
10
10
|
# @return [GraphQL::BaseType, nil]
|
11
11
|
def self.build_type(types, ast_node)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
when GraphQL::Language::Nodes::NonNullType
|
16
|
-
ast_inner_type = ast_node.of_type
|
17
|
-
inner_type = build_type(types, ast_inner_type)
|
18
|
-
wrap_type(inner_type, GraphQL::NonNullType)
|
19
|
-
when GraphQL::Language::Nodes::ListType
|
20
|
-
ast_inner_type = ast_node.of_type
|
21
|
-
inner_type = build_type(types, ast_inner_type)
|
22
|
-
wrap_type(inner_type, GraphQL::ListType)
|
23
|
-
end
|
12
|
+
t = type_from_ast(types, ast_node)
|
13
|
+
# maybe nil:
|
14
|
+
t ? t.graphql_definition : t
|
24
15
|
end
|
25
16
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
17
|
+
class << self
|
18
|
+
private
|
19
|
+
|
20
|
+
def type_from_ast(types, ast_node)
|
21
|
+
case ast_node
|
22
|
+
when GraphQL::Language::Nodes::TypeName
|
23
|
+
types.fetch(ast_node.name, nil)
|
24
|
+
when GraphQL::Language::Nodes::NonNullType
|
25
|
+
ast_inner_type = ast_node.of_type
|
26
|
+
inner_type = build_type(types, ast_inner_type)
|
27
|
+
wrap_type(inner_type, GraphQL::Schema::NonNull)
|
28
|
+
when GraphQL::Language::Nodes::ListType
|
29
|
+
ast_inner_type = ast_node.of_type
|
30
|
+
inner_type = build_type(types, ast_inner_type)
|
31
|
+
wrap_type(inner_type, GraphQL::Schema::List)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def wrap_type(of_type, wrapper)
|
36
|
+
if of_type.nil?
|
37
|
+
nil
|
38
|
+
else
|
39
|
+
wrapper.new(of_type)
|
40
|
+
end
|
31
41
|
end
|
32
42
|
end
|
33
43
|
end
|
data/lib/graphql/schema/union.rb
CHANGED
@@ -5,19 +5,13 @@ module GraphQL
|
|
5
5
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def possible_types(*types
|
8
|
+
def possible_types(*types)
|
9
9
|
if types.any?
|
10
|
-
|
11
|
-
type_memberships << type_membership_class.new(self, t, **options)
|
12
|
-
end
|
10
|
+
@possible_types = types
|
13
11
|
else
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
visible_types << type_membership.object_type
|
18
|
-
end
|
19
|
-
end
|
20
|
-
visible_types
|
12
|
+
all_possible_types = @possible_types || []
|
13
|
+
all_possible_types += super if defined?(super)
|
14
|
+
all_possible_types.uniq
|
21
15
|
end
|
22
16
|
end
|
23
17
|
|
@@ -25,7 +19,8 @@ module GraphQL
|
|
25
19
|
type_defn = GraphQL::UnionType.new
|
26
20
|
type_defn.name = graphql_name
|
27
21
|
type_defn.description = description
|
28
|
-
type_defn.
|
22
|
+
type_defn.possible_types = possible_types
|
23
|
+
type_defn.ast_node = ast_node
|
29
24
|
if respond_to?(:resolve_type)
|
30
25
|
type_defn.resolve_type = method(:resolve_type)
|
31
26
|
end
|
@@ -33,23 +28,9 @@ module GraphQL
|
|
33
28
|
type_defn
|
34
29
|
end
|
35
30
|
|
36
|
-
def type_membership_class(membership_class = nil)
|
37
|
-
if membership_class
|
38
|
-
@type_membership_class = membership_class
|
39
|
-
else
|
40
|
-
@type_membership_class || find_inherited_value(:type_membership_class, GraphQL::Schema::TypeMembership)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
31
|
def kind
|
45
32
|
GraphQL::TypeKinds::UNION
|
46
33
|
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def type_memberships
|
51
|
-
@type_memberships ||= []
|
52
|
-
end
|
53
34
|
end
|
54
35
|
end
|
55
36
|
end
|
@@ -77,18 +77,6 @@ module GraphQL
|
|
77
77
|
}
|
78
78
|
end
|
79
79
|
|
80
|
-
def self.count_at_least(item_name, minimum_count, get_items_proc)
|
81
|
-
->(type) {
|
82
|
-
items = get_items_proc.call(type)
|
83
|
-
|
84
|
-
if items.size < minimum_count
|
85
|
-
"#{type.name} must define at least #{minimum_count} #{item_name}. #{items.size} defined."
|
86
|
-
else
|
87
|
-
nil
|
88
|
-
end
|
89
|
-
}
|
90
|
-
end
|
91
|
-
|
92
80
|
def self.assert_named_items_are_valid(item_name, get_items_proc)
|
93
81
|
->(type) {
|
94
82
|
items = get_items_proc.call(type)
|
@@ -104,9 +92,7 @@ module GraphQL
|
|
104
92
|
}
|
105
93
|
end
|
106
94
|
|
107
|
-
HAS_AT_LEAST_ONE_FIELD = Rules.count_at_least("field", 1, ->(type) { type.all_fields })
|
108
95
|
FIELDS_ARE_VALID = Rules.assert_named_items_are_valid("field", ->(type) { type.all_fields })
|
109
|
-
HAS_AT_LEAST_ONE_ARGUMENT = Rules.count_at_least("argument", 1, ->(type) { type.arguments })
|
110
96
|
|
111
97
|
HAS_ONE_OR_MORE_POSSIBLE_TYPES = ->(type) {
|
112
98
|
type.possible_types.length >= 1 ? nil : "must have at least one possible type"
|
@@ -135,7 +121,7 @@ module GraphQL
|
|
135
121
|
|
136
122
|
TYPE_IS_VALID_INPUT_TYPE = ->(type) {
|
137
123
|
outer_type = type.type
|
138
|
-
inner_type = outer_type.
|
124
|
+
inner_type = outer_type.respond_to?(:unwrap) ? outer_type.unwrap : nil
|
139
125
|
|
140
126
|
case inner_type
|
141
127
|
when GraphQL::ScalarType, GraphQL::InputObjectType, GraphQL::EnumType
|
@@ -274,13 +260,11 @@ module GraphQL
|
|
274
260
|
Rules::DESCRIPTION_IS_STRING_OR_NIL,
|
275
261
|
],
|
276
262
|
GraphQL::ObjectType => [
|
277
|
-
Rules::HAS_AT_LEAST_ONE_FIELD,
|
278
263
|
Rules.assert_property_list_of(:interfaces, GraphQL::InterfaceType),
|
279
264
|
Rules::FIELDS_ARE_VALID,
|
280
265
|
Rules::INTERFACES_ARE_IMPLEMENTED,
|
281
266
|
],
|
282
267
|
GraphQL::InputObjectType => [
|
283
|
-
Rules::HAS_AT_LEAST_ONE_ARGUMENT,
|
284
268
|
Rules::ARGUMENTS_ARE_STRING_TO_ARGUMENT,
|
285
269
|
Rules::ARGUMENTS_ARE_VALID,
|
286
270
|
],
|