graphql-rails-api 0.9.3.2 → 0.9.5
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_add_fields/graphql_add_fields_generator.rb +26 -38
- data/lib/generators/graphql_mutations/graphql_mutations_generator.rb +49 -58
- data/lib/generators/graphql_rails_api/install_generator.rb +72 -83
- data/lib/generators/graphql_resource/graphql_resource_generator.rb +69 -93
- data/lib/graphql/hydrate_query.rb +26 -42
- data/lib/graphql/rails/api/version.rb +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3613d8a2bc521ba1e8c8cdcc120b72ac56b5d6db12ac829c21d608605164aef4
|
4
|
+
data.tar.gz: 8365841223a6f4390e8fdbd870d5f3a48d1982b69dba3d1eb05b385dd54eb509
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bb630bcffe4434a46f1e9eeba4ef1f601f6dc77bc0bd1df8089249141b4997e7afc5e8ea8bd018e415cf02ba1b9f1efbef9f86ffe20b4f70bfd9231767fc3f4
|
7
|
+
data.tar.gz: '09c3d6d3967e433b58746f125ec9071024fe18609f42d91cee150c88017ec63d0c15abd4d0102f19ab042ca3f812298f86482d9575139248dd5ce4b5fb0e3b4a'
|
@@ -8,13 +8,13 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
8
8
|
end
|
9
9
|
|
10
10
|
TYPES_MAPPING = {
|
11
|
-
'id' => '
|
12
|
-
'uuid' => '
|
13
|
-
'boolean' => '
|
14
|
-
'float' => '
|
15
|
-
'decimal' => '
|
16
|
-
'integer' => '
|
17
|
-
'bigint' => '
|
11
|
+
'id' => 'String',
|
12
|
+
'uuid' => 'String',
|
13
|
+
'boolean' => 'Boolean',
|
14
|
+
'float' => 'Float',
|
15
|
+
'decimal' => 'Float',
|
16
|
+
'integer' => 'Integer',
|
17
|
+
'bigint' => 'Integer'
|
18
18
|
}.freeze
|
19
19
|
|
20
20
|
def create_graphql_files
|
@@ -35,30 +35,30 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
35
35
|
add_has_many_to_models(@resource) if options.propagation?
|
36
36
|
add_has_many_fields_to_types(@resource) if options.propagation?
|
37
37
|
|
38
|
-
system('bundle exec rails db:migrate') if options.migrate?
|
38
|
+
# system('bundle exec rails db:migrate') if options.migrate?
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
42
42
|
|
43
43
|
def types_mapping(type)
|
44
|
-
TYPES_MAPPING[type] || '
|
44
|
+
TYPES_MAPPING[type] || 'String'
|
45
45
|
end
|
46
46
|
|
47
47
|
def complete_graphql_input_type
|
48
48
|
return if map_types(input_type: true).blank?
|
49
49
|
|
50
|
-
write_at("#{@mutations_directory}/input_type.rb",
|
50
|
+
write_at("#{@mutations_directory}/input_type.rb", 7, " #{map_types(input_type: true)}\n")
|
51
51
|
end
|
52
52
|
|
53
53
|
def complete_graphql_type(resource)
|
54
54
|
return if map_types(input_type: false).blank?
|
55
55
|
|
56
|
-
write_at("#{graphql_resource_directory(resource)}/type.rb",
|
56
|
+
write_at("#{graphql_resource_directory(resource)}/type.rb", 6, " #{map_types(input_type: false)}\n")
|
57
57
|
end
|
58
58
|
|
59
59
|
def parse_args
|
60
60
|
@id_db_type = 'uuid'
|
61
|
-
@id_type = '
|
61
|
+
@id_type = 'String'
|
62
62
|
|
63
63
|
@resource = file_name.singularize
|
64
64
|
@has_many = []
|
@@ -114,13 +114,8 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
114
114
|
end
|
115
115
|
|
116
116
|
write_at(
|
117
|
-
file_name,
|
118
|
-
|
119
|
-
field :#{resource.singularize}_ids, types[#{@id_type}] do
|
120
|
-
resolve CollectionIdsResolver
|
121
|
-
end
|
122
|
-
field :#{resource.pluralize}, types[#{resource.pluralize.camelize}::Type]
|
123
|
-
STRING
|
117
|
+
file_name, 6,
|
118
|
+
" field :#{resource.pluralize}, [#{resource.pluralize.camelize}::Type], null: true\n"
|
124
119
|
)
|
125
120
|
|
126
121
|
input_type_file_name = "app/graphql/#{field.pluralize}/mutations/input_type.rb"
|
@@ -130,10 +125,8 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
130
125
|
end
|
131
126
|
|
132
127
|
write_at(
|
133
|
-
input_type_file_name,
|
134
|
-
|
135
|
-
argument :#{resource.singularize}_ids, types[#{@id_type}]
|
136
|
-
STRING
|
128
|
+
input_type_file_name, 7,
|
129
|
+
" argument :#{resource.singularize}_ids, [#{@id_type}], required: false\n"
|
137
130
|
)
|
138
131
|
end
|
139
132
|
|
@@ -145,11 +138,8 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
145
138
|
end
|
146
139
|
|
147
140
|
write_at(
|
148
|
-
file_name,
|
149
|
-
|
150
|
-
field :#{field.singularize}_id, #{@id_type}
|
151
|
-
field :#{field.singularize}, #{field.pluralize.camelize}::Type
|
152
|
-
STRING
|
141
|
+
file_name, 6,
|
142
|
+
" field :#{field.singularize}_id, #{@id_type}, null: false\n field :#{field.singularize}, #{field.pluralize.camelize}::Type, null: false\n"
|
153
143
|
)
|
154
144
|
input_type_file_name = "app/graphql/#{resource.pluralize}/mutations/input_type.rb"
|
155
145
|
if File.read(input_type_file_name).include?("argument :#{field.singularize}_id") ||
|
@@ -158,10 +148,8 @@ class GraphqlAddFieldsGenerator < Rails::Generators::NamedBase
|
|
158
148
|
end
|
159
149
|
|
160
150
|
write_at(
|
161
|
-
input_type_file_name,
|
162
|
-
|
163
|
-
argument :#{field.singularize}_id, #{@id_type}
|
164
|
-
STRING
|
151
|
+
input_type_file_name, 7,
|
152
|
+
" argument :#{field.singularize}_id, #{@id_type}, required: false\n"
|
165
153
|
)
|
166
154
|
end
|
167
155
|
|
@@ -225,14 +213,14 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
225
213
|
result = args&.map do |k, v|
|
226
214
|
field_name = k
|
227
215
|
field_type = types_mapping(v)
|
228
|
-
res = "#{input_type ? 'argument' : 'field'} :#{field_name}, #{field_type}"
|
216
|
+
res = "#{input_type ? 'argument' : 'field'} :#{field_name}, #{field_type}, #{input_type ? "required: false" : "null: true"}"
|
229
217
|
if !input_type && field_name.ends_with?('_id') && @belongs_to_fields.key?(field_name)
|
230
|
-
res += "\n
|
218
|
+
res += "\n field :#{field_name.gsub('_id', '')}, " \
|
231
219
|
"#{field_name.gsub('_id', '').pluralize.camelize}::Type"
|
232
220
|
end
|
233
221
|
res
|
234
|
-
end&.join("\n ")
|
235
|
-
input_type ? result.gsub("field :id, #{@id_type}\n", '') : result
|
222
|
+
end&.join("\n " + (" " if input_type).to_s)
|
223
|
+
input_type ? result.gsub("field :id, #{@id_type}, null: false\n", '') : result
|
236
224
|
end
|
237
225
|
|
238
226
|
# Helpers methods
|
@@ -248,13 +236,13 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
248
236
|
file = open(file_name)
|
249
237
|
line_count = file.readlines.size
|
250
238
|
line_nb = 0
|
251
|
-
file.each do |l|
|
239
|
+
IO.readlines(file).each do |l|
|
252
240
|
line_nb += 1
|
253
241
|
break if l.include?('ApplicationRecord')
|
254
242
|
end
|
255
243
|
raise 'Your model must inherit from ApplicationRecord to make it work' if line_nb >= line_count
|
256
244
|
|
257
|
-
write_at(file_name, line_nb +
|
245
|
+
write_at(file_name, line_nb + 1, " #{line}\n")
|
258
246
|
end
|
259
247
|
|
260
248
|
def generate_has_many_migration(resource, has_many:)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class GraphqlMutationsGenerator < Rails::Generators::NamedBase
|
2
|
-
|
3
2
|
def generate
|
4
3
|
resource = file_name.underscore.singularize
|
5
4
|
dir = "app/graphql/#{resource.pluralize}/mutations"
|
@@ -7,55 +6,30 @@ class GraphqlMutationsGenerator < Rails::Generators::NamedBase
|
|
7
6
|
generate_create_mutation(dir, resource)
|
8
7
|
generate_update_mutation(dir, resource)
|
9
8
|
generate_destroy_mutation(dir, resource)
|
10
|
-
generate_bulk_create_mutation(dir, resource)
|
11
|
-
generate_bulk_update_mutation(dir, resource)
|
12
9
|
end
|
13
10
|
|
14
11
|
private
|
15
12
|
|
16
|
-
def generate_bulk_create_mutation(dir, resource)
|
17
|
-
File.write(
|
18
|
-
"#{dir}/bulk_create.rb",
|
19
|
-
<<~STRING
|
20
|
-
#{resource_class(resource)}::Mutations::BulkCreate = GraphQL::Field.define do
|
21
|
-
description 'creates some #{resource_class(resource).pluralize}'
|
22
|
-
type types[#{resource_class(resource)}::Type]
|
23
|
-
|
24
|
-
argument :#{resource}, !types[#{resource_class(resource)}::Mutations::InputType]
|
25
|
-
|
26
|
-
resolve ApplicationService.call(:#{resource}, :bulk_create)
|
27
|
-
end
|
28
|
-
STRING
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def generate_bulk_update_mutation(dir, resource)
|
33
|
-
File.write(
|
34
|
-
"#{dir}/bulk_update.rb",
|
35
|
-
<<~STRING
|
36
|
-
#{resource_class(resource)}::Mutations::BulkUpdate = GraphQL::Field.define do
|
37
|
-
description 'Updates some #{resource_class(resource).pluralize}'
|
38
|
-
type types[#{resource_class(resource)}::Type]
|
39
|
-
|
40
|
-
argument :#{resource}, !types[#{resource_class(resource)}::Mutations::InputType]
|
41
|
-
|
42
|
-
resolve ApplicationService.call(:#{resource}, :bulk_update)
|
43
|
-
end
|
44
|
-
STRING
|
45
|
-
)
|
46
|
-
end
|
47
|
-
|
48
13
|
def generate_create_mutation(dir, resource)
|
49
14
|
File.write(
|
50
15
|
"#{dir}/create.rb",
|
51
16
|
<<~STRING
|
52
|
-
#{resource_class(resource)}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
17
|
+
module #{resource_class(resource)}
|
18
|
+
module Mutations
|
19
|
+
class Create < GraphQL::Schema::Mutation
|
20
|
+
graphql_name "Create#{resource_class(resource)}"
|
21
|
+
description "Create a #{resource_class(resource).singularize}"
|
22
|
+
|
23
|
+
field :errors, [String], null: true
|
24
|
+
field :#{resource}, #{resource_class(resource)}::Type, null: true
|
25
|
+
|
26
|
+
argument :attributes, #{resource_class(resource)}::Mutations::InputType, required: false
|
27
|
+
|
28
|
+
def resolve(attributes:)
|
29
|
+
ApplicationService.call(:#{resource}, :create, context, attributes)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
59
33
|
end
|
60
34
|
STRING
|
61
35
|
)
|
@@ -65,14 +39,23 @@ class GraphqlMutationsGenerator < Rails::Generators::NamedBase
|
|
65
39
|
File.write(
|
66
40
|
"#{dir}/update.rb",
|
67
41
|
<<~STRING
|
68
|
-
#{resource_class(resource)}
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
42
|
+
module #{resource_class(resource)}
|
43
|
+
module Mutations
|
44
|
+
class Update < GraphQL::Schema::Mutation
|
45
|
+
graphql_name "Update#{resource_class(resource)}"
|
46
|
+
description "Update a #{resource_class(resource).singularize}"
|
47
|
+
|
48
|
+
field :errors, [String], null: true
|
49
|
+
field :#{resource}, #{resource_class(resource)}::Type, null: true
|
50
|
+
|
51
|
+
argument :id, String, required: true
|
52
|
+
argument :attributes, #{resource_class(resource)}::Mutations::InputType, required: false
|
53
|
+
|
54
|
+
def resolve(id:, attributes:)
|
55
|
+
ApplicationService.call(:#{resource}, :update, context, id, attributes)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
76
59
|
end
|
77
60
|
STRING
|
78
61
|
)
|
@@ -82,13 +65,22 @@ class GraphqlMutationsGenerator < Rails::Generators::NamedBase
|
|
82
65
|
File.write(
|
83
66
|
"#{dir}/destroy.rb",
|
84
67
|
<<~STRING
|
85
|
-
#{resource_class(resource)}
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
68
|
+
module #{resource_class(resource)}
|
69
|
+
module Mutations
|
70
|
+
class Destroy < GraphQL::Schema::Mutation
|
71
|
+
graphql_name "Destroy#{resource_class(resource)}"
|
72
|
+
description "Destroy a #{resource_class(resource).singularize}"
|
73
|
+
|
74
|
+
field :errors, [String], null: true
|
75
|
+
field :#{resource}, #{resource_class(resource)}::Type, null: true
|
76
|
+
|
77
|
+
argument :id, String, required: true
|
78
|
+
|
79
|
+
def resolve(id:)
|
80
|
+
ApplicationService.call(:#{resource}, :destroy, context, id)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
92
84
|
end
|
93
85
|
STRING
|
94
86
|
)
|
@@ -97,5 +89,4 @@ class GraphqlMutationsGenerator < Rails::Generators::NamedBase
|
|
97
89
|
def resource_class(resource)
|
98
90
|
@resource_class ||= resource.pluralize.camelize
|
99
91
|
end
|
100
|
-
|
101
92
|
end
|
@@ -3,7 +3,6 @@ require 'graphql/rails/api/config'
|
|
3
3
|
module GraphqlRailsApi
|
4
4
|
class InstallGenerator < Rails::Generators::Base
|
5
5
|
|
6
|
-
class_option('apollo_compatibility', type: :boolean, default: true)
|
7
6
|
class_option('generate_graphql_route', type: :boolean, default: true)
|
8
7
|
|
9
8
|
def generate_files
|
@@ -165,18 +164,18 @@ end
|
|
165
164
|
File.write(
|
166
165
|
'app/graphql/mutation_type.rb',
|
167
166
|
<<~'STRING'
|
168
|
-
MutationType
|
169
|
-
|
167
|
+
class MutationType < GraphQL::Schema::Object
|
168
|
+
graphql_name "Mutation"
|
169
|
+
description "The mutation root of this schema"
|
170
170
|
|
171
171
|
Graphql::Rails::Api::Config.mutation_resources.each do |methd, resources|
|
172
172
|
resources.each do |resource|
|
173
173
|
field(
|
174
174
|
"#{methd}_#{resource.singularize}".to_sym,
|
175
|
-
"#{resource.camelize}::Mutations::#{methd.camelize}".constantize
|
175
|
+
mutation: "#{resource.camelize}::Mutations::#{methd.camelize}".constantize
|
176
176
|
)
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
180
179
|
end
|
181
180
|
STRING
|
182
181
|
)
|
@@ -186,59 +185,71 @@ end
|
|
186
185
|
File.write(
|
187
186
|
'app/graphql/query_type.rb',
|
188
187
|
<<~'STRING'
|
189
|
-
QueryType
|
190
|
-
|
188
|
+
class QueryType < GraphQL::Schema::Object
|
189
|
+
description "The query root of this schema"
|
191
190
|
|
192
191
|
Graphql::Rails::Api::Config.query_resources.each do |resource|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
192
|
+
klass = Class.new(GraphQL::Schema::Object) do
|
193
|
+
graphql_name "Paginated#{resource.classify}"
|
194
|
+
|
195
|
+
field :total_count, Integer, null: false
|
196
|
+
field :page, Integer, null: false
|
197
|
+
field :per_page, Integer, null: false
|
198
|
+
field :data, ["#{resource.pluralize.camelize}::Type".constantize], null: false
|
198
199
|
end
|
199
200
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
201
|
+
resource.pluralize.camelize.constantize.const_set(
|
202
|
+
:PaginatedType,
|
203
|
+
klass
|
204
|
+
)
|
205
|
+
|
206
|
+
field "paginated_#{resource.pluralize}", "#{resource.camelize}::PaginatedType".constantize, null: false do
|
207
|
+
description "Return paginated #{resource.classify}"
|
208
|
+
argument :page, Integer, required: true
|
209
|
+
argument :per_page, Integer, required: true
|
210
|
+
argument :filter, String, required: false
|
211
|
+
argument :order_by, type: String, required: false
|
208
212
|
end
|
209
213
|
|
210
|
-
|
214
|
+
define_method("paginated_#{resource.pluralize}") do |page:, per_page:, filter: nil, order_by: nil|
|
215
|
+
arguments = {
|
216
|
+
page: page,
|
217
|
+
per_page: per_page,
|
218
|
+
filter: filter,
|
219
|
+
order_by: order_by
|
220
|
+
}
|
221
|
+
ApplicationService.call(resource, :paginated_index, context, arguments)
|
222
|
+
end
|
211
223
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
224
|
+
field resource.pluralize.to_sym, ["#{resource.camelize}::Type".constantize], null: false do
|
225
|
+
description "All #{resource.pluralize}"
|
226
|
+
argument :page, Integer, required: false
|
227
|
+
argument :per_page, Integer, required: false
|
228
|
+
argument :filter, String, required: false
|
229
|
+
argument :order_by, String, required: false
|
230
|
+
end
|
216
231
|
|
232
|
+
define_method(resource.pluralize) do |page: nil, per_page: nil, filter: nil, order_by: nil|
|
233
|
+
arguments = {page: page, per_page: per_page, filter: filter, order_by: order_by}
|
234
|
+
ApplicationService.call(resource, :index, context, arguments)
|
235
|
+
end
|
236
|
+
|
237
|
+
field resource.singularize.to_sym, "#{resource.camelize}::Type".constantize, null: false do
|
238
|
+
description "A #{resource.singularize}"
|
239
|
+
argument :id, String, required: true
|
240
|
+
end
|
241
|
+
|
242
|
+
define_method(resource.singularize) do |id:|
|
243
|
+
arguments = {id: id}
|
244
|
+
ApplicationService.call(resource, :show, context, arguments)
|
245
|
+
end
|
246
|
+
end
|
217
247
|
end
|
248
|
+
|
218
249
|
STRING
|
219
250
|
)
|
220
251
|
end
|
221
252
|
|
222
|
-
def apollo_compat
|
223
|
-
<<~'STRING'
|
224
|
-
# /!\ do not remove /!\
|
225
|
-
# Apollo Data compat.
|
226
|
-
ClientDirective = GraphQL::Directive.define do
|
227
|
-
name 'client'
|
228
|
-
locations([GraphQL::Directive::FIELD])
|
229
|
-
default_directive true
|
230
|
-
end
|
231
|
-
ConnectionDirective = GraphQL::Directive.define do
|
232
|
-
name 'connection'
|
233
|
-
locations([GraphQL::Directive::FIELD])
|
234
|
-
argument :key, GraphQL::STRING_TYPE
|
235
|
-
argument :filter, GraphQL::STRING_TYPE.to_list_type
|
236
|
-
default_directive true
|
237
|
-
end
|
238
|
-
# end of Apollo Data compat.
|
239
|
-
STRING
|
240
|
-
end
|
241
|
-
|
242
253
|
def write_schema
|
243
254
|
logger = <<~'STRING'
|
244
255
|
type_error_logger = Logger.new("#{Rails.root}/log/graphql_type_errors.log")
|
@@ -252,18 +263,20 @@ end
|
|
252
263
|
File.write(
|
253
264
|
"app/graphql/#{@app_name}_schema.rb",
|
254
265
|
<<~STRING
|
255
|
-
#{
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
266
|
+
class #{@app_name.camelize}Schema < GraphQL::Schema
|
267
|
+
query QueryType
|
268
|
+
mutation MutationType
|
269
|
+
max_depth 15
|
270
|
+
|
271
|
+
def self.type_error(err, query_ctx)
|
272
|
+
type_error_logger = Logger.new("#{Rails.root}/log/graphql_type_errors.log")
|
273
|
+
|
274
|
+
type_error_logger.error(
|
275
|
+
"#{err} for #{query_ctx.query.query_string} with #{query_ctx.query.provided_variables}"
|
276
|
+
)
|
277
|
+
end
|
265
278
|
end
|
266
|
-
STRING
|
279
|
+
<<~STRING
|
267
280
|
)
|
268
281
|
end
|
269
282
|
|
@@ -317,41 +330,17 @@ end
|
|
317
330
|
return not_allowed if not_allowed_to_create_resource(object)
|
318
331
|
|
319
332
|
if object.save
|
320
|
-
object
|
333
|
+
{ singular_resource => Graphql::HydrateQuery.new(model.all, @context, user: user, id: object.id).run }
|
321
334
|
else
|
322
335
|
graphql_error(object.errors.full_messages.join(', '))
|
323
336
|
end
|
324
337
|
end
|
325
338
|
|
326
|
-
def bulk_create
|
327
|
-
result = model.import(params.map { |p| p.select { |param| model.new.respond_to?(param) } })
|
328
|
-
result.each { |e| e.run_callbacks(:save) }
|
329
|
-
hyd = Graphql::HydrateQuery.new(model.where(id: result.ids), @context).run.compact + result.failed_instances.map do |i|
|
330
|
-
graphql_error(i.errors.full_messages)
|
331
|
-
end
|
332
|
-
return hyd.first if hyd.all? { |e| e.is_a?(GraphQL::ExecutionError) }
|
333
|
-
|
334
|
-
hyd
|
335
|
-
end
|
336
|
-
|
337
|
-
def bulk_update
|
338
|
-
visible_ids = model.where(id: params.map { |p| p[:id] }).pluck(:id)
|
339
|
-
return not_allowed if (model.visible_for(user: user).pluck(:id) & visible_ids).size < visible_ids.size
|
340
|
-
|
341
|
-
hash = params.each_with_object({}) { |p, h| h[p.delete(:id)] = p }
|
342
|
-
failed_instances = []
|
343
|
-
result = model.update(hash.keys, hash.values).map { |e| e.errors.blank? ? e : (failed_instances << e && nil) }
|
344
|
-
hyd = Graphql::HydrateQuery.new(model.where(id: result.compact.map(&:id)), @context).run.compact + failed_instances.map do |i|
|
345
|
-
graphql_error(i.errors.full_messages)
|
346
|
-
end
|
347
|
-
hyd.all? { |e| e.is_a?(GraphQL::ExecutionError) } ? hyd.first : hyd
|
348
|
-
end
|
349
|
-
|
350
339
|
def update
|
351
340
|
return not_allowed if write_not_allowed
|
352
341
|
|
353
342
|
if object.update_attributes(params)
|
354
|
-
object
|
343
|
+
{ singular_resource => Graphql::HydrateQuery.new(model.all, @context, user: user, id: object.id).run }
|
355
344
|
else
|
356
345
|
graphql_error(object.errors.full_messages.join(', '))
|
357
346
|
end
|
@@ -362,7 +351,7 @@ end
|
|
362
351
|
return not_allowed if write_not_allowed
|
363
352
|
|
364
353
|
if object.destroy
|
365
|
-
object
|
354
|
+
{ singular_resource => object.attributes }
|
366
355
|
else
|
367
356
|
graphql_error(object.errors.full_messages.join(', '))
|
368
357
|
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
2
|
-
|
3
2
|
%i[
|
4
3
|
migration model mutations service graphql_input_type
|
5
|
-
graphql_type propagation
|
4
|
+
graphql_type propagation migrate
|
6
5
|
].each do |opt|
|
7
6
|
class_option(opt, type: :boolean, default: true)
|
8
7
|
end
|
9
8
|
|
10
9
|
TYPES_MAPPING = {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
"id" => "String",
|
11
|
+
"uuid" => "String",
|
12
|
+
"boolean" => "Boolean",
|
13
|
+
"float" => "Float",
|
14
|
+
"decimal" => "Float",
|
15
|
+
"integer" => "Integer",
|
16
|
+
"bigint" => "Integer"
|
18
17
|
}.freeze
|
19
18
|
|
20
19
|
def create_graphql_files
|
@@ -42,18 +41,18 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
42
41
|
add_has_many_to_models(@resource) if options.propagation?
|
43
42
|
add_has_many_fields_to_types(@resource) if options.propagation?
|
44
43
|
|
45
|
-
system(
|
44
|
+
# system("bundle exec rails db:migrate") if options.migrate?
|
46
45
|
end
|
47
46
|
|
48
47
|
private
|
49
48
|
|
50
49
|
def types_mapping(type)
|
51
|
-
TYPES_MAPPING[type] ||
|
50
|
+
TYPES_MAPPING[type] || "String"
|
52
51
|
end
|
53
52
|
|
54
53
|
def parse_args
|
55
|
-
@id_db_type =
|
56
|
-
@id_type =
|
54
|
+
@id_db_type = "uuid"
|
55
|
+
@id_type = "String"
|
57
56
|
|
58
57
|
@resource = file_name.singularize
|
59
58
|
@has_many = []
|
@@ -62,21 +61,21 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
62
61
|
@belongs_to_fields = {}
|
63
62
|
|
64
63
|
@args = args.each_with_object({}) do |f, hash|
|
65
|
-
next if f.split(
|
66
|
-
|
67
|
-
case f.split(
|
68
|
-
when
|
69
|
-
hash["#{f.split(
|
70
|
-
@belongs_to_fields["#{f.split(
|
71
|
-
when
|
72
|
-
when
|
64
|
+
next if f.split(":").count != 2
|
65
|
+
|
66
|
+
case f.split(":").first
|
67
|
+
when "belongs_to"
|
68
|
+
hash["#{f.split(":").last.singularize}_id"] = @id_db_type
|
69
|
+
@belongs_to_fields["#{f.split(":").last.singularize}_id"] = @id_db_type
|
70
|
+
when "has_many" then @has_many << f.split(":").last.pluralize
|
71
|
+
when "many_to_many" then @many_to_many << f.split(":").last.pluralize
|
73
72
|
else
|
74
|
-
hash[f.split(
|
73
|
+
hash[f.split(":").first] = f.split(":").last
|
75
74
|
end
|
76
75
|
end
|
77
76
|
|
78
77
|
@fields_to_migration = @args.map do |f|
|
79
|
-
"t.#{f.reverse.join(
|
78
|
+
"t.#{f.reverse.join(" :")}"
|
80
79
|
end.join("\n ")
|
81
80
|
end
|
82
81
|
|
@@ -90,7 +89,7 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
90
89
|
File.write(
|
91
90
|
migration_file,
|
92
91
|
<<~STRING
|
93
|
-
class Create#{resource.camelize} < ActiveRecord::Migration[
|
92
|
+
class Create#{resource.camelize} < ActiveRecord::Migration[7.0]
|
94
93
|
def change
|
95
94
|
create_table :#{resource.pluralize}, id: :uuid do |t|
|
96
95
|
#{fields}
|
@@ -110,33 +109,20 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
110
109
|
generate_graphql_input_type(resource) if options.graphql_input_type?
|
111
110
|
end
|
112
111
|
|
113
|
-
def generate_graphql_connection(resource)
|
114
|
-
File.write(
|
115
|
-
"#{graphql_resource_directory(resource)}/connection.rb",
|
116
|
-
<<~STRING
|
117
|
-
#{resource_class(resource)}::Connection = #{resource.pluralize.camelize}::Type.define_connection do
|
118
|
-
name '#{resource.camelize}Connection'
|
119
|
-
|
120
|
-
field :total_count, types.Int do
|
121
|
-
resolve ->(obj, _, _) { obj.nodes.count }
|
122
|
-
end
|
123
|
-
end
|
124
|
-
STRING
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
128
112
|
def generate_graphql_input_type(resource)
|
129
113
|
FileUtils.mkdir_p(@mutations_directory) unless File.directory?(@mutations_directory)
|
130
114
|
|
131
115
|
File.write(
|
132
116
|
"#{@mutations_directory}/input_type.rb",
|
133
117
|
<<~STRING
|
134
|
-
#{resource_class(resource)}
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
118
|
+
module #{resource_class(resource)}
|
119
|
+
module Mutations
|
120
|
+
class InputType < GraphQL::Schema::InputObject
|
121
|
+
graphql_name "#{resource.camelize}InputType"
|
122
|
+
description "Attributes for creating or updating a #{resource}"
|
123
|
+
#{map_types(input_type: true)}
|
124
|
+
end
|
125
|
+
end
|
140
126
|
end
|
141
127
|
STRING
|
142
128
|
)
|
@@ -146,12 +132,16 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
146
132
|
File.write(
|
147
133
|
"#{graphql_resource_directory(resource)}/type.rb",
|
148
134
|
<<~STRING
|
149
|
-
#{resource_class(resource)}
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
135
|
+
module #{resource_class(resource)}
|
136
|
+
class Type < GraphQL::Schema::Object
|
137
|
+
graphql_name "#{resource.camelize}"
|
138
|
+
description "A #{resource}"
|
139
|
+
|
140
|
+
field :id, #{@id_type}, null: false
|
141
|
+
field :created_at, String, null: false
|
142
|
+
field :updated_at, String, null: false
|
143
|
+
#{map_types(input_type: false)}
|
144
|
+
end
|
155
145
|
end
|
156
146
|
STRING
|
157
147
|
)
|
@@ -168,13 +158,7 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
168
158
|
return
|
169
159
|
end
|
170
160
|
write_at(
|
171
|
-
file_name,
|
172
|
-
<<-STRING
|
173
|
-
field :#{resource.singularize}_ids, types[#{@id_type}] do
|
174
|
-
resolve CollectionIdsResolver
|
175
|
-
end
|
176
|
-
field :#{resource.pluralize}, types[#{resource.pluralize.camelize}::Type]
|
177
|
-
STRING
|
161
|
+
file_name, 6," field :#{resource.pluralize}, [#{resource.pluralize.camelize}::Type], null: true\n"
|
178
162
|
)
|
179
163
|
|
180
164
|
input_type_file_name = "app/graphql/#{field.pluralize}/mutations/input_type.rb"
|
@@ -183,10 +167,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
183
167
|
return
|
184
168
|
end
|
185
169
|
write_at(
|
186
|
-
input_type_file_name,
|
187
|
-
|
188
|
-
argument :#{resource.singularize}_ids, types[#{@id_type}]
|
189
|
-
STRING
|
170
|
+
input_type_file_name, 7,
|
171
|
+
" argument :#{resource.singularize}_ids, [#{@id_type}], required: false\n"
|
190
172
|
)
|
191
173
|
|
192
174
|
end
|
@@ -199,11 +181,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
199
181
|
end
|
200
182
|
|
201
183
|
write_at(
|
202
|
-
file_name,
|
203
|
-
|
204
|
-
field :#{field.singularize}_id, #{@id_type}
|
205
|
-
field :#{field.singularize}, #{field.pluralize.camelize}::Type
|
206
|
-
STRING
|
184
|
+
file_name, 6,
|
185
|
+
" field :#{field.singularize}_id, #{@id_type}, null: false\n field :#{field.singularize}, #{field.pluralize.camelize}::Type, null: false\n"
|
207
186
|
)
|
208
187
|
input_type_file_name = "app/graphql/#{resource.pluralize}/mutations/input_type.rb"
|
209
188
|
if File.read(input_type_file_name).include?("argument :#{field.singularize}_id") ||
|
@@ -212,10 +191,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
212
191
|
end
|
213
192
|
|
214
193
|
write_at(
|
215
|
-
input_type_file_name,
|
216
|
-
|
217
|
-
argument :#{field.singularize}_id, #{@id_type}
|
218
|
-
STRING
|
194
|
+
input_type_file_name, 7,
|
195
|
+
" argument :#{field.singularize}_id, #{@id_type}, required: false\n"
|
219
196
|
)
|
220
197
|
end
|
221
198
|
|
@@ -225,8 +202,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
225
202
|
add_belongs_to_field_to_type(resource, f)
|
226
203
|
end
|
227
204
|
@belongs_to_fields.each do |f, _|
|
228
|
-
add_has_many_fields_to_type(f.gsub(
|
229
|
-
add_belongs_to_field_to_type(f.gsub(
|
205
|
+
add_has_many_fields_to_type(f.gsub("_id", ""), resource)
|
206
|
+
add_belongs_to_field_to_type(f.gsub("_id", ""), resource)
|
230
207
|
end
|
231
208
|
end
|
232
209
|
|
@@ -242,9 +219,8 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
242
219
|
end
|
243
220
|
|
244
221
|
def generate_service(resource)
|
245
|
-
|
246
222
|
FileUtils.mkdir_p("app/graphql/#{resource.pluralize}/") unless File.directory?("app/graphql/#{resource.pluralize}/")
|
247
|
-
|
223
|
+
|
248
224
|
File.write(
|
249
225
|
"app/graphql/#{resource.pluralize}/service.rb",
|
250
226
|
<<~STRING
|
@@ -261,9 +237,9 @@ class GraphqlResourceGenerator < Rails::Generators::NamedBase
|
|
261
237
|
@many_to_many.each do |field|
|
262
238
|
generate_create_migration(
|
263
239
|
"#{resource}_#{field}",
|
264
|
-
|
265
|
-
t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
266
|
-
|
240
|
+
<<~STRING
|
241
|
+
t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
242
|
+
t.#{@id_db_type} :#{field.underscore.singularize}_id
|
267
243
|
STRING
|
268
244
|
)
|
269
245
|
generate_empty_model("#{resource}_#{field.singularize}")
|
@@ -285,7 +261,7 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
285
261
|
add_to_model(field, "belongs_to :#{resource.singularize}")
|
286
262
|
end
|
287
263
|
@belongs_to_fields.each do |k, _|
|
288
|
-
field = k.gsub(
|
264
|
+
field = k.gsub("_id", "")
|
289
265
|
add_to_model(field, "has_many :#{resource.pluralize}")
|
290
266
|
add_to_model(resource, "belongs_to :#{field.singularize}")
|
291
267
|
end
|
@@ -295,14 +271,15 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
295
271
|
result = args&.map do |k, v|
|
296
272
|
field_name = k
|
297
273
|
field_type = types_mapping(v)
|
298
|
-
res = "#{input_type ?
|
299
|
-
|
300
|
-
|
301
|
-
|
274
|
+
res = "#{input_type ? "argument" : "field"} :#{field_name}, #{field_type}, #{input_type ? "required: false" : "null: true"}"
|
275
|
+
|
276
|
+
if !input_type && field_name.ends_with?("_id") && @belongs_to_fields.key?(field_name)
|
277
|
+
res += "\n field :#{field_name.gsub("_id", "")}, " \
|
278
|
+
"#{field_name.gsub("_id", "").pluralize.camelize}::Type, null: false"
|
302
279
|
end
|
303
280
|
res
|
304
|
-
end&.join("\n ")
|
305
|
-
input_type ? result.gsub("field :id, #{@id_type}\n",
|
281
|
+
end&.join("\n " + (" " if input_type).to_s)
|
282
|
+
input_type ? result.gsub("field :id, #{@id_type}, null: false\n", "") : result
|
306
283
|
end
|
307
284
|
|
308
285
|
# Helpers methods
|
@@ -312,19 +289,19 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
312
289
|
end
|
313
290
|
|
314
291
|
def add_to_model(model, line)
|
315
|
-
file_name = File.join("app","models","#{model.underscore.singularize}.rb")
|
292
|
+
file_name = File.join("app", "models", "#{model.underscore.singularize}.rb")
|
316
293
|
return if !File.exist?(file_name) || File.read(file_name).include?(line)
|
317
294
|
|
318
295
|
file = open(file_name)
|
319
296
|
line_count = file.readlines.size
|
320
297
|
line_nb = 0
|
321
|
-
file.each do |l|
|
298
|
+
IO.readlines(file).each do |l|
|
322
299
|
line_nb += 1
|
323
|
-
break if l.include?(
|
300
|
+
break if l.include?("ApplicationRecord")
|
324
301
|
end
|
325
|
-
raise
|
302
|
+
raise "Your model must inherit from ApplicationRecord to make it work" if line_nb >= line_count
|
326
303
|
|
327
|
-
write_at(file_name, line_nb +
|
304
|
+
write_at(file_name, line_nb + 1, " #{line}\n")
|
328
305
|
end
|
329
306
|
|
330
307
|
def generate_has_many_migration(resource, has_many:)
|
@@ -335,7 +312,7 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
335
312
|
File.write(
|
336
313
|
migration_file,
|
337
314
|
<<~STRING
|
338
|
-
class Add#{resource.singularize.camelize}IdTo#{has_many.camelize} < ActiveRecord::Migration[
|
315
|
+
class Add#{resource.singularize.camelize}IdTo#{has_many.camelize} < ActiveRecord::Migration[7.0]
|
339
316
|
def change
|
340
317
|
add_column :#{has_many.pluralize}, :#{resource.singularize}_id, :#{@id_db_type}
|
341
318
|
end
|
@@ -349,7 +326,7 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
349
326
|
end
|
350
327
|
|
351
328
|
def write_at(file_name, line, data)
|
352
|
-
open(file_name,
|
329
|
+
open(file_name, "r+") do |f|
|
353
330
|
while (line -= 1).positive?
|
354
331
|
f.readline
|
355
332
|
end
|
@@ -360,5 +337,4 @@ t.#{@id_db_type} :#{resource.underscore.singularize}_id
|
|
360
337
|
f.write(rest)
|
361
338
|
end
|
362
339
|
end
|
363
|
-
|
364
340
|
end
|
@@ -24,7 +24,7 @@ module Graphql
|
|
24
24
|
def run
|
25
25
|
if @id
|
26
26
|
@model = @model.where(id: @id)
|
27
|
-
deep_pluck_to_structs(
|
27
|
+
deep_pluck_to_structs(irep_node(model_name.singularize)).first
|
28
28
|
else
|
29
29
|
@model = @model.limit(@per_page)
|
30
30
|
@model = @model.offset(@per_page * (@page - 1))
|
@@ -32,7 +32,7 @@ module Graphql
|
|
32
32
|
transform_filter if @filter.present?
|
33
33
|
transform_order if @order_by.present?
|
34
34
|
|
35
|
-
deep_pluck_to_structs(
|
35
|
+
deep_pluck_to_structs(irep_node(model_name.pluralize))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -45,7 +45,7 @@ module Graphql
|
|
45
45
|
@model = @model.offset(@per_page * (@page - 1))
|
46
46
|
|
47
47
|
OpenStruct.new(
|
48
|
-
data: deep_pluck_to_structs(
|
48
|
+
data: deep_pluck_to_structs(irep_node(model_name.pluralize, paginated: true)),
|
49
49
|
total_count: @total,
|
50
50
|
per_page: @per_page,
|
51
51
|
page: @page
|
@@ -73,7 +73,7 @@ module Graphql
|
|
73
73
|
end
|
74
74
|
|
75
75
|
@model = if %i[string text].include?(field_type)
|
76
|
-
@model.order(Arel.sql("#{ordered_field} #{sign}"))
|
76
|
+
@model.order(Arel.sql("upper(#{ordered_field}) #{sign}"))
|
77
77
|
else
|
78
78
|
@model.order(Arel.sql("#{ordered_field} #{sign}"))
|
79
79
|
end
|
@@ -120,8 +120,6 @@ module Graphql
|
|
120
120
|
handle_LessNode(node, model)
|
121
121
|
elsif node.instance_of?(RKelly::Nodes::GreaterNode)
|
122
122
|
handle_GreaterNode(node, model)
|
123
|
-
elsif node.instance_of?(RKelly::Nodes::ModulusNode)
|
124
|
-
handle_ModulusNode(node, model)
|
125
123
|
else
|
126
124
|
raise GraphQL::ExecutionError, "Invalid filter: #{node.class} unknown operator"
|
127
125
|
end
|
@@ -139,37 +137,6 @@ module Graphql
|
|
139
137
|
handle_node(node.left, model).or(handle_node(node.value, model))
|
140
138
|
end
|
141
139
|
|
142
|
-
def handle_ModulusNode(node, model)
|
143
|
-
arel_field, model, type, value = handle_operator_node(node, model)
|
144
|
-
arel_field.name = arel_field.name.underscore
|
145
|
-
|
146
|
-
if value.nil?
|
147
|
-
model.where(arel_field.eq(nil))
|
148
|
-
elsif type == :text || type == :string
|
149
|
-
model.where(arel_field.matches("%" + sanitize_sql_like(value) + "%"))
|
150
|
-
elsif type == :datetime
|
151
|
-
if value.instance_of?(DateTime)
|
152
|
-
model.where(arel_field.gteq(value).and(arel_field.lteq(value + 1.day)))
|
153
|
-
else
|
154
|
-
model.where(
|
155
|
-
Arel::Nodes::NamedFunction.new(
|
156
|
-
"CAST",
|
157
|
-
[Arel::Nodes::As.new(arel_field, Arel::Nodes::SqlLiteral.new("text"))]
|
158
|
-
).matches("%" + sanitize_sql_like(value) + "%")
|
159
|
-
)
|
160
|
-
end
|
161
|
-
elsif type == :uuid
|
162
|
-
model.where(
|
163
|
-
Arel::Nodes::NamedFunction.new(
|
164
|
-
"CAST",
|
165
|
-
[Arel::Nodes::As.new(arel_field, Arel::Nodes::SqlLiteral.new("text"))]
|
166
|
-
).matches("%" + sanitize_sql_like(value) + "%")
|
167
|
-
)
|
168
|
-
else
|
169
|
-
model.where(arel_field.eq(value))
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
140
|
def handle_dot_accessor_node(node, model)
|
174
141
|
associated_model = node.left.value.value
|
175
142
|
accessor = node.left.accessor
|
@@ -404,13 +371,29 @@ module Graphql
|
|
404
371
|
parent_class_name.constantize.reflections[child.to_s.underscore]&.klass
|
405
372
|
end
|
406
373
|
|
407
|
-
def
|
408
|
-
|
409
|
-
|
374
|
+
def irep_node(name, paginated: false)
|
375
|
+
child = @context.query.lookahead.ast_nodes.first.children[@context[:query_index]]
|
376
|
+
result = if paginated
|
377
|
+
child.children.find { |n| n.name == "data" }.children
|
378
|
+
else
|
379
|
+
child.children
|
380
|
+
end
|
381
|
+
@context[:query_index] += 1
|
382
|
+
result
|
383
|
+
end
|
384
|
+
|
385
|
+
def parse_fields(global_fields)
|
386
|
+
return if global_fields.blank?
|
387
|
+
|
388
|
+
fields = global_fields.map do |field|
|
389
|
+
next if field.class != GraphQL::Language::Nodes::Field
|
390
|
+
field
|
391
|
+
end.compact
|
392
|
+
|
410
393
|
return if fields.blank?
|
411
394
|
|
412
|
-
fields.each_with_object({}) do |
|
413
|
-
h[
|
395
|
+
fields.each_with_object({}) do |node, h|
|
396
|
+
h[node.name.underscore] = node.children.blank? ? nil : parse_fields(node.children)
|
414
397
|
end
|
415
398
|
end
|
416
399
|
|
@@ -418,4 +401,5 @@ module Graphql
|
|
418
401
|
@model.class.to_s.split("::").first.underscore.pluralize
|
419
402
|
end
|
420
403
|
end
|
404
|
+
|
421
405
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-rails-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- poilon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.0.15
|
20
20
|
- - "<="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 2.0.15
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 2.0.15
|
30
30
|
- - "<="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 2.0.15
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: deep_pluck_with_authorization
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: '0'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
60
|
+
version: '0'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rkelly-remix
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|