graphql 2.1.7 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +3 -0
- data/lib/generators/graphql/templates/base_resolver.erb +6 -0
- data/lib/graphql/dataloader/async_dataloader.rb +88 -0
- data/lib/graphql/dataloader/source.rb +3 -2
- data/lib/graphql/dataloader.rb +85 -135
- data/lib/graphql/language/lexer.rb +271 -177
- data/lib/graphql/language/nodes.rb +72 -54
- data/lib/graphql/language/parser.rb +686 -1986
- data/lib/graphql/language/printer.rb +16 -12
- data/lib/graphql/schema/argument.rb +6 -1
- data/lib/graphql/schema.rb +6 -5
- data/lib/graphql/testing/helpers.rb +125 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -0
- metadata +6 -3
- data/lib/graphql/language/parser.y +0 -560
@@ -337,14 +337,16 @@ module GraphQL
|
|
337
337
|
print_string("union ")
|
338
338
|
print_string(union_type.name)
|
339
339
|
print_directives(union_type.directives)
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
340
|
+
if union_type.types.any?
|
341
|
+
print_string(" = ")
|
342
|
+
i = 0
|
343
|
+
union_type.types.each do |t|
|
344
|
+
if i > 0
|
345
|
+
print_string(" | ")
|
346
|
+
end
|
347
|
+
print_string(t.name)
|
348
|
+
i += 1
|
345
349
|
end
|
346
|
-
print_string(t.name)
|
347
|
-
i += 1
|
348
350
|
end
|
349
351
|
end
|
350
352
|
|
@@ -353,12 +355,14 @@ module GraphQL
|
|
353
355
|
print_string("enum ")
|
354
356
|
print_string(enum_type.name)
|
355
357
|
print_directives(enum_type.directives)
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
358
|
+
if enum_type.values.any?
|
359
|
+
print_string(" {\n")
|
360
|
+
enum_type.values.each.with_index do |value, i|
|
361
|
+
print_description(value, indent: " ", first_in_block: i == 0)
|
362
|
+
print_enum_value_definition(value)
|
363
|
+
end
|
364
|
+
print_string("}")
|
360
365
|
end
|
361
|
-
print_string("}")
|
362
366
|
end
|
363
367
|
|
364
368
|
def print_enum_value_definition(enum_value)
|
@@ -221,8 +221,13 @@ module GraphQL
|
|
221
221
|
#
|
222
222
|
# This will have to be called later, when the runtime object _is_ available.
|
223
223
|
value
|
224
|
-
|
224
|
+
elsif obj.respond_to?(@prepare)
|
225
225
|
obj.public_send(@prepare, value)
|
226
|
+
elsif owner.respond_to?(@prepare)
|
227
|
+
owner.public_send(@prepare, value, context || obj.context)
|
228
|
+
else
|
229
|
+
raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}. "\
|
230
|
+
"Could not find prepare method #{@prepare} on #{obj.class} or #{owner}."
|
226
231
|
end
|
227
232
|
elsif @prepare.respond_to?(:call)
|
228
233
|
@prepare.call(value, context || obj.context)
|
data/lib/graphql/schema.rb
CHANGED
@@ -384,6 +384,11 @@ module GraphQL
|
|
384
384
|
(superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
|
385
385
|
end
|
386
386
|
|
387
|
+
# @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility?
|
388
|
+
def has_defined_type?(type_name)
|
389
|
+
own_types.key?(type_name) || introspection_system.types.key?(type_name) || (superclass.respond_to?(:has_defined_type?) ? superclass.has_defined_type?(type_name) : false)
|
390
|
+
end
|
391
|
+
|
387
392
|
# @api private
|
388
393
|
attr_writer :connections
|
389
394
|
|
@@ -939,11 +944,7 @@ module GraphQL
|
|
939
944
|
end
|
940
945
|
|
941
946
|
def resolve_type(type, obj, ctx)
|
942
|
-
|
943
|
-
type
|
944
|
-
else
|
945
|
-
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
|
946
|
-
end
|
947
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{type.name})"
|
947
948
|
end
|
948
949
|
# rubocop:enable Lint/DuplicateMethods
|
949
950
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Testing
|
4
|
+
module Helpers
|
5
|
+
# @param schema_class [Class<GraphQL::Schema>]
|
6
|
+
# @return [Module] A helpers module which always uses the given schema
|
7
|
+
def self.for(schema_class)
|
8
|
+
Module.new do
|
9
|
+
include SchemaHelpers
|
10
|
+
@@schema_class_for_helpers = schema_class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Error < GraphQL::Error
|
15
|
+
end
|
16
|
+
|
17
|
+
class TypeNotVisibleError < Error
|
18
|
+
def initialize(type_name:)
|
19
|
+
message = "`#{type_name}` should be `visible?` this field resolution and `context`, but it was not"
|
20
|
+
super(message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class FieldNotVisibleError < Error
|
25
|
+
def initialize(type_name:, field_name:)
|
26
|
+
message = "`#{type_name}.#{field_name}` should be `visible?` for this resolution, but it was not"
|
27
|
+
super(message)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TypeNotDefinedError < Error
|
32
|
+
def initialize(type_name:)
|
33
|
+
message = "No type named `#{type_name}` is defined; choose another type name or define this type."
|
34
|
+
super(message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class FieldNotDefinedError < Error
|
39
|
+
def initialize(type_name:, field_name:)
|
40
|
+
message = "`#{type_name}` has no field named `#{field_name}`; pick another name or define this field."
|
41
|
+
super(message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_graphql_field(schema, field_path, object, arguments: {}, context: {})
|
46
|
+
type_name, *field_names = field_path.split(".")
|
47
|
+
dummy_query = GraphQL::Query.new(schema, context: context)
|
48
|
+
query_context = dummy_query.context
|
49
|
+
object_type = dummy_query.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
|
50
|
+
if object_type
|
51
|
+
graphql_result = object
|
52
|
+
field_names.each do |field_name|
|
53
|
+
inner_object = graphql_result
|
54
|
+
graphql_result = object_type.wrap(inner_object, query_context)
|
55
|
+
if graphql_result.nil?
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
visible_field = dummy_query.get_field(object_type, field_name)
|
59
|
+
if visible_field
|
60
|
+
dummy_query.context.dataloader.run_isolated {
|
61
|
+
field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
|
62
|
+
field_args = schema.sync_lazy(field_args)
|
63
|
+
graphql_result = visible_field.resolve(graphql_result, field_args.keyword_arguments, query_context)
|
64
|
+
graphql_result = schema.sync_lazy(graphql_result)
|
65
|
+
}
|
66
|
+
object_type = visible_field.type.unwrap
|
67
|
+
elsif object_type.all_field_definitions.any? { |f| f.graphql_name == field_name }
|
68
|
+
raise FieldNotVisibleError.new(field_name: field_name, type_name: type_name)
|
69
|
+
else
|
70
|
+
raise FieldNotDefinedError.new(type_name: type_name, field_name: field_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
graphql_result
|
74
|
+
elsif schema.has_defined_type?(type_name)
|
75
|
+
raise TypeNotVisibleError.new(type_name: type_name)
|
76
|
+
else
|
77
|
+
raise TypeNotDefinedError.new(type_name: type_name)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_resolution_context(schema, type:, object:, context:{})
|
82
|
+
resolution_context = ResolutionAssertionContext.new(
|
83
|
+
self,
|
84
|
+
schema: schema,
|
85
|
+
type_name: type,
|
86
|
+
object: object,
|
87
|
+
context: context
|
88
|
+
)
|
89
|
+
yield(resolution_context)
|
90
|
+
end
|
91
|
+
|
92
|
+
class ResolutionAssertionContext
|
93
|
+
def initialize(test, type_name:, object:, schema:, context:)
|
94
|
+
@test = test
|
95
|
+
@type_name = type_name
|
96
|
+
@object = object
|
97
|
+
@schema = schema
|
98
|
+
@context = context
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
def run_graphql_field(field_name, arguments: {})
|
103
|
+
if @schema
|
104
|
+
@test.run_graphql_field(@schema, "#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
|
105
|
+
else
|
106
|
+
@test.run_graphql_field("#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
module SchemaHelpers
|
112
|
+
include Helpers
|
113
|
+
|
114
|
+
def run_graphql_field(field_path, object, arguments: {}, context: {})
|
115
|
+
super(@@schema_class_for_helpers, field_path, object, arguments: arguments, context: context)
|
116
|
+
end
|
117
|
+
|
118
|
+
def with_resolution_context(*args, **kwargs, &block)
|
119
|
+
# schema will be added later
|
120
|
+
super(nil, *args, **kwargs, &block)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
data/lib/graphql/version.rb
CHANGED
data/lib/graphql.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
11
|
+
date: 2023-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: racc
|
@@ -270,6 +270,7 @@ files:
|
|
270
270
|
- lib/generators/graphql/templates/base_input_object.erb
|
271
271
|
- lib/generators/graphql/templates/base_interface.erb
|
272
272
|
- lib/generators/graphql/templates/base_object.erb
|
273
|
+
- lib/generators/graphql/templates/base_resolver.erb
|
273
274
|
- lib/generators/graphql/templates/base_scalar.erb
|
274
275
|
- lib/generators/graphql/templates/base_union.erb
|
275
276
|
- lib/generators/graphql/templates/enum.erb
|
@@ -308,6 +309,7 @@ files:
|
|
308
309
|
- lib/graphql/backtrace/tracer.rb
|
309
310
|
- lib/graphql/coercion_error.rb
|
310
311
|
- lib/graphql/dataloader.rb
|
312
|
+
- lib/graphql/dataloader/async_dataloader.rb
|
311
313
|
- lib/graphql/dataloader/null_dataloader.rb
|
312
314
|
- lib/graphql/dataloader/request.rb
|
313
315
|
- lib/graphql/dataloader/request_all.rb
|
@@ -359,7 +361,6 @@ files:
|
|
359
361
|
- lib/graphql/language/lexer.rb
|
360
362
|
- lib/graphql/language/nodes.rb
|
361
363
|
- lib/graphql/language/parser.rb
|
362
|
-
- lib/graphql/language/parser.y
|
363
364
|
- lib/graphql/language/printer.rb
|
364
365
|
- lib/graphql/language/sanitized_printer.rb
|
365
366
|
- lib/graphql/language/static_visitor.rb
|
@@ -552,6 +553,8 @@ files:
|
|
552
553
|
- lib/graphql/subscriptions/event.rb
|
553
554
|
- lib/graphql/subscriptions/instrumentation.rb
|
554
555
|
- lib/graphql/subscriptions/serialize.rb
|
556
|
+
- lib/graphql/testing.rb
|
557
|
+
- lib/graphql/testing/helpers.rb
|
555
558
|
- lib/graphql/tracing.rb
|
556
559
|
- lib/graphql/tracing/active_support_notifications_trace.rb
|
557
560
|
- lib/graphql/tracing/active_support_notifications_tracing.rb
|