lighthouse-graphql 0.1.1 → 0.2.0
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/CHANGELOG.md +154 -1
- data/README.md +42 -2
- data/docs/authorization.md +116 -57
- data/docs/best-practices.md +16 -3
- data/docs/caching.md +161 -0
- data/docs/configuration.md +83 -4
- data/docs/custom-directives.md +5 -1
- data/docs/directives.md +117 -38
- data/docs/getting-started.md +84 -0
- data/docs/mutations.md +260 -0
- data/docs/performance.md +138 -0
- data/docs/relationships.md +80 -33
- data/docs/resolvers.md +179 -0
- data/docs/validation.md +132 -0
- data/lib/generators/lighthouse/builder_generator.rb +30 -0
- data/lib/generators/lighthouse/class_generator.rb +61 -0
- data/lib/generators/lighthouse/install/install_generator.rb +127 -0
- data/lib/generators/lighthouse/install/templates/graphql.config.yml.tt +8 -0
- data/lib/generators/lighthouse/install/templates/graphql_controller.rb.tt +57 -0
- data/lib/generators/lighthouse/install/templates/initializer.rb.tt +67 -0
- data/lib/generators/lighthouse/install/templates/schema.graphql.tt +19 -0
- data/lib/generators/lighthouse/install/templates/schema.rb.tt +10 -0
- data/lib/generators/lighthouse/mutation_generator.rb +30 -0
- data/lib/generators/lighthouse/query_generator.rb +29 -0
- data/lib/generators/lighthouse/validator_generator.rb +36 -0
- data/lib/lighthouse/cache_control.rb +126 -0
- data/lib/lighthouse/caching.rb +68 -0
- data/lib/lighthouse/config.rb +85 -19
- data/lib/lighthouse/contracts/arg_builder.rb +8 -12
- data/lib/lighthouse/contracts/arg_manipulator.rb +8 -12
- data/lib/lighthouse/contracts/directive.rb +10 -14
- data/lib/lighthouse/contracts/field_manipulator.rb +8 -12
- data/lib/lighthouse/contracts/field_middleware.rb +7 -11
- data/lib/lighthouse/contracts/field_resolver.rb +9 -13
- data/lib/lighthouse/dataloader_sources/association_loader.rb +28 -19
- data/lib/lighthouse/dataloader_sources/model_loader.rb +10 -14
- data/lib/lighthouse/dataloader_sources/relation_count_loader.rb +16 -0
- data/lib/lighthouse/dataloader_sources/relation_page_loader.rb +18 -0
- data/lib/lighthouse/directive_resolvers/aggregate_resolver.rb +57 -69
- data/lib/lighthouse/directive_resolvers/all_resolver.rb +26 -57
- data/lib/lighthouse/directive_resolvers/association_resolvers.rb +161 -0
- data/lib/lighthouse/directive_resolvers/auth_resolver.rb +41 -38
- data/lib/lighthouse/directive_resolvers/base.rb +142 -86
- data/lib/lighthouse/directive_resolvers/builder_applier.rb +58 -56
- data/lib/lighthouse/directive_resolvers/cache_resolvers.rb +133 -0
- data/lib/lighthouse/directive_resolvers/can_resolvers.rb +177 -0
- data/lib/lighthouse/directive_resolvers/convention_resolver.rb +70 -0
- data/lib/lighthouse/directive_resolvers/count_resolver.rb +42 -48
- data/lib/lighthouse/directive_resolvers/field_resolver.rb +27 -68
- data/lib/lighthouse/directive_resolvers/find_resolver.rb +42 -52
- data/lib/lighthouse/directive_resolvers/first_resolver.rb +39 -45
- data/lib/lighthouse/directive_resolvers/guard_resolver.rb +16 -22
- data/lib/lighthouse/directive_resolvers/method_resolver.rb +19 -25
- data/lib/lighthouse/directive_resolvers/model_mutation_resolver.rb +219 -0
- data/lib/lighthouse/directive_resolvers/paginate_resolver.rb +70 -128
- data/lib/lighthouse/directive_resolvers/rename_resolver.rb +18 -24
- data/lib/lighthouse/directive_resolvers/resolution.rb +31 -27
- data/lib/lighthouse/directive_resolvers/validator_resolver.rb +193 -0
- data/lib/lighthouse/directive_resolvers/where_conditions_applier.rb +164 -163
- data/lib/lighthouse/directives/arguments/base.rb +23 -31
- data/lib/lighthouse/directives/arguments/filters.rb +113 -93
- data/lib/lighthouse/directives/arguments/order_by.rb +41 -41
- data/lib/lighthouse/directives/pagination_info_types.rb +69 -0
- data/lib/lighthouse/directives/pagination_manipulator.rb +176 -0
- data/lib/lighthouse/directives/registry.rb +210 -141
- data/lib/lighthouse/directives/where_conditions_directive.rb +236 -200
- data/lib/lighthouse/errors.rb +27 -0
- data/lib/lighthouse/federation_directives.rb +53 -0
- data/lib/lighthouse/field_resolver_stack.rb +56 -0
- data/lib/lighthouse/generated_resolvers.rb +82 -0
- data/lib/lighthouse/graphql/version.rb +1 -1
- data/lib/lighthouse/graphql_ruby_patches.rb +18 -0
- data/lib/lighthouse/ide_helper.rb +98 -0
- data/lib/lighthouse/namespaces.rb +21 -0
- data/lib/lighthouse/nested_mutations/belongs_to_operations.rb +50 -0
- data/lib/lighthouse/nested_mutations/executor.rb +149 -0
- data/lib/lighthouse/nested_mutations/has_operations.rb +66 -0
- data/lib/lighthouse/nested_mutations/many_to_many_operations.rb +44 -0
- data/lib/lighthouse/nested_mutations/partitioner.rb +125 -0
- data/lib/lighthouse/nested_mutations.rb +210 -0
- data/lib/lighthouse/pagination.rb +221 -0
- data/lib/lighthouse/persisted_queries.rb +167 -0
- data/lib/lighthouse/railtie.rb +26 -0
- data/lib/lighthouse/rb_lighthouse.rb +50 -29
- data/lib/lighthouse/reference_resolver.rb +13 -15
- data/lib/lighthouse/relation_batch.rb +156 -0
- data/lib/lighthouse/resolver_dispatch.rb +26 -0
- data/lib/lighthouse/schema_cache.rb +120 -0
- data/lib/lighthouse/schema_factory.rb +27 -37
- data/lib/lighthouse/schema_generator.rb +196 -239
- data/lib/lighthouse/schema_implementation.rb +51 -48
- data/lib/lighthouse/sdl_loader.rb +17 -20
- data/lib/lighthouse/support/arguments.rb +119 -0
- data/lib/lighthouse/support/authorization.rb +18 -19
- data/lib/lighthouse/support/batching.rb +16 -0
- data/lib/lighthouse/support/directive_args.rb +26 -24
- data/lib/lighthouse/support/model_resolver.rb +56 -56
- data/lib/lighthouse/support/naming.rb +55 -59
- data/lib/lighthouse/tasks/lighthouse.rake +33 -0
- data/lib/lighthouse/where_conditions/operator_map.rb +25 -29
- metadata +51 -63
- data/lib/lighthouse/directive_resolvers/belongs_to_many_resolver.rb +0 -56
- data/lib/lighthouse/directive_resolvers/belongs_to_resolver.rb +0 -47
- data/lib/lighthouse/directive_resolvers/can_resolver.rb +0 -86
- data/lib/lighthouse/directive_resolvers/has_many_resolver.rb +0 -109
- data/lib/lighthouse/directive_resolvers/has_one_resolver.rb +0 -43
- data/lib/lighthouse/directives/relation_directive.rb +0 -332
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Lighthouse
|
|
4
|
-
module GraphQL
|
|
5
|
-
module Directives
|
|
6
|
-
# AST transformer that converts list-typed relationship fields annotated
|
|
7
|
-
# with relationship directives (e.g. @hasMany, @paginate) into
|
|
8
|
-
# Connection/Paginator return types and injects pagination arguments.
|
|
9
|
-
class RelationDirective
|
|
10
|
-
DIRECTIVE_NAMES = %w[hasMany belongsToMany hasManyThrough paginate all].freeze
|
|
11
|
-
|
|
12
|
-
def self.manipulate(sdl)
|
|
13
|
-
return sdl unless sdl.is_a?(String) && !sdl.empty?
|
|
14
|
-
|
|
15
|
-
begin
|
|
16
|
-
document = ::GraphQL::Language::Parser.parse(sdl)
|
|
17
|
-
rescue StandardError => e
|
|
18
|
-
warn("Lighthouse::GraphQL::Directives::RelationDirective: parse failed: #{e.class}: #{e.message}")
|
|
19
|
-
return sdl
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
existing_def_names = document.definitions.filter_map { |d| d.respond_to?(:name) ? d.name : nil }
|
|
23
|
-
produced_inner_types = []
|
|
24
|
-
|
|
25
|
-
document.definitions.each do |definition|
|
|
26
|
-
next unless definition.is_a?(::GraphQL::Language::Nodes::ObjectTypeDefinition)
|
|
27
|
-
|
|
28
|
-
definition.fields.each do |field|
|
|
29
|
-
next unless field.type
|
|
30
|
-
next if field.directives.nil? || field.directives.empty?
|
|
31
|
-
next unless field.directives.any? { |d| DIRECTIVE_NAMES.include?(d.name) }
|
|
32
|
-
|
|
33
|
-
list_inner = list_inner_named_type(field.type)
|
|
34
|
-
next unless list_inner
|
|
35
|
-
|
|
36
|
-
produce_connection, produce_paginator = pagination_kind_for(field.directives)
|
|
37
|
-
next unless produce_connection || produce_paginator
|
|
38
|
-
|
|
39
|
-
produced_inner_types << list_inner unless produced_inner_types.include?(list_inner)
|
|
40
|
-
|
|
41
|
-
# Replace list type with Connection/Paginator return type, preserving outer nullability.
|
|
42
|
-
new_named_type =
|
|
43
|
-
if produce_connection
|
|
44
|
-
"#{list_inner}Connection"
|
|
45
|
-
else
|
|
46
|
-
"#{list_inner}Paginator"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
field.instance_variable_set(:@type, replace_with_named_type(field.type, new_named_type))
|
|
50
|
-
|
|
51
|
-
if produce_connection
|
|
52
|
-
field.instance_variable_set(:@arguments, ensure_connection_arguments(field.arguments || []))
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
return sdl if produced_inner_types.empty?
|
|
58
|
-
|
|
59
|
-
# Add Connection/Edge/Paginator utility types where missing.
|
|
60
|
-
new_defs = []
|
|
61
|
-
produced_inner_types.each do |inner|
|
|
62
|
-
conn_name = "#{inner}Connection"
|
|
63
|
-
edge_name = "#{inner}Edge"
|
|
64
|
-
paginator_name = "#{inner}Paginator"
|
|
65
|
-
|
|
66
|
-
unless existing_def_names.include?(conn_name)
|
|
67
|
-
new_defs << build_connection_type(conn_name, edge_name, inner)
|
|
68
|
-
existing_def_names << conn_name
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
unless existing_def_names.include?(edge_name)
|
|
72
|
-
new_defs << build_edge_type(edge_name, inner)
|
|
73
|
-
existing_def_names << edge_name
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
unless existing_def_names.include?(paginator_name)
|
|
77
|
-
new_defs << build_paginator_type(paginator_name, inner)
|
|
78
|
-
existing_def_names << paginator_name
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
unless existing_def_names.include?('PaginatorInfo')
|
|
83
|
-
new_defs << build_paginator_info_type
|
|
84
|
-
existing_def_names << 'PaginatorInfo'
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
unless existing_def_names.include?('PageInfo')
|
|
88
|
-
new_defs << build_page_info_type
|
|
89
|
-
existing_def_names << 'PageInfo'
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
modified_sdl = ::GraphQL::Language::Printer.new.print(document)
|
|
93
|
-
modified_sdl + "\n\n" + new_defs.map { |d| ::GraphQL::Language::Printer.new.print(d) }.join("\n\n")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def self.pagination_kind_for(directives)
|
|
97
|
-
# For relation directives, always use Connection.
|
|
98
|
-
if directives.any? { |d| d.name != 'paginate' && DIRECTIVE_NAMES.include?(d.name) }
|
|
99
|
-
return [true, false]
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
paginate = directives.find { |d| d.name == 'paginate' }
|
|
103
|
-
return [false, false] unless paginate
|
|
104
|
-
|
|
105
|
-
type_arg = directive_arg_literal(paginate, 'type')&.to_s&.upcase
|
|
106
|
-
if %w[CONNECTION CURSOR].include?(type_arg)
|
|
107
|
-
[true, false]
|
|
108
|
-
else
|
|
109
|
-
[false, true]
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def self.directive_arg_literal(directive, name)
|
|
114
|
-
arg = directive.arguments&.find { |a| a.name == name }
|
|
115
|
-
return nil unless arg
|
|
116
|
-
arg.value.respond_to?(:value) ? arg.value.value : arg.value
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def self.list_inner_named_type(type_node)
|
|
120
|
-
case type_node
|
|
121
|
-
when ::GraphQL::Language::Nodes::NonNullType
|
|
122
|
-
list_inner_named_type(type_node.of_type)
|
|
123
|
-
when ::GraphQL::Language::Nodes::ListType
|
|
124
|
-
unwrap_named_type(type_node.of_type)
|
|
125
|
-
else
|
|
126
|
-
nil
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def self.unwrap_named_type(type_node)
|
|
131
|
-
case type_node
|
|
132
|
-
when ::GraphQL::Language::Nodes::NonNullType
|
|
133
|
-
unwrap_named_type(type_node.of_type)
|
|
134
|
-
when ::GraphQL::Language::Nodes::TypeName
|
|
135
|
-
type_node.name
|
|
136
|
-
else
|
|
137
|
-
nil
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def self.replace_with_named_type(type_node, new_name)
|
|
142
|
-
new_type = ::GraphQL::Language::Nodes::TypeName.new(name: new_name)
|
|
143
|
-
if type_node.is_a?(::GraphQL::Language::Nodes::NonNullType)
|
|
144
|
-
::GraphQL::Language::Nodes::NonNullType.new(of_type: new_type)
|
|
145
|
-
else
|
|
146
|
-
new_type
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def self.ensure_connection_arguments(existing_args)
|
|
151
|
-
existing_names = existing_args.map(&:name)
|
|
152
|
-
args = existing_args.map do |arg|
|
|
153
|
-
next arg unless %w[after before first last].include?(arg.name)
|
|
154
|
-
next arg if arg.description && !arg.description.empty?
|
|
155
|
-
|
|
156
|
-
::GraphQL::Language::Nodes::InputValueDefinition.new(
|
|
157
|
-
name: arg.name,
|
|
158
|
-
type: arg.type,
|
|
159
|
-
directives: arg.directives || [],
|
|
160
|
-
default_value: arg.default_value,
|
|
161
|
-
description: connection_arg_description(arg.name)
|
|
162
|
-
)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
%w[after before first last].each do |name|
|
|
166
|
-
next if existing_names.include?(name)
|
|
167
|
-
|
|
168
|
-
type =
|
|
169
|
-
if %w[first last].include?(name)
|
|
170
|
-
::GraphQL::Language::Nodes::TypeName.new(name: 'Int')
|
|
171
|
-
else
|
|
172
|
-
::GraphQL::Language::Nodes::TypeName.new(name: 'String')
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
args << ::GraphQL::Language::Nodes::InputValueDefinition.new(
|
|
176
|
-
name: name,
|
|
177
|
-
type: type,
|
|
178
|
-
directives: [],
|
|
179
|
-
default_value: nil,
|
|
180
|
-
description: connection_arg_description(name)
|
|
181
|
-
)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
args
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def self.build_connection_type(conn_name, edge_name, node_name)
|
|
188
|
-
::GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
|
189
|
-
name: conn_name,
|
|
190
|
-
interfaces: [],
|
|
191
|
-
directives: [],
|
|
192
|
-
description: "The connection type for #{node_name}.",
|
|
193
|
-
fields: [
|
|
194
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
195
|
-
name: 'edges',
|
|
196
|
-
type: ::GraphQL::Language::Nodes::ListType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: edge_name)),
|
|
197
|
-
arguments: [],
|
|
198
|
-
directives: [],
|
|
199
|
-
description: 'A list of edges.'
|
|
200
|
-
),
|
|
201
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
202
|
-
name: 'nodes',
|
|
203
|
-
type: ::GraphQL::Language::Nodes::ListType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: node_name)),
|
|
204
|
-
arguments: [],
|
|
205
|
-
directives: [],
|
|
206
|
-
description: 'A list of nodes.'
|
|
207
|
-
),
|
|
208
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
209
|
-
name: 'pageInfo',
|
|
210
|
-
type: ::GraphQL::Language::Nodes::NonNullType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: 'PageInfo')),
|
|
211
|
-
arguments: [],
|
|
212
|
-
directives: [],
|
|
213
|
-
description: 'Information to aid in pagination.'
|
|
214
|
-
)
|
|
215
|
-
]
|
|
216
|
-
)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def self.build_edge_type(edge_name, node_name)
|
|
220
|
-
::GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
|
221
|
-
name: edge_name,
|
|
222
|
-
interfaces: [],
|
|
223
|
-
directives: [],
|
|
224
|
-
description: 'An edge in a connection.',
|
|
225
|
-
fields: [
|
|
226
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
227
|
-
name: 'cursor',
|
|
228
|
-
type: ::GraphQL::Language::Nodes::NonNullType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: 'String')),
|
|
229
|
-
arguments: [],
|
|
230
|
-
directives: [],
|
|
231
|
-
description: 'A cursor for use in pagination.'
|
|
232
|
-
),
|
|
233
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
234
|
-
name: 'node',
|
|
235
|
-
type: ::GraphQL::Language::Nodes::TypeName.new(name: node_name),
|
|
236
|
-
arguments: [],
|
|
237
|
-
directives: [],
|
|
238
|
-
description: 'The item at the end of the edge.'
|
|
239
|
-
)
|
|
240
|
-
]
|
|
241
|
-
)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def self.build_paginator_type(paginator_name, inner_name)
|
|
245
|
-
::GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
|
246
|
-
name: paginator_name,
|
|
247
|
-
interfaces: [],
|
|
248
|
-
directives: [],
|
|
249
|
-
description: "A paginated list of #{inner_name} items.",
|
|
250
|
-
fields: [
|
|
251
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
252
|
-
name: 'paginatorInfo',
|
|
253
|
-
type: ::GraphQL::Language::Nodes::NonNullType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: 'PaginatorInfo')),
|
|
254
|
-
arguments: [],
|
|
255
|
-
directives: [],
|
|
256
|
-
description: 'Pagination information about the list of items.'
|
|
257
|
-
),
|
|
258
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
259
|
-
name: 'data',
|
|
260
|
-
type: ::GraphQL::Language::Nodes::ListType.new(of_type: ::GraphQL::Language::Nodes::TypeName.new(name: inner_name)),
|
|
261
|
-
arguments: [],
|
|
262
|
-
directives: [],
|
|
263
|
-
description: "A list of #{inner_name} items."
|
|
264
|
-
)
|
|
265
|
-
]
|
|
266
|
-
)
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def self.build_paginator_info_type
|
|
270
|
-
::GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
|
271
|
-
name: 'PaginatorInfo',
|
|
272
|
-
interfaces: [],
|
|
273
|
-
directives: [],
|
|
274
|
-
description: 'Information about pagination in a paginator.',
|
|
275
|
-
fields: [
|
|
276
|
-
field_def('count', 'Int', non_null: true),
|
|
277
|
-
field_def('currentPage', 'Int', non_null: true),
|
|
278
|
-
field_def('firstItem', 'Int'),
|
|
279
|
-
field_def('hasMorePages', 'Boolean', non_null: true),
|
|
280
|
-
field_def('lastItem', 'Int'),
|
|
281
|
-
field_def('lastPage', 'Int', non_null: true),
|
|
282
|
-
field_def('perPage', 'Int', non_null: true),
|
|
283
|
-
field_def('total', 'Int', non_null: true)
|
|
284
|
-
]
|
|
285
|
-
)
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def self.build_page_info_type
|
|
289
|
-
# Minimal Relay PageInfo. GraphQL-Ruby can also supply this via Relay,
|
|
290
|
-
# but SDL-first apps may not include it.
|
|
291
|
-
::GraphQL::Language::Nodes::ObjectTypeDefinition.new(
|
|
292
|
-
name: 'PageInfo',
|
|
293
|
-
interfaces: [],
|
|
294
|
-
directives: [],
|
|
295
|
-
description: nil,
|
|
296
|
-
fields: [
|
|
297
|
-
field_def('hasNextPage', 'Boolean', non_null: true),
|
|
298
|
-
field_def('hasPreviousPage', 'Boolean', non_null: true),
|
|
299
|
-
field_def('startCursor', 'String'),
|
|
300
|
-
field_def('endCursor', 'String')
|
|
301
|
-
]
|
|
302
|
-
)
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def self.field_def(name, type_name, non_null: false)
|
|
306
|
-
type = ::GraphQL::Language::Nodes::TypeName.new(name: type_name)
|
|
307
|
-
type = ::GraphQL::Language::Nodes::NonNullType.new(of_type: type) if non_null
|
|
308
|
-
::GraphQL::Language::Nodes::FieldDefinition.new(
|
|
309
|
-
name: name,
|
|
310
|
-
type: type,
|
|
311
|
-
arguments: [],
|
|
312
|
-
directives: [],
|
|
313
|
-
description: nil
|
|
314
|
-
)
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
def self.connection_arg_description(name)
|
|
318
|
-
case name
|
|
319
|
-
when 'after'
|
|
320
|
-
'Returns the elements in the list that come after the specified cursor.'
|
|
321
|
-
when 'before'
|
|
322
|
-
'Returns the elements in the list that come before the specified cursor.'
|
|
323
|
-
when 'first'
|
|
324
|
-
'Returns the first _n_ elements from the list.'
|
|
325
|
-
when 'last'
|
|
326
|
-
'Returns the last _n_ elements from the list.'
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
end
|