shale-builder 0.3.0 → 0.4.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 +4 -4
- data/.rubocop.yml +19 -1
- data/CHANGELOG.md +30 -15
- data/Gemfile +7 -1
- data/Gemfile.lock +89 -43
- data/README.md +76 -0
- data/lib/shale/attribute.rb +15 -1
- data/lib/shale/builder/nested_validations.rb +61 -0
- data/lib/shale/builder/version.rb +1 -1
- data/lib/shale/builder.rb +29 -9
- data/lib/tapioca/dsl/compilers/shale.rb +17 -13
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a79ea1df97f6d5d49af0d596144d931b5aacea98e142866d7e322497fbeaae5
|
4
|
+
data.tar.gz: 59f671f470be89ed4854798843657160c87163de286a867be73c4832bb4a2df2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f763a5973d2d15c2a2c314ae61ed61f7455724f624f38852f8cd4d174fe2bf12af7bee2eb37a847b5940f9779fa4ad2960eff6a99259c12d0445d16fb63b8775
|
7
|
+
data.tar.gz: e872ffe315cec734fa77af67b1be80efded4b750194e66c2e41d069302b5dc18cc4bd0f3da2932528661cc2fa1d84ff90a08f3326c7052a65030987f5c4685eb
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
inherit_gem:
|
2
|
-
rubocop-espago:
|
2
|
+
rubocop-espago: sorbet.yml
|
3
3
|
|
4
4
|
AllCops:
|
5
5
|
TargetRubyVersion: 3.1
|
@@ -14,3 +14,21 @@ Style/TrailingCommaInArguments:
|
|
14
14
|
|
15
15
|
Naming/BlockForwarding:
|
16
16
|
Enabled: false
|
17
|
+
|
18
|
+
Sorbet/ForbidTSig:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Sorbet/RedundantExtendTSig:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Sorbet/ForbidMixesInClassMethods:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Sorbet/ForbidTUnsafe:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Sorbet/ForbidTHelpers:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/DocumentDynamicEvalDefinition:
|
34
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -5,23 +5,38 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
-
## [0.
|
8
|
+
## [0.4.1] - 2025-10-14
|
9
9
|
|
10
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.
|
10
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.4.0...v0.4.1)
|
11
11
|
|
12
12
|
### Changes
|
13
|
-
-
|
13
|
+
- Fix `Shale::Builder::alias_attribute`, improve changelog
|
14
|
+
|
15
|
+
## [0.4.0] - 2025-10-14
|
16
|
+
|
17
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.3.0...v0.4.0)
|
18
|
+
|
19
|
+
### Changes
|
20
|
+
- Add `Shale::Builder::NestedValidations`
|
21
|
+
- Add `Shale::Builder#alias_attribute`
|
22
|
+
|
23
|
+
## [0.3.0] - 2025-09-24
|
24
|
+
|
25
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.2.1...v0.3.0)
|
26
|
+
|
27
|
+
### Changes
|
28
|
+
- Add support for `BigDecimal`
|
14
29
|
|
15
30
|
## [0.2.1] - 2024-07-16
|
16
31
|
|
17
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.2.
|
32
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.2.0...v0.2.1)
|
18
33
|
|
19
34
|
### Changes
|
20
35
|
- Add additional sorbet type documentation
|
21
36
|
|
22
37
|
## [0.2.0] - 2024-06-11
|
23
38
|
|
24
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.
|
39
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.9...v0.2.0)
|
25
40
|
|
26
41
|
### Changes
|
27
42
|
- Add support for `return_type` and `setter_type` in custom primitive shale types
|
@@ -29,21 +44,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
29
44
|
|
30
45
|
## [0.1.9] - 2024-06-03
|
31
46
|
|
32
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
47
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.8...v0.1.9)
|
33
48
|
|
34
49
|
### Changes
|
35
50
|
- Fix the signature of `new` class method
|
36
51
|
|
37
52
|
## [0.1.8] - 2024-05-15
|
38
53
|
|
39
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
54
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.7...v0.1.8)
|
40
55
|
|
41
56
|
### Changes
|
42
57
|
- Sort attribute names in the tapioca compiler
|
43
58
|
|
44
59
|
## [0.1.7] - 2024-05-13
|
45
60
|
|
46
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
61
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.6...v0.1.7)
|
47
62
|
|
48
63
|
### Changes
|
49
64
|
- Drop support for Ruby 3.0
|
@@ -51,35 +66,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
51
66
|
|
52
67
|
## [0.1.6] - 2024-05-13
|
53
68
|
|
54
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
69
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.5...v0.1.6)
|
55
70
|
|
56
71
|
### Changes
|
57
72
|
- Add support for doc strings in the tapioca compiler
|
58
73
|
|
59
74
|
## [0.1.5] - 2024-05-13
|
60
75
|
|
61
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
76
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.4...v0.1.5)
|
62
77
|
|
63
78
|
### Changes
|
64
79
|
- Fix a bug in the tapioca compiler
|
65
80
|
|
66
81
|
## [0.1.4] - 2024-05-13
|
67
82
|
|
68
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
83
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.3...v0.1.4)
|
69
84
|
|
70
85
|
### Changes
|
71
86
|
- Add a tapioca compiler for shale and shale builder
|
72
87
|
|
73
88
|
## [0.1.3] - 2023-11-23
|
74
89
|
|
75
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
90
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.2...v0.1.3)
|
76
91
|
|
77
92
|
### Changes
|
78
93
|
- Change shale version dependency from `< 1.0` to `< 2.0`
|
79
94
|
|
80
95
|
## [0.1.2] - 2023-10-11
|
81
96
|
|
82
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
97
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.1...v0.1.2)
|
83
98
|
|
84
99
|
### Changes
|
85
100
|
- Add support for collections
|
@@ -87,14 +102,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
87
102
|
|
88
103
|
## [0.1.1] - 2023-02-22
|
89
104
|
|
90
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.
|
105
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.0...v0.1.1)
|
91
106
|
|
92
107
|
### Changes
|
93
108
|
- Add support for inheritance
|
94
109
|
|
95
110
|
## [0.1.0] - 2023-02-21
|
96
111
|
|
97
|
-
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.
|
112
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.0.0...v0.1.0)
|
98
113
|
|
99
114
|
### Changes
|
100
115
|
- Initial release
|
data/Gemfile
CHANGED
@@ -5,10 +5,16 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in diggable.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
+
gem 'activemodel', '~> 8.0' # validations
|
9
|
+
gem 'base64', '~> 0.3' # Base64
|
8
10
|
gem 'byebug', '~> 11.1' # debugger
|
9
11
|
gem 'minitest', '~> 5.0' # test framework
|
12
|
+
gem 'mutex_m', '~> 0.3' # Mutexes
|
13
|
+
gem 'racc', '~> 1.8' # parser
|
10
14
|
gem 'rake', '~> 13.0' # automation tasks
|
11
|
-
gem 'rubocop
|
15
|
+
gem 'rubocop', '~> 1.81' # ruby linter
|
16
|
+
gem 'rubocop-espago', '~> 1.2' # Espago rubocop config
|
17
|
+
gem 'rubocop-sorbet', '~> 0.11' # sorbet rubocop config
|
12
18
|
gem 'shoulda-context', '~> 2.0' # more pleasant test syntax
|
13
19
|
gem 'sorbet', '>= 0.5' # static typechecker
|
14
20
|
gem 'tapioca', '> 0.13' # RBI generator for sorbet
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
shale-builder (0.
|
4
|
+
shale-builder (0.4.1)
|
5
5
|
booleans (>= 0.1)
|
6
6
|
shale (< 2.0)
|
7
7
|
sorbet-runtime (> 0.5)
|
@@ -9,73 +9,113 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
|
12
|
+
activemodel (8.0.3)
|
13
|
+
activesupport (= 8.0.3)
|
14
|
+
activesupport (8.0.3)
|
15
|
+
base64
|
16
|
+
benchmark (>= 0.3)
|
17
|
+
bigdecimal
|
18
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
19
|
+
connection_pool (>= 2.2.5)
|
20
|
+
drb
|
21
|
+
i18n (>= 1.6, < 2)
|
22
|
+
logger (>= 1.4.2)
|
23
|
+
minitest (>= 5.1)
|
24
|
+
securerandom (>= 0.3)
|
25
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
26
|
+
uri (>= 0.13.1)
|
27
|
+
ast (2.4.3)
|
28
|
+
base64 (0.3.0)
|
29
|
+
benchmark (0.4.1)
|
13
30
|
bigdecimal (3.2.3)
|
14
31
|
booleans (0.1.1)
|
15
32
|
byebug (11.1.3)
|
16
|
-
|
17
|
-
|
33
|
+
concurrent-ruby (1.3.5)
|
34
|
+
connection_pool (2.5.4)
|
35
|
+
drb (2.2.3)
|
36
|
+
erubi (1.13.1)
|
37
|
+
i18n (1.14.7)
|
38
|
+
concurrent-ruby (~> 1.0)
|
39
|
+
json (2.15.1)
|
40
|
+
language_server-protocol (3.17.0.5)
|
41
|
+
lint_roller (1.1.0)
|
42
|
+
logger (1.7.0)
|
18
43
|
minitest (5.17.0)
|
44
|
+
mutex_m (0.3.0)
|
19
45
|
netrc (0.11.0)
|
20
|
-
parallel (1.
|
21
|
-
parser (3.
|
46
|
+
parallel (1.27.0)
|
47
|
+
parser (3.3.9.0)
|
22
48
|
ast (~> 2.4.1)
|
23
|
-
|
49
|
+
racc
|
50
|
+
prism (1.5.2)
|
51
|
+
racc (1.8.1)
|
24
52
|
rainbow (3.1.1)
|
25
53
|
rake (13.0.6)
|
26
|
-
rbi (0.
|
27
|
-
prism (
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
54
|
+
rbi (0.3.7)
|
55
|
+
prism (~> 1.0)
|
56
|
+
rbs (>= 3.4.4)
|
57
|
+
rbs (3.9.5)
|
58
|
+
logger
|
59
|
+
regexp_parser (2.11.3)
|
60
|
+
rubocop (1.81.1)
|
32
61
|
json (~> 2.3)
|
62
|
+
language_server-protocol (~> 3.17.0.2)
|
63
|
+
lint_roller (~> 1.1.0)
|
33
64
|
parallel (~> 1.10)
|
34
|
-
parser (>= 3.
|
65
|
+
parser (>= 3.3.0.2)
|
35
66
|
rainbow (>= 2.2.2, < 4.0)
|
36
|
-
regexp_parser (>=
|
37
|
-
|
38
|
-
rubocop-ast (>= 1.24.1, < 2.0)
|
67
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
68
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
39
69
|
ruby-progressbar (~> 1.7)
|
40
|
-
unicode-display_width (>= 2.4.0, <
|
41
|
-
rubocop-ast (1.
|
42
|
-
parser (>= 3.
|
43
|
-
|
70
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
71
|
+
rubocop-ast (1.47.1)
|
72
|
+
parser (>= 3.3.7.2)
|
73
|
+
prism (~> 1.4)
|
74
|
+
rubocop-espago (1.2.0)
|
44
75
|
rubocop
|
45
|
-
|
76
|
+
rubocop-sorbet (0.11.0)
|
77
|
+
lint_roller
|
78
|
+
rubocop (>= 1.75.2)
|
79
|
+
ruby-progressbar (1.13.0)
|
80
|
+
securerandom (0.4.1)
|
46
81
|
shale (1.2.2)
|
47
82
|
bigdecimal
|
48
83
|
shoulda-context (2.0.0)
|
49
|
-
sorbet (0.
|
50
|
-
sorbet-static (= 0.
|
51
|
-
sorbet-runtime (0.
|
52
|
-
sorbet-static (0.
|
53
|
-
sorbet-static (0.
|
54
|
-
sorbet-static-and-runtime (0.
|
55
|
-
sorbet (= 0.
|
56
|
-
sorbet-runtime (= 0.
|
57
|
-
spoom (1.
|
84
|
+
sorbet (0.6.12642)
|
85
|
+
sorbet-static (= 0.6.12642)
|
86
|
+
sorbet-runtime (0.6.12642)
|
87
|
+
sorbet-static (0.6.12642-universal-darwin)
|
88
|
+
sorbet-static (0.6.12642-x86_64-linux)
|
89
|
+
sorbet-static-and-runtime (0.6.12642)
|
90
|
+
sorbet (= 0.6.12642)
|
91
|
+
sorbet-runtime (= 0.6.12642)
|
92
|
+
spoom (1.6.1)
|
58
93
|
erubi (>= 1.10.0)
|
59
|
-
prism (>= 0.
|
94
|
+
prism (>= 0.28.0)
|
95
|
+
rbi (>= 0.2.3)
|
60
96
|
sorbet-static-and-runtime (>= 0.5.10187)
|
61
97
|
thor (>= 0.19.2)
|
62
|
-
tapioca (0.
|
98
|
+
tapioca (0.16.11)
|
99
|
+
benchmark
|
63
100
|
bundler (>= 2.2.25)
|
64
101
|
netrc (>= 0.11.0)
|
65
102
|
parallel (>= 1.21.0)
|
66
|
-
rbi (
|
103
|
+
rbi (~> 0.2)
|
67
104
|
sorbet-static-and-runtime (>= 0.5.11087)
|
68
105
|
spoom (>= 1.2.0)
|
69
106
|
thor (>= 1.2.0)
|
70
107
|
yard-sorbet
|
71
|
-
thor (1.
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
108
|
+
thor (1.4.0)
|
109
|
+
tzinfo (2.0.6)
|
110
|
+
concurrent-ruby (~> 1.0)
|
111
|
+
unicode-display_width (3.2.0)
|
112
|
+
unicode-emoji (~> 4.1)
|
113
|
+
unicode-emoji (4.1.0)
|
114
|
+
uri (1.0.4)
|
115
|
+
yard (0.9.37)
|
116
|
+
yard-sorbet (0.9.0)
|
117
|
+
sorbet-runtime
|
118
|
+
yard
|
79
119
|
|
80
120
|
PLATFORMS
|
81
121
|
arm64-darwin-20
|
@@ -84,10 +124,16 @@ PLATFORMS
|
|
84
124
|
x86_64-linux
|
85
125
|
|
86
126
|
DEPENDENCIES
|
127
|
+
activemodel (~> 8.0)
|
128
|
+
base64 (~> 0.3)
|
87
129
|
byebug (~> 11.1)
|
88
130
|
minitest (~> 5.0)
|
131
|
+
mutex_m (~> 0.3)
|
132
|
+
racc (~> 1.8)
|
89
133
|
rake (~> 13.0)
|
90
|
-
rubocop
|
134
|
+
rubocop (~> 1.81)
|
135
|
+
rubocop-espago (~> 1.2)
|
136
|
+
rubocop-sorbet (~> 0.11)
|
91
137
|
shale-builder!
|
92
138
|
shoulda-context (~> 2.0)
|
93
139
|
sorbet (>= 0.5)
|
data/README.md
CHANGED
@@ -213,6 +213,82 @@ transaction = Transaction.build do |t|
|
|
213
213
|
end
|
214
214
|
```
|
215
215
|
|
216
|
+
### Nested Validations
|
217
|
+
|
218
|
+
There is an additional module `Shale::Builder::NestedValidations` that provides
|
219
|
+
support for seamless nested validations using `ActiveModel`.
|
220
|
+
|
221
|
+
In order to load it do:
|
222
|
+
|
223
|
+
```rb
|
224
|
+
require 'shale/builder/nested_validations'
|
225
|
+
```
|
226
|
+
|
227
|
+
Then you can use it like so
|
228
|
+
|
229
|
+
```rb
|
230
|
+
class AmountType < ::Shale::Mapper
|
231
|
+
include ::Shale::Builder
|
232
|
+
include ::ActiveModel::Validations
|
233
|
+
include ::Shale::Builder::NestedValidations
|
234
|
+
|
235
|
+
attribute :value, ::Shale::Type::Float
|
236
|
+
attribute :currency, ::Shale::Type::String
|
237
|
+
|
238
|
+
validates :value, presence: true
|
239
|
+
end
|
240
|
+
|
241
|
+
class TransactionType < ::Shale::Mapper
|
242
|
+
include ::Shale::Builder
|
243
|
+
include ::ActiveModel::Validations
|
244
|
+
include ::Shale::Builder::NestedValidations
|
245
|
+
|
246
|
+
attribute :cvv_code, ::Shale::Type::String
|
247
|
+
attribute :amount, AmountType
|
248
|
+
|
249
|
+
validates :cvv_code, presence: true
|
250
|
+
validates :amount, presence: true
|
251
|
+
end
|
252
|
+
|
253
|
+
obj = TransactionType.build do |t|
|
254
|
+
t.amount do |a|
|
255
|
+
a.currency = 'USD'
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
obj.valid? #=> false
|
260
|
+
obj.errors #=> #<ActiveModel::Errors [#<ActiveModel::Error attribute=cvv_code, type=blank, options={}>, #<ActiveModel::NestedError attribute=amount.value, type=blank, options={}>]>
|
261
|
+
obj.errors.messages #=> {cvv_code: ["can't be blank"], "amount.value": ["can't be blank"]}
|
262
|
+
```
|
263
|
+
|
264
|
+
You MUST include `ActiveModel::Validations` before `Shale::Builder::NestedValidations`.
|
265
|
+
|
266
|
+
### Attribute aliases
|
267
|
+
|
268
|
+
You can easily create aliases for attributes using `alias_attribute`
|
269
|
+
|
270
|
+
Then you can use it like so
|
271
|
+
|
272
|
+
```rb
|
273
|
+
require 'shale/builder'
|
274
|
+
|
275
|
+
class Amount < Shale::Mapper
|
276
|
+
include Shale::Builder
|
277
|
+
|
278
|
+
attribute :value, Shale::Type::Float
|
279
|
+
attribute :currency, Shale::Type::String
|
280
|
+
|
281
|
+
alias_attribute :val, :value
|
282
|
+
end
|
283
|
+
|
284
|
+
a = Amount.build do |a|
|
285
|
+
a.val = 3.2
|
286
|
+
end
|
287
|
+
|
288
|
+
a.val #=> 3.2
|
289
|
+
a.value #=> 3.2
|
290
|
+
```
|
291
|
+
|
216
292
|
### Sorbet support
|
217
293
|
|
218
294
|
Shale-builder adds support for sorbet and tapioca.
|
data/lib/shale/attribute.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'shale'
|
5
5
|
|
@@ -11,5 +11,19 @@ module Shale
|
|
11
11
|
# in a Ruby String.
|
12
12
|
sig { returns(T.nilable(String)) }
|
13
13
|
attr_accessor :doc
|
14
|
+
|
15
|
+
# Contains the documentation comment for the shale attribute
|
16
|
+
# in a Ruby String.
|
17
|
+
sig { returns(T.nilable(T::Array[Symbol])) }
|
18
|
+
attr_accessor :aliases
|
19
|
+
|
20
|
+
sig { returns(T::Array[Symbol]) }
|
21
|
+
def all_names
|
22
|
+
names = [name]
|
23
|
+
aliases = self.aliases
|
24
|
+
return names unless aliases
|
25
|
+
|
26
|
+
names + aliases
|
27
|
+
end
|
14
28
|
end
|
15
29
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'shale'
|
5
|
+
require 'booleans'
|
6
|
+
|
7
|
+
module Shale
|
8
|
+
module Builder
|
9
|
+
# Include in a class tha already includes `Shale::Builder` to add support
|
10
|
+
# for nested ActiveModel validations.
|
11
|
+
#
|
12
|
+
# @requires_ancestor: Object
|
13
|
+
module NestedValidations
|
14
|
+
extend T::Sig
|
15
|
+
extend T::Helpers
|
16
|
+
|
17
|
+
# @requires_ancestor: singleton(Shale::Mapper)
|
18
|
+
module ClassMethods
|
19
|
+
extend T::Sig
|
20
|
+
|
21
|
+
sig { returns(T::Hash[Symbol, Shale::Attribute]) }
|
22
|
+
def validatable_attributes
|
23
|
+
@validatable_attributes ||= attributes.select do |_, val|
|
24
|
+
val.validatable?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
mixes_in_class_methods ClassMethods
|
29
|
+
|
30
|
+
sig { returns(T::Boolean) }
|
31
|
+
def valid?
|
32
|
+
result = super
|
33
|
+
errlist = errors
|
34
|
+
|
35
|
+
attrs = T.unsafe(self).class.validatable_attributes
|
36
|
+
attrs.each_key do |name|
|
37
|
+
val = public_send(name)
|
38
|
+
next unless val
|
39
|
+
next if val.valid?
|
40
|
+
|
41
|
+
result = false
|
42
|
+
val.errors.each do |err|
|
43
|
+
errlist.import(err, attribute: "#{name}.#{err.attribute}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module Shale
|
55
|
+
class Attribute # rubocop:disable Style/Documentation
|
56
|
+
sig { returns(T::Boolean) }
|
57
|
+
def validatable?
|
58
|
+
Boolean(type.is_a?(Class) && type < ::ActiveModel::Validations)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/shale/builder.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'shale'
|
5
5
|
require 'sorbet-runtime'
|
@@ -40,6 +40,7 @@ module Shale
|
|
40
40
|
# end
|
41
41
|
#
|
42
42
|
module Builder
|
43
|
+
extend T::Sig
|
43
44
|
extend T::Helpers
|
44
45
|
|
45
46
|
class << self
|
@@ -66,6 +67,7 @@ module Shale
|
|
66
67
|
module ClassMethods
|
67
68
|
extend T::Sig
|
68
69
|
extend T::Generic
|
70
|
+
|
69
71
|
abstract!
|
70
72
|
has_attached_class!
|
71
73
|
|
@@ -96,18 +98,20 @@ module Shale
|
|
96
98
|
|
97
99
|
sig do
|
98
100
|
params(
|
99
|
-
name:
|
100
|
-
type:
|
101
|
+
name: T.any(String, Symbol),
|
102
|
+
type: Class,
|
101
103
|
collection: T::Boolean,
|
102
|
-
default:
|
103
|
-
doc:
|
104
|
-
kwargs:
|
105
|
-
block:
|
104
|
+
default: T.nilable(Proc),
|
105
|
+
doc: T.nilable(String),
|
106
|
+
kwargs: Object,
|
107
|
+
block: T.nilable(T.proc.void),
|
106
108
|
).void
|
107
109
|
end
|
108
110
|
def attribute(name, type, collection: false, default: nil, doc: nil, **kwargs, &block)
|
109
111
|
super(name, type, collection:, default:, **kwargs, &block)
|
110
|
-
attributes[name.to_sym]
|
112
|
+
if (attr_def = attributes[name.to_sym])
|
113
|
+
attr_def.doc = doc
|
114
|
+
end
|
111
115
|
return unless type < ::Shale::Mapper
|
112
116
|
|
113
117
|
if collection
|
@@ -136,8 +140,24 @@ module Shale
|
|
136
140
|
RUBY
|
137
141
|
end
|
138
142
|
|
139
|
-
|
143
|
+
# Create an alias for the getter and setter of an attribute.
|
144
|
+
sig { params(new_name: Symbol, old_name: Symbol).void }
|
145
|
+
def alias_attribute(new_name, old_name)
|
146
|
+
attr = attributes.fetch(old_name)
|
147
|
+
(attr.aliases ||= []) << new_name
|
140
148
|
|
149
|
+
builder_methods_module.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
150
|
+
def #{new_name}
|
151
|
+
#{old_name}
|
152
|
+
end
|
153
|
+
|
154
|
+
def #{new_name}=(val)
|
155
|
+
self.#{old_name} = val
|
156
|
+
end
|
157
|
+
RUBY
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
141
161
|
mixes_in_class_methods(ClassMethods)
|
142
162
|
|
143
163
|
end
|
@@ -52,12 +52,6 @@ module Tapioca
|
|
52
52
|
getter_without_block_type = return_type.to_s
|
53
53
|
end
|
54
54
|
|
55
|
-
if has_shale_builder && attribute.type < ::Shale::Mapper
|
56
|
-
generate_mapper_getter(mod, attribute.name, return_type, getter_without_block_type, comments)
|
57
|
-
else
|
58
|
-
mod.create_method(attribute.name, return_type: getter_without_block_type, comments: comments)
|
59
|
-
end
|
60
|
-
|
61
55
|
setter_type, nilable = shale_type_to_sorbet_setter_type(attribute)
|
62
56
|
if attribute.collection?
|
63
57
|
setter_type_str = "T.nilable(T::Array[#{setter_type}])"
|
@@ -67,13 +61,22 @@ module Tapioca
|
|
67
61
|
setter_type_str = setter_type.to_s
|
68
62
|
end
|
69
63
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
64
|
+
attribute.all_names.each do |name|
|
65
|
+
name_str = name.to_s
|
66
|
+
if has_shale_builder && attribute.type < ::Shale::Mapper
|
67
|
+
generate_mapper_getter(mod, name_str, return_type, getter_without_block_type, comments)
|
68
|
+
else
|
69
|
+
mod.create_method(name_str, return_type: getter_without_block_type, comments: comments)
|
70
|
+
end
|
71
|
+
|
72
|
+
# setter
|
73
|
+
mod.create_method(
|
74
|
+
"#{name_str}=",
|
75
|
+
parameters: [create_param('value', type: setter_type_str)],
|
76
|
+
return_type: setter_type_str,
|
77
|
+
comments: comments,
|
78
|
+
)
|
79
|
+
end
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
@@ -90,6 +93,7 @@ module Tapioca
|
|
90
93
|
end
|
91
94
|
def generate_mapper_getter(mod, method_name, type, getter_without_block_type, comments)
|
92
95
|
if mod.respond_to?(:create_sig)
|
96
|
+
mod = T.unsafe(mod)
|
93
97
|
# for tapioca < 0.16.0
|
94
98
|
sigs = T.let([], T::Array[RBI::Sig])
|
95
99
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shale-builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mateusz Drewniak
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- Rakefile
|
70
70
|
- lib/shale/attribute.rb
|
71
71
|
- lib/shale/builder.rb
|
72
|
+
- lib/shale/builder/nested_validations.rb
|
72
73
|
- lib/shale/builder/version.rb
|
73
74
|
- lib/shale/mapper.rbi
|
74
75
|
- lib/tapioca/dsl/compilers/shale.rb
|