ar_serializer 1.0.0 → 1.1.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/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
|