ar_serializer 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +14 -14
- data/README.md +6 -6
- data/lib/ar_serializer.rb +5 -5
- data/lib/ar_serializer/field.rb +11 -22
- data/lib/ar_serializer/graphql/parser.rb +3 -3
- data/lib/ar_serializer/graphql/types.rb +8 -0
- data/lib/ar_serializer/serializer.rb +27 -30
- data/lib/ar_serializer/type_script.rb +41 -13
- data/lib/ar_serializer/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5dcdb4d958a8a3c5f45333e6d046d8070b817e9ace01ff9c5129421117a4d96
|
4
|
+
data.tar.gz: 3e37de9cd29f69b6a9fc98a297fc40eb700127403e01604cc779f0225ecd2196
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6f6050647dfe4baf84dd2801c3158447c91653dd70894a92a9eedd8c1a3b84e6da8182854ccf380f0c66ed4927774d83ed5dfc8c327d1d9ab9189c71d10d0bc
|
7
|
+
data.tar.gz: ac83b599db7be347c547b7bd1a6a3a2b0d28825220df5d862899151fe26d1aa4843a34851e3af683d7ff2245b4d904cfbf191a1a5e837dd7758b57cb7023fb83
|
data/Gemfile.lock
CHANGED
@@ -1,33 +1,32 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ar_serializer (1.
|
4
|
+
ar_serializer (1.1.0)
|
5
5
|
activerecord
|
6
6
|
top_n_loader
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activemodel (
|
12
|
-
activesupport (=
|
13
|
-
activerecord (
|
14
|
-
activemodel (=
|
15
|
-
activesupport (=
|
16
|
-
|
17
|
-
activesupport (5.2.3)
|
11
|
+
activemodel (6.0.2.1)
|
12
|
+
activesupport (= 6.0.2.1)
|
13
|
+
activerecord (6.0.2.1)
|
14
|
+
activemodel (= 6.0.2.1)
|
15
|
+
activesupport (= 6.0.2.1)
|
16
|
+
activesupport (6.0.2.1)
|
18
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
19
18
|
i18n (>= 0.7, < 2)
|
20
19
|
minitest (~> 5.1)
|
21
20
|
tzinfo (~> 1.1)
|
22
|
-
|
21
|
+
zeitwerk (~> 2.2)
|
23
22
|
coderay (1.1.2)
|
24
23
|
concurrent-ruby (1.1.5)
|
25
24
|
docile (1.3.1)
|
26
|
-
i18n (1.
|
25
|
+
i18n (1.7.0)
|
27
26
|
concurrent-ruby (~> 1.0)
|
28
27
|
json (2.1.0)
|
29
28
|
method_source (0.9.2)
|
30
|
-
minitest (5.
|
29
|
+
minitest (5.13.0)
|
31
30
|
pry (0.12.2)
|
32
31
|
coderay (~> 1.1.0)
|
33
32
|
method_source (~> 0.9.0)
|
@@ -39,10 +38,11 @@ GEM
|
|
39
38
|
simplecov-html (0.10.2)
|
40
39
|
sqlite3 (1.4.0)
|
41
40
|
thread_safe (0.3.6)
|
42
|
-
top_n_loader (1.0.
|
41
|
+
top_n_loader (1.0.1)
|
43
42
|
activerecord
|
44
|
-
tzinfo (1.2.
|
43
|
+
tzinfo (1.2.6)
|
45
44
|
thread_safe (~> 0.1)
|
45
|
+
zeitwerk (2.2.2)
|
46
46
|
|
47
47
|
PLATFORMS
|
48
48
|
ruby
|
@@ -56,4 +56,4 @@ DEPENDENCIES
|
|
56
56
|
sqlite3
|
57
57
|
|
58
58
|
BUNDLED WITH
|
59
|
-
1.
|
59
|
+
2.1.2
|
data/README.md
CHANGED
@@ -85,11 +85,11 @@ class Post < ActiveRecord::Base
|
|
85
85
|
has_many :comments
|
86
86
|
serializer_field :comments
|
87
87
|
end
|
88
|
-
ArSerializer.serialize Post.all, comments: [:id, params: { order: { id: :desc }, limit: 2 }]
|
88
|
+
ArSerializer.serialize Post.all, { comments: [:id, params: { order: { id: :desc }, limit: 2 }] }
|
89
89
|
|
90
90
|
# context and params
|
91
91
|
class Post < ActiveRecord::Base
|
92
|
-
serializer_field :created_at do |context, params|
|
92
|
+
serializer_field :created_at do |context, **params|
|
93
93
|
created_at.in_time_zone(context[:tz]).strftime params[:format]
|
94
94
|
end
|
95
95
|
end
|
@@ -123,10 +123,10 @@ class User < ActiveRecord::Base
|
|
123
123
|
serializer_field :o_posts, association: :posts, only: :title
|
124
124
|
serializer_field :e_posts, association: :posts, except: :comments
|
125
125
|
end
|
126
|
-
ArSerializer.serialize user, o_posts: :title, e_posts: :body
|
127
|
-
ArSerializer.serialize user, o_posts: :*, e_posts: :*
|
128
|
-
ArSerializer.serialize user, o_posts: :body #=> Error
|
129
|
-
ArSerializer.serialize user, e_posts: :comments #=> Error
|
126
|
+
ArSerializer.serialize user, { o_posts: :title, e_posts: :body }
|
127
|
+
ArSerializer.serialize user, { o_posts: :*, e_posts: :* }
|
128
|
+
ArSerializer.serialize user, { o_posts: :body } #=> Error
|
129
|
+
ArSerializer.serialize user, { e_posts: :comments } #=> Error
|
130
130
|
|
131
131
|
# types
|
132
132
|
class User < ActiveRecord::Base
|
data/lib/ar_serializer.rb
CHANGED
@@ -4,8 +4,8 @@ require 'ar_serializer/field'
|
|
4
4
|
require 'active_record'
|
5
5
|
|
6
6
|
module ArSerializer
|
7
|
-
def self.serialize(
|
8
|
-
Serializer.serialize(
|
7
|
+
def self.serialize(model, query, **option)
|
8
|
+
Serializer.serialize(model, query, **option)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -50,7 +50,7 @@ module ArSerializer::Serializable
|
|
50
50
|
namespaces = namespace.is_a?(Array) ? namespace : [namespace]
|
51
51
|
namespaces.each do |ns|
|
52
52
|
names.each do |name|
|
53
|
-
field = ArSerializer::Field.create(self, association || name, option, &data_block)
|
53
|
+
field = ArSerializer::Field.create(self, association || name, **option, &data_block)
|
54
54
|
_serializer_namespace(ns)[name.to_s] = field
|
55
55
|
end
|
56
56
|
end
|
@@ -64,8 +64,8 @@ module ArSerializer::Serializable
|
|
64
64
|
_custom_preloaders[name] = block
|
65
65
|
end
|
66
66
|
|
67
|
-
def serializer_defaults(
|
68
|
-
serializer_field :defaults,
|
67
|
+
def serializer_defaults(**args, &block)
|
68
|
+
serializer_field :defaults, **args, &block
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
data/lib/ar_serializer/field.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ar_serializer/error'
|
2
|
+
require 'top_n_loader'
|
2
3
|
|
3
4
|
class ArSerializer::Field
|
4
5
|
attr_reader :includes, :preloaders, :data_block, :only, :except, :order_column
|
@@ -72,7 +73,7 @@ class ArSerializer::Field
|
|
72
73
|
|
73
74
|
def validate_attributes(attributes)
|
74
75
|
return unless @only || @except
|
75
|
-
keys = attributes.
|
76
|
+
keys = attributes.map(&:first).map(&:to_s) - ['*']
|
76
77
|
return unless (@only && (keys - @only).present?) || (@except && (keys & @except).present?)
|
77
78
|
invalid_keys = [*(@only && keys - @only), *(@except && keys & @except)].uniq
|
78
79
|
raise ArSerializer::InvalidQuery, "unpermitted attribute: #{invalid_keys}"
|
@@ -82,22 +83,12 @@ class ArSerializer::Field
|
|
82
83
|
preloader = lambda do |models|
|
83
84
|
klass.joins(association_name).where(id: models.map(&:id)).group(:id).count
|
84
85
|
end
|
85
|
-
data_block = lambda do |preloaded, _context, _params|
|
86
|
+
data_block = lambda do |preloaded, _context, **_params|
|
86
87
|
preloaded[id] || 0
|
87
88
|
end
|
88
89
|
new preloaders: [preloader], data_block: data_block, type: :int
|
89
90
|
end
|
90
91
|
|
91
|
-
def self.top_n_loader_available?
|
92
|
-
return @top_n_loader_available unless @top_n_loader_available.nil?
|
93
|
-
@top_n_loader_available = begin
|
94
|
-
require 'top_n_loader'
|
95
|
-
true
|
96
|
-
rescue LoadError
|
97
|
-
nil
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
92
|
def self.type_from_column_type(klass, name)
|
102
93
|
type = type_from_attribute_type klass, name.to_s
|
103
94
|
return :any if type.nil?
|
@@ -172,11 +163,11 @@ class ArSerializer::Field
|
|
172
163
|
preloaders = []
|
173
164
|
includes ||= name if klass.respond_to?(:reflect_on_association) && klass.reflect_on_association(name)
|
174
165
|
end
|
175
|
-
data_block ||= ->(preloaded, _context, _params) { preloaded[id] } if preloaders.size == 1
|
166
|
+
data_block ||= ->(preloaded, _context, **_params) { preloaded[id] } if preloaders.size == 1
|
176
167
|
raise ArgumentError, 'data_block needed if multiple preloaders are present' if !preloaders.empty? && data_block.nil?
|
177
168
|
new(
|
178
169
|
includes: includes, preloaders: preloaders, only: only, except: except, order_column: order_column, type: type, params_type: params_type,
|
179
|
-
data_block: data_block || ->(_context, _params) { send name }
|
170
|
+
data_block: data_block || ->(_context, **_params) { send name }
|
180
171
|
)
|
181
172
|
end
|
182
173
|
|
@@ -194,7 +185,7 @@ class ArSerializer::Field
|
|
194
185
|
end
|
195
186
|
info = klass._serializer_field_info(key)
|
196
187
|
key = info&.order_column || key.to_s.underscore
|
197
|
-
raise ArSerializer::InvalidQuery, "unpermitted order key: #{key}" unless klass.has_attribute?(key) && info
|
188
|
+
raise ArSerializer::InvalidQuery, "unpermitted order key: #{key}" unless klass.primary_key == key.to_s || (klass.has_attribute?(key) && info)
|
198
189
|
raise ArSerializer::InvalidQuery, "invalid order mode: #{mode.inspect}" unless [:asc, :desc, 'asc', 'desc'].include? mode
|
199
190
|
[key.to_sym, mode.to_sym]
|
200
191
|
end
|
@@ -206,11 +197,11 @@ class ArSerializer::Field
|
|
206
197
|
end
|
207
198
|
params_type = { limit?: :int, order?: [{ :* => %w[asc desc] }, 'asc', 'desc'] }
|
208
199
|
else
|
209
|
-
preloader = lambda do |models, _context, _params|
|
200
|
+
preloader = lambda do |models, _context, **_params|
|
210
201
|
preload_association klass, models, name
|
211
202
|
end
|
212
203
|
end
|
213
|
-
data_block = lambda do |preloaded, _context, _params|
|
204
|
+
data_block = lambda do |preloaded, _context, **_params|
|
214
205
|
preloaded ? preloaded[id] || [] : send(name)
|
215
206
|
end
|
216
207
|
new preloaders: [preloader], data_block: data_block, only: only, except: except, type: type, params_type: params_type
|
@@ -219,16 +210,14 @@ class ArSerializer::Field
|
|
219
210
|
def self.preload_association(klass, models, name, limit: nil, order: nil)
|
220
211
|
limit = limit&.to_i
|
221
212
|
order_key, order_mode = parse_order klass.reflect_on_association(name).klass, order
|
222
|
-
|
223
|
-
return TopNLoader.load_associations klass, models.map(&:id), name, limit: limit, order: { order_key => order_mode }
|
224
|
-
end
|
213
|
+
return TopNLoader.load_associations klass, models.map(&:id), name, limit: limit, order: { order_key => order_mode } if limit
|
225
214
|
ActiveRecord::Associations::Preloader.new.preload models, name
|
226
|
-
return if
|
215
|
+
return if order.nil?
|
227
216
|
models.map do |model|
|
228
217
|
records_nonnils, records_nils = model.send(name).partition(&order_key)
|
229
218
|
records = records_nils.sort_by(&:id) + records_nonnils.sort_by { |r| [r[order_key], r.id] }
|
230
219
|
records.reverse! if order_mode == :desc
|
231
|
-
[model.id,
|
220
|
+
[model.id, records]
|
232
221
|
end.to_h
|
233
222
|
end
|
234
223
|
end
|
@@ -9,8 +9,8 @@ class ArSerializer::GraphQL::Parser
|
|
9
9
|
@chars = query.chars
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.parse(
|
13
|
-
new(
|
12
|
+
def self.parse(query, **option)
|
13
|
+
new(query, **option).parse
|
14
14
|
end
|
15
15
|
|
16
16
|
def parse
|
@@ -194,7 +194,7 @@ class ArSerializer::GraphQL::Parser
|
|
194
194
|
args = parse_args
|
195
195
|
consume_blank
|
196
196
|
fields = parse_fields
|
197
|
-
[name, {
|
197
|
+
[(alias_name || name), { field: name, params: args, attributes: fields }.compact]
|
198
198
|
end
|
199
199
|
|
200
200
|
def parse_fields
|
@@ -38,7 +38,15 @@ module ArSerializer::GraphQL
|
|
38
38
|
type.collect_types types
|
39
39
|
end
|
40
40
|
|
41
|
+
def args_required?
|
42
|
+
return false if field.arguments == :any
|
43
|
+
field.arguments.any? do |key, type|
|
44
|
+
!key.match?(/\?$/) && !(type.is_a?(Array) && type.include?(nil))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
41
48
|
def args_ts_type
|
49
|
+
return 'any' if field.arguments == :any
|
42
50
|
arg_types = field.arguments.map do |key, type|
|
43
51
|
"#{key}: #{TypeClass.from(type).ts_type}"
|
44
52
|
end
|
@@ -37,9 +37,9 @@ module ArSerializer::Serializer
|
|
37
37
|
Thread.current[:ar_serializer_current_namespaces] = namespaces_was
|
38
38
|
end
|
39
39
|
|
40
|
-
def self.serialize(model,
|
40
|
+
def self.serialize(model, query, context: nil, include_id: false, use: nil)
|
41
41
|
with_namespaces use do
|
42
|
-
attributes = parse_args(
|
42
|
+
attributes = parse_args(query)[:attributes]
|
43
43
|
if model.is_a?(ArSerializer::Serializable)
|
44
44
|
output = {}
|
45
45
|
_serialize [[model, output]], attributes, context, include_id
|
@@ -59,21 +59,22 @@ module ArSerializer::Serializer
|
|
59
59
|
next unless klass.respond_to? :_serializer_field_info
|
60
60
|
models = value_outputs.map(&:first)
|
61
61
|
value_outputs.each { |value, output| output[:id] = value.id } if include_id && klass.method_defined?(:id)
|
62
|
-
if attributes
|
63
|
-
all_keys = klass._serializer_field_keys.map(&:to_sym)
|
62
|
+
if attributes.any? { |k, _| k == :* }
|
63
|
+
all_keys = klass._serializer_field_keys.map(&:to_sym) - [:defaults]
|
64
64
|
all_keys &= only.map(&:to_sym) if only
|
65
65
|
all_keys -= except.map(&:to_sym) if except
|
66
|
-
attributes = all_keys.map { |k| [k, {}] }.
|
67
|
-
attributes.delete :*
|
66
|
+
attributes = all_keys.map { |k| [k, {}] } + attributes.reject { |k, _| k == :* }
|
68
67
|
end
|
69
|
-
attributes.
|
70
|
-
|
71
|
-
|
68
|
+
attributes.each do |name, sub_args|
|
69
|
+
field_name = sub_args[:field_name] || name
|
70
|
+
field = klass._serializer_field_info field_name
|
71
|
+
raise ArSerializer::InvalidQuery, "No serializer field `#{field_name}`#{" namespaces: #{current_namespaces}" if current_namespaces} for #{klass}" unless field
|
72
72
|
ActiveRecord::Associations::Preloader.new.preload models, field.includes if field.includes.present?
|
73
73
|
end
|
74
74
|
|
75
75
|
preloader_params = attributes.flat_map do |name, sub_args|
|
76
|
-
|
76
|
+
field_name = sub_args[:field_name] || name
|
77
|
+
klass._serializer_field_info(field_name).preloaders.map do |p|
|
77
78
|
[p, sub_args[:params]]
|
78
79
|
end
|
79
80
|
end
|
@@ -84,9 +85,9 @@ module ArSerializer::Serializer
|
|
84
85
|
preloader_values = preloader_params.compact.uniq.map do |key|
|
85
86
|
preloader, params = key
|
86
87
|
if preloader.arity < 0
|
87
|
-
[key, preloader.call(models, context, params || {})]
|
88
|
+
[key, preloader.call(models, context, **(params || {}))]
|
88
89
|
else
|
89
|
-
[key, preloader.call(*[models, context, params || {}
|
90
|
+
[key, preloader.call(*[models, context].take(preloader.arity), **(params || {}))]
|
90
91
|
end
|
91
92
|
end.to_h
|
92
93
|
|
@@ -102,11 +103,12 @@ module ArSerializer::Serializer
|
|
102
103
|
params = sub_arg[:params]
|
103
104
|
sub_calls = []
|
104
105
|
column_name = sub_arg[:column_name] || name
|
105
|
-
|
106
|
+
field_name = sub_arg[:field_name] || name
|
107
|
+
info = klass._serializer_field_info field_name
|
106
108
|
preloadeds = info.preloaders.map { |p| preloader_values[[p, params]] } || []
|
107
109
|
data_block = info.data_block
|
108
110
|
value_outputs.each do |value, output|
|
109
|
-
child = value.instance_exec(*preloadeds, context, params || {}, &data_block)
|
111
|
+
child = value.instance_exec(*preloadeds, context, **(params || {}), &data_block)
|
110
112
|
if child.is_a?(Array) && child.all? { |el| el.is_a? ArSerializer::Serializable }
|
111
113
|
output[column_name] = child.map do |record|
|
112
114
|
data = {}
|
@@ -117,10 +119,6 @@ module ArSerializer::Serializer
|
|
117
119
|
sub_output, record_elements = child.ar_serializer_build_sub_calls
|
118
120
|
record_elements.each { |o| sub_calls << o }
|
119
121
|
output[column_name] = sub_output
|
120
|
-
elsif child.is_a? ArSerializer::CompositeValue
|
121
|
-
sub_output, record_elements = child.build
|
122
|
-
record_elements.each { |o| sub_calls << o }
|
123
|
-
output[column_name] = sub_output
|
124
122
|
elsif child.is_a? ArSerializer::Serializable
|
125
123
|
data = {}
|
126
124
|
sub_calls << [child, data]
|
@@ -151,27 +149,26 @@ module ArSerializer::Serializer
|
|
151
149
|
end
|
152
150
|
|
153
151
|
def self.parse_args(args, only_attributes: false)
|
154
|
-
attributes =
|
152
|
+
attributes = []
|
155
153
|
params = nil
|
156
154
|
column_name = nil
|
155
|
+
field_name = nil
|
157
156
|
(args.is_a?(Array) ? args : [args]).each do |arg|
|
158
157
|
if arg.is_a?(Symbol) || arg.is_a?(String)
|
159
|
-
attributes[arg.to_sym
|
158
|
+
attributes << [arg.to_sym, {}]
|
160
159
|
elsif arg.is_a? Hash
|
161
160
|
arg.each do |key, value|
|
162
161
|
sym_key = key.to_sym
|
163
|
-
if only_attributes
|
164
|
-
|
165
|
-
|
166
|
-
end
|
167
|
-
if sym_key == :as
|
162
|
+
if !only_attributes && sym_key == :field
|
163
|
+
field_name = value
|
164
|
+
elsif !only_attributes && sym_key == :as
|
168
165
|
column_name = value
|
169
|
-
elsif
|
170
|
-
attributes.
|
171
|
-
elsif sym_key == :params
|
166
|
+
elsif !only_attributes && %i[attributes query].include?(sym_key)
|
167
|
+
attributes.concat parse_args(value, only_attributes: true)
|
168
|
+
elsif !only_attributes && sym_key == :params
|
172
169
|
params = deep_with_indifferent_access value
|
173
170
|
else
|
174
|
-
attributes[sym_key
|
171
|
+
attributes << [sym_key, value == true ? {} : parse_args(value)]
|
175
172
|
end
|
176
173
|
end
|
177
174
|
else
|
@@ -179,6 +176,6 @@ module ArSerializer::Serializer
|
|
179
176
|
end
|
180
177
|
end
|
181
178
|
return attributes if only_attributes
|
182
|
-
{ attributes: attributes, column_name: column_name, params: params || {} }
|
179
|
+
{ attributes: attributes, column_name: column_name, field_name: field_name, params: params || {} }
|
183
180
|
end
|
184
181
|
end
|
@@ -4,32 +4,60 @@ module ArSerializer::TypeScript
|
|
4
4
|
def self.generate_type_definition(*classes)
|
5
5
|
types = related_serializer_types classes.flatten
|
6
6
|
[
|
7
|
+
'type NonAliasQuery = true | string | string[] | ({ field?: undefined } & { [key: string]: any })',
|
7
8
|
types.map { |t| data_type_definition t },
|
8
9
|
types.map { |t| query_type_definition t }
|
9
10
|
].join "\n"
|
10
11
|
end
|
11
12
|
|
13
|
+
FieldInfo = Struct.new :name, :params_required?, :params_type, :query_type, :sub_query_params
|
14
|
+
|
12
15
|
def self.query_type_definition(type)
|
13
16
|
field_definitions = type.fields.map do |field|
|
14
17
|
association_type = field.type.association_type
|
15
|
-
if association_type
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
"#{field.name}?: true | { as: string }"
|
24
|
-
end
|
18
|
+
query_type = "Type#{association_type.name}Query" if association_type
|
19
|
+
params_type = field.args_ts_type unless field.args.empty?
|
20
|
+
params_required = field.args_required?
|
21
|
+
attrs = []
|
22
|
+
attrs << "query?: #{query_type}" if query_type
|
23
|
+
attrs << "params#{'?' unless params_required}: #{params_type}" if params_type
|
24
|
+
sub_query_params = attrs
|
25
|
+
FieldInfo.new field.name, params_required, params_type, query_type, sub_query_params
|
25
26
|
end
|
26
|
-
|
27
|
+
accept_wildcard = !field_definitions.any?(&:params_required?)
|
27
28
|
query_type_name = "Type#{type.name}Query"
|
29
|
+
standalone_fields_name = "Type#{type.name}StandaloneFields"
|
30
|
+
alias_query_type_name = "Type#{type.name}AliasFieldQuery"
|
28
31
|
base_query_type_name = "Type#{type.name}QueryBase"
|
32
|
+
standalone_fields_definition = field_definitions.reject(&:params_required?).map do |info|
|
33
|
+
"'#{info.name}'"
|
34
|
+
end.join(' | ')
|
35
|
+
standalone_fields_definition += " | '*'" if accept_wildcard
|
36
|
+
alias_query_type_definition = field_definitions.map do |info|
|
37
|
+
attrs = ["field: '#{info.name}'", *info.sub_query_params].join('; ')
|
38
|
+
" | { #{attrs} }\n"
|
39
|
+
end.join
|
40
|
+
base_query_type_definition = field_definitions.map do |info|
|
41
|
+
types = []
|
42
|
+
unless info.params_required?
|
43
|
+
types << true
|
44
|
+
types << info.query_type if info.query_type
|
45
|
+
end
|
46
|
+
types << "{ field: never; #{info.sub_query_params.join('; ')} }" unless info.sub_query_params.empty?
|
47
|
+
" #{info.name}: #{types.join(' | ')}"
|
48
|
+
end.join("\n")
|
49
|
+
base_query_type_definition += "\n '*': true" if accept_wildcard
|
29
50
|
<<~TYPE
|
30
|
-
export type #{query_type_name} =
|
51
|
+
export type #{query_type_name} = #{standalone_fields_name} | Readonly<#{standalone_fields_name}[]>
|
52
|
+
| (
|
53
|
+
{ [key in keyof #{base_query_type_name}]?: key extends '*' ? true : #{base_query_type_name}[key] | #{alias_query_type_name} }
|
54
|
+
& { [key: string]: #{alias_query_type_name} | NonAliasQuery }
|
55
|
+
)
|
56
|
+
export type #{standalone_fields_name} = #{standalone_fields_definition.presence || 'never'}
|
57
|
+
export type #{alias_query_type_name} =
|
58
|
+
#{alias_query_type_definition.presence || 'never'}
|
31
59
|
export interface #{base_query_type_name} {
|
32
|
-
#{
|
60
|
+
#{base_query_type_definition}
|
33
61
|
}
|
34
62
|
TYPE
|
35
63
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- tompng
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '0'
|
155
155
|
requirements: []
|
156
|
-
rubygems_version: 3.
|
156
|
+
rubygems_version: 3.1.2
|
157
157
|
signing_key:
|
158
158
|
specification_version: 4
|
159
159
|
summary: ActiveRecord serializer, avoid N+1
|