alba 3.11.0 → 4.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18b9be1d51ec5b7bed2d31fc59904a57c8dc7f4e24eb1a7cb6364a42ec8a27ec
4
- data.tar.gz: 4112d0ace0fda10a9e6aee754e2b056b6488924fddbd5f12040652a2fcbbda75
3
+ metadata.gz: 5d12f771fcf00170b05fe313ce064b0215f134d75a14d1238d0766e3964d562f
4
+ data.tar.gz: b9c77e2574d7b502fc450140483eef2d66eeb3cb7e1a6c6497bb2b29d173d095
5
5
  SHA512:
6
- metadata.gz: 7bee8581bad84469254b1282b3c81bdaf493be4f2c5ee1b31747b16f2908f4e2639d783ac9fa7e6f345b361117512f0ce4b208a81a2f000e05455d3bc875b08b
7
- data.tar.gz: 6939052cd6b8ea09f23df209874c858aadc032193a0ab5729bd04d33bbf7d24e3223cc642494a0095ca4a8f7a4b182fdd4cbd4e9781c1d4689e205953c2ca2e7
6
+ metadata.gz: 6ed47193f8bb3ff7395b51ca990fc438665f40fad85eefdc4cfbe7e53a7c783c9b34456d2c931f967e0767cae63a737f807f1a47abf14f2d5ef4e14d6b8f249a
7
+ data.tar.gz: d2231e2244a99fd960b778df059813ee99b64e8ff8d83e13dcebeb15da655e2c5b5127f28ee2f4efcb5e294816424bfc32f3021695c03b791e9d30caffc3e42d
data/CHANGELOG.md CHANGED
@@ -6,6 +6,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 4.0.1 2026-10-17
10
+
11
+ ### Added
12
+
13
+ - Ship the RBS signatures in the gem so applications can load them [#575](https://github.com/okuramasafumi/alba/pull/575)
14
+
15
+ ### Changed
16
+
17
+ - Improve RBS signatures for resource classes, serialization results, callbacks, inflectors, and custom types [#576](https://github.com/okuramasafumi/alba/pull/576)
18
+ - Correct RBS signatures to allow anonymous resource classes to have no name [#579](https://github.com/okuramasafumi/alba/pull/579)
19
+ - Rename the `Alba::Association.new` keyword argument `condition:` to `modifier:` to clarify its purpose
20
+
21
+ ### Fixed
22
+
23
+ - Raise `TypeError` instead of `NoMethodError` when automatic type conversion is enabled without a converter
24
+ - Raise `Alba::Error` instead of `NoMethodError` when `root_key!` is used on an anonymous resource class [#580](https://github.com/okuramasafumi/alba/pull/580)
25
+
26
+ ## 4.0.0 2026-08-28
27
+
28
+ ### Changed
29
+
30
+ - Call #nil? on attribute values only when a nil handler is set [#546](https://github.com/okuramasafumi/alba/pull/546)
31
+
32
+ ### Removed
33
+
34
+ - Remove the deprecated inference methods `Alba.enable_inference!`, `Alba.disable_inference!`, and `Alba.inferring`; use `Alba.inflector` and `Alba.inflector=` instead
35
+ - Remove the deprecated `Alba.resource_with`; use `Alba.resource_for` instead
36
+ - Remove deprecated support for overriding `Alba::Resource#attributes`; override `Alba::Resource#select` to filter attributes instead
37
+ - Remove the deprecated `converter` and `collection_converter` serialization hooks
38
+ - Remove the deprecated `select` keyword argument from `Alba::Resource#initialize`; the `Alba::Resource#select` filtering method remains available
39
+
9
40
  ## 3.11.0 2026-07-25
10
41
 
11
42
  ### Added
data/README.md CHANGED
@@ -12,16 +12,6 @@
12
12
 
13
13
  Alba is a JSON serializer for Ruby, JRuby, and TruffleRuby.
14
14
 
15
- ## IMPORTANT NOTICE
16
-
17
- Both version `3.0.0` and `2.4.2` contain important bug fix.
18
- ~~However, version `3.0.0` has some bugs (see https://github.com/okuramasafumi/alba/issues/342).
19
- Until they get fixed, it's highly recommended to upgrade to version `2.4.2`.
20
- Dependabot and similar tools might create an automated Pull Request to upgrade to `3.0.0`, so it might be required to upgrade to `2.4.2` manually.~~
21
- Version `3.0.1` has been released so Ruby 3 users should upgrade to `3.0.1`.
22
- For Ruby 2 users, it's highly recommended to upgrade to `2.4.2`.
23
- Sorry for the inconvenience.
24
-
25
15
  ## TL;DR
26
16
 
27
17
  Alba allows you to do something like below.
@@ -13,7 +13,7 @@ module Alba
13
13
  attr_reader :name
14
14
 
15
15
  # @param name [Symbol, String] name of the method to fetch association
16
- # @param condition [Proc, nil] a proc filtering data
16
+ # @param modifier [Proc, nil] a Proc to modify the association
17
17
  # @param resource [Class<Alba::Resource>, Proc, String, Symbol, nil]
18
18
  # a resource class for the association, a proc returning a resource class or a name of the resource
19
19
  # @param source [Proc, nil] a proc to specify the source of the association
@@ -25,7 +25,7 @@ module Alba
25
25
  # @param block [Block] used to define resource when resource arg is absent
26
26
  def initialize(
27
27
  name:,
28
- condition: nil,
28
+ modifier: nil,
29
29
  resource: nil,
30
30
  source: nil,
31
31
  with_traits: nil,
@@ -36,14 +36,11 @@ module Alba
36
36
  &block
37
37
  )
38
38
  @name = name
39
- @condition = condition
40
- @resource = resource
39
+ @modifier = modifier
40
+ @resource = resource || resource_from(nesting, key_transformation, block, helper)
41
41
  @source = source
42
42
  @with_traits = with_traits
43
43
  @params = params
44
- return if @resource
45
-
46
- assign_resource(nesting, key_transformation, block, helper)
47
44
  end
48
45
 
49
46
  # This is the same API in `NestedAttribute`
@@ -82,7 +79,7 @@ module Alba
82
79
  else
83
80
  target.is_a?(Hash) ? target.fetch(@name) : target.__send__(@name)
84
81
  end
85
- o = @condition.call(o, params, target) if @condition
82
+ o = @modifier.call(o, params, target) if @modifier
86
83
  o
87
84
  end
88
85
 
@@ -99,14 +96,14 @@ module Alba
99
96
  end
100
97
  end
101
98
 
102
- def assign_resource(nesting, key_transformation, block, helper)
103
- @resource = if block
104
- Alba.resource_class(helper: helper, key_transformation: key_transformation, &block)
105
- elsif Alba.inflector
106
- Alba.infer_resource_class(@name, nesting: nesting)
107
- else
108
- raise ArgumentError, 'When Alba.inflector is nil, either resource or block is required'
109
- end
99
+ def resource_from(nesting, key_transformation, block, helper)
100
+ if block
101
+ Alba.resource_class(helper: helper, key_transformation: key_transformation, &block)
102
+ elsif Alba.inflector
103
+ Alba.infer_resource_class(@name, nesting: nesting)
104
+ else
105
+ raise ArgumentError, 'When Alba.inflector is nil, either resource or block is required'
106
+ end
110
107
  end
111
108
 
112
109
  def to_h_with_each_resource(object, within, params)
data/lib/alba/resource.rb CHANGED
@@ -51,13 +51,11 @@ module Alba
51
51
  # @param within [Alba::WITHIN_DEFAULT, Hash, Array, nil, false, true]
52
52
  # determines what associations to be serialized. If not set, it serializes all associations.
53
53
  # @param with_traits [Symbol, Array<Symbol>, nil] specified traits
54
- # @param select [Method] DEPRECATED noop
55
- def initialize(object, params: EMPTY_HASH, within: WITHIN_DEFAULT, with_traits: nil, select: nil)
54
+ def initialize(object, params: EMPTY_HASH, within: WITHIN_DEFAULT, with_traits: nil)
56
55
  @object = object
57
56
  @params = params
58
57
  @within = within
59
58
  @with_traits = with_traits
60
- warn '`select` keyword for Alba::Resource is deprecated', category: :deprecated, uplevel: 1 if select
61
59
  _setup
62
60
  end
63
61
 
@@ -127,10 +125,6 @@ module Alba
127
125
  end
128
126
  end
129
127
 
130
- def deprecated_serializable_hash
131
- Alba.collection?(@object) ? serializable_hash_for_collection : converter.call(@object)
132
- end
133
-
134
128
  def serialize_with(hash)
135
129
  serialized_json = encode(hash)
136
130
  return serialized_json unless @_layout
@@ -167,18 +161,6 @@ module Alba
167
161
  end
168
162
  end
169
163
 
170
- def deprecated_serializable_hash_for_collection
171
- if @_collection_key
172
- @object.to_h do |item|
173
- k = item.public_send(@_collection_key)
174
- key = Alba.regularize_key(k)
175
- [key, converter.call(item)]
176
- end
177
- else
178
- @object.each_with_object([], &collection_converter)
179
- end
180
- end
181
-
182
164
  # @return [String]
183
165
  def fetch_key
184
166
  k = Alba.collection?(@object) ? _key_for_collection : _key
@@ -200,6 +182,8 @@ module Alba
200
182
  raise Alba::Error, 'You must set inflector when setting root key as true.' unless inflector
201
183
 
202
184
  class_name = self.class.name
185
+ raise Alba::Error, 'An anonymous resource class has no name to derive a root key from. Set the key explicitly.' unless class_name
186
+
203
187
  suffix = class_name.end_with?('Resource') ? 'Resource' : 'Serializer'
204
188
  name = inflector.demodulize(class_name).delete_suffix(suffix)
205
189
  underscore_name = inflector.underscore(name)
@@ -210,23 +194,8 @@ module Alba
210
194
  @_transforming_root_key
211
195
  end
212
196
 
213
- def converter
214
- lambda do |obj|
215
- attributes_to_hash(obj, {})
216
- end
217
- end
218
-
219
- def collection_converter
220
- lambda do |obj, a|
221
- a << {}
222
- h = a.last
223
- attributes_to_hash(obj, h)
224
- a
225
- end
226
- end
227
-
228
197
  def attributes_to_hash(obj, hash)
229
- attributes.each do |key, attribute|
198
+ @_attributes.each do |key, attribute|
230
199
  set_key_and_attribute_body_from(obj, key, attribute, hash)
231
200
  rescue ::Alba::Error, FrozenError, TypeError
232
201
  raise
@@ -236,14 +205,6 @@ module Alba
236
205
  @with_traits.nil? ? hash : hash.merge!(hash_from_traits(obj))
237
206
  end
238
207
 
239
- # This is default behavior for getting attributes for serialization
240
- # Override this method to filter certain attributes
241
- #
242
- # @deprecated in favor of `select`
243
- def attributes
244
- @_attributes
245
- end
246
-
247
208
  # Default implementation for selecting attributes
248
209
  # Override this method to filter attributes based on key and value
249
210
  def select(_key, _value, _attribute)
@@ -299,7 +260,7 @@ module Alba
299
260
  else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
300
261
  # :nocov:
301
262
  end
302
- value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
263
+ nil_handler && value.nil? ? instance_exec(obj, key, attribute, &nil_handler) : value # steep:ignore
303
264
  end
304
265
 
305
266
  def fetch_attribute_from_object_and_resource(obj, attribute)
@@ -353,16 +314,8 @@ module Alba
353
314
  attr_reader(*INTERNAL_VARIABLES.keys)
354
315
 
355
316
  # This `method_added` is used for defining "resource methods"
356
- def method_added(method_name) # rubocop:disable Metrics/MethodLength
317
+ def method_added(method_name)
357
318
  case method_name
358
- when :collection_converter, :converter
359
- warn "Defining ##{method_name} methods is deprecated", category: :deprecated, uplevel: 1
360
- alias_method :serializable_hash_for_collection, :deprecated_serializable_hash_for_collection
361
- private(:serializable_hash_for_collection)
362
- alias_method :serializable_hash, :deprecated_serializable_hash
363
- alias_method :to_h, :deprecated_serializable_hash
364
- when :attributes
365
- warn 'Overriding `attributes` is deprecated, use `select` instead.', category: :deprecated, uplevel: 1
366
319
  when :select
367
320
  @_select_arity = instance_method(:select).arity
368
321
  when :_setup # noop
@@ -437,7 +390,7 @@ module Alba
437
390
  # Set association
438
391
  #
439
392
  # @param name [String, Symbol] name of the association, used as key when `key` param doesn't exist
440
- # @param condition [Proc, nil] a Proc to modify the association
393
+ # @param modifier [Proc, nil] a Proc to modify the association
441
394
  # @param resource [Class<Alba::Resource>, String, Proc, nil] representing resource for this association
442
395
  # @param serializer [Class<Alba::Resource>, String, Proc, nil] alias for `resource`
443
396
  # @param source [Proc, nil] a Proc to customize the association source
@@ -451,11 +404,11 @@ module Alba
451
404
  # @param block [Block]
452
405
  # @return [void]
453
406
  # @see Alba::Association#initialize
454
- def association(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: EMPTY_HASH, **options, &block)
407
+ def association(name, modifier = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: EMPTY_HASH, **options, &block)
455
408
  resource ||= serializer
456
409
  transformation = @_key_transformation_cascade ? @_transform_type : :none
457
410
  assoc = Association.new(
458
- name: name, condition: condition, resource: resource, source: source, with_traits: with_traits,
411
+ name: name, modifier: modifier, resource: resource, source: source, with_traits: with_traits,
459
412
  params: params, nesting: nesting, key_transformation: transformation, helper: @_helper,
460
413
  &block
461
414
  )
@@ -467,11 +420,10 @@ module Alba
467
420
  alias has_many association
468
421
 
469
422
  def nesting
470
- if name.nil?
471
- nil
472
- else
473
- name.rpartition('::').first.then { |n| n.empty? ? nil : n }
474
- end
423
+ class_name = name
424
+ return if class_name.nil?
425
+
426
+ class_name.rpartition('::').first.then { |n| n.empty? ? nil : n }
475
427
  end
476
428
  private :nesting
477
429
 
@@ -595,7 +547,7 @@ module Alba
595
547
  end
596
548
 
597
549
  # Set error handler
598
- # If this is set it's used as a error handler overriding global one
550
+ # Defaults to raising errors when no handler is set.
599
551
  #
600
552
  # @param handler [Symbol] `:raise`, `:ignore` or `:nullify`
601
553
  # @param block [Block]
data/lib/alba/type.rb CHANGED
@@ -32,7 +32,7 @@ module Alba
32
32
  #
33
33
  # @param obj [Object] object to convert
34
34
  def convert(obj)
35
- @auto_convert ? @converter.call(obj) : raise(TypeError)
35
+ @auto_convert && @converter ? @converter.call(obj) : raise(TypeError) # steep:ignore
36
36
  end
37
37
 
38
38
  # Enable auto convert with given converter
data/lib/alba/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alba
4
- VERSION = '3.11.0'
4
+ VERSION = '4.0.1'
5
5
  end
data/lib/alba.rb CHANGED
@@ -97,34 +97,6 @@ module Alba
97
97
  object.is_a?(Enumerable) && @non_collection_types.none? { |type| object.is_a?(type) }
98
98
  end
99
99
 
100
- # Enable inference for key and resource name
101
- #
102
- # @param with [Symbol, Class, Module] inflector
103
- # When it's a Symbol, it sets inflector with given name
104
- # When it's a Class or a Module, it sets given object to inflector
105
- # @deprecated Use {.inflector=} instead
106
- def enable_inference!(with:)
107
- Alba::Deprecation.warn('Alba.enable_inference! is deprecated. Use `Alba.inflector=` instead.')
108
- @inflector = inflector_from(with)
109
- @inferring = true
110
- end
111
-
112
- # Disable inference for key and resource name
113
- #
114
- # @deprecated Use {.inflector=} instead
115
- def disable_inference!
116
- Alba::Deprecation.warn('Alba.disable_inference! is deprecated. Use `Alba.inflector = nil` instead.')
117
- @inferring = false
118
- @inflector = nil
119
- end
120
-
121
- # @deprecated Use {.inflector} instead
122
- # @return [Boolean] whether inference is enabled or not
123
- def inferring
124
- Alba::Deprecation.warn('Alba.inferring is deprecated. Use `Alba.inflector` instead.')
125
- @inferring
126
- end
127
-
128
100
  # Set an inflector
129
101
  #
130
102
  # @param inflector [Symbol, Class, Module] inflector
@@ -140,7 +112,7 @@ module Alba
140
112
  # @param block [Block] resource body
141
113
  # @return [Class<Alba::Resource>] resource class
142
114
  def resource_class(helper: nil, key_transformation: :none, &block)
143
- klass = Class.new(resolved_default_superclass)
115
+ klass = Class.new(resolved_default_superclass) # : Class & Alba::resource_class
144
116
  klass.include(Alba::Resource)
145
117
  klass.helper(helper) if helper
146
118
  klass.transform_keys(key_transformation)
@@ -148,11 +120,11 @@ module Alba
148
120
  klass
149
121
  end
150
122
 
151
- # @param name [String] a String Alba infers resource name with
123
+ # @param name [String, Symbol] a name Alba infers resource name with
152
124
  # @param nesting [String, nil] namespace Alba tries to find resource class in
153
125
  # @return [Class<Alba::Resource>] resource class
154
126
  def infer_resource_class(name, nesting: nil)
155
- raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Set inflector before use.' unless Alba.inflector
127
+ raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Set inflector before use.' unless inflector
156
128
 
157
129
  const_parent = nesting.nil? ? Object : Object.const_get(nesting)
158
130
  begin
@@ -231,8 +203,6 @@ module Alba
231
203
  def reset!
232
204
  @encoder = default_encoder
233
205
  @symbolize_keys = false
234
- @_on_error = :raise
235
- @_on_nil = nil
236
206
  @types = {}
237
207
  @non_collection_types = [Struct, Range, Hash]
238
208
  @default_superclass = ::Object
@@ -240,12 +210,6 @@ module Alba
240
210
  register_default_types
241
211
  end
242
212
 
243
- # @deprecated Use resource_for instead
244
- def resource_with(object, with: :inference, &block)
245
- Kernel.warn('Alba.resource_with is deprecated. Use `Alba.resource_for` instead.')
246
- _resource_for(object, with: with, &block)
247
- end
248
-
249
213
  # Get a resource object from arguments
250
214
  # If block is given, it creates a resource class with the block
251
215
  # Otherwise, it behaves depending on `with` argument
@@ -360,7 +324,7 @@ module Alba
360
324
 
361
325
  def register_default_types # rubocop:disable Metrics/AbcSize
362
326
  [String, :String].each do |t|
363
- register_type(t, check: ->(obj) { obj.is_a?(String) }, converter: lambda(&:to_s))
327
+ register_type(t, check: ->(obj) { obj.is_a?(String) }, converter: lambda(&:to_s)) # steep:ignore
364
328
  end
365
329
  [Integer, :Integer].each do |t|
366
330
  register_type(t, check: ->(obj) { obj.is_a?(Integer) }, converter: ->(obj) { Integer(obj) })
@@ -0,0 +1,46 @@
1
+ module Alba
2
+ # Representing association
3
+ class Association
4
+ # Class methods
5
+ self.@const_cache: Hash[Symbol | String, Class]
6
+
7
+ @modifier: untyped
8
+ @resource: untyped
9
+ @source: Proc?
10
+ @with_traits: Symbol | Array[Symbol] | nil
11
+ @params: generic_hash
12
+
13
+ def self.const_cache: () -> Hash[Symbol | String, Class]
14
+
15
+ # Instance variables and methods
16
+ attr_reader name: Symbol | String
17
+
18
+ def initialize: (
19
+ name: Symbol | String,
20
+ ?modifier: Proc?,
21
+ ?resource: (Class | Proc | String | Symbol)?,
22
+ ?source: Proc?,
23
+ ?with_traits: (Symbol | Array[Symbol])?,
24
+ ?params: generic_hash,
25
+ ?nesting: String?,
26
+ ?key_transformation: Alba::transform_type,
27
+ ?helper: Module?
28
+ ) ?{ () [self: singleton(Resource)] -> void } -> void
29
+
30
+ def key_transformation=: (Symbol | String type) -> void
31
+
32
+ def to_h: (
33
+ untyped target,
34
+ ?within: within,
35
+ ?params: generic_hash
36
+ ) -> (generic_hash | Array[generic_hash] | nil)
37
+
38
+ private
39
+
40
+ def object_from: (untyped target, generic_hash params) -> untyped
41
+ def constantize: (Class | Symbol | String resource) -> Class
42
+ def resource_from: (String? nesting, Alba::transform_type key_transformation, (^() [self: singleton(::Alba::Resource)] -> void)? block, Module? helper) -> Alba::resource_class
43
+ def to_h_with_each_resource: (Enumerable[untyped] object, within within, generic_hash params) -> Array[generic_hash]
44
+ def to_h_with_constantize_resource: (untyped object, within within, generic_hash params) -> generic_hash
45
+ end
46
+ end
@@ -0,0 +1,24 @@
1
+ module Alba
2
+ # Represents attribute with `if` option
3
+ class ConditionalAttribute
4
+ type condition = Symbol | Proc
5
+ @body: untyped
6
+ @condition: untyped
7
+
8
+ def initialize: (
9
+ body: Alba::Resource::attribute,
10
+ condition: condition
11
+ ) -> void
12
+
13
+ def with_passing_condition: (
14
+ resource: Alba::Resource::InstanceMethods,
15
+ ?object: untyped
16
+ ) { (Alba::Resource::attribute) -> untyped } -> untyped
17
+
18
+ private
19
+
20
+ def condition_passes?: (Alba::Resource::InstanceMethods resource, untyped object) -> bool
21
+ def with_two_arity_proc_condition?: () -> bool
22
+ def second_object: (untyped object, Alba::Resource::InstanceMethods resource) -> untyped
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Alba
2
+ # A constant to remove key from serialized JSON
3
+ REMOVE_KEY: Object
4
+ end
@@ -0,0 +1,13 @@
1
+ module Alba
2
+ # Adapter module for ActiveSupport inflector
3
+ # Note: This is already defined in alba.rbs but moved here for consistency
4
+ module DefaultInflector
5
+ def self.camelize: (String key) -> String
6
+ def self.camelize_lower: (String key) -> String
7
+ def self.dasherize: (String key) -> String
8
+ def self.underscore: (String key) -> String
9
+ def self.classify: (String | Symbol key) -> String
10
+ def self.demodulize: (String key) -> String
11
+ def self.pluralize: (String key) -> String
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module Alba
2
+ # Module for printing deprecation warning
3
+ module Deprecation
4
+ def self?.warn: (_ToS message) -> nil
5
+ def caller_locations: (Range[Integer]) -> Array[Thread::Backtrace::Location]
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ module Alba
2
+ # Base error class for Alba
3
+ class Error < StandardError
4
+ end
5
+
6
+ # Raised when an unsupported backend is specified
7
+ class UnsupportedBackend < Error
8
+ end
9
+
10
+ # Raised when an unknown type is specified
11
+ class UnsupportedType < Error
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Alba
2
+ # Layout serialization
3
+ class Layout
4
+ @body: untyped
5
+ @resource: untyped
6
+ @serialized_json: String
7
+
8
+ def object: () -> untyped
9
+ def params: () -> generic_hash
10
+ def serializable_hash: () -> generic_hash
11
+ def to_h: () -> generic_hash
12
+
13
+ def self.def_delegators: (Symbol, *Symbol) -> void
14
+
15
+ def initialize: (
16
+ file: String?,
17
+ inline: Proc?
18
+ ) -> void
19
+
20
+ def serialize: (
21
+ resource: Alba::Resource::_InstanceMethods,
22
+ serialized_json: String,
23
+ binding: Binding
24
+ ) -> String
25
+
26
+ private
27
+
28
+ attr_reader serialized_json: String
29
+
30
+ def check_and_return: (Object obj, String message, Class klass) -> Object
31
+ def serialize_within_string_layout: (Binding bnd) -> String
32
+ def serialize_within_inline_layout: () -> String
33
+ def encode: (generic_hash hash) -> String
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module Alba
2
+ # Representing nested attribute
3
+ class NestedAttribute
4
+ attr_writer key_transformation: Symbol | String
5
+
6
+ @key_transformation: Symbol | String
7
+ @block: untyped
8
+ @klass: untyped
9
+
10
+ def initialize: (
11
+ klass: untyped,
12
+ ?key_transformation: Alba::transform_type
13
+ ) { () [self: singleton(Alba::Resource)] -> void } -> void
14
+
15
+ def value: (
16
+ object: untyped,
17
+ params: generic_hash,
18
+ within: within
19
+ ) -> generic_hash
20
+ end
21
+ end
@@ -0,0 +1,152 @@
1
+ module Alba
2
+ module Resource
3
+ type attribute = String | Symbol | ^(untyped) [self: ::Alba::Resource::InstanceMethods] -> untyped | ConditionalAttribute | NestedAttribute | TypedAttribute | Association
4
+ type instance_proc = ^(*untyped) [self: InstanceMethods] -> untyped
5
+ type metadata_proc = ^() [self: InstanceMethods] -> generic_hash
6
+
7
+ INTERNAL_VARIABLES: Hash[Symbol, untyped]
8
+ WITHIN_DEFAULT: Object
9
+ EMPTY_HASH: generic_hash
10
+
11
+ def self.included: (Class) -> void
12
+
13
+ interface _InstanceMethods
14
+ def nil?: () -> bool
15
+ def object: () -> untyped
16
+ def params: () -> generic_hash
17
+ def serialize: (?root_key: root_key_type, ?meta: generic_hash) -> String
18
+ def to_json: (?generic_hash, ?root_key: root_key_type, ?meta: generic_hash) -> String
19
+ def as_json: (?generic_hash, ?root_key: root_key_type, ?meta: generic_hash) -> serializable_hash_type
20
+ def serializable_hash: () -> serializable_hash_type
21
+ alias to_h serializable_hash
22
+ end
23
+
24
+ interface _ClassMethods
25
+ def method_added: (Symbol) -> void
26
+ def inherited: (Class) -> void
27
+ def attributes: (*(Symbol | String), ?if: instance_proc | Symbol | nil, **untyped) -> void
28
+ def assign_attributes: (Array[Symbol | String], instance_proc | Symbol | nil) -> void
29
+ def assign_attributes_with_types: (Hash[Symbol | String, untyped], instance_proc | Symbol | nil) ?{ (untyped) [self: InstanceMethods] -> untyped } -> void
30
+ def attribute: (?Symbol | String | nil, ?if: instance_proc | Symbol | nil, **untyped) ?{ (untyped) [self: InstanceMethods] -> untyped } -> void
31
+ def association: (Symbol | String, ?instance_proc?, ?resource: (Class | Proc | String | Symbol)?, ?serializer: (Class | Proc | String | Symbol)?, ?source: Proc?, ?key: key_type, ?with_traits: Symbol | Array[Symbol] | nil, ?params: generic_hash, **untyped) ?{ () [self: singleton(Resource)] -> void } -> (Alba::Association | Alba::ConditionalAttribute)
32
+ alias one association
33
+ alias many association
34
+ alias has_one association
35
+ alias has_many association
36
+ def nesting: () -> String?
37
+ def nested_attribute: (Symbol | String, **untyped) ?{ () [self: singleton(Resource)] -> void } -> (Alba::ConditionalAttribute | Alba::NestedAttribute)
38
+ alias nested nested_attribute
39
+ def trait: (Symbol | String) ?{ () [self: singleton(Resource)] -> void } -> Proc
40
+ def root_key: (Symbol | String, ?Symbol | String | nil) -> Symbol?
41
+ def root_key_for_collection: (Symbol | String) -> Symbol
42
+ def root_key!: () -> class_key_type
43
+ def meta: (?Symbol?) ?{ () [self: InstanceMethods] -> generic_hash } -> [Symbol?, metadata_proc?]
44
+ def layout: (?file: String?, ?inline: Proc?) -> Alba::Layout
45
+ def transform_keys: (Symbol | String, ?root: bool, ?cascade: bool) -> bool
46
+ def transform_keys!: (Symbol | String) -> untyped
47
+ def collection_key: (Symbol | String) -> Symbol
48
+ def on_error: (?( :raise | :ignore | :nullify | nil) handler) ?{ (*untyped) [self: InstanceMethods] -> untyped } -> (Proc | :raise | :ignore | :nullify)?
49
+ def validated_error_handler: ((:raise | :ignore | :nullify | nil) handler) -> (:raise | :ignore | :nullify)?
50
+ def on_nil: () ?{ (*untyped) [self: InstanceMethods] -> untyped } -> instance_proc?
51
+ def helper: (?Module) ?{ (Module) [self: Module] -> untyped } -> Module
52
+ def prefer_resource_method!: () -> Symbol
53
+ def prefer_object_method!: () -> Symbol
54
+ end
55
+
56
+ module InstanceMethods
57
+ @object: untyped
58
+ @params: generic_hash
59
+ @within: untyped
60
+ @with_traits: Symbol | Array[Symbol] | nil
61
+
62
+ def initialize: (untyped, ?params: generic_hash, ?within: within, ?with_traits: Symbol | Array[Symbol] | nil) -> void
63
+ include _InstanceMethods
64
+
65
+ def hash_from_traits: (untyped) -> generic_hash
66
+ def serialize_with: (untyped) -> String
67
+ def hash_with_metadata: (generic_hash, generic_hash) -> generic_hash
68
+ def _metadata: (metadata_proc?, generic_hash) -> generic_hash
69
+ def serializable_hash_for_collection: () -> (Array[generic_hash] | Hash[root_key_type, generic_hash])
70
+ def fetch_key: () -> root_key_type
71
+ def _key_for_collection: () -> root_key_type
72
+ def _key: () -> root_key_type
73
+ def resource_name: (?pluralized: bool) -> String
74
+ def transforming_root_key?: () -> bool
75
+ def attributes_to_hash: (untyped, generic_hash) -> generic_hash
76
+ def select: (key_type, untyped, attribute) -> bool
77
+ def set_key_and_attribute_body_from: (untyped, untyped, attribute, generic_hash) -> void
78
+ def do_select: (key_type, untyped, attribute) -> bool
79
+ def handle_error: (StandardError, untyped, Symbol | String, attribute, generic_hash) -> void
80
+ def transform_key: (Symbol | String | nil) -> untyped
81
+ def fetch_attribute: (untyped, key_type, attribute) -> untyped
82
+ def fetch_attribute_from_object_and_resource: (untyped, Symbol) -> untyped
83
+ def _fetch_attribute_from_object_first: (untyped, Symbol) -> untyped
84
+ def _fetch_attribute_from_resource_first: (untyped, Symbol) -> untyped
85
+ def nil_handler: () -> instance_proc?
86
+ def yield_if_within: (Symbol) { (within) -> untyped } -> untyped
87
+ def check_within: (Symbol) -> within
88
+ def _setup: () -> void
89
+
90
+ # These methods are available on the eventual resource instance. Declaring
91
+ # them here models the module's inclusion context for Steep.
92
+ def class: () -> Class
93
+ def instance_eval: [A] () { () [self: self] -> A } -> A
94
+ def instance_exec: [A] (untyped) { (untyped) [self: self] -> A } -> A
95
+ | [A] (*untyped) { (*untyped) [self: self] -> A } -> A
96
+ def __send__: (Symbol, *untyped) -> untyped
97
+ def binding: () -> Binding
98
+ def encode: (untyped) -> String
99
+ end
100
+
101
+ interface _ClassContext
102
+ def alias_method: (Symbol, Symbol) -> Symbol
103
+ def private: (*Symbol) -> void
104
+ def instance_method: (Symbol) -> UnboundMethod
105
+ def include: (*Module) -> self
106
+ def extend: (*Module) -> self
107
+ def class_eval: [A] () { () [self: untyped] -> A } -> A
108
+ def module_eval: [A] () { () [self: untyped] -> A } -> A
109
+ def name: () -> String?
110
+ def dup: () -> untyped
111
+ def new: (*untyped, **untyped) -> Resource::_InstanceMethods
112
+ def _resource_methods: () -> Array[Symbol]
113
+ end
114
+
115
+ module ClassMethods
116
+ @_attributes: Hash[Symbol | String, attribute]
117
+ @_key: class_key_type
118
+ @_key_for_collection: class_key_type
119
+ @_meta: [Symbol?, metadata_proc?]?
120
+ @_transform_type: transform_type
121
+ @_transforming_root_key: bool
122
+ @_key_transformation_cascade: bool
123
+ @_on_error: (Proc | :raise | :ignore | :nullify)?
124
+ @_on_nil: instance_proc?
125
+ @_layout: Layout?
126
+ @_collection_key: key_type
127
+ @_helper: Module?
128
+ @_resource_methods: Array[Symbol]
129
+ @_select_arity: Integer?
130
+ @_traits: Hash[Symbol, Proc]
131
+
132
+ def alias_method: (Symbol, Symbol) -> Symbol
133
+ def private: (*Symbol) -> void
134
+ def instance_method: (Symbol) -> UnboundMethod
135
+ def include: (*Module) -> self
136
+ def extend: (*Module) -> self
137
+ def class_eval: [A] () { () [self: untyped] -> A } -> A
138
+ def module_eval: [A] () { () [self: untyped] -> A } -> A
139
+ def name: () -> String?
140
+ def dup: () -> untyped
141
+ def new: (*untyped, **untyped) -> Resource::_InstanceMethods
142
+ def _resource_methods: () -> Array[Symbol]
143
+
144
+ include _ClassMethods
145
+ end
146
+
147
+ include InstanceMethods
148
+ extend ClassMethods
149
+ end
150
+
151
+ Serializer: singleton(Resource)
152
+ end
data/sig/alba/type.rbs ADDED
@@ -0,0 +1,26 @@
1
+ module Alba
2
+ # Representing type itself, combined with TypedAttribute
3
+ class Type
4
+ type converter = nil | ^(untyped) [self: Type] -> untyped
5
+ type check = bool | ^(untyped) [self: Type] -> bool
6
+
7
+ attr_reader name: Symbol | String | Class
8
+ attr_writer auto_convert: bool
9
+
10
+ @name: Symbol | String | Class
11
+ @check: untyped
12
+ @converter: converter
13
+ @auto_convert: bool
14
+
15
+ def initialize: (
16
+ Symbol | String | Class name,
17
+ check: check,
18
+ converter: converter,
19
+ ?auto_convert: bool
20
+ ) -> void
21
+
22
+ def check: (Object value) -> bool
23
+ def convert: (Object obj) -> untyped
24
+ def auto_convert_with: (converter converter) -> void
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ module Alba
2
+ # Representing typed attributes to encapsulate logic about types
3
+ class TypedAttribute
4
+ attr_reader name: Symbol | String
5
+
6
+ @name: Symbol | String
7
+ @type: Alba::Type
8
+ @block: untyped
9
+
10
+ def initialize: (
11
+ name: Symbol | String,
12
+ type: Symbol | Class,
13
+ converter: untyped
14
+ ) ?{ (untyped) [self: Alba::Resource::InstanceMethods] -> untyped } -> void
15
+
16
+ def value: (?object: untyped) { (Symbol | String) -> untyped } -> untyped
17
+
18
+ private
19
+
20
+ def display_value_for: (untyped value) -> String
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ module Alba
2
+ # Current version of Alba
3
+ VERSION: String
4
+ end
data/sig/alba.rbs ADDED
@@ -0,0 +1,82 @@
1
+ module Alba
2
+ type generic_hash = Hash[Symbol | String, untyped]
3
+ type key_type = Symbol | String | nil
4
+ type root_key_type = Symbol | String | nil
5
+ type class_key_type = root_key_type | true
6
+ type transform_type = Symbol
7
+ type backend_type = :oj | :oj_strict | :oj_rails | :oj_default | :active_support | :default | :json | :custom | nil
8
+ type encoder_type = ^(untyped) [self: top] -> String
9
+ type inflector_type = _Inflector?
10
+ type resource_class = _ResourceClass
11
+ type with_type = :inference | Class | ^(untyped) -> resource_class
12
+ type within = generic_hash | Array[Symbol | String] | Symbol | bool | nil | Object
13
+ type serializable_hash_type = generic_hash | Array[generic_hash] | Hash[root_key_type, generic_hash] | Hash[root_key_type, Array[generic_hash]]
14
+
15
+ interface _ResourceClass
16
+ include Resource::_ClassMethods
17
+
18
+ def new: (Object? object, ?params: generic_hash, ?within: within, ?with_traits: Symbol | Array[Symbol] | nil) -> Resource::_InstanceMethods
19
+ def class_eval: () { () [self: singleton(Resource)] -> void } -> void
20
+ end
21
+
22
+ interface _Inflector
23
+ def camelize: (String) -> String
24
+ def camelize_lower: (String) -> String
25
+ def dasherize: (String) -> String
26
+ def underscore: (String) -> String
27
+ def classify: (String | Symbol) -> String
28
+ def demodulize: (String) -> String
29
+ def pluralize: (String) -> String
30
+ def inspect: () -> String
31
+ def respond_to?: (Symbol) -> bool
32
+ end
33
+
34
+ self.@backend: backend_type
35
+ self.@encoder: encoder_type
36
+ self.@inflector: inflector_type
37
+ self.@symbolize_keys: bool
38
+ self.@types: Hash[Symbol | Class, Type]
39
+ self.@non_collection_types: Array[Class]
40
+ self.@default_superclass: Class | String | Symbol
41
+ self.@_transformed_keys: Hash[transform_type, Hash[String | Symbol, key_type]]
42
+
43
+ attr_reader self.backend: backend_type
44
+ attr_reader self.encoder: encoder_type
45
+ attr_reader self.inflector: inflector_type
46
+ attr_reader self.non_collection_types: Array[Class]
47
+ attr_writer self.default_superclass: Class | String | Symbol
48
+
49
+ def self.backend=: (backend_type) -> void
50
+ def self.encoder=: (encoder_type) -> void
51
+ def self.serialize: (?untyped object, ?with: with_type, ?root_key: root_key_type) ?{ () [self: singleton(Resource)] -> void } -> String
52
+ def self.hashify: (?untyped object, ?with: with_type, ?root_key: root_key_type) ?{ () [self: singleton(Resource)] -> void } -> (serializable_hash_type | Array[serializable_hash_type] | Hash[root_key_type, Array[serializable_hash_type]])
53
+ def self.collection?: (Object? object) -> bool
54
+ def self.inflector=: (:default | :active_support | :dry | inflector_type) -> void
55
+ def self.resource_class: (?helper: Module?, ?key_transformation: transform_type) ?{ () [self: singleton(Resource)] -> void } -> resource_class
56
+ def self.infer_resource_class: (String | Symbol, ?nesting: String?) -> resource_class
57
+ def self.symbolize_keys!: () -> bool
58
+ def self.stringify_keys!: () -> bool
59
+ def self.regularize_key: (root_key_type) -> key_type
60
+ def self.transform_key: (String | Symbol, transform_type: transform_type) -> key_type
61
+ def self.register_type: (Symbol | Class, ?check: Alba::Type::check, ?converter: Alba::Type::converter, ?auto_convert: bool) -> void
62
+ def self.find_type: (Symbol | Class) -> Type
63
+ def self.reset!: () -> void
64
+ def self.resource_for: (untyped, ?params: generic_hash, ?with: with_type) -> Resource::_InstanceMethods
65
+ | (untyped, ?params: generic_hash, ?with: with_type) ?{ () [self: singleton(Resource)] -> void } -> untyped
66
+
67
+ def self._resource_for: (untyped, ?params: generic_hash, ?with: with_type) ?{ () [self: singleton(Resource)] -> void } -> Resource::_InstanceMethods
68
+ def self.inflector_from: (:default | :active_support | :dry | _Inflector | nil) -> inflector_type
69
+ def self.set_encoder_from_backend: () -> encoder_type
70
+ def self.try_oj: (mode: Symbol) -> encoder_type
71
+ def self.try_active_support: () -> encoder_type
72
+ def self.default_encoder: () -> encoder_type
73
+ def self.hashify_collection: (Enumerable[untyped], with_type, root_key_type) ?{ () [self: singleton(Resource)] -> void } -> (Array[serializable_hash_type] | Hash[root_key_type, Array[serializable_hash_type]])
74
+ def self.validate_inflector: (_Inflector) -> _Inflector
75
+ def self.reset_transform_keys: () -> Hash[transform_type, Hash[String | Symbol, key_type]]
76
+ def self.resolved_default_superclass: () -> untyped
77
+ def self.register_default_types: () -> void
78
+ end
79
+
80
+ module Oj
81
+ def self.dump: (untyped, **untyped) -> String
82
+ end
data/sig/manifest.yaml ADDED
@@ -0,0 +1,6 @@
1
+ dependencies:
2
+ - name: rbs
3
+ - name: logger
4
+ - name: json
5
+ - name: erb
6
+ - name: forwardable
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alba
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OKURA Masafumi
@@ -34,6 +34,20 @@ files:
34
34
  - lib/alba/type.rb
35
35
  - lib/alba/typed_attribute.rb
36
36
  - lib/alba/version.rb
37
+ - sig/alba.rbs
38
+ - sig/alba/association.rbs
39
+ - sig/alba/conditional_attribute.rbs
40
+ - sig/alba/constants.rbs
41
+ - sig/alba/default_inflector.rbs
42
+ - sig/alba/deprecation.rbs
43
+ - sig/alba/errors.rbs
44
+ - sig/alba/layout.rbs
45
+ - sig/alba/nested_attribute.rbs
46
+ - sig/alba/resource.rbs
47
+ - sig/alba/type.rbs
48
+ - sig/alba/typed_attribute.rbs
49
+ - sig/alba/version.rbs
50
+ - sig/manifest.yaml
37
51
  homepage: https://github.com/okuramasafumi/alba
38
52
  licenses:
39
53
  - MIT