serega 0.40.0 → 0.41.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/LICENSE.txt +21 -0
- data/README.md +204 -108
- data/VERSION +1 -1
- data/lib/serega/attribute.rb +2 -0
- data/lib/serega/attribute_normalizer.rb +2 -0
- data/lib/serega/attribute_value_resolvers/batch.rb +3 -0
- data/lib/serega/attribute_value_resolvers/const.rb +3 -0
- data/lib/serega/attribute_value_resolvers/delegate.rb +4 -0
- data/lib/serega/attribute_value_resolvers/hash_access.rb +6 -0
- data/lib/serega/attribute_value_resolvers/keyword.rb +3 -0
- data/lib/serega/data_builder.rb +2 -0
- data/lib/serega/engine/level.rb +2 -0
- data/lib/serega/engine/level_queue.rb +2 -0
- data/lib/serega/engine/loader.rb +3 -0
- data/lib/serega/helpers/serializer_class_helper.rb +2 -0
- data/lib/serega/object_serializer.rb +2 -0
- data/lib/serega/plan.rb +3 -0
- data/lib/serega/plan_point.rb +2 -0
- data/lib/serega/plugins/activerecord_preloads/activerecord_preloads.rb +22 -16
- data/lib/serega/plugins/activerecord_preloads/lib/preloader.rb +6 -0
- data/lib/serega/plugins/camel_case/camel_case.rb +13 -13
- data/lib/serega/plugins/context_metadata/context_metadata.rb +8 -1
- data/lib/serega/plugins/depth_limit/depth_limit.rb +15 -12
- data/lib/serega/plugins/explicit_many_option/explicit_many_option.rb +12 -10
- data/lib/serega/plugins/explicit_many_option/validations/check_opt_many.rb +1 -0
- data/lib/serega/plugins/formatters/formatters.rb +18 -10
- data/lib/serega/plugins/if/if.rb +29 -32
- data/lib/serega/plugins/if/validations/check_opt_if.rb +1 -0
- data/lib/serega/plugins/if/validations/check_opt_if_value.rb +1 -0
- data/lib/serega/plugins/if/validations/check_opt_unless.rb +1 -0
- data/lib/serega/plugins/if/validations/check_opt_unless_value.rb +1 -0
- data/lib/serega/plugins/metadata/meta_attribute.rb +2 -0
- data/lib/serega/plugins/metadata/metadata.rb +14 -12
- data/lib/serega/plugins/metadata/validations/check_block.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_opt_const.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_opt_hide_empty.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_opt_hide_nil.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_opt_value.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_opts.rb +1 -0
- data/lib/serega/plugins/metadata/validations/check_path.rb +1 -0
- data/lib/serega/plugins/presenter/presenter.rb +10 -7
- data/lib/serega/plugins/root/root.rb +12 -6
- data/lib/serega/plugins/string_modifiers/parse_string_modifiers.rb +1 -0
- data/lib/serega/plugins/string_modifiers/string_modifiers.rb +21 -0
- data/lib/serega/plugins.rb +2 -0
- data/lib/serega/utils/collection_detector.rb +2 -0
- data/lib/serega/utils/enum_deep_dup.rb +2 -0
- data/lib/serega/utils/enum_deep_freeze.rb +2 -0
- data/lib/serega/utils/method_signature.rb +2 -0
- data/lib/serega/utils/serialized_attribute_error.rb +2 -0
- data/lib/serega/utils/symbol_name.rb +2 -0
- data/lib/serega/utils/to_hash.rb +2 -0
- data/lib/serega/validations/attribute/check_block.rb +3 -0
- data/lib/serega/validations/attribute/check_name.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_base_serializer.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_batch.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_const.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_delegate.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_hash_access.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_hide.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_many.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_method.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_preload.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_serializer.rb +3 -0
- data/lib/serega/validations/attribute/check_opt_value.rb +3 -0
- data/lib/serega/validations/check_attribute_params.rb +3 -0
- data/lib/serega/validations/check_batch_loader_params.rb +3 -0
- data/lib/serega/validations/check_initiate_params.rb +3 -0
- data/lib/serega/validations/check_serialize_params.rb +3 -0
- data/lib/serega/validations/initiate/check_modifiers.rb +3 -0
- data/lib/serega/validations/utils/check_allowed_keys.rb +3 -0
- data/lib/serega/validations/utils/check_opt_is_bool.rb +3 -0
- data/lib/serega/validations/utils/check_opt_is_hash.rb +3 -0
- data/lib/serega/validations/utils/check_opt_is_string_or_symbol.rb +3 -0
- data/lib/serega.rb +95 -1
- metadata +13 -16
data/lib/serega/plugins/if/if.rb
CHANGED
|
@@ -3,46 +3,34 @@
|
|
|
3
3
|
class Serega
|
|
4
4
|
module SeregaPlugins
|
|
5
5
|
#
|
|
6
|
-
# Plugin
|
|
7
|
-
# attributes so we can remove attributes from response in various ways.
|
|
6
|
+
# Plugin :if
|
|
8
7
|
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# Adds `:if`, `:unless`, `:if_value`, `:unless_value` attribute options to
|
|
9
|
+
# conditionally remove attributes from the response.
|
|
11
10
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
11
|
+
# `:if`/`:unless` receive the serialized object and context, and are
|
|
12
|
+
# checked before the attribute value is found. `:if_value`/`:unless_value`
|
|
13
|
+
# receive the already-found value and context, checked after. The latter
|
|
14
|
+
# two cannot be used with the `:serializer` option, since a relationship
|
|
15
|
+
# has no "serialized value" of its own — use `:if`/`:unless` instead.
|
|
14
16
|
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
+
# See also the plugin-free `:hide` option (README.md#selecting-fields),
|
|
18
|
+
# which hides an attribute unconditionally.
|
|
17
19
|
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
+
# @example
|
|
21
|
+
# class UserSerializer < Serega
|
|
22
|
+
# attribute :email, if: :active? # if user.active?
|
|
23
|
+
# attribute :email, if: proc { |user, ctx| user == ctx[:current_user] } # using context
|
|
24
|
+
# attribute :email, if: CustomPolicy.method(:view_email?) # any callable
|
|
20
25
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# attribute :email, if: proc {|user, ctx| user == ctx[:current_user]} # using context
|
|
26
|
-
# attribute :email, if: CustomPolicy.method(:view_email?) # You can provide own callable object
|
|
27
|
-
#
|
|
28
|
-
# attribute :email, unless: :hidden? # unless user.hidden?
|
|
29
|
-
# attribute :email, unless: proc {|user| user.hidden?} # same
|
|
30
|
-
# attribute :email, unless: proc {|user, context| context[:show_emails]} # using context
|
|
31
|
-
# attribute :email, unless: CustomPolicy.method(:hide_email?) # You can provide own callable object
|
|
32
|
-
#
|
|
33
|
-
# attribute :email, if_value: :present? # if email.present?
|
|
34
|
-
# attribute :email, if_value: proc {|email| email.present?} # same
|
|
35
|
-
# attribute :email, if_value: proc {|email, ctx| ctx[:show_emails]} # using context
|
|
36
|
-
# attribute :email, if_value: CustomPolicy.method(:view_email?) # You can provide own callable object
|
|
37
|
-
#
|
|
38
|
-
# attribute :email, unless_value: :blank? # unless email.blank?
|
|
39
|
-
# attribute :email, unless_value: proc {|email| email.blank?} # same
|
|
40
|
-
# attribute :email, unless_value: proc {|email, context| context[:show_emails]} # using context
|
|
41
|
-
# attribute :email, unless_value: CustomPolicy.method(:hide_email?) # You can provide own callable object
|
|
42
|
-
# end
|
|
26
|
+
# attribute :email, unless: :hidden? # unless user.hidden?
|
|
27
|
+
# attribute :email, if_value: :present? # if email.present?
|
|
28
|
+
# attribute :email, unless_value: :blank? # unless email.blank?
|
|
29
|
+
# end
|
|
43
30
|
#
|
|
44
31
|
module If
|
|
45
32
|
# @return [Symbol] Plugin name
|
|
33
|
+
# @private
|
|
46
34
|
def self.plugin_name
|
|
47
35
|
:if
|
|
48
36
|
end
|
|
@@ -55,6 +43,7 @@ class Serega
|
|
|
55
43
|
#
|
|
56
44
|
# @return [void]
|
|
57
45
|
#
|
|
46
|
+
# @private
|
|
58
47
|
def self.load_plugin(serializer_class, **_opts)
|
|
59
48
|
require_relative "validations/check_opt_if"
|
|
60
49
|
require_relative "validations/check_opt_if_value"
|
|
@@ -77,6 +66,7 @@ class Serega
|
|
|
77
66
|
#
|
|
78
67
|
# @return [void]
|
|
79
68
|
#
|
|
69
|
+
# @private
|
|
80
70
|
def self.after_load_plugin(serializer_class, **opts)
|
|
81
71
|
serializer_class.config.attribute_keys << :if << :if_value << :unless << :unless_value
|
|
82
72
|
end
|
|
@@ -86,6 +76,7 @@ class Serega
|
|
|
86
76
|
#
|
|
87
77
|
# @see SeregaAttributeNormalizer::AttributeInstanceMethods
|
|
88
78
|
#
|
|
79
|
+
# @private
|
|
89
80
|
module AttributeNormalizerInstanceMethods
|
|
90
81
|
#
|
|
91
82
|
# Returns prepared attribute :if_options.
|
|
@@ -135,6 +126,7 @@ class Serega
|
|
|
135
126
|
#
|
|
136
127
|
# Resolves keyword-based conditions for if/unless options
|
|
137
128
|
#
|
|
129
|
+
# @private
|
|
138
130
|
class KeywordConditionResolver
|
|
139
131
|
def initialize(keyword)
|
|
140
132
|
@keyword = keyword
|
|
@@ -156,6 +148,7 @@ class Serega
|
|
|
156
148
|
#
|
|
157
149
|
# @see Serega::SeregaAttribute
|
|
158
150
|
#
|
|
151
|
+
# @private
|
|
159
152
|
module AttributeInstanceMethods
|
|
160
153
|
# @return [Hash] provided :if options
|
|
161
154
|
attr_reader :opt_if
|
|
@@ -177,6 +170,7 @@ class Serega
|
|
|
177
170
|
#
|
|
178
171
|
# @see Serega::SeregaPlanPoint::InstanceMethods
|
|
179
172
|
#
|
|
173
|
+
# @private
|
|
180
174
|
module PlanPointInstanceMethods
|
|
181
175
|
#
|
|
182
176
|
# @return [Boolean] Should we show attribute or not
|
|
@@ -225,6 +219,7 @@ class Serega
|
|
|
225
219
|
#
|
|
226
220
|
# @see Serega::SeregaValidations::CheckAttributeParams
|
|
227
221
|
#
|
|
222
|
+
# @private
|
|
228
223
|
module CheckAttributeParamsInstanceMethods
|
|
229
224
|
private
|
|
230
225
|
|
|
@@ -247,6 +242,7 @@ class Serega
|
|
|
247
242
|
#
|
|
248
243
|
# @see Serega::SeregaDataBuilder
|
|
249
244
|
#
|
|
245
|
+
# @private
|
|
250
246
|
module DataBuilderClassMethods
|
|
251
247
|
private
|
|
252
248
|
|
|
@@ -264,6 +260,7 @@ class Serega
|
|
|
264
260
|
#
|
|
265
261
|
# @see Serega::SeregaObjectSerializer
|
|
266
262
|
#
|
|
263
|
+
# @private
|
|
267
264
|
module ObjectSerializerInstanceMethods
|
|
268
265
|
private
|
|
269
266
|
|
|
@@ -3,23 +3,20 @@
|
|
|
3
3
|
class Serega
|
|
4
4
|
module SeregaPlugins
|
|
5
5
|
#
|
|
6
|
-
# Plugin
|
|
6
|
+
# Plugin :metadata
|
|
7
7
|
#
|
|
8
8
|
# Depends on: `:root` plugin, that must be loaded first
|
|
9
9
|
#
|
|
10
|
-
# Adds
|
|
10
|
+
# Adds metadata to the serialized response via the class-level
|
|
11
|
+
# `meta_attribute` method, which accepts:
|
|
11
12
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# - `*path` [Array of Symbols] - nested hash keys.
|
|
13
|
+
# - `*path` [Array<Symbol>] - nested hash keys
|
|
15
14
|
# - `**options` [Hash]
|
|
16
|
-
#
|
|
17
|
-
# - `:
|
|
18
|
-
# - `:
|
|
19
|
-
# - `:
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
# - `&block` [Proc] - describes value for current meta attribute
|
|
15
|
+
# - `:const` - a constant metadata value
|
|
16
|
+
# - `:value` - a `#callable` producing the metadata value
|
|
17
|
+
# - `:hide_nil` - hide the key if the value is nil (`false` by default)
|
|
18
|
+
# - `:hide_empty` - hide the key if the value is nil or empty (`false` by default)
|
|
19
|
+
# - `&block` - computes the value for this meta attribute
|
|
23
20
|
#
|
|
24
21
|
# @example
|
|
25
22
|
# class AppSerializer < Serega
|
|
@@ -39,6 +36,7 @@ class Serega
|
|
|
39
36
|
#
|
|
40
37
|
module Metadata
|
|
41
38
|
# @return [Symbol] Plugin name
|
|
39
|
+
# @private
|
|
42
40
|
def self.plugin_name
|
|
43
41
|
:metadata
|
|
44
42
|
end
|
|
@@ -50,6 +48,7 @@ class Serega
|
|
|
50
48
|
#
|
|
51
49
|
# @return [void]
|
|
52
50
|
#
|
|
51
|
+
# @private
|
|
53
52
|
def self.before_load_plugin(serializer_class, **_opts)
|
|
54
53
|
unless serializer_class.plugin_used?(:root)
|
|
55
54
|
raise SeregaError, "Plugin #{plugin_name.inspect} must be loaded after the :root plugin. Please load the :root plugin first"
|
|
@@ -64,6 +63,7 @@ class Serega
|
|
|
64
63
|
#
|
|
65
64
|
# @return [void]
|
|
66
65
|
#
|
|
66
|
+
# @private
|
|
67
67
|
def self.load_plugin(serializer_class, **_opts)
|
|
68
68
|
serializer_class.extend(ClassMethods)
|
|
69
69
|
serializer_class.include(InstanceMethods)
|
|
@@ -91,6 +91,7 @@ class Serega
|
|
|
91
91
|
#
|
|
92
92
|
# @return [void]
|
|
93
93
|
#
|
|
94
|
+
# @private
|
|
94
95
|
def self.after_load_plugin(serializer_class, **_opts)
|
|
95
96
|
serializer_class.config.opts[:metadata] = {attribute_keys: %i[const hide_nil hide_empty value]}
|
|
96
97
|
end
|
|
@@ -183,6 +184,7 @@ class Serega
|
|
|
183
184
|
#
|
|
184
185
|
# @see Serega
|
|
185
186
|
#
|
|
187
|
+
# @private
|
|
186
188
|
module InstanceMethods
|
|
187
189
|
private
|
|
188
190
|
|
|
@@ -15,12 +15,10 @@ class Serega
|
|
|
15
15
|
# - The original object is accessible via __getobj__ (standard SimpleDelegator API).
|
|
16
16
|
# - The serialization context is accessible via the private method __ctx__.
|
|
17
17
|
#
|
|
18
|
-
#
|
|
19
|
-
# class
|
|
20
|
-
# a bare `plugin :presenter` adds no wrapping overhead. The check is
|
|
21
|
-
# denormalized: `SerializerClass.custom_presenter?` is asked once per
|
|
22
|
-
# object serializer and the result is reused for the whole level.
|
|
18
|
+
# The `presenter do ... end` block is evaluated inside the serializer's own
|
|
19
|
+
# Presenter class, so multiple blocks accumulate.
|
|
23
20
|
#
|
|
21
|
+
# @example
|
|
24
22
|
# class UserSerializer < Serega
|
|
25
23
|
# plugin :presenter
|
|
26
24
|
#
|
|
@@ -38,10 +36,9 @@ class Serega
|
|
|
38
36
|
# end
|
|
39
37
|
# end
|
|
40
38
|
#
|
|
41
|
-
# The `presenter do ... end` block is evaluated inside the serializer's own
|
|
42
|
-
# Presenter class, so multiple blocks accumulate.
|
|
43
39
|
module Presenter
|
|
44
40
|
# @return [Symbol] Plugin name
|
|
41
|
+
# @private
|
|
45
42
|
def self.plugin_name
|
|
46
43
|
:presenter
|
|
47
44
|
end
|
|
@@ -54,6 +51,7 @@ class Serega
|
|
|
54
51
|
#
|
|
55
52
|
# @return [void]
|
|
56
53
|
#
|
|
54
|
+
# @private
|
|
57
55
|
def self.load_plugin(serializer_class, **_opts)
|
|
58
56
|
serializer_class.extend(ClassMethods)
|
|
59
57
|
serializer_class::SeregaObjectSerializer.include(SeregaObjectSerializerInstanceMethods)
|
|
@@ -67,6 +65,7 @@ class Serega
|
|
|
67
65
|
#
|
|
68
66
|
# @return [void]
|
|
69
67
|
#
|
|
68
|
+
# @private
|
|
70
69
|
def self.after_load_plugin(serializer_class, **_opts)
|
|
71
70
|
presenter_class = Class.new(Presenter)
|
|
72
71
|
presenter_class.serializer_class = serializer_class
|
|
@@ -79,8 +78,10 @@ class Serega
|
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
# Presenter class
|
|
81
|
+
# @private
|
|
82
82
|
class Presenter < SimpleDelegator
|
|
83
83
|
# Presenter instance methods
|
|
84
|
+
# @private
|
|
84
85
|
module InstanceMethods
|
|
85
86
|
#
|
|
86
87
|
# @param object [Object] Serialized object to wrap
|
|
@@ -187,6 +188,7 @@ class Serega
|
|
|
187
188
|
#
|
|
188
189
|
# @return [Boolean] whether custom presenter methods were defined
|
|
189
190
|
#
|
|
191
|
+
# @private
|
|
190
192
|
def custom_presenter?
|
|
191
193
|
self::Presenter.modified?
|
|
192
194
|
end
|
|
@@ -207,6 +209,7 @@ class Serega
|
|
|
207
209
|
#
|
|
208
210
|
# @see Serega::SeregaObjectSerializer
|
|
209
211
|
#
|
|
212
|
+
# @private
|
|
210
213
|
module SeregaObjectSerializerInstanceMethods
|
|
211
214
|
# The custom-presenter check is made once per object serializer here
|
|
212
215
|
# and its result is reused for every enqueued chunk of the level.
|
|
@@ -5,7 +5,7 @@ class Serega
|
|
|
5
5
|
#
|
|
6
6
|
# Plugin :root
|
|
7
7
|
#
|
|
8
|
-
#
|
|
8
|
+
# Adds a root key to serialized data.
|
|
9
9
|
#
|
|
10
10
|
# Accepts options:
|
|
11
11
|
# - :root - specifies root for all responses
|
|
@@ -16,14 +16,12 @@ class Serega
|
|
|
16
16
|
# - config.root.one
|
|
17
17
|
# - config.root.many
|
|
18
18
|
# - config.root.one=
|
|
19
|
-
# - config.
|
|
19
|
+
# - config.root.many=
|
|
20
20
|
#
|
|
21
21
|
# Default root is `:data`.
|
|
22
22
|
#
|
|
23
|
-
# Root also
|
|
24
|
-
#
|
|
25
|
-
# Also root can be removed for all responses by providing `root: nil`. In this case no root will be added to response, but
|
|
26
|
-
# you still can to add it per serialization
|
|
23
|
+
# Root can also be changed per serialization, or removed entirely by
|
|
24
|
+
# providing `root: nil` (per serialization it can still be added back).
|
|
27
25
|
#
|
|
28
26
|
# @example Define plugin
|
|
29
27
|
# class UserSerializer < Serega
|
|
@@ -56,6 +54,7 @@ class Serega
|
|
|
56
54
|
ROOT_DEFAULT = :data
|
|
57
55
|
|
|
58
56
|
# @return [Symbol] Plugin name
|
|
57
|
+
# @private
|
|
59
58
|
def self.plugin_name
|
|
60
59
|
:root
|
|
61
60
|
end
|
|
@@ -67,6 +66,7 @@ class Serega
|
|
|
67
66
|
#
|
|
68
67
|
# @return [void]
|
|
69
68
|
#
|
|
69
|
+
# @private
|
|
70
70
|
def self.before_load_plugin(serializer_class, **opts)
|
|
71
71
|
allowed_keys = %i[root root_one root_many]
|
|
72
72
|
opts.each_key do |key|
|
|
@@ -88,6 +88,7 @@ class Serega
|
|
|
88
88
|
#
|
|
89
89
|
# @return [void]
|
|
90
90
|
#
|
|
91
|
+
# @private
|
|
91
92
|
def self.load_plugin(serializer_class, **_opts)
|
|
92
93
|
serializer_class.extend(ClassMethods)
|
|
93
94
|
serializer_class.include(InstanceMethods)
|
|
@@ -103,6 +104,7 @@ class Serega
|
|
|
103
104
|
#
|
|
104
105
|
# @return [void]
|
|
105
106
|
#
|
|
107
|
+
# @private
|
|
106
108
|
def self.after_load_plugin(serializer_class, **opts)
|
|
107
109
|
config = serializer_class.config
|
|
108
110
|
default = opts.fetch(:root, ROOT_DEFAULT)
|
|
@@ -214,6 +216,7 @@ class Serega
|
|
|
214
216
|
#
|
|
215
217
|
# @see Serega
|
|
216
218
|
#
|
|
219
|
+
# @private
|
|
217
220
|
module InstanceMethods
|
|
218
221
|
#
|
|
219
222
|
# Serializes provided object to a tree of Ruby Data objects.
|
|
@@ -226,6 +229,8 @@ class Serega
|
|
|
226
229
|
# @return [Data, Array<Data>, nil] Serialization result as Data object(s)
|
|
227
230
|
#
|
|
228
231
|
def to_data(object, opts = nil)
|
|
232
|
+
opts = normalize_serialization_opts(opts)
|
|
233
|
+
object = prepare_objects(object, opts[:context])
|
|
229
234
|
opts = prepare_initial_serialization_opts(object, opts)
|
|
230
235
|
serialized_data = serialize(object, opts)
|
|
231
236
|
self.class::SeregaDataBuilder.call(self, serialized_data, opts)
|
|
@@ -261,6 +266,7 @@ class Serega
|
|
|
261
266
|
#
|
|
262
267
|
# @see Serega::SeregaDataBuilder
|
|
263
268
|
#
|
|
269
|
+
# @private
|
|
264
270
|
module DataBuilderClassMethods
|
|
265
271
|
#
|
|
266
272
|
# @param serializer [Serega] Serializer instance carrying the plan
|
|
@@ -2,8 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
class Serega
|
|
4
4
|
module SeregaPlugins
|
|
5
|
+
#
|
|
6
|
+
# Plugin :string_modifiers
|
|
7
|
+
#
|
|
8
|
+
# Allows `:only`, `:except` and `:with` to be given as a single comma-separated
|
|
9
|
+
# string, with nested attributes in parentheses. Useful for accepting a field
|
|
10
|
+
# list straight from a query parameter.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# class UserSerializer < Serega
|
|
14
|
+
# plugin :string_modifiers
|
|
15
|
+
#
|
|
16
|
+
# attribute :username
|
|
17
|
+
# attribute :first_name
|
|
18
|
+
# attribute :addresses, serializer: AddressSerializer, hide: true
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# UserSerializer.to_h(user, only: "username,addresses(line1,line2)")
|
|
22
|
+
#
|
|
5
23
|
module StringModifiers
|
|
6
24
|
# @return [Symbol] Plugin name
|
|
25
|
+
# @private
|
|
7
26
|
def self.plugin_name
|
|
8
27
|
:string_modifiers
|
|
9
28
|
end
|
|
@@ -16,6 +35,7 @@ class Serega
|
|
|
16
35
|
#
|
|
17
36
|
# @return [void]
|
|
18
37
|
#
|
|
38
|
+
# @private
|
|
19
39
|
def self.load_plugin(serializer_class, **_opts)
|
|
20
40
|
serializer_class.include(InstanceMethods)
|
|
21
41
|
require_relative "parse_string_modifiers"
|
|
@@ -26,6 +46,7 @@ class Serega
|
|
|
26
46
|
#
|
|
27
47
|
# @see Serega
|
|
28
48
|
#
|
|
49
|
+
# @private
|
|
29
50
|
module InstanceMethods
|
|
30
51
|
private
|
|
31
52
|
|
data/lib/serega/plugins.rb
CHANGED
|
@@ -17,6 +17,7 @@ class Serega
|
|
|
17
17
|
#
|
|
18
18
|
# @return [void]
|
|
19
19
|
#
|
|
20
|
+
# @private
|
|
20
21
|
def register_plugin(name, mod)
|
|
21
22
|
@plugins[name] = mod
|
|
22
23
|
end
|
|
@@ -36,6 +37,7 @@ class Serega
|
|
|
36
37
|
#
|
|
37
38
|
# @return [Class<Module>] Plugin core module
|
|
38
39
|
#
|
|
40
|
+
# @private
|
|
39
41
|
def find_plugin(name)
|
|
40
42
|
return name if name.is_a?(Module)
|
|
41
43
|
return @plugins[name] if @plugins.key?(name)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Serega
|
|
4
|
+
# @private
|
|
4
5
|
module SeregaUtils
|
|
5
6
|
#
|
|
6
7
|
# Utility to check if an object should be serialized as a collection.
|
|
@@ -8,6 +9,7 @@ class Serega
|
|
|
8
9
|
# Hashes and Structs are Enumerable, but enumerate their own member
|
|
9
10
|
# values, so they are treated as single objects.
|
|
10
11
|
#
|
|
12
|
+
# @private
|
|
11
13
|
class CollectionDetector
|
|
12
14
|
class << self
|
|
13
15
|
#
|
|
@@ -4,10 +4,12 @@ class Serega
|
|
|
4
4
|
#
|
|
5
5
|
# Utilities
|
|
6
6
|
#
|
|
7
|
+
# @private
|
|
7
8
|
module SeregaUtils
|
|
8
9
|
#
|
|
9
10
|
# Utility to make method arguments signature
|
|
10
11
|
#
|
|
12
|
+
# @private
|
|
11
13
|
class MethodSignature
|
|
12
14
|
SYMBOL_TO_PROC_SIGNATURE_RUBY2 = [[:rest]]
|
|
13
15
|
SYMBOL_TO_PROC_SIGNATURE_RUBY3 = [[:req], [:rest]]
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Serega
|
|
4
|
+
# @private
|
|
4
5
|
module SeregaUtils
|
|
5
6
|
#
|
|
6
7
|
# Reraises an error, adding which attribute and serializer were being
|
|
@@ -8,6 +9,7 @@ class Serega
|
|
|
8
9
|
# and the batch attach phase so the message stays identical for every
|
|
9
10
|
# attribute, whether its value is resolved inline or during batch loading.
|
|
10
11
|
#
|
|
12
|
+
# @private
|
|
11
13
|
module SerializedAttributeError
|
|
12
14
|
module_function
|
|
13
15
|
|
data/lib/serega/utils/to_hash.rb
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Serega
|
|
4
|
+
# @private
|
|
4
5
|
module SeregaValidations
|
|
5
6
|
#
|
|
6
7
|
# Attribute parameters validators
|
|
7
8
|
#
|
|
9
|
+
# @private
|
|
8
10
|
module Attribute
|
|
9
11
|
#
|
|
10
12
|
# Attribute `block` parameter validator
|
|
11
13
|
#
|
|
14
|
+
# @private
|
|
12
15
|
class CheckBlock
|
|
13
16
|
# Explains the changed attribute block behavior. Shown when the block
|
|
14
17
|
# looks like an old-style value block — it accepts parameters or
|