graphql 2.3.14 → 2.4.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/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis.rb +1 -1
- data/lib/graphql/dataloader/async_dataloader.rb +3 -2
- data/lib/graphql/dataloader/source.rb +1 -1
- data/lib/graphql/dataloader.rb +31 -10
- data/lib/graphql/execution/interpreter/resolve.rb +10 -6
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +38 -4
- data/lib/graphql/language/lexer.rb +15 -12
- data/lib/graphql/language/nodes.rb +22 -14
- data/lib/graphql/language/parser.rb +5 -0
- data/lib/graphql/language/printer.rb +23 -7
- data/lib/graphql/language.rb +6 -5
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query.rb +49 -16
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +23 -8
- data/lib/graphql/schema/always_visible.rb +6 -3
- data/lib/graphql/schema/argument.rb +14 -1
- data/lib/graphql/schema/build_from_definition.rb +1 -0
- data/lib/graphql/schema/enum.rb +3 -0
- data/lib/graphql/schema/enum_value.rb +9 -1
- data/lib/graphql/schema/field.rb +35 -14
- data/lib/graphql/schema/input_object.rb +20 -7
- data/lib/graphql/schema/interface.rb +1 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +2 -2
- data/lib/graphql/schema/member/has_fields.rb +2 -2
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/resolver.rb +3 -4
- data/lib/graphql/schema/validator/required_validator.rb +28 -4
- data/lib/graphql/schema/visibility/migration.rb +186 -0
- data/lib/graphql/schema/visibility/profile.rb +523 -0
- data/lib/graphql/schema/visibility.rb +75 -0
- data/lib/graphql/schema/warden.rb +77 -15
- data/lib/graphql/schema.rb +203 -61
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +2 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +2 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +2 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +11 -1
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +10 -1
- data/lib/graphql/static_validation/validation_context.rb +15 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -1
- data/lib/graphql/subscriptions.rb +3 -1
- data/lib/graphql/testing/helpers.rb +2 -1
- data/lib/graphql/tracing/notifications_trace.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- metadata +11 -9
- data/lib/graphql/schema/subset.rb +0 -509
- data/lib/graphql/schema/types_migration.rb +0 -187
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26e43b0bc48317698ed17f8a11498c19a7a4a0df9d33fdc9785edc47ae1147b6
|
4
|
+
data.tar.gz: 74402e930ebe03a451bc2bdb82285642aeeba7222ab491dd9329400fc852eb41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1d97c4397ca8410f6b62c3ea2de9a0a4b18ca610adcb92de9676c5377b00a071cbff4fbd0396760eea9ab359e4b0b8cdfff1630c9fa83de51cfd31b0b96307f
|
7
|
+
data.tar.gz: d9250a9ad1d57f40e7b0151484f77a66e11a361f8b0f50938f42219eb8322a9b4dc59c59102f4b49f62a28e90f03b8f9e0cf5b2799b5fd5080dbcf443cebac15
|
@@ -18,7 +18,7 @@ module Graphql
|
|
18
18
|
class_option :orm, banner: "NAME", type: :string, required: true,
|
19
19
|
desc: "ORM to generate the controller for"
|
20
20
|
|
21
|
-
class_option
|
21
|
+
class_option :namespaced_types,
|
22
22
|
type: :boolean,
|
23
23
|
required: false,
|
24
24
|
default: false,
|
data/lib/graphql/analysis.rb
CHANGED
@@ -81,7 +81,7 @@ module GraphQL
|
|
81
81
|
end
|
82
82
|
rescue Timeout::Error
|
83
83
|
[GraphQL::AnalysisError.new("Timeout on validation of query")]
|
84
|
-
rescue GraphQL::UnauthorizedError
|
84
|
+
rescue GraphQL::UnauthorizedError, GraphQL::ExecutionError
|
85
85
|
# This error was raised during analysis and will be returned the client before execution
|
86
86
|
[]
|
87
87
|
end
|
@@ -12,6 +12,7 @@ module GraphQL
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run
|
15
|
+
jobs_fiber_limit, total_fiber_limit = calculate_fiber_limit
|
15
16
|
job_fibers = []
|
16
17
|
next_job_fibers = []
|
17
18
|
source_tasks = []
|
@@ -23,7 +24,7 @@ module GraphQL
|
|
23
24
|
first_pass = false
|
24
25
|
fiber_vars = get_fiber_variables
|
25
26
|
|
26
|
-
while (f = (job_fibers.shift || spawn_job_fiber))
|
27
|
+
while (f = (job_fibers.shift || (((job_fibers.size + next_job_fibers.size + source_tasks.size) < jobs_fiber_limit) && spawn_job_fiber)))
|
27
28
|
if f.alive?
|
28
29
|
finished = run_fiber(f)
|
29
30
|
if !finished
|
@@ -37,7 +38,7 @@ module GraphQL
|
|
37
38
|
Sync do |root_task|
|
38
39
|
set_fiber_variables(fiber_vars)
|
39
40
|
while source_tasks.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) }
|
40
|
-
while (task = source_tasks.shift || spawn_source_task(root_task, sources_condition))
|
41
|
+
while (task = (source_tasks.shift || (((job_fibers.size + next_job_fibers.size + source_tasks.size + next_source_tasks.size) < total_fiber_limit) && spawn_source_task(root_task, sources_condition))))
|
41
42
|
if task.alive?
|
42
43
|
root_task.yield # give the source task a chance to run
|
43
44
|
next_source_tasks << task
|
@@ -98,7 +98,7 @@ module GraphQL
|
|
98
98
|
while pending_result_keys.any? { |key| !@results.key?(key) }
|
99
99
|
iterations += 1
|
100
100
|
if iterations > MAX_ITERATIONS
|
101
|
-
raise "#{self.class}#sync tried #{MAX_ITERATIONS} times to load pending keys (#{pending_result_keys}), but they still weren't loaded. There is likely a circular dependency."
|
101
|
+
raise "#{self.class}#sync tried #{MAX_ITERATIONS} times to load pending keys (#{pending_result_keys}), but they still weren't loaded. There is likely a circular dependency#{@dataloader.fiber_limit ? " or `fiber_limit: #{@dataloader.fiber_limit}` is set too low" : ""}."
|
102
102
|
end
|
103
103
|
@dataloader.yield
|
104
104
|
end
|
data/lib/graphql/dataloader.rb
CHANGED
@@ -24,18 +24,23 @@ module GraphQL
|
|
24
24
|
#
|
25
25
|
class Dataloader
|
26
26
|
class << self
|
27
|
-
attr_accessor :default_nonblocking
|
27
|
+
attr_accessor :default_nonblocking, :default_fiber_limit
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
def self.use(schema, nonblocking: nil)
|
33
|
-
schema.dataloader_class = if nonblocking
|
30
|
+
def self.use(schema, nonblocking: nil, fiber_limit: nil)
|
31
|
+
dataloader_class = if nonblocking
|
34
32
|
warn("`nonblocking: true` is deprecated from `GraphQL::Dataloader`, please use `GraphQL::Dataloader::AsyncDataloader` instead. Docs: https://graphql-ruby.org/dataloader/async_dataloader.")
|
35
|
-
|
33
|
+
Class.new(self) { self.default_nonblocking = true }
|
36
34
|
else
|
37
35
|
self
|
38
36
|
end
|
37
|
+
|
38
|
+
if fiber_limit
|
39
|
+
dataloader_class = Class.new(dataloader_class)
|
40
|
+
dataloader_class.default_fiber_limit = fiber_limit
|
41
|
+
end
|
42
|
+
|
43
|
+
schema.dataloader_class = dataloader_class
|
39
44
|
end
|
40
45
|
|
41
46
|
# Call the block with a Dataloader instance,
|
@@ -50,14 +55,18 @@ module GraphQL
|
|
50
55
|
result
|
51
56
|
end
|
52
57
|
|
53
|
-
def initialize(nonblocking: self.class.default_nonblocking)
|
58
|
+
def initialize(nonblocking: self.class.default_nonblocking, fiber_limit: self.class.default_fiber_limit)
|
54
59
|
@source_cache = Hash.new { |h, k| h[k] = {} }
|
55
60
|
@pending_jobs = []
|
56
61
|
if !nonblocking.nil?
|
57
62
|
@nonblocking = nonblocking
|
58
63
|
end
|
64
|
+
@fiber_limit = fiber_limit
|
59
65
|
end
|
60
66
|
|
67
|
+
# @return [Integer, nil]
|
68
|
+
attr_reader :fiber_limit
|
69
|
+
|
61
70
|
def nonblocking?
|
62
71
|
@nonblocking
|
63
72
|
end
|
@@ -178,6 +187,7 @@ module GraphQL
|
|
178
187
|
end
|
179
188
|
|
180
189
|
def run
|
190
|
+
jobs_fiber_limit, total_fiber_limit = calculate_fiber_limit
|
181
191
|
job_fibers = []
|
182
192
|
next_job_fibers = []
|
183
193
|
source_fibers = []
|
@@ -187,7 +197,7 @@ module GraphQL
|
|
187
197
|
while first_pass || job_fibers.any?
|
188
198
|
first_pass = false
|
189
199
|
|
190
|
-
while (f = (job_fibers.shift || spawn_job_fiber))
|
200
|
+
while (f = (job_fibers.shift || (((next_job_fibers.size + job_fibers.size) < jobs_fiber_limit) && spawn_job_fiber)))
|
191
201
|
if f.alive?
|
192
202
|
finished = run_fiber(f)
|
193
203
|
if !finished
|
@@ -197,8 +207,8 @@ module GraphQL
|
|
197
207
|
end
|
198
208
|
join_queues(job_fibers, next_job_fibers)
|
199
209
|
|
200
|
-
while source_fibers.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) }
|
201
|
-
while (f = source_fibers.shift || spawn_source_fiber)
|
210
|
+
while (source_fibers.any? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) })
|
211
|
+
while (f = source_fibers.shift || (((job_fibers.size + source_fibers.size + next_source_fibers.size + next_job_fibers.size) < total_fiber_limit) && spawn_source_fiber))
|
202
212
|
if f.alive?
|
203
213
|
finished = run_fiber(f)
|
204
214
|
if !finished
|
@@ -242,6 +252,17 @@ module GraphQL
|
|
242
252
|
|
243
253
|
private
|
244
254
|
|
255
|
+
def calculate_fiber_limit
|
256
|
+
total_fiber_limit = @fiber_limit || Float::INFINITY
|
257
|
+
if total_fiber_limit < 4
|
258
|
+
raise ArgumentError, "Dataloader fiber limit is too low (#{total_fiber_limit}), it must be at least 4"
|
259
|
+
end
|
260
|
+
total_fiber_limit -= 1 # deduct one fiber for `manager`
|
261
|
+
# Deduct at least one fiber for sources
|
262
|
+
jobs_fiber_limit = total_fiber_limit - 2
|
263
|
+
return jobs_fiber_limit, total_fiber_limit
|
264
|
+
end
|
265
|
+
|
245
266
|
def join_queues(prev_queue, new_queue)
|
246
267
|
@nonblocking && Fiber.scheduler.run
|
247
268
|
prev_queue.concat(new_queue)
|
@@ -12,12 +12,16 @@ module GraphQL
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.resolve_each_depth(lazies_at_depth, dataloader)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
smallest_depth = nil
|
16
|
+
lazies_at_depth.each_key do |depth_key|
|
17
|
+
smallest_depth ||= depth_key
|
18
|
+
if depth_key < smallest_depth
|
19
|
+
smallest_depth = depth_key
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if smallest_depth
|
24
|
+
lazies = lazies_at_depth.delete(smallest_depth)
|
21
25
|
if lazies.any?
|
22
26
|
dataloader.append_job {
|
23
27
|
lazies.each(&:value) # resolve these Lazy instances
|
@@ -39,7 +39,7 @@ module GraphQL
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def inspect
|
42
|
-
if (name.nil? || parent_class
|
42
|
+
if (name.nil? || parent_class&.name.nil?) && parent_class.respond_to?(:mutation) && (mutation = parent_class.mutation)
|
43
43
|
"#{mutation.inspect}::#{parent_class.graphql_name}::InvalidNullError"
|
44
44
|
else
|
45
45
|
super
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Language
|
4
|
+
module Comment
|
5
|
+
def self.print(str, indent: '')
|
6
|
+
lines = str.split("\n").map do |line|
|
7
|
+
comment_str = "".dup
|
8
|
+
comment_str << indent
|
9
|
+
comment_str << "# "
|
10
|
+
comment_str << line
|
11
|
+
comment_str.rstrip
|
12
|
+
end
|
13
|
+
|
14
|
+
lines.join("\n") + "\n"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -18,6 +18,7 @@ module GraphQL
|
|
18
18
|
include_built_in_directives: false, include_built_in_scalars: false, always_include_schema: false
|
19
19
|
)
|
20
20
|
@schema = schema
|
21
|
+
@context = context
|
21
22
|
@always_include_schema = always_include_schema
|
22
23
|
@include_introspection_types = include_introspection_types
|
23
24
|
@include_built_in_scalars = include_built_in_scalars
|
@@ -58,6 +59,7 @@ module GraphQL
|
|
58
59
|
|
59
60
|
GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
60
61
|
name: object_type.graphql_name,
|
62
|
+
comment: object_type.comment,
|
61
63
|
interfaces: ints,
|
62
64
|
fields: build_field_nodes(@types.fields(object_type)),
|
63
65
|
description: object_type.description,
|
@@ -68,6 +70,7 @@ module GraphQL
|
|
68
70
|
def build_field_node(field)
|
69
71
|
GraphQL::Language::Nodes::FieldDefinition.new(
|
70
72
|
name: field.graphql_name,
|
73
|
+
comment: field.comment,
|
71
74
|
arguments: build_argument_nodes(@types.arguments(field)),
|
72
75
|
type: build_type_name_node(field.type),
|
73
76
|
description: field.description,
|
@@ -78,6 +81,7 @@ module GraphQL
|
|
78
81
|
def build_union_type_node(union_type)
|
79
82
|
GraphQL::Language::Nodes::UnionTypeDefinition.new(
|
80
83
|
name: union_type.graphql_name,
|
84
|
+
comment: union_type.comment,
|
81
85
|
description: union_type.description,
|
82
86
|
types: @types.possible_types(union_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
83
87
|
directives: directives(union_type),
|
@@ -87,6 +91,7 @@ module GraphQL
|
|
87
91
|
def build_interface_type_node(interface_type)
|
88
92
|
GraphQL::Language::Nodes::InterfaceTypeDefinition.new(
|
89
93
|
name: interface_type.graphql_name,
|
94
|
+
comment: interface_type.comment,
|
90
95
|
interfaces: @types.interfaces(interface_type).sort_by(&:graphql_name).map { |type| build_type_name_node(type) },
|
91
96
|
description: interface_type.description,
|
92
97
|
fields: build_field_nodes(@types.fields(interface_type)),
|
@@ -97,6 +102,7 @@ module GraphQL
|
|
97
102
|
def build_enum_type_node(enum_type)
|
98
103
|
GraphQL::Language::Nodes::EnumTypeDefinition.new(
|
99
104
|
name: enum_type.graphql_name,
|
105
|
+
comment: enum_type.comment,
|
100
106
|
values: @types.enum_values(enum_type).sort_by(&:graphql_name).map do |enum_value|
|
101
107
|
build_enum_value_node(enum_value)
|
102
108
|
end,
|
@@ -108,6 +114,7 @@ module GraphQL
|
|
108
114
|
def build_enum_value_node(enum_value)
|
109
115
|
GraphQL::Language::Nodes::EnumValueDefinition.new(
|
110
116
|
name: enum_value.graphql_name,
|
117
|
+
comment: enum_value.comment,
|
111
118
|
description: enum_value.description,
|
112
119
|
directives: directives(enum_value),
|
113
120
|
)
|
@@ -116,6 +123,7 @@ module GraphQL
|
|
116
123
|
def build_scalar_type_node(scalar_type)
|
117
124
|
GraphQL::Language::Nodes::ScalarTypeDefinition.new(
|
118
125
|
name: scalar_type.graphql_name,
|
126
|
+
comment: scalar_type.comment,
|
119
127
|
description: scalar_type.description,
|
120
128
|
directives: directives(scalar_type),
|
121
129
|
)
|
@@ -130,6 +138,7 @@ module GraphQL
|
|
130
138
|
|
131
139
|
argument_node = GraphQL::Language::Nodes::InputValueDefinition.new(
|
132
140
|
name: argument.graphql_name,
|
141
|
+
comment: argument.comment,
|
133
142
|
description: argument.description,
|
134
143
|
type: build_type_name_node(argument.type),
|
135
144
|
default_value: default_value,
|
@@ -142,6 +151,7 @@ module GraphQL
|
|
142
151
|
def build_input_object_node(input_object)
|
143
152
|
GraphQL::Language::Nodes::InputObjectTypeDefinition.new(
|
144
153
|
name: input_object.graphql_name,
|
154
|
+
comment: input_object.comment,
|
145
155
|
fields: build_argument_nodes(@types.arguments(input_object)),
|
146
156
|
description: input_object.description,
|
147
157
|
directives: directives(input_object),
|
@@ -259,7 +269,33 @@ module GraphQL
|
|
259
269
|
end
|
260
270
|
definitions = build_directive_nodes(dirs_to_build)
|
261
271
|
all_types = @types.all_types
|
262
|
-
type_nodes = build_type_definition_nodes(all_types
|
272
|
+
type_nodes = build_type_definition_nodes(all_types)
|
273
|
+
|
274
|
+
if (ex_t = schema.extra_types).any?
|
275
|
+
dummy_query = Class.new(GraphQL::Schema::Object) do
|
276
|
+
graphql_name "DummyQuery"
|
277
|
+
(all_types + ex_t).each_with_index do |type, idx|
|
278
|
+
if !type.kind.input_object? && !type.introspection?
|
279
|
+
field "f#{idx}", type
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
extra_types_schema = Class.new(GraphQL::Schema) do
|
285
|
+
query(dummy_query)
|
286
|
+
end
|
287
|
+
|
288
|
+
extra_types_types = GraphQL::Query.new(extra_types_schema, "{ __typename }", context: @context).types # rubocop:disable Development/ContextIsPassedCop
|
289
|
+
# Temporarily replace `@types` with something from this example schema.
|
290
|
+
# It'd be much nicer to pass this in, but that would be a big refactor :S
|
291
|
+
prev_types = @types
|
292
|
+
@types = extra_types_types
|
293
|
+
type_nodes += build_type_definition_nodes(ex_t)
|
294
|
+
@types = prev_types
|
295
|
+
end
|
296
|
+
|
297
|
+
type_nodes.sort_by!(&:name)
|
298
|
+
|
263
299
|
if @include_one_of
|
264
300
|
# This may have been set to true when iterating over all types
|
265
301
|
definitions.concat(build_directive_nodes([GraphQL::Schema::Directive::OneOf]))
|
@@ -282,9 +318,7 @@ module GraphQL
|
|
282
318
|
types = types.reject { |type| type.kind.scalar? && type.default_scalar? }
|
283
319
|
end
|
284
320
|
|
285
|
-
types
|
286
|
-
.map { |type| build_type_definition_node(type) }
|
287
|
-
.sort_by(&:name)
|
321
|
+
types.map { |type| build_type_definition_node(type) }
|
288
322
|
end
|
289
323
|
|
290
324
|
def build_field_nodes(fields)
|
@@ -19,7 +19,7 @@ module GraphQL
|
|
19
19
|
@scanner.eos?
|
20
20
|
end
|
21
21
|
|
22
|
-
attr_reader :pos
|
22
|
+
attr_reader :pos, :tokens_count
|
23
23
|
|
24
24
|
def advance
|
25
25
|
@scanner.skip(IGNORE_REGEXP)
|
@@ -57,20 +57,23 @@ module GraphQL
|
|
57
57
|
@scanner.skip(IDENTIFIER_REGEXP)
|
58
58
|
:IDENTIFIER
|
59
59
|
when ByteFor::NUMBER
|
60
|
-
@scanner.skip(NUMERIC_REGEXP)
|
60
|
+
if len = @scanner.skip(NUMERIC_REGEXP)
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
if GraphQL.reject_numbers_followed_by_names
|
63
|
+
new_pos = @scanner.pos
|
64
|
+
peek_byte = @string.getbyte(new_pos)
|
65
|
+
next_first_byte = FIRST_BYTES[peek_byte]
|
66
|
+
if next_first_byte == ByteFor::NAME || next_first_byte == ByteFor::IDENTIFIER
|
67
|
+
number_part = token_value
|
68
|
+
name_part = @scanner.scan(IDENTIFIER_REGEXP)
|
69
|
+
raise_parse_error("Name after number is not allowed (in `#{number_part}#{name_part}`)")
|
70
|
+
end
|
70
71
|
end
|
72
|
+
# Check for a matched decimal:
|
73
|
+
@scanner[1] ? :FLOAT : :INT
|
74
|
+
else
|
75
|
+
raise_parse_error("Expected a number, but it was malformed (#{@string[@pos].inspect})")
|
71
76
|
end
|
72
|
-
# Check for a matched decimal:
|
73
|
-
@scanner[1] ? :FLOAT : :INT
|
74
77
|
when ByteFor::ELLIPSIS
|
75
78
|
if @string.getbyte(@pos + 1) != 46 || @string.getbyte(@pos + 2) != 46
|
76
79
|
raise_parse_error("Expected `...`, actual: #{@string[@pos..@pos + 2].inspect}")
|
@@ -270,15 +270,17 @@ module GraphQL
|
|
270
270
|
"col: nil",
|
271
271
|
"pos: nil",
|
272
272
|
"filename: nil",
|
273
|
-
"source: nil"
|
273
|
+
"source: nil"
|
274
274
|
]
|
275
275
|
|
276
|
+
IGNORED_MARSHALLING_KEYWORDS = [:comment]
|
277
|
+
|
276
278
|
def generate_initialize
|
277
279
|
return if method_defined?(:marshal_load, false) # checking for `:initialize` doesn't work right
|
278
280
|
|
279
281
|
scalar_method_names = @scalar_methods
|
280
282
|
# TODO: These probably should be scalar methods, but `types` returns an array
|
281
|
-
[:types, :description].each do |extra_method|
|
283
|
+
[:types, :description, :comment].each do |extra_method|
|
282
284
|
if method_defined?(extra_method)
|
283
285
|
scalar_method_names += [extra_method]
|
284
286
|
end
|
@@ -307,6 +309,12 @@ module GraphQL
|
|
307
309
|
keywords = scalar_method_names.map { |m| "#{m}: #{m}"} +
|
308
310
|
children_method_names.map { |m| "#{m}: #{m}" }
|
309
311
|
|
312
|
+
ignored_keywords = IGNORED_MARSHALLING_KEYWORDS.map do |keyword|
|
313
|
+
"#{keyword.to_s}: nil"
|
314
|
+
end
|
315
|
+
|
316
|
+
marshalling_method_names = all_method_names - IGNORED_MARSHALLING_KEYWORDS
|
317
|
+
|
310
318
|
module_eval <<-RUBY, __FILE__, __LINE__
|
311
319
|
def initialize(#{arguments.join(", ")})
|
312
320
|
@line = line
|
@@ -317,7 +325,7 @@ module GraphQL
|
|
317
325
|
#{assignments.join("\n")}
|
318
326
|
end
|
319
327
|
|
320
|
-
def self.from_a(filename, line, col, #{
|
328
|
+
def self.from_a(filename, line, col, #{marshalling_method_names.join(", ")}, #{ignored_keywords.join(", ")})
|
321
329
|
self.new(filename: filename, line: line, col: col, #{keywords.join(", ")})
|
322
330
|
end
|
323
331
|
|
@@ -325,12 +333,12 @@ module GraphQL
|
|
325
333
|
[
|
326
334
|
line, col, # use methods here to force them to be calculated
|
327
335
|
@filename,
|
328
|
-
#{
|
336
|
+
#{marshalling_method_names.map { |n| "@#{n}," }.join}
|
329
337
|
]
|
330
338
|
end
|
331
339
|
|
332
340
|
def marshal_load(values)
|
333
|
-
@line, @col, @filename #{
|
341
|
+
@line, @col, @filename #{marshalling_method_names.map { |n| ", @#{n}"}.join} = values
|
334
342
|
end
|
335
343
|
RUBY
|
336
344
|
end
|
@@ -635,7 +643,7 @@ module GraphQL
|
|
635
643
|
end
|
636
644
|
|
637
645
|
class ScalarTypeDefinition < AbstractNode
|
638
|
-
attr_reader :description
|
646
|
+
attr_reader :description, :comment
|
639
647
|
scalar_methods :name
|
640
648
|
children_methods({
|
641
649
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -652,7 +660,7 @@ module GraphQL
|
|
652
660
|
end
|
653
661
|
|
654
662
|
class InputValueDefinition < AbstractNode
|
655
|
-
attr_reader :description
|
663
|
+
attr_reader :description, :comment
|
656
664
|
scalar_methods :name, :type, :default_value
|
657
665
|
children_methods({
|
658
666
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -661,7 +669,7 @@ module GraphQL
|
|
661
669
|
end
|
662
670
|
|
663
671
|
class FieldDefinition < AbstractNode
|
664
|
-
attr_reader :description
|
672
|
+
attr_reader :description, :comment
|
665
673
|
scalar_methods :name, :type
|
666
674
|
children_methods({
|
667
675
|
arguments: GraphQL::Language::Nodes::InputValueDefinition,
|
@@ -681,7 +689,7 @@ module GraphQL
|
|
681
689
|
end
|
682
690
|
|
683
691
|
class ObjectTypeDefinition < AbstractNode
|
684
|
-
attr_reader :description
|
692
|
+
attr_reader :description, :comment
|
685
693
|
scalar_methods :name, :interfaces
|
686
694
|
children_methods({
|
687
695
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -700,7 +708,7 @@ module GraphQL
|
|
700
708
|
end
|
701
709
|
|
702
710
|
class InterfaceTypeDefinition < AbstractNode
|
703
|
-
attr_reader :description
|
711
|
+
attr_reader :description, :comment
|
704
712
|
scalar_methods :name
|
705
713
|
children_methods({
|
706
714
|
interfaces: GraphQL::Language::Nodes::TypeName,
|
@@ -721,7 +729,7 @@ module GraphQL
|
|
721
729
|
end
|
722
730
|
|
723
731
|
class UnionTypeDefinition < AbstractNode
|
724
|
-
attr_reader :description, :types
|
732
|
+
attr_reader :description, :comment, :types
|
725
733
|
scalar_methods :name
|
726
734
|
children_methods({
|
727
735
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -739,7 +747,7 @@ module GraphQL
|
|
739
747
|
end
|
740
748
|
|
741
749
|
class EnumValueDefinition < AbstractNode
|
742
|
-
attr_reader :description
|
750
|
+
attr_reader :description, :comment
|
743
751
|
scalar_methods :name
|
744
752
|
children_methods({
|
745
753
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -748,7 +756,7 @@ module GraphQL
|
|
748
756
|
end
|
749
757
|
|
750
758
|
class EnumTypeDefinition < AbstractNode
|
751
|
-
attr_reader :description
|
759
|
+
attr_reader :description, :comment
|
752
760
|
scalar_methods :name
|
753
761
|
children_methods({
|
754
762
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -767,7 +775,7 @@ module GraphQL
|
|
767
775
|
end
|
768
776
|
|
769
777
|
class InputObjectTypeDefinition < AbstractNode
|
770
|
-
attr_reader :description
|
778
|
+
attr_reader :description, :comment
|
771
779
|
scalar_methods :name
|
772
780
|
children_methods({
|
773
781
|
directives: GraphQL::Language::Nodes::Directive,
|
@@ -255,14 +255,14 @@ module GraphQL
|
|
255
255
|
|
256
256
|
|
257
257
|
def print_scalar_type_definition(scalar_type, extension: false)
|
258
|
-
extension ? print_string("extend ") :
|
258
|
+
extension ? print_string("extend ") : print_description_and_comment(scalar_type)
|
259
259
|
print_string("scalar ")
|
260
260
|
print_string(scalar_type.name)
|
261
261
|
print_directives(scalar_type.directives)
|
262
262
|
end
|
263
263
|
|
264
264
|
def print_object_type_definition(object_type, extension: false)
|
265
|
-
extension ? print_string("extend ") :
|
265
|
+
extension ? print_string("extend ") : print_description_and_comment(object_type)
|
266
266
|
print_string("type ")
|
267
267
|
print_string(object_type.name)
|
268
268
|
print_implements(object_type) unless object_type.interfaces.empty?
|
@@ -294,7 +294,7 @@ module GraphQL
|
|
294
294
|
end
|
295
295
|
|
296
296
|
def print_arguments(arguments, indent: "")
|
297
|
-
if arguments.all? { |arg| !arg.description }
|
297
|
+
if arguments.all? { |arg| !arg.description && !arg.comment }
|
298
298
|
print_string("(")
|
299
299
|
arguments.each_with_index do |arg, i|
|
300
300
|
print_input_value_definition(arg)
|
@@ -306,6 +306,7 @@ module GraphQL
|
|
306
306
|
|
307
307
|
print_string("(\n")
|
308
308
|
arguments.each_with_index do |arg, i|
|
309
|
+
print_comment(arg, indent: " " + indent, first_in_block: i == 0)
|
309
310
|
print_description(arg, indent: " " + indent, first_in_block: i == 0)
|
310
311
|
print_string(" ")
|
311
312
|
print_string(indent)
|
@@ -328,7 +329,7 @@ module GraphQL
|
|
328
329
|
end
|
329
330
|
|
330
331
|
def print_interface_type_definition(interface_type, extension: false)
|
331
|
-
extension ? print_string("extend ") :
|
332
|
+
extension ? print_string("extend ") : print_description_and_comment(interface_type)
|
332
333
|
print_string("interface ")
|
333
334
|
print_string(interface_type.name)
|
334
335
|
print_implements(interface_type) if interface_type.interfaces.any?
|
@@ -337,7 +338,7 @@ module GraphQL
|
|
337
338
|
end
|
338
339
|
|
339
340
|
def print_union_type_definition(union_type, extension: false)
|
340
|
-
extension ? print_string("extend ") :
|
341
|
+
extension ? print_string("extend ") : print_description_and_comment(union_type)
|
341
342
|
print_string("union ")
|
342
343
|
print_string(union_type.name)
|
343
344
|
print_directives(union_type.directives)
|
@@ -355,7 +356,7 @@ module GraphQL
|
|
355
356
|
end
|
356
357
|
|
357
358
|
def print_enum_type_definition(enum_type, extension: false)
|
358
|
-
extension ? print_string("extend ") :
|
359
|
+
extension ? print_string("extend ") : print_description_and_comment(enum_type)
|
359
360
|
print_string("enum ")
|
360
361
|
print_string(enum_type.name)
|
361
362
|
print_directives(enum_type.directives)
|
@@ -363,6 +364,7 @@ module GraphQL
|
|
363
364
|
print_string(" {\n")
|
364
365
|
enum_type.values.each.with_index do |value, i|
|
365
366
|
print_description(value, indent: " ", first_in_block: i == 0)
|
367
|
+
print_comment(value, indent: " ", first_in_block: i == 0)
|
366
368
|
print_enum_value_definition(value)
|
367
369
|
end
|
368
370
|
print_string("}")
|
@@ -377,7 +379,7 @@ module GraphQL
|
|
377
379
|
end
|
378
380
|
|
379
381
|
def print_input_object_type_definition(input_object_type, extension: false)
|
380
|
-
extension ? print_string("extend ") :
|
382
|
+
extension ? print_string("extend ") : print_description_and_comment(input_object_type)
|
381
383
|
print_string("input ")
|
382
384
|
print_string(input_object_type.name)
|
383
385
|
print_directives(input_object_type.directives)
|
@@ -385,6 +387,7 @@ module GraphQL
|
|
385
387
|
print_string(" {\n")
|
386
388
|
input_object_type.fields.each.with_index do |field, i|
|
387
389
|
print_description(field, indent: " ", first_in_block: i == 0)
|
390
|
+
print_comment(field, indent: " ", first_in_block: i == 0)
|
388
391
|
print_string(" ")
|
389
392
|
print_input_value_definition(field)
|
390
393
|
print_string("\n")
|
@@ -424,6 +427,18 @@ module GraphQL
|
|
424
427
|
print_string(GraphQL::Language::BlockString.print(node.description, indent: indent))
|
425
428
|
end
|
426
429
|
|
430
|
+
def print_comment(node, indent: "", first_in_block: true)
|
431
|
+
return unless node.comment
|
432
|
+
|
433
|
+
print_string("\n") if indent != "" && !first_in_block
|
434
|
+
print_string(GraphQL::Language::Comment.print(node.comment, indent: indent))
|
435
|
+
end
|
436
|
+
|
437
|
+
def print_description_and_comment(node)
|
438
|
+
print_description(node)
|
439
|
+
print_comment(node)
|
440
|
+
end
|
441
|
+
|
427
442
|
def print_field_definitions(fields)
|
428
443
|
return if fields.empty?
|
429
444
|
|
@@ -431,6 +446,7 @@ module GraphQL
|
|
431
446
|
i = 0
|
432
447
|
fields.each do |field|
|
433
448
|
print_description(field, indent: " ", first_in_block: i == 0)
|
449
|
+
print_comment(field, indent: " ", first_in_block: i == 0)
|
434
450
|
print_string(" ")
|
435
451
|
print_field_definition(field)
|
436
452
|
print_string("\n")
|