shale-builder 0.2.4 → 0.4.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/.rubocop.yml +19 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +58 -0
- data/Gemfile +7 -2
- data/Gemfile.lock +94 -78
- data/README.md +94 -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 +31 -9
- data/lib/tapioca/dsl/compilers/shale.rb +26 -15
- metadata +4 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da77acaa0e4c63b3155b114625c4da322066c92447ce1297915eac5e4facef71
|
4
|
+
data.tar.gz: 043214cb3659bc261089c29306082051e1cf14dc222e8852336b9cf9f4dd102e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e00a2bbeb8ba5c240543520d7a881e2b10fc3e79cf941250230c5906e7ba85742b31611a04154f45e953ba8ec16a1c6dbbd5dc7c6a72e895d25f646e01a19b7
|
7
|
+
data.tar.gz: 1f5462ad104ca4ffdb7f68d895a517d70dd67b7fe666da7baed61bddd2c68de101061d992abad6895045cb6dc8c958ec59a57cc39cbc51a8fb56056e1bafd5ed
|
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/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.4.5
|
data/CHANGELOG.md
CHANGED
@@ -1,50 +1,108 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [0.4.0] - 2025-10-14
|
9
|
+
|
10
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.3.0...v0.2.1)
|
11
|
+
|
12
|
+
### Changes
|
13
|
+
- Add `Shale::Builder::NestedValidations`
|
14
|
+
- Add `Shale::Builder#alias_attribute`
|
15
|
+
|
16
|
+
## [0.3.0] - 2025-09-24
|
17
|
+
|
18
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.2.1...v0.3.0)
|
19
|
+
|
20
|
+
### Changes
|
21
|
+
- Add support for `BigDecimal`
|
22
|
+
|
1
23
|
## [0.2.1] - 2024-07-16
|
2
24
|
|
25
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.2.0...v0.2.1)
|
26
|
+
|
27
|
+
### Changes
|
3
28
|
- Add additional sorbet type documentation
|
4
29
|
|
5
30
|
## [0.2.0] - 2024-06-11
|
6
31
|
|
32
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.9...v0.2.0)
|
33
|
+
|
34
|
+
### Changes
|
7
35
|
- Add support for `return_type` and `setter_type` in custom primitive shale types
|
8
36
|
- Add a more thorough description of sorbet and tapioca support in the README
|
9
37
|
|
10
38
|
## [0.1.9] - 2024-06-03
|
11
39
|
|
40
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.8...v0.1.9)
|
41
|
+
|
42
|
+
### Changes
|
12
43
|
- Fix the signature of `new` class method
|
13
44
|
|
14
45
|
## [0.1.8] - 2024-05-15
|
15
46
|
|
47
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.7...v0.1.8)
|
48
|
+
|
49
|
+
### Changes
|
16
50
|
- Sort attribute names in the tapioca compiler
|
17
51
|
|
18
52
|
## [0.1.7] - 2024-05-13
|
19
53
|
|
54
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.6...v0.1.7)
|
55
|
+
|
56
|
+
### Changes
|
20
57
|
- Drop support for Ruby 3.0
|
21
58
|
- Add support for Ruby 3.3
|
22
59
|
|
23
60
|
## [0.1.6] - 2024-05-13
|
24
61
|
|
62
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.5...v0.1.6)
|
63
|
+
|
64
|
+
### Changes
|
25
65
|
- Add support for doc strings in the tapioca compiler
|
26
66
|
|
27
67
|
## [0.1.5] - 2024-05-13
|
28
68
|
|
69
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.4...v0.1.5)
|
70
|
+
|
71
|
+
### Changes
|
29
72
|
- Fix a bug in the tapioca compiler
|
30
73
|
|
31
74
|
## [0.1.4] - 2024-05-13
|
32
75
|
|
76
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.3...v0.1.4)
|
77
|
+
|
78
|
+
### Changes
|
33
79
|
- Add a tapioca compiler for shale and shale builder
|
34
80
|
|
35
81
|
## [0.1.3] - 2023-11-23
|
36
82
|
|
83
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.2...v0.1.3)
|
84
|
+
|
85
|
+
### Changes
|
37
86
|
- Change shale version dependency from `< 1.0` to `< 2.0`
|
38
87
|
|
39
88
|
## [0.1.2] - 2023-10-11
|
40
89
|
|
90
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.1...v0.1.2)
|
91
|
+
|
92
|
+
### Changes
|
41
93
|
- Add support for collections
|
42
94
|
- Drop support for Ruby 2.7
|
43
95
|
|
44
96
|
## [0.1.1] - 2023-02-22
|
45
97
|
|
98
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.1.0...v0.1.1)
|
99
|
+
|
100
|
+
### Changes
|
46
101
|
- Add support for inheritance
|
47
102
|
|
48
103
|
## [0.1.0] - 2023-02-21
|
49
104
|
|
105
|
+
[Diff](https://github.com/Verseth/ruby-shale-builder/compare/v0.0.0...v0.1.0)
|
106
|
+
|
107
|
+
### Changes
|
50
108
|
- Initial release
|
data/Gemfile
CHANGED
@@ -5,11 +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
|
-
gem 'solargraph', '~> 0.48' # language server
|
14
19
|
gem 'sorbet', '>= 0.5' # static typechecker
|
15
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.0)
|
5
5
|
booleans (>= 0.1)
|
6
6
|
shale (< 2.0)
|
7
7
|
sorbet-runtime (> 0.5)
|
@@ -9,119 +9,135 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
|
13
|
-
|
14
|
-
|
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)
|
30
|
+
bigdecimal (3.2.3)
|
15
31
|
booleans (0.1.1)
|
16
32
|
byebug (11.1.3)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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)
|
26
43
|
minitest (5.17.0)
|
44
|
+
mutex_m (0.3.0)
|
27
45
|
netrc (0.11.0)
|
28
|
-
|
29
|
-
|
30
|
-
nokogiri (1.16.5-x86_64-linux)
|
31
|
-
racc (~> 1.4)
|
32
|
-
parallel (1.22.1)
|
33
|
-
parser (3.2.1.0)
|
46
|
+
parallel (1.27.0)
|
47
|
+
parser (3.3.9.0)
|
34
48
|
ast (~> 2.4.1)
|
35
|
-
|
36
|
-
|
49
|
+
racc
|
50
|
+
prism (1.5.2)
|
51
|
+
racc (1.8.1)
|
37
52
|
rainbow (3.1.1)
|
38
53
|
rake (13.0.6)
|
39
|
-
rbi (0.
|
40
|
-
prism (
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
rubocop (1.45.1)
|
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)
|
47
61
|
json (~> 2.3)
|
62
|
+
language_server-protocol (~> 3.17.0.2)
|
63
|
+
lint_roller (~> 1.1.0)
|
48
64
|
parallel (~> 1.10)
|
49
|
-
parser (>= 3.
|
65
|
+
parser (>= 3.3.0.2)
|
50
66
|
rainbow (>= 2.2.2, < 4.0)
|
51
|
-
regexp_parser (>=
|
52
|
-
|
53
|
-
rubocop-ast (>= 1.24.1, < 2.0)
|
67
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
68
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
54
69
|
ruby-progressbar (~> 1.7)
|
55
|
-
unicode-display_width (>= 2.4.0, <
|
56
|
-
rubocop-ast (1.
|
57
|
-
parser (>= 3.
|
58
|
-
|
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)
|
59
75
|
rubocop
|
60
|
-
|
61
|
-
|
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)
|
81
|
+
shale (1.2.2)
|
82
|
+
bigdecimal
|
62
83
|
shoulda-context (2.0.0)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
parser (~> 3.0)
|
73
|
-
reverse_markdown (>= 1.0.5, < 3)
|
74
|
-
rubocop (>= 0.52)
|
75
|
-
thor (~> 1.0)
|
76
|
-
tilt (~> 2.0)
|
77
|
-
yard (~> 0.9, >= 0.9.24)
|
78
|
-
sorbet (0.5.11372)
|
79
|
-
sorbet-static (= 0.5.11372)
|
80
|
-
sorbet-runtime (0.5.11372)
|
81
|
-
sorbet-static (0.5.11372-universal-darwin)
|
82
|
-
sorbet-static (0.5.11372-x86_64-linux)
|
83
|
-
sorbet-static-and-runtime (0.5.11372)
|
84
|
-
sorbet (= 0.5.11372)
|
85
|
-
sorbet-runtime (= 0.5.11372)
|
86
|
-
spoom (1.3.2)
|
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)
|
87
93
|
erubi (>= 1.10.0)
|
88
|
-
prism (>= 0.
|
94
|
+
prism (>= 0.28.0)
|
95
|
+
rbi (>= 0.2.3)
|
89
96
|
sorbet-static-and-runtime (>= 0.5.10187)
|
90
97
|
thor (>= 0.19.2)
|
91
|
-
tapioca (0.
|
98
|
+
tapioca (0.16.11)
|
99
|
+
benchmark
|
92
100
|
bundler (>= 2.2.25)
|
93
101
|
netrc (>= 0.11.0)
|
94
102
|
parallel (>= 1.21.0)
|
95
|
-
rbi (
|
103
|
+
rbi (~> 0.2)
|
96
104
|
sorbet-static-and-runtime (>= 0.5.11087)
|
97
105
|
spoom (>= 1.2.0)
|
98
106
|
thor (>= 1.2.0)
|
99
107
|
yard-sorbet
|
100
|
-
thor (1.
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
109
119
|
|
110
120
|
PLATFORMS
|
111
121
|
arm64-darwin-20
|
112
122
|
arm64-darwin-22
|
123
|
+
arm64-darwin-24
|
113
124
|
x86_64-linux
|
114
125
|
|
115
126
|
DEPENDENCIES
|
127
|
+
activemodel (~> 8.0)
|
128
|
+
base64 (~> 0.3)
|
116
129
|
byebug (~> 11.1)
|
117
130
|
minitest (~> 5.0)
|
131
|
+
mutex_m (~> 0.3)
|
132
|
+
racc (~> 1.8)
|
118
133
|
rake (~> 13.0)
|
119
|
-
rubocop
|
134
|
+
rubocop (~> 1.81)
|
135
|
+
rubocop-espago (~> 1.2)
|
136
|
+
rubocop-sorbet (~> 0.11)
|
120
137
|
shale-builder!
|
121
138
|
shoulda-context (~> 2.0)
|
122
|
-
solargraph (~> 0.48)
|
123
139
|
sorbet (>= 0.5)
|
124
140
|
tapioca (> 0.13)
|
125
141
|
|
126
142
|
BUNDLED WITH
|
127
|
-
2.
|
143
|
+
2.7.2
|
data/README.md
CHANGED
@@ -213,6 +213,100 @@ 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
|
+
class AmountType < ::Shale::Mapper
|
274
|
+
include ::Shale::Builder
|
275
|
+
include ::ActiveModel::Validations
|
276
|
+
include ::Shale::Builder::NestedValidations
|
277
|
+
|
278
|
+
attribute :value, ::Shale::Type::Float
|
279
|
+
attribute :currency, ::Shale::Type::String
|
280
|
+
|
281
|
+
validates :value, presence: true
|
282
|
+
end
|
283
|
+
|
284
|
+
class TransactionType < ::Shale::Mapper
|
285
|
+
include ::Shale::Builder
|
286
|
+
include ::ActiveModel::Validations
|
287
|
+
include ::Shale::Builder::NestedValidations
|
288
|
+
|
289
|
+
attribute :cvv_code, ::Shale::Type::String
|
290
|
+
attribute :amount, AmountType
|
291
|
+
|
292
|
+
validates :cvv_code, presence: true
|
293
|
+
validates :amount, presence: true
|
294
|
+
end
|
295
|
+
|
296
|
+
obj = TransactionType.build do |t|
|
297
|
+
t.amount do |a|
|
298
|
+
a.currency = 'USD'
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
obj.valid? #=> false
|
303
|
+
obj.errors #=> #<ActiveModel::Errors [#<ActiveModel::Error attribute=cvv_code, type=blank, options={}>, #<ActiveModel::NestedError attribute=amount.value, type=blank, options={}>]>
|
304
|
+
obj.errors.messages #=> {cvv_code: ["can't be blank"], "amount.value": ["can't be blank"]}
|
305
|
+
```
|
306
|
+
|
307
|
+
You MUST include `ActiveModel::Validations` before `Shale::Builder::NestedValidations`.
|
308
|
+
|
309
|
+
|
216
310
|
### Sorbet support
|
217
311
|
|
218
312
|
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
|
@@ -137,8 +141,26 @@ module Shale
|
|
137
141
|
end
|
138
142
|
|
139
143
|
end
|
140
|
-
|
141
144
|
mixes_in_class_methods(ClassMethods)
|
142
145
|
|
146
|
+
# Create an alias for the getter and setter of an attribute.
|
147
|
+
sig { params(new_name: Symbol, old_name: Symbol).void }
|
148
|
+
def alias_attribute(new_name, old_name)
|
149
|
+
klass = T.unsafe(self).class
|
150
|
+
|
151
|
+
attr = klass.attributes[old_name]
|
152
|
+
(attr.aliases ||= []) << new_name
|
153
|
+
|
154
|
+
klass.builder_methods_module.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
155
|
+
def #{new_name}
|
156
|
+
#{old_name}
|
157
|
+
end
|
158
|
+
|
159
|
+
def #{new_name}=(val)
|
160
|
+
self.#{old_name} = val
|
161
|
+
end
|
162
|
+
RUBY
|
163
|
+
end
|
164
|
+
|
143
165
|
end
|
144
166
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'shale'
|
5
5
|
require 'booleans'
|
6
|
+
require 'bigdecimal'
|
6
7
|
begin
|
7
8
|
require 'shale/builder'
|
8
9
|
rescue LoadError
|
@@ -51,12 +52,6 @@ module Tapioca
|
|
51
52
|
getter_without_block_type = return_type.to_s
|
52
53
|
end
|
53
54
|
|
54
|
-
if has_shale_builder && attribute.type < ::Shale::Mapper
|
55
|
-
generate_mapper_getter(mod, attribute.name, return_type, getter_without_block_type, comments)
|
56
|
-
else
|
57
|
-
mod.create_method(attribute.name, return_type: getter_without_block_type, comments: comments)
|
58
|
-
end
|
59
|
-
|
60
55
|
setter_type, nilable = shale_type_to_sorbet_setter_type(attribute)
|
61
56
|
if attribute.collection?
|
62
57
|
setter_type_str = "T.nilable(T::Array[#{setter_type}])"
|
@@ -66,13 +61,22 @@ module Tapioca
|
|
66
61
|
setter_type_str = setter_type.to_s
|
67
62
|
end
|
68
63
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
76
80
|
end
|
77
81
|
end
|
78
82
|
|
@@ -89,6 +93,7 @@ module Tapioca
|
|
89
93
|
end
|
90
94
|
def generate_mapper_getter(mod, method_name, type, getter_without_block_type, comments)
|
91
95
|
if mod.respond_to?(:create_sig)
|
96
|
+
mod = T.unsafe(mod)
|
92
97
|
# for tapioca < 0.16.0
|
93
98
|
sigs = T.let([], T::Array[RBI::Sig])
|
94
99
|
|
@@ -148,7 +153,9 @@ module Tapioca
|
|
148
153
|
::Shale::Type::Time => Time,
|
149
154
|
::Shale::Type::Date => Date,
|
150
155
|
::Shale::Type::Boolean => T::Boolean,
|
151
|
-
}.
|
156
|
+
}.tap do |h|
|
157
|
+
h[::Shale::Type::Decimal] = BigDecimal if defined?(::Shale::Type::Decimal)
|
158
|
+
end.freeze,
|
152
159
|
T::Hash[Class, Object],
|
153
160
|
)
|
154
161
|
|
@@ -162,7 +169,11 @@ module Tapioca
|
|
162
169
|
::Shale::Type::Time => Time,
|
163
170
|
::Shale::Type::Date => Date,
|
164
171
|
::Shale::Type::Boolean => Object,
|
165
|
-
}.
|
172
|
+
}.tap do |h|
|
173
|
+
if defined?(::Shale::Type::Decimal)
|
174
|
+
h[::Shale::Type::Decimal] = T.any(BigDecimal, String, Float, Integer, NilClass)
|
175
|
+
end
|
176
|
+
end.freeze,
|
166
177
|
T::Hash[Class, Object],
|
167
178
|
)
|
168
179
|
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
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.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mateusz Drewniak
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: booleans
|
@@ -70,6 +69,7 @@ files:
|
|
70
69
|
- Rakefile
|
71
70
|
- lib/shale/attribute.rb
|
72
71
|
- lib/shale/builder.rb
|
72
|
+
- lib/shale/builder/nested_validations.rb
|
73
73
|
- lib/shale/builder/version.rb
|
74
74
|
- lib/shale/mapper.rbi
|
75
75
|
- lib/tapioca/dsl/compilers/shale.rb
|
@@ -81,7 +81,6 @@ metadata:
|
|
81
81
|
source_code_uri: https://github.com/Verseth/ruby-shale-builder
|
82
82
|
changelog_uri: https://github.com/Verseth/ruby-shale-builder/blob/main/CHANGELOG.md
|
83
83
|
rubygems_mfa_required: 'true'
|
84
|
-
post_install_message:
|
85
84
|
rdoc_options: []
|
86
85
|
require_paths:
|
87
86
|
- lib
|
@@ -96,8 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
95
|
- !ruby/object:Gem::Version
|
97
96
|
version: '0'
|
98
97
|
requirements: []
|
99
|
-
rubygems_version: 3.
|
100
|
-
signing_key:
|
98
|
+
rubygems_version: 3.7.2
|
101
99
|
specification_version: 4
|
102
100
|
summary: An addon to the shale Ruby gem which adds a simple yet powerful builder DSL.
|
103
101
|
test_files: []
|