nxt_support 0.1.8 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +17 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile.lock +36 -138
- data/README.md +127 -10
- data/bin/release +8 -0
- data/lib/nxt_support/models/duration_attribute_accessor.rb +62 -0
- data/lib/nxt_support/models/email.rb +2 -2
- data/lib/nxt_support/models.rb +1 -0
- data/lib/nxt_support/preprocessor.rb +1 -1
- data/lib/nxt_support/services/base.rb +33 -0
- data/lib/nxt_support/services.rb +1 -0
- data/lib/nxt_support/util/enum/value.rb +7 -0
- data/lib/nxt_support/util/enum.rb +43 -0
- data/lib/nxt_support/util/enum_hash.rb +2 -25
- data/lib/nxt_support/util.rb +2 -0
- data/lib/nxt_support/version.rb +1 -1
- data/lib/nxt_support.rb +1 -0
- data/nxt_support.gemspec +4 -3
- metadata +33 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04156bb470e9230b1d2d6eb97b40ac553d6f54d945875eac31ed48148907ac29
|
4
|
+
data.tar.gz: 4daca280e15ef43fdd8e465b39ec9810930ad66fdd668ce300bdfb9431f47e71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36e8e83265ea3d5accc6ff7fdd67221ea4d88c8e9b451e92dc7cc7806c0e8f9e0c44ec609d25d1ef13c04acca86a20196f0bd36921a470502243ceca551af90c
|
7
|
+
data.tar.gz: bf5edfb86fdac8909c673405094179adcf0ca8200a7935c7bcde48e4e4b162f65cee2f7443b8cbec6b242c5f15120bd0da3c1b3cafff207f662c23ff89c8ccc4
|
data/.circleci/config.yml
CHANGED
@@ -2,18 +2,31 @@
|
|
2
2
|
#
|
3
3
|
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
|
4
4
|
#
|
5
|
-
version: 2
|
5
|
+
version: 2.1
|
6
|
+
|
7
|
+
workflows:
|
8
|
+
build:
|
9
|
+
jobs:
|
10
|
+
- build:
|
11
|
+
matrix:
|
12
|
+
parameters:
|
13
|
+
ruby-version: ["2.6.8", "2.7.4", "3.0.2"]
|
14
|
+
|
6
15
|
jobs:
|
7
16
|
build:
|
17
|
+
parameters:
|
18
|
+
ruby-version:
|
19
|
+
type: string
|
20
|
+
|
8
21
|
docker:
|
9
22
|
# specify the version you desire here
|
10
|
-
- image: circleci/ruby
|
23
|
+
- image: circleci/ruby:<< parameters.ruby-version >>-node
|
11
24
|
|
12
25
|
working_directory: ~/repo
|
13
26
|
|
14
27
|
steps:
|
15
28
|
- checkout
|
16
|
-
|
29
|
+
|
17
30
|
- run:
|
18
31
|
name: Install apt dependencies
|
19
32
|
command: |
|
@@ -26,7 +39,7 @@ jobs:
|
|
26
39
|
- restore_cache:
|
27
40
|
keys:
|
28
41
|
- v1-dependencies-{{ checksum "Gemfile.lock" }}
|
29
|
-
|
42
|
+
|
30
43
|
- run: gem install bundler
|
31
44
|
|
32
45
|
- run:
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
# v0.1.15 2021-03-26
|
2
|
+
- Switched Rails dependency to ActiveRecord and ActiveSupport
|
3
|
+
|
4
|
+
# v0.1.14 2020-11-25
|
5
|
+
- Added `NxtSupport::DurationAttributeAccessor`
|
6
|
+
|
7
|
+
# v0.1.13 2020-11-13
|
8
|
+
- Fixed `Email::REGEXP` to be more generous about hostname
|
9
|
+
|
10
|
+
# v0.1.12 2020-11-11
|
11
|
+
- Added `bin/release` script to publish GitHub tags
|
12
|
+
|
13
|
+
# v0.1.11 2020-10-29
|
14
|
+
|
15
|
+
- Introduced `NxtSupport::Services::Base`
|
16
|
+
|
17
|
+
# v0.1.10 2020-10-10
|
18
|
+
|
19
|
+
- Introduced `NxtSupport::Enum`
|
20
|
+
- Deprecated `NxtSupport::EnumHash`
|
21
|
+
|
22
|
+
|
23
|
+
# v0.1.9 2020-09-09
|
24
|
+
|
25
|
+
- Fix `NxtSupport::PreprocessAttributes` to use new `nxt_registry 0.3.0` interface
|
26
|
+
|
1
27
|
# v0.1.8 2020-09-09
|
2
28
|
|
3
29
|
- Added `NxtSupport::BirthDate`
|
data/Gemfile.lock
CHANGED
@@ -1,162 +1,60 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nxt_support (0.
|
4
|
+
nxt_support (0.2.0)
|
5
|
+
activerecord
|
6
|
+
activesupport
|
5
7
|
nxt_init
|
6
8
|
nxt_registry
|
7
|
-
rails
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
activejob (= 6.0.3.2)
|
19
|
-
activerecord (= 6.0.3.2)
|
20
|
-
activestorage (= 6.0.3.2)
|
21
|
-
activesupport (= 6.0.3.2)
|
22
|
-
mail (>= 2.7.1)
|
23
|
-
actionmailer (6.0.3.2)
|
24
|
-
actionpack (= 6.0.3.2)
|
25
|
-
actionview (= 6.0.3.2)
|
26
|
-
activejob (= 6.0.3.2)
|
27
|
-
mail (~> 2.5, >= 2.5.4)
|
28
|
-
rails-dom-testing (~> 2.0)
|
29
|
-
actionpack (6.0.3.2)
|
30
|
-
actionview (= 6.0.3.2)
|
31
|
-
activesupport (= 6.0.3.2)
|
32
|
-
rack (~> 2.0, >= 2.0.8)
|
33
|
-
rack-test (>= 0.6.3)
|
34
|
-
rails-dom-testing (~> 2.0)
|
35
|
-
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
36
|
-
actiontext (6.0.3.2)
|
37
|
-
actionpack (= 6.0.3.2)
|
38
|
-
activerecord (= 6.0.3.2)
|
39
|
-
activestorage (= 6.0.3.2)
|
40
|
-
activesupport (= 6.0.3.2)
|
41
|
-
nokogiri (>= 1.8.5)
|
42
|
-
actionview (6.0.3.2)
|
43
|
-
activesupport (= 6.0.3.2)
|
44
|
-
builder (~> 3.1)
|
45
|
-
erubi (~> 1.4)
|
46
|
-
rails-dom-testing (~> 2.0)
|
47
|
-
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
48
|
-
activejob (6.0.3.2)
|
49
|
-
activesupport (= 6.0.3.2)
|
50
|
-
globalid (>= 0.3.6)
|
51
|
-
activemodel (6.0.3.2)
|
52
|
-
activesupport (= 6.0.3.2)
|
53
|
-
activerecord (6.0.3.2)
|
54
|
-
activemodel (= 6.0.3.2)
|
55
|
-
activesupport (= 6.0.3.2)
|
56
|
-
activestorage (6.0.3.2)
|
57
|
-
actionpack (= 6.0.3.2)
|
58
|
-
activejob (= 6.0.3.2)
|
59
|
-
activerecord (= 6.0.3.2)
|
60
|
-
marcel (~> 0.3.1)
|
61
|
-
activesupport (6.0.3.2)
|
13
|
+
activemodel (6.1.4.1)
|
14
|
+
activesupport (= 6.1.4.1)
|
15
|
+
activerecord (6.1.4.1)
|
16
|
+
activemodel (= 6.1.4.1)
|
17
|
+
activesupport (= 6.1.4.1)
|
18
|
+
activesupport (6.1.4.1)
|
62
19
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
63
|
-
i18n (>=
|
64
|
-
minitest (
|
65
|
-
tzinfo (~>
|
66
|
-
zeitwerk (~> 2.
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
diff-lcs (1.3)
|
72
|
-
erubi (1.9.0)
|
73
|
-
globalid (0.4.2)
|
74
|
-
activesupport (>= 4.2.0)
|
75
|
-
i18n (1.8.5)
|
20
|
+
i18n (>= 1.6, < 2)
|
21
|
+
minitest (>= 5.1)
|
22
|
+
tzinfo (~> 2.0)
|
23
|
+
zeitwerk (~> 2.3)
|
24
|
+
coderay (1.1.3)
|
25
|
+
concurrent-ruby (1.1.9)
|
26
|
+
diff-lcs (1.4.4)
|
27
|
+
i18n (1.8.10)
|
76
28
|
concurrent-ruby (~> 1.0)
|
77
|
-
loofah (2.7.0)
|
78
|
-
crass (~> 1.0.2)
|
79
|
-
nokogiri (>= 1.5.9)
|
80
|
-
mail (2.7.1)
|
81
|
-
mini_mime (>= 0.1.1)
|
82
|
-
marcel (0.3.3)
|
83
|
-
mimemagic (~> 0.3.2)
|
84
29
|
method_source (1.0.0)
|
85
|
-
|
86
|
-
mini_mime (1.0.2)
|
87
|
-
mini_portile2 (2.4.0)
|
88
|
-
minitest (5.14.2)
|
89
|
-
nio4r (2.5.3)
|
90
|
-
nokogiri (1.10.10)
|
91
|
-
mini_portile2 (~> 2.4.0)
|
30
|
+
minitest (5.14.4)
|
92
31
|
nxt_init (0.1.5)
|
93
32
|
activesupport
|
94
|
-
nxt_registry (0.
|
33
|
+
nxt_registry (0.3.10)
|
95
34
|
activesupport
|
96
|
-
pry (0.
|
35
|
+
pry (0.14.0)
|
97
36
|
coderay (~> 1.1)
|
98
37
|
method_source (~> 1.0)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
actiontext (= 6.0.3.2)
|
108
|
-
actionview (= 6.0.3.2)
|
109
|
-
activejob (= 6.0.3.2)
|
110
|
-
activemodel (= 6.0.3.2)
|
111
|
-
activerecord (= 6.0.3.2)
|
112
|
-
activestorage (= 6.0.3.2)
|
113
|
-
activesupport (= 6.0.3.2)
|
114
|
-
bundler (>= 1.3.0)
|
115
|
-
railties (= 6.0.3.2)
|
116
|
-
sprockets-rails (>= 2.0.0)
|
117
|
-
rails-dom-testing (2.0.3)
|
118
|
-
activesupport (>= 4.2.0)
|
119
|
-
nokogiri (>= 1.6)
|
120
|
-
rails-html-sanitizer (1.3.0)
|
121
|
-
loofah (~> 2.3)
|
122
|
-
railties (6.0.3.2)
|
123
|
-
actionpack (= 6.0.3.2)
|
124
|
-
activesupport (= 6.0.3.2)
|
125
|
-
method_source
|
126
|
-
rake (>= 0.8.7)
|
127
|
-
thor (>= 0.20.3, < 2.0)
|
128
|
-
rake (13.0.1)
|
129
|
-
rspec (3.9.0)
|
130
|
-
rspec-core (~> 3.9.0)
|
131
|
-
rspec-expectations (~> 3.9.0)
|
132
|
-
rspec-mocks (~> 3.9.0)
|
133
|
-
rspec-core (3.9.0)
|
134
|
-
rspec-support (~> 3.9.0)
|
135
|
-
rspec-expectations (3.9.0)
|
38
|
+
rake (13.0.3)
|
39
|
+
rspec (3.10.0)
|
40
|
+
rspec-core (~> 3.10.0)
|
41
|
+
rspec-expectations (~> 3.10.0)
|
42
|
+
rspec-mocks (~> 3.10.0)
|
43
|
+
rspec-core (3.10.1)
|
44
|
+
rspec-support (~> 3.10.0)
|
45
|
+
rspec-expectations (3.10.1)
|
136
46
|
diff-lcs (>= 1.2.0, < 2.0)
|
137
|
-
rspec-support (~> 3.
|
138
|
-
rspec-mocks (3.
|
47
|
+
rspec-support (~> 3.10.0)
|
48
|
+
rspec-mocks (3.10.2)
|
139
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
140
|
-
rspec-support (~> 3.
|
141
|
-
rspec-support (3.
|
50
|
+
rspec-support (~> 3.10.0)
|
51
|
+
rspec-support (3.10.2)
|
142
52
|
rspec_junit_formatter (0.4.1)
|
143
53
|
rspec-core (>= 2, < 4, != 2.12.0)
|
144
|
-
sprockets (4.0.2)
|
145
|
-
concurrent-ruby (~> 1.0)
|
146
|
-
rack (> 1, < 3)
|
147
|
-
sprockets-rails (3.2.1)
|
148
|
-
actionpack (>= 4.0)
|
149
|
-
activesupport (>= 4.0)
|
150
|
-
sprockets (>= 3.0.0)
|
151
54
|
sqlite3 (1.4.2)
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
thread_safe (~> 0.1)
|
156
|
-
websocket-driver (0.7.3)
|
157
|
-
websocket-extensions (>= 0.1.0)
|
158
|
-
websocket-extensions (0.1.5)
|
159
|
-
zeitwerk (2.4.0)
|
55
|
+
tzinfo (2.0.4)
|
56
|
+
concurrent-ruby (~> 1.0)
|
57
|
+
zeitwerk (2.4.2)
|
160
58
|
|
161
59
|
PLATFORMS
|
162
60
|
ruby
|
@@ -171,4 +69,4 @@ DEPENDENCIES
|
|
171
69
|
sqlite3
|
172
70
|
|
173
71
|
BUNDLED WITH
|
174
|
-
2.
|
72
|
+
2.2.25
|
data/README.md
CHANGED
@@ -52,7 +52,7 @@ The `safely_find_or_create_by` method provided by this concern catches such an e
|
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
class Book < ApplicationRecord
|
55
|
-
|
55
|
+
include NxtSupport::SafelyFindOrCreateable
|
56
56
|
end
|
57
57
|
|
58
58
|
Book.safely_find_or_create_by!(market: 'de', title: 'Moche!')
|
@@ -64,7 +64,7 @@ The `NxtSupport::AssignableValues` allows you to restrict the possible values fo
|
|
64
64
|
|
65
65
|
```ruby
|
66
66
|
class Book < ApplicationRecord
|
67
|
-
|
67
|
+
include NxtSupport::AssignableValues
|
68
68
|
|
69
69
|
# You can use a block
|
70
70
|
assignable_values_for :genre do
|
@@ -136,6 +136,48 @@ book.save
|
|
136
136
|
book.views #=> "1001"
|
137
137
|
```
|
138
138
|
|
139
|
+
#### NxtSupport::DurationAttributeAccessor
|
140
|
+
|
141
|
+
This mixin provides the accessors for `ActiveSupport::Duration` attributes.
|
142
|
+
Imagine you have a database table that needs to store some kind of duration data:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
ActiveRecord::Schema.define do
|
146
|
+
create_table :courses, force: true do |t|
|
147
|
+
t.string :class_duration
|
148
|
+
t.string :topic_duration
|
149
|
+
t.string :total_duration
|
150
|
+
end
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
And an appropriate model:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
class Course < ActiveRecord::Base
|
158
|
+
include NxtSupport::DurationAttributeAccessor
|
159
|
+
|
160
|
+
duration_attribute_accessor :class_duration, :topic_duration, :total_duration
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
164
|
+
You can then pass the `ActiveSupport::Duration` objects as arguments and get them back:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
course = Course.new(
|
168
|
+
class_duration: 1.hour,
|
169
|
+
topic_duration: 1.month,
|
170
|
+
total_duration: 1.year
|
171
|
+
)
|
172
|
+
|
173
|
+
# Fields persist in the database as ISO8601-compliant strings
|
174
|
+
course # => #<#<Course:0x00007f8bcf2bcfc0>:0x00007f8bcf2c7920 id: nil, class_duration: "PT1H", topic_duration: "P1M", total_duration: "P1Y">
|
175
|
+
course.class_duration # => 1 hour
|
176
|
+
course.topic_duration # => 1 month
|
177
|
+
course.total_duration # => 1 year
|
178
|
+
```
|
179
|
+
|
180
|
+
|
139
181
|
### NxtSupport/Serializers
|
140
182
|
|
141
183
|
Enjoy mixins for your serializers.
|
@@ -156,22 +198,26 @@ end
|
|
156
198
|
|
157
199
|
Enjoy some useful utilities
|
158
200
|
|
159
|
-
#### NxtSupport::
|
201
|
+
#### NxtSupport::Enum
|
160
202
|
|
161
|
-
`NxtSupport::
|
162
|
-
|
163
|
-
no value for the key.
|
203
|
+
`NxtSupport::Enum` provides a simple interface to organize enums.
|
204
|
+
Values will be normalized to be underscore and downcase and access with [] is raising a `KeyError` in case there is
|
205
|
+
no value for the key. There are also normalized readers for all your values.
|
164
206
|
|
165
207
|
```ruby
|
166
208
|
class Book
|
167
|
-
STATES = NxtSupport::
|
209
|
+
STATES = NxtSupport::Enum['draft', 'revised', 'Published', 'in weird State']
|
168
210
|
end
|
169
211
|
|
170
212
|
Book::STATES[:draft] # 'draft'
|
213
|
+
Book::STATES.draft # 'draft'
|
171
214
|
Book::STATES['revised'] # 'revised'
|
215
|
+
Book::STATES.revised # 'revised'
|
172
216
|
Book::STATES['published'] # 'Published'
|
217
|
+
Book::STATES.published # 'Published'
|
173
218
|
Book::STATES['Published'] # KeyError
|
174
219
|
Book::STATES['in_weird_state'] # 'in weird State'
|
220
|
+
Book::STATES.in_weird_state # 'in weird State'
|
175
221
|
|
176
222
|
```
|
177
223
|
|
@@ -249,7 +295,7 @@ TestClass.translate_hash(hash, tuple)
|
|
249
295
|
|
250
296
|
#### NxtSupport::Crystalizer
|
251
297
|
|
252
|
-
`NxtSupport::Crystalizer` crystallizes a shared value from an array of elements and screams in case the value is not
|
298
|
+
`NxtSupport::Crystalizer` crystallizes a shared value from an array of elements and screams in case the value is not
|
253
299
|
the same across the collection. This is useful in a scenario where you want to guarantee that certain objects share the same
|
254
300
|
attribute. Let's say you want to ensure that all users in your collection reference the same department, then the idea
|
255
301
|
is that you can crystallize the department from your collection.
|
@@ -257,8 +303,8 @@ is that you can crystallize the department from your collection.
|
|
257
303
|
```ruby
|
258
304
|
NxtSupport::Crystalizer.new(collection: ['andy', 'andy']).call # => 'andy'
|
259
305
|
NxtSupport::Crystalizer.new(collection: []).call # NxtSupport::Crystalizer::Error
|
260
|
-
NxtSupport::Crystalizer.new(collection: ['andy', 'scotty']).call # NxtSupport::Crystalizer::Error
|
261
|
-
NxtSupport::Crystalizer.new(collection: insurances, attribute: :effective_at).call # => shared effective_at or error in case of different effective_ats
|
306
|
+
NxtSupport::Crystalizer.new(collection: ['andy', 'scotty']).call # NxtSupport::Crystalizer::Error
|
307
|
+
NxtSupport::Crystalizer.new(collection: insurances, attribute: :effective_at).call # => shared effective_at or error in case of different effective_ats
|
262
308
|
```
|
263
309
|
|
264
310
|
#### NxtSupport::BirthDate
|
@@ -270,6 +316,62 @@ NxtSupport::BirthDate.new(date: '1990-08-08').to_age # => 30
|
|
270
316
|
NxtSupport::BirthDate.new(date: '1990-08-08').to_age_in_months # => 361
|
271
317
|
```
|
272
318
|
|
319
|
+
### NxtSupport/Services
|
320
|
+
Enjoy your service objects.
|
321
|
+
|
322
|
+
#### NxtSupport::Services::Base
|
323
|
+
|
324
|
+
`NxtSupport::Services::Base` gives you some convenient sugar for service objects.
|
325
|
+
Instead of:
|
326
|
+
```ruby
|
327
|
+
WeatherFetcher.new(location: 'Heidelberg').call
|
328
|
+
```
|
329
|
+
|
330
|
+
You can use:
|
331
|
+
```ruby
|
332
|
+
WeatherFetcher.call(location: 'Heidelberg')
|
333
|
+
```
|
334
|
+
|
335
|
+
##### Usage
|
336
|
+
You have to include `NxtSupport::Services::Base` in your service:
|
337
|
+
```ruby
|
338
|
+
class WeatherFetcher
|
339
|
+
include NxtSupport::Services::Base
|
340
|
+
|
341
|
+
def call
|
342
|
+
'Getting the weather..'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
```
|
346
|
+
|
347
|
+
Use it:
|
348
|
+
```ruby
|
349
|
+
WeatherFetcher.call # => 'Getting the weather..'
|
350
|
+
```
|
351
|
+
|
352
|
+
##### With a custom method name
|
353
|
+
If you implement a method other than `#call`, you can use `#class_interface :your_method`
|
354
|
+
```ruby
|
355
|
+
class HomeBuilder
|
356
|
+
include NxtSupport::Services::Base
|
357
|
+
include NxtInit
|
358
|
+
|
359
|
+
attr_init :width, :length, :height, :roof_type
|
360
|
+
|
361
|
+
class_interface :build
|
362
|
+
|
363
|
+
def build
|
364
|
+
"Building #{width}x#{length}x#{height} house with a #{roof_type} roof"
|
365
|
+
end
|
366
|
+
end
|
367
|
+
```
|
368
|
+
|
369
|
+
Use it:
|
370
|
+
```ruby
|
371
|
+
HomeBuilder.build(width: 20, length: 40, height: 15, roof_type: :pitched)
|
372
|
+
# => Building 20x40x15 house with a pitched roof
|
373
|
+
```
|
374
|
+
|
273
375
|
## Development
|
274
376
|
|
275
377
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -280,6 +382,21 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
280
382
|
|
281
383
|
Bug reports and pull requests are welcome on GitHub at https://github.com/nxt_insurance/nxt_support.
|
282
384
|
|
385
|
+
## Publishing
|
386
|
+
### GitHub Tags and Releases
|
387
|
+
Use this command to push the tag to the GitHub Releases page as well as to RubyGems:
|
388
|
+
```sh
|
389
|
+
bin/release
|
390
|
+
```
|
391
|
+
|
392
|
+
### RubyGems
|
393
|
+
For pushing to rubygems:
|
394
|
+
1. Make sure you have ownership rights on RubyGems
|
395
|
+
2. Release the new gem version
|
396
|
+
```sh
|
397
|
+
bundle exec rake release
|
398
|
+
```
|
399
|
+
|
283
400
|
## License
|
284
401
|
|
285
402
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/release
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
|
3
|
+
GEM_VERSION=$(ruby -e '$LOAD_PATH << File.join(File.dirname(__FILE__), "lib"); require "nxt_support/version"; print NxtSupport::VERSION')
|
4
|
+
|
5
|
+
git tag -m "Release $GEM_VERSION" -a v$GEM_VERSION HEAD
|
6
|
+
git push origin --tags
|
7
|
+
|
8
|
+
bundle exec rake release
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module NxtSupport
|
2
|
+
module DurationAttributeAccessor
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def duration_attribute_accessor(*attrs)
|
7
|
+
duration_attribute_reader(*attrs)
|
8
|
+
duration_attribute_writer(*attrs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def duration_attribute_reader(*attrs)
|
12
|
+
attrs.each do |attr_name|
|
13
|
+
define_duration_attribute_reader(attr_name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def duration_attribute_writer(*attrs)
|
18
|
+
attrs.each do |attr_name|
|
19
|
+
define_duration_attribute_writer(attr_name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def define_duration_attribute_reader(attr_name)
|
26
|
+
define_method(attr_name) do
|
27
|
+
duration_string = read_attribute(attr_name)
|
28
|
+
return if duration_string.nil?
|
29
|
+
|
30
|
+
ActiveSupport::Duration.parse(duration_string)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def define_duration_attribute_writer(attr_name)
|
35
|
+
define_method("#{attr_name}=") do |value|
|
36
|
+
case value
|
37
|
+
when ActiveSupport::Duration
|
38
|
+
write_attribute(attr_name, value.iso8601)
|
39
|
+
when String
|
40
|
+
if is_valid_iso8601_duration?(value)
|
41
|
+
write_attribute(attr_name, value)
|
42
|
+
else
|
43
|
+
raise ArgumentError, "'#{value}' is not a valid iso8601 string"
|
44
|
+
end
|
45
|
+
when NilClass
|
46
|
+
write_attribute(attr_name, value)
|
47
|
+
else
|
48
|
+
raise ArgumentError, 'Please provide an ActiveSupport::Duration object or an iso8601 formatted string'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def is_valid_iso8601_duration?(string)
|
56
|
+
ActiveSupport::Duration.parse(string)
|
57
|
+
true
|
58
|
+
rescue ActiveSupport::Duration::ISO8601Parser::ParsingError
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -5,8 +5,8 @@ module NxtSupport
|
|
5
5
|
# (2) No whitespace characters
|
6
6
|
# (3) At least one non-whitespace character before the '@' character
|
7
7
|
# (4) No dot ('.') character directly after the '@' character
|
8
|
-
# (5) A hostname after the '@' character of at least
|
8
|
+
# (5) A hostname after the '@' character of at least one non-whitespace characters length
|
9
9
|
# (6) At least one top level domain ending (e.g. '.com') after the hostname, separated from the hostname by a dot ('.')
|
10
|
-
REGEXP = /\A[^@\s]+@[
|
10
|
+
REGEXP = /\A[^@\s]+@([^.@\s]+\.)+[^.^@\s]+\z/.freeze
|
11
11
|
end
|
12
12
|
end
|
data/lib/nxt_support/models.rb
CHANGED
@@ -3,3 +3,4 @@ require "nxt_support/models/safely_find_or_createable"
|
|
3
3
|
require "nxt_support/models/indifferently_accessible_json_attrs"
|
4
4
|
require "nxt_support/models/assignable_values"
|
5
5
|
require "nxt_support/models/preprocess_attributes"
|
6
|
+
require "nxt_support/models/duration_attribute_accessor"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module NxtSupport
|
2
|
+
module Services
|
3
|
+
module Base
|
4
|
+
module ClassMethods
|
5
|
+
def class_interface(config = :call)
|
6
|
+
if config.is_a?(Symbol)
|
7
|
+
define_singleton_method config do |*args, **opts|
|
8
|
+
build_instance(*args, **opts).send(config)
|
9
|
+
end
|
10
|
+
else
|
11
|
+
raise ArgumentError, "Wrong configuration. Please use 'class_interface :your_method_name'"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Ruby <2.7-specific check. If the gem is updated to 2.7, `**opts` will work.
|
18
|
+
def build_instance(*args, **opts)
|
19
|
+
if opts.empty?
|
20
|
+
new(*args, **{})
|
21
|
+
else
|
22
|
+
new(*args, **opts)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.included(base)
|
28
|
+
base.extend(ClassMethods)
|
29
|
+
base.class_interface
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "nxt_support/services/base"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module NxtSupport
|
2
|
+
class Enum
|
3
|
+
def initialize(*keys)
|
4
|
+
@store = ActiveSupport::HashWithIndifferentAccess.new
|
5
|
+
|
6
|
+
keys.each do |key|
|
7
|
+
normalized_key = normalized_key(key)
|
8
|
+
store[normalized_key] = NxtSupport::Enum::Value.new(key)
|
9
|
+
define_getter(normalized_key)
|
10
|
+
end
|
11
|
+
|
12
|
+
freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.[](*keys)
|
16
|
+
new(*keys)
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](key)
|
20
|
+
store[key] || (raise KeyError, "No value for key '#{key}' in #{store}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_h
|
24
|
+
store
|
25
|
+
end
|
26
|
+
|
27
|
+
delegate_missing_to :to_h
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :store
|
32
|
+
|
33
|
+
def normalized_key(key)
|
34
|
+
key.to_s.downcase.underscore.gsub(/\s+/, '_')
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_getter(normalized_key)
|
38
|
+
define_singleton_method normalized_key do
|
39
|
+
store[normalized_key]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,27 +1,4 @@
|
|
1
1
|
module NxtSupport
|
2
|
-
|
3
|
-
|
4
|
-
super()
|
5
|
-
|
6
|
-
keys.each do |key|
|
7
|
-
self[normalized_key(key)] = key.to_s
|
8
|
-
end
|
9
|
-
|
10
|
-
freeze
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.[](*keys)
|
14
|
-
new(*keys)
|
15
|
-
end
|
16
|
-
|
17
|
-
def [](key)
|
18
|
-
super(key) || (raise KeyError, "No value for key '#{key}' in #{inspect}")
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def normalized_key(key)
|
24
|
-
key.to_s.downcase.underscore.gsub(/\s+/, '_')
|
25
|
-
end
|
26
|
-
end
|
2
|
+
# Deprecated
|
3
|
+
EnumHash = Class.new(Enum)
|
27
4
|
end
|
data/lib/nxt_support/util.rb
CHANGED
data/lib/nxt_support/version.rb
CHANGED
data/lib/nxt_support.rb
CHANGED
data/nxt_support.gemspec
CHANGED
@@ -5,8 +5,8 @@ require "nxt_support/version"
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "nxt_support"
|
7
7
|
spec.version = NxtSupport::VERSION
|
8
|
-
spec.authors = ["Nils Sommer", "Andreas Robecke"]
|
9
|
-
spec.email = ["mail@nilssommer.de", "a.robecke@getsafe.de"]
|
8
|
+
spec.authors = ["Nils Sommer", "Andreas Robecke", "Nicolai Stoianov", "Akihiko Ito"]
|
9
|
+
spec.email = ["mail@nilssommer.de", "a.robecke@getsafe.de", "n.stoianov@hellogetsafe.com", "abc@akihiko.eu"]
|
10
10
|
|
11
11
|
spec.summary = "Support through reusable Mixins and Helpers for Ruby on Rails Applications"
|
12
12
|
spec.homepage = "https://github.com/nxt-insurance/nxt_support"
|
@@ -27,7 +27,8 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
-
spec.add_dependency "
|
30
|
+
spec.add_dependency "activerecord"
|
31
|
+
spec.add_dependency "activesupport"
|
31
32
|
spec.add_dependency "nxt_init"
|
32
33
|
spec.add_dependency "nxt_registry"
|
33
34
|
spec.add_development_dependency "bundler"
|
metadata
CHANGED
@@ -1,18 +1,34 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nxt_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nils Sommer
|
8
8
|
- Andreas Robecke
|
9
|
-
|
9
|
+
- Nicolai Stoianov
|
10
|
+
- Akihiko Ito
|
11
|
+
autorequire:
|
10
12
|
bindir: exe
|
11
13
|
cert_chain: []
|
12
|
-
date:
|
14
|
+
date: 2021-09-13 00:00:00.000000000 Z
|
13
15
|
dependencies:
|
14
16
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
17
|
+
name: activerecord
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
17
33
|
requirements:
|
18
34
|
- - ">="
|
@@ -123,10 +139,12 @@ dependencies:
|
|
123
139
|
- - ">="
|
124
140
|
- !ruby/object:Gem::Version
|
125
141
|
version: '0'
|
126
|
-
description:
|
142
|
+
description:
|
127
143
|
email:
|
128
144
|
- mail@nilssommer.de
|
129
145
|
- a.robecke@getsafe.de
|
146
|
+
- n.stoianov@hellogetsafe.com
|
147
|
+
- abc@akihiko.eu
|
130
148
|
executables: []
|
131
149
|
extensions: []
|
132
150
|
extra_rdoc_files: []
|
@@ -135,6 +153,7 @@ files:
|
|
135
153
|
- ".editorconfig"
|
136
154
|
- ".gitignore"
|
137
155
|
- ".rspec"
|
156
|
+
- ".ruby-version"
|
138
157
|
- ".ruby_version"
|
139
158
|
- ".travis.yml"
|
140
159
|
- CHANGELOG.md
|
@@ -144,11 +163,13 @@ files:
|
|
144
163
|
- README.md
|
145
164
|
- Rakefile
|
146
165
|
- bin/console
|
166
|
+
- bin/release
|
147
167
|
- bin/rspec
|
148
168
|
- bin/setup
|
149
169
|
- lib/nxt_support.rb
|
150
170
|
- lib/nxt_support/models.rb
|
151
171
|
- lib/nxt_support/models/assignable_values.rb
|
172
|
+
- lib/nxt_support/models/duration_attribute_accessor.rb
|
152
173
|
- lib/nxt_support/models/email.rb
|
153
174
|
- lib/nxt_support/models/indifferently_accessible_json_attrs.rb
|
154
175
|
- lib/nxt_support/models/preprocess_attributes.rb
|
@@ -158,9 +179,13 @@ files:
|
|
158
179
|
- lib/nxt_support/preprocessors/strip_preprocessor.rb
|
159
180
|
- lib/nxt_support/serializers.rb
|
160
181
|
- lib/nxt_support/serializers/has_time_attributes.rb
|
182
|
+
- lib/nxt_support/services.rb
|
183
|
+
- lib/nxt_support/services/base.rb
|
161
184
|
- lib/nxt_support/util.rb
|
162
185
|
- lib/nxt_support/util/birth_date.rb
|
163
186
|
- lib/nxt_support/util/crystalizer.rb
|
187
|
+
- lib/nxt_support/util/enum.rb
|
188
|
+
- lib/nxt_support/util/enum/value.rb
|
164
189
|
- lib/nxt_support/util/enum_hash.rb
|
165
190
|
- lib/nxt_support/util/hash_translator.rb
|
166
191
|
- lib/nxt_support/version.rb
|
@@ -173,7 +198,7 @@ metadata:
|
|
173
198
|
homepage_uri: https://github.com/nxt-insurance/nxt_support
|
174
199
|
source_code_uri: https://github.com/nxt-insurance/nxt_support
|
175
200
|
changelog_uri: https://github.com/nxt-insurance/nxt_support/CHANGELOG.md
|
176
|
-
post_install_message:
|
201
|
+
post_install_message:
|
177
202
|
rdoc_options: []
|
178
203
|
require_paths:
|
179
204
|
- lib
|
@@ -188,8 +213,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
213
|
- !ruby/object:Gem::Version
|
189
214
|
version: '0'
|
190
215
|
requirements: []
|
191
|
-
rubygems_version: 3.
|
192
|
-
signing_key:
|
216
|
+
rubygems_version: 3.2.22
|
217
|
+
signing_key:
|
193
218
|
specification_version: 4
|
194
219
|
summary: Support through reusable Mixins and Helpers for Ruby on Rails Applications
|
195
220
|
test_files: []
|