alba 3.0.3 → 3.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/.github/workflows/codeql-analysis.yml +3 -3
- data/.github/workflows/main.yml +7 -2
- data/.rubocop.yml +0 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -4
- data/README.md +60 -0
- data/Rakefile +9 -7
- data/lib/alba/layout.rb +9 -9
- data/lib/alba/resource.rb +36 -26
- data/lib/alba/version.rb +1 -1
- data/lib/alba.rb +7 -8
- 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: d0bea04ee2e971c750f9d62eca519a5401e48ab1361199581bad50f3a89e7544
|
4
|
+
data.tar.gz: 726fc7d31243362d2ef4165a3784a1a36eb8f067af00fc9c25664ff1c15650ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f249c1974afc00291145059d9fcb61250948138d0ccbf33cadf1b221be1318c3425b24a0a12b16233452363ec7eda292da3a798a3534465eafba9594740e301c
|
7
|
+
data.tar.gz: 3e5e3e6d6c5889fa26adf5f3164bac67f7904de765e55e67c3290e38024838bbd2439a1e4e69e2b284dd39624eb5094fd8740cc15ca56794ca1d5fdbd76d8288
|
@@ -42,7 +42,7 @@ jobs:
|
|
42
42
|
|
43
43
|
# Initializes the CodeQL tools for scanning.
|
44
44
|
- name: Initialize CodeQL
|
45
|
-
uses: github/codeql-action/init@
|
45
|
+
uses: github/codeql-action/init@v3
|
46
46
|
with:
|
47
47
|
languages: ${{ matrix.language }}
|
48
48
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
@@ -53,7 +53,7 @@ jobs:
|
|
53
53
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
54
54
|
# If this step fails, then you should remove it and run the build manually (see below)
|
55
55
|
- name: Autobuild
|
56
|
-
uses: github/codeql-action/autobuild@
|
56
|
+
uses: github/codeql-action/autobuild@v3
|
57
57
|
|
58
58
|
# ℹ️ Command-line programs to run using the OS shell.
|
59
59
|
# 📚 https://git.io/JvXDl
|
@@ -67,4 +67,4 @@ jobs:
|
|
67
67
|
# make release
|
68
68
|
|
69
69
|
- name: Perform CodeQL Analysis
|
70
|
-
uses: github/codeql-action/analyze@
|
70
|
+
uses: github/codeql-action/analyze@v3
|
data/.github/workflows/main.yml
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
name: CI
|
2
2
|
|
3
|
-
on:
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
pull_request:
|
4
8
|
|
5
9
|
jobs:
|
6
10
|
build:
|
@@ -29,6 +33,7 @@ jobs:
|
|
29
33
|
run: |
|
30
34
|
bundle exec rake
|
31
35
|
- name: CodeCov
|
32
|
-
uses: codecov/codecov-action@
|
36
|
+
uses: codecov/codecov-action@v4
|
33
37
|
with:
|
34
38
|
files: ./coverage/coverage.xml
|
39
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [3.1.0] 2024-03-23
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Add the ability to change key for metadata [#362](https://github.com/okuramasafumi/alba/pull/362)
|
14
|
+
|
9
15
|
## [3.0.3] 2023-12-25
|
10
16
|
|
11
17
|
### Fixed
|
data/Gemfile
CHANGED
@@ -9,12 +9,12 @@ gem 'ffaker', require: false # For testing
|
|
9
9
|
gem 'minitest', '~> 5.14' # For test
|
10
10
|
gem 'railties', require: false # For Rails integration testing
|
11
11
|
gem 'rake', '~> 13.0' # For test and automation
|
12
|
-
gem 'rubocop', '
|
12
|
+
gem 'rubocop', '~> 1.62.0', require: false # For lint
|
13
13
|
gem 'rubocop-gem_dev', '>= 0.3.0', require: false # For lint
|
14
14
|
gem 'rubocop-md', '~> 1.0', require: false # For lint
|
15
|
-
gem 'rubocop-minitest', '
|
16
|
-
gem 'rubocop-performance', '
|
17
|
-
gem 'rubocop-rake', '
|
15
|
+
gem 'rubocop-minitest', '~> 0.35.0', require: false # For lint
|
16
|
+
gem 'rubocop-performance', '~> 1.20.2', require: false # For lint
|
17
|
+
gem 'rubocop-rake', '~> 0.6.0', require: false # For lint
|
18
18
|
gem 'ruby-lsp', require: false # For language server
|
19
19
|
gem 'simplecov', '~> 0.22.0', require: false # For test coverage
|
20
20
|
gem 'simplecov-cobertura', require: false # For test coverage
|
data/README.md
CHANGED
@@ -130,6 +130,7 @@ You can find the documentation on [RubyDoc](https://rubydoc.info/github/okuramas
|
|
130
130
|
* Selectable backend
|
131
131
|
* Key transformation
|
132
132
|
* Root key and association resource name inference
|
133
|
+
* Inline definition without explicit classes
|
133
134
|
* Error handling
|
134
135
|
* Nil handling
|
135
136
|
* Circular associations control
|
@@ -1232,6 +1233,65 @@ UserResource.new([user]).serialize
|
|
1232
1233
|
|
1233
1234
|
UserResource.new([user]).serialize(meta: {foo: :bar})
|
1234
1235
|
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"meta":{"size":1,"foo":"bar"}}'
|
1236
|
+
```
|
1237
|
+
|
1238
|
+
You can change the key for metadata. If you change the key, it also affects the key when you pass `meta` option.
|
1239
|
+
|
1240
|
+
```ruby
|
1241
|
+
# You can change meta key
|
1242
|
+
class UserResourceWithDifferentMetaKey
|
1243
|
+
include Alba::Resource
|
1244
|
+
|
1245
|
+
root_key :user, :users
|
1246
|
+
|
1247
|
+
attributes :id, :name
|
1248
|
+
|
1249
|
+
meta :my_meta do
|
1250
|
+
{foo: :bar}
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
UserResourceWithDifferentMetaKey.new([user]).serialize
|
1255
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"my_meta":{"foo":"bar"}}'
|
1256
|
+
|
1257
|
+
UserResourceWithDifferentMetaKey.new([user]).serialize(meta: {extra: 42})
|
1258
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"meta":{"size":1,"extra":42}}'
|
1259
|
+
|
1260
|
+
class UserResourceChangingMetaKeyOnly
|
1261
|
+
include Alba::Resource
|
1262
|
+
|
1263
|
+
root_key :user, :users
|
1264
|
+
|
1265
|
+
attributes :id, :name
|
1266
|
+
|
1267
|
+
meta :my_meta
|
1268
|
+
end
|
1269
|
+
|
1270
|
+
UserResourceChangingMetaKeyOnly.new([user]).serialize
|
1271
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}]}'
|
1272
|
+
|
1273
|
+
UserResourceChangingMetaKeyOnly.new([user]).serialize(meta: {extra: 42})
|
1274
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"my_meta":{"extra":42}}'
|
1275
|
+
```
|
1276
|
+
|
1277
|
+
It's also possible to remove the key for metadata, resulting a flat structure.
|
1278
|
+
|
1279
|
+
```ruby
|
1280
|
+
class UserResourceRemovingMetaKey
|
1281
|
+
include Alba::Resource
|
1282
|
+
|
1283
|
+
root_key :user, :users
|
1284
|
+
|
1285
|
+
attributes :id, :name
|
1286
|
+
|
1287
|
+
meta nil
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
UserResourceRemovingMetaKey.new([user]).serialize
|
1291
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}]}'
|
1292
|
+
|
1293
|
+
UserResourceRemovingMetaKey.new([user]).serialize(meta: {extra: 42})
|
1294
|
+
# => '{"users":[{"id":1,"name":"Masafumi OKURA"}],"extra":42}'
|
1235
1295
|
|
1236
1296
|
# You can set metadata with `meta` option alone
|
1237
1297
|
|
data/Rakefile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
3
|
|
4
|
-
|
4
|
+
if ENV['BUNDLE_GEMFILE'] == File.expand_path('Gemfile') || ENV['BUNDLE_GEMFILE'].empty? || ENV['BUNDLE_GEMFILE'].nil?
|
5
|
+
ENV['BUNDLE_GEMFILE'] = File.expand_path('Gemfile')
|
6
|
+
end
|
5
7
|
|
6
8
|
Rake::TestTask.new(:test) do |t|
|
7
|
-
t.libs <<
|
8
|
-
t.libs <<
|
9
|
-
file_list = ENV[
|
9
|
+
t.libs << 'test'
|
10
|
+
t.libs << 'lib'
|
11
|
+
file_list = ENV['BUNDLE_GEMFILE'] == File.expand_path('Gemfile') ? FileList['test/**/*_test.rb'] : FileList['test/dependencies/test_dependencies.rb']
|
10
12
|
t.test_files = file_list
|
11
13
|
end
|
12
14
|
|
13
|
-
task :
|
15
|
+
task default: :test
|
data/lib/alba/layout.rb
CHANGED
@@ -12,17 +12,17 @@ module Alba
|
|
12
12
|
# @param file [String] name of the layout file
|
13
13
|
# @param inline [Proc] a proc returning JSON string or a Hash representing JSON
|
14
14
|
def initialize(file:, inline:)
|
15
|
-
if file
|
16
|
-
|
15
|
+
@body = if file
|
16
|
+
raise ArgumentError, 'File layout must be a String representing filename' unless file.is_a?(String)
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
file
|
19
|
+
elsif inline
|
20
|
+
raise ArgumentError, 'Inline layout must be a Proc returning a Hash or a String' unless inline.is_a?(Proc)
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
inline
|
23
|
+
else
|
24
|
+
raise ArgumentError, 'Layout must be either String or Proc'
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
# Serialize within layout
|
data/lib/alba/resource.rb
CHANGED
@@ -22,7 +22,7 @@ module Alba
|
|
22
22
|
# @private
|
23
23
|
def self.included(base) # rubocop:disable Metrics/MethodLength
|
24
24
|
super
|
25
|
-
setup_method_body = 'private def _setup;'
|
25
|
+
setup_method_body = +'private def _setup;'
|
26
26
|
base.class_eval do
|
27
27
|
# Initialize
|
28
28
|
INTERNAL_VARIABLES.each do |name, initial|
|
@@ -66,7 +66,14 @@ module Alba
|
|
66
66
|
# @see #serialize
|
67
67
|
# @see https://github.com/rails/rails/blob/7-0-stable/actionpack/lib/action_controller/metal/renderers.rb#L156
|
68
68
|
def to_json(options = {}, root_key: nil, meta: {})
|
69
|
-
|
69
|
+
confusing_options = options.keys.select { |k| k.to_sym == :only || k.to_sym == :except }
|
70
|
+
unless confusing_options.empty?
|
71
|
+
confusing_options.sort!
|
72
|
+
confusing_options.map! { |s| "\"#{s}\"" }
|
73
|
+
message = "You passed #{confusing_options.join(' and ')} options but ignored. Please refer to the document: https://github.com/okuramasafumi/alba/blob/main/docs/rails.md"
|
74
|
+
Kernel.warn(message)
|
75
|
+
end
|
76
|
+
serialize(root_key: root_key, meta: meta)
|
70
77
|
end
|
71
78
|
|
72
79
|
# Returns a Hash correspondng {#serialize}
|
@@ -96,17 +103,6 @@ module Alba
|
|
96
103
|
|
97
104
|
private
|
98
105
|
|
99
|
-
def _to_json(root_key, meta, options)
|
100
|
-
confusing_options = options.keys.select { |k| k.to_sym == :only || k.to_sym == :except }
|
101
|
-
unless confusing_options.empty?
|
102
|
-
confusing_options.sort!
|
103
|
-
confusing_options.map! { |s| "\"#{s}\"" }
|
104
|
-
message = "You passed #{confusing_options.join(' and ')} options but ignored. Please refer to the document: https://github.com/okuramasafumi/alba/blob/main/docs/rails.md"
|
105
|
-
Kernel.warn(message)
|
106
|
-
end
|
107
|
-
serialize(root_key: root_key, meta: meta)
|
108
|
-
end
|
109
|
-
|
110
106
|
def serialize_with(hash)
|
111
107
|
serialized_json = encode(hash)
|
112
108
|
return serialized_json unless @_layout
|
@@ -115,13 +111,22 @@ module Alba
|
|
115
111
|
end
|
116
112
|
|
117
113
|
def hash_with_metadata(hash, meta)
|
118
|
-
return hash if meta.empty? && @_meta.nil?
|
114
|
+
return hash if meta.empty? && @_meta&.last.nil?
|
115
|
+
|
116
|
+
key, block = @_meta || :meta
|
119
117
|
|
120
|
-
|
121
|
-
|
118
|
+
if key
|
119
|
+
hash[key] = _metadata(block, meta)
|
120
|
+
else
|
121
|
+
_metadata(block, meta).each { |k, v| hash[k] = v }
|
122
|
+
end
|
122
123
|
hash
|
123
124
|
end
|
124
125
|
|
126
|
+
def _metadata(block, meta)
|
127
|
+
block ? instance_eval(&block).merge(meta) : meta
|
128
|
+
end
|
129
|
+
|
125
130
|
def serializable_hash_for_collection
|
126
131
|
if @_collection_key
|
127
132
|
@object.to_h do |item|
|
@@ -212,14 +217,17 @@ module Alba
|
|
212
217
|
end
|
213
218
|
|
214
219
|
def handle_error(error, obj, key, attribute, hash)
|
215
|
-
on_error = @_on_error || :raise
|
216
|
-
case on_error # rubocop:disable Style/MissingElse
|
220
|
+
case (on_error = @_on_error || :raise)
|
217
221
|
when :raise, nil then raise(error)
|
218
222
|
when :nullify then hash[key] = nil
|
219
223
|
when :ignore then nil
|
220
224
|
when Proc
|
221
225
|
key, value = on_error.call(error, obj, key, attribute, self.class)
|
222
226
|
hash[key] = value
|
227
|
+
else
|
228
|
+
# :nocov:
|
229
|
+
raise Alba::Error, 'Impossible path'
|
230
|
+
# :nocov:
|
223
231
|
end
|
224
232
|
end
|
225
233
|
|
@@ -233,11 +241,15 @@ module Alba
|
|
233
241
|
end
|
234
242
|
|
235
243
|
def _transform_key(inflector, key)
|
236
|
-
case @_transform_type
|
244
|
+
case @_transform_type
|
237
245
|
when :camel then inflector.camelize(key)
|
238
246
|
when :lower_camel then inflector.camelize_lower(key)
|
239
247
|
when :dash then inflector.dasherize(key)
|
240
248
|
when :snake then inflector.underscore(key)
|
249
|
+
else
|
250
|
+
# :nocov:
|
251
|
+
raise Alba::Error, "Unknown transform type: #{@_transform_type}"
|
252
|
+
# :nocov:
|
241
253
|
end
|
242
254
|
end
|
243
255
|
|
@@ -249,7 +261,9 @@ module Alba
|
|
249
261
|
when TypedAttribute then attribute.value(obj)
|
250
262
|
when NestedAttribute then attribute.value(object: obj, params: params, within: @within)
|
251
263
|
when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: obj) { |attr| fetch_attribute(obj, key, attr) }
|
264
|
+
# :nocov:
|
252
265
|
else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
|
266
|
+
# :nocov:
|
253
267
|
end
|
254
268
|
value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
|
255
269
|
end
|
@@ -266,11 +280,7 @@ module Alba
|
|
266
280
|
|
267
281
|
def _fetch_attribute_from_resource_first(obj, attribute)
|
268
282
|
if @_resource_methods.include?(attribute)
|
269
|
-
|
270
|
-
__send__(attribute, obj)
|
271
|
-
rescue NoMethodError
|
272
|
-
obj.__send__(attribute)
|
273
|
-
end
|
283
|
+
__send__(attribute, obj)
|
274
284
|
else
|
275
285
|
obj.__send__(attribute)
|
276
286
|
end
|
@@ -445,8 +455,8 @@ module Alba
|
|
445
455
|
end
|
446
456
|
|
447
457
|
# Set metadata
|
448
|
-
def meta(&block)
|
449
|
-
@_meta = block
|
458
|
+
def meta(key = :meta, &block)
|
459
|
+
@_meta = [key, block]
|
450
460
|
end
|
451
461
|
|
452
462
|
# Set layout
|
data/lib/alba/version.rb
CHANGED
data/lib/alba.rb
CHANGED
@@ -114,14 +114,11 @@ module Alba
|
|
114
114
|
raise Alba::Error, 'Inference is disabled so Alba cannot infer resource name. Set inflector before use.' unless Alba.inflector
|
115
115
|
|
116
116
|
const_parent = nesting.nil? ? Object : Object.const_get(nesting)
|
117
|
-
# rubocop-performance 1.20.2 might resolve this
|
118
|
-
# rubocop:disable Performance/StringIdentifierArgument
|
119
117
|
begin
|
120
118
|
const_parent.const_get("#{inflector.classify(name)}Resource")
|
121
119
|
rescue NameError # Retry for serializer
|
122
120
|
const_parent.const_get("#{inflector.classify(name)}Serializer")
|
123
121
|
end
|
124
|
-
# rubocop:enable Performance/StringIdentifierArgument
|
125
122
|
end
|
126
123
|
|
127
124
|
# Configure Alba to symbolize keys
|
@@ -242,11 +239,13 @@ module Alba
|
|
242
239
|
inflector
|
243
240
|
end
|
244
241
|
|
245
|
-
def register_default_types
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
242
|
+
def register_default_types
|
243
|
+
[String, :String].each do |t|
|
244
|
+
register_type(t, check: ->(obj) { obj.is_a?(String) }, converter: ->(obj) { obj.to_s })
|
245
|
+
end
|
246
|
+
[Integer, :Integer].each do |t|
|
247
|
+
register_type(t, check: ->(obj) { obj.is_a?(Integer) }, converter: ->(obj) { Integer(obj) })
|
248
|
+
end
|
250
249
|
register_type(:Boolean, check: ->(obj) { [true, false].include?(obj) }, converter: ->(obj) { !!obj })
|
251
250
|
end
|
252
251
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OKURA Masafumi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
|
14
14
|
flexibility and usability.
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
|
-
rubygems_version: 3.
|
97
|
+
rubygems_version: 3.5.6
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: Alba is the fastest JSON serializer for Ruby.
|