decanter 3.1.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +2 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +48 -48
- data/README.md +19 -0
- data/decanter.gemspec +3 -3
- data/lib/decanter/core.rb +41 -18
- data/lib/decanter/version.rb +1 -1
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7ee762570171d13eede776ea7715f54e3daa9228e09b8a83f278c857eaeb04c
|
4
|
+
data.tar.gz: 4dee8cfa404faeb3362925832d53b4e55c0f82cddd2427416c0fdf79a66ff85e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd1b076ac0cbe78783ab19b4ae43d8fb7d87bd46b76155ec08dcbdfb55638415667c1ad19ccdeff4f81e0b0482c2ef32292a1686df648ee52e0b3ce4824ea069
|
7
|
+
data.tar.gz: d34c06b627f4c1b4773829cd9e3003f3a8eb167a97acfa55be361628078d8230d8be1664d576d49eb6de9705d56f95c478ff52c56c2c656b1882d167df69e499
|
data/.github/CODEOWNERS
ADDED
@@ -4,5 +4,5 @@
|
|
4
4
|
## Author Checklist
|
5
5
|
- [ ] Add unit test(s)
|
6
6
|
- [ ] Update documentation (if necessary)
|
7
|
-
- [ ] Update version in `version.rb` following [versioning guidelines](https://github.com/LaunchPadLab/opex/blob/master/gists/gem-guidelines.md#pull-requests-and-deployments)
|
7
|
+
- [ ] Update version in `version.rb` following [versioning guidelines](https://github.com/LaunchPadLab/opex-public/blob/master/gists/gem-guidelines.md#pull-requests-and-deployments)
|
8
8
|
|
data/CONTRIBUTING.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Contributing
|
2
2
|
|
3
|
-
Thanks for your interest in contributing! This project follows our [Gem guidelines](https://github.com/LaunchPadLab/opex/blob/master/gists/gem-guidelines.md).
|
3
|
+
Thanks for your interest in contributing! This project follows our [Gem guidelines](https://github.com/LaunchPadLab/opex-public/blob/master/gists/gem-guidelines.md).
|
4
4
|
|
5
5
|
## Code of Conduct
|
6
6
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,90 +1,90 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
decanter (3.
|
4
|
+
decanter (3.3.0)
|
5
5
|
actionpack (>= 4.2.10)
|
6
|
-
activesupport
|
6
|
+
activesupport (~> 5.2)
|
7
7
|
rails-html-sanitizer (>= 1.0.4)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
actionpack (5.
|
13
|
-
actionview (= 5.
|
14
|
-
activesupport (= 5.
|
15
|
-
rack (~> 2.0)
|
12
|
+
actionpack (5.2.4.4)
|
13
|
+
actionview (= 5.2.4.4)
|
14
|
+
activesupport (= 5.2.4.4)
|
15
|
+
rack (~> 2.0, >= 2.0.8)
|
16
16
|
rack-test (>= 0.6.3)
|
17
17
|
rails-dom-testing (~> 2.0)
|
18
18
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
19
|
-
actionview (5.
|
20
|
-
activesupport (= 5.
|
19
|
+
actionview (5.2.4.4)
|
20
|
+
activesupport (= 5.2.4.4)
|
21
21
|
builder (~> 3.1)
|
22
22
|
erubi (~> 1.4)
|
23
23
|
rails-dom-testing (~> 2.0)
|
24
24
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
25
|
-
activesupport (5.
|
25
|
+
activesupport (5.2.4.4)
|
26
26
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
27
|
-
i18n (
|
27
|
+
i18n (>= 0.7, < 2)
|
28
28
|
minitest (~> 5.1)
|
29
29
|
tzinfo (~> 1.1)
|
30
|
-
builder (3.2.
|
31
|
-
concurrent-ruby (1.
|
32
|
-
crass (1.0.
|
33
|
-
diff-lcs (1.
|
30
|
+
builder (3.2.4)
|
31
|
+
concurrent-ruby (1.1.7)
|
32
|
+
crass (1.0.6)
|
33
|
+
diff-lcs (1.4.4)
|
34
34
|
docile (1.1.5)
|
35
35
|
dotenv (2.2.1)
|
36
|
-
erubi (1.
|
37
|
-
i18n (
|
36
|
+
erubi (1.9.0)
|
37
|
+
i18n (1.8.5)
|
38
38
|
concurrent-ruby (~> 1.0)
|
39
|
-
json (2.
|
40
|
-
loofah (2.
|
39
|
+
json (2.3.0)
|
40
|
+
loofah (2.7.0)
|
41
41
|
crass (~> 1.0.2)
|
42
42
|
nokogiri (>= 1.5.9)
|
43
|
-
method_source (0.
|
44
|
-
mini_portile2 (2.
|
45
|
-
minitest (5.
|
46
|
-
nokogiri (1.
|
47
|
-
mini_portile2 (~> 2.
|
48
|
-
rack (2.
|
49
|
-
rack-test (
|
43
|
+
method_source (1.0.0)
|
44
|
+
mini_portile2 (2.4.0)
|
45
|
+
minitest (5.14.2)
|
46
|
+
nokogiri (1.10.10)
|
47
|
+
mini_portile2 (~> 2.4.0)
|
48
|
+
rack (2.2.3)
|
49
|
+
rack-test (1.1.0)
|
50
50
|
rack (>= 1.0, < 3)
|
51
51
|
rails-dom-testing (2.0.3)
|
52
52
|
activesupport (>= 4.2.0)
|
53
53
|
nokogiri (>= 1.6)
|
54
|
-
rails-html-sanitizer (1.0
|
55
|
-
loofah (~> 2.
|
56
|
-
railties (5.
|
57
|
-
actionpack (= 5.
|
58
|
-
activesupport (= 5.
|
54
|
+
rails-html-sanitizer (1.3.0)
|
55
|
+
loofah (~> 2.3)
|
56
|
+
railties (5.2.4.4)
|
57
|
+
actionpack (= 5.2.4.4)
|
58
|
+
activesupport (= 5.2.4.4)
|
59
59
|
method_source
|
60
60
|
rake (>= 0.8.7)
|
61
|
-
thor (>= 0.
|
62
|
-
rake (
|
63
|
-
rspec-core (3.
|
64
|
-
rspec-support (~> 3.
|
65
|
-
rspec-expectations (3.
|
61
|
+
thor (>= 0.19.0, < 2.0)
|
62
|
+
rake (12.3.3)
|
63
|
+
rspec-core (3.9.3)
|
64
|
+
rspec-support (~> 3.9.3)
|
65
|
+
rspec-expectations (3.9.3)
|
66
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
-
rspec-support (~> 3.
|
68
|
-
rspec-mocks (3.
|
67
|
+
rspec-support (~> 3.9.0)
|
68
|
+
rspec-mocks (3.9.1)
|
69
69
|
diff-lcs (>= 1.2.0, < 2.0)
|
70
|
-
rspec-support (~> 3.
|
71
|
-
rspec-rails (3.
|
70
|
+
rspec-support (~> 3.9.0)
|
71
|
+
rspec-rails (3.9.1)
|
72
72
|
actionpack (>= 3.0)
|
73
73
|
activesupport (>= 3.0)
|
74
74
|
railties (>= 3.0)
|
75
|
-
rspec-core (~> 3.
|
76
|
-
rspec-expectations (~> 3.
|
77
|
-
rspec-mocks (~> 3.
|
78
|
-
rspec-support (~> 3.
|
79
|
-
rspec-support (3.
|
75
|
+
rspec-core (~> 3.9.0)
|
76
|
+
rspec-expectations (~> 3.9.0)
|
77
|
+
rspec-mocks (~> 3.9.0)
|
78
|
+
rspec-support (~> 3.9.0)
|
79
|
+
rspec-support (3.9.4)
|
80
80
|
simplecov (0.15.1)
|
81
81
|
docile (~> 1.1.0)
|
82
82
|
json (>= 1.8, < 3)
|
83
83
|
simplecov-html (~> 0.10.0)
|
84
84
|
simplecov-html (0.10.2)
|
85
|
-
thor (0.
|
85
|
+
thor (1.0.1)
|
86
86
|
thread_safe (0.3.6)
|
87
|
-
tzinfo (1.2.
|
87
|
+
tzinfo (1.2.7)
|
88
88
|
thread_safe (~> 0.1)
|
89
89
|
|
90
90
|
PLATFORMS
|
@@ -94,8 +94,8 @@ DEPENDENCIES
|
|
94
94
|
bundler (~> 1.9)
|
95
95
|
decanter!
|
96
96
|
dotenv
|
97
|
-
rake (~>
|
98
|
-
rspec-rails
|
97
|
+
rake (~> 12.0)
|
98
|
+
rspec-rails (~> 3.9)
|
99
99
|
simplecov (~> 0.15.1)
|
100
100
|
|
101
101
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -220,6 +220,25 @@ end
|
|
220
220
|
|
221
221
|
_Note: we recommend using [Active Record validations](https://guides.rubyonrails.org/active_record_validations.html) to check for presence of an attribute, rather than using the `required` option. This method is intended for use in non-RESTful routes or cases where Active Record validations are not available._
|
222
222
|
|
223
|
+
|
224
|
+
### Default values
|
225
|
+
|
226
|
+
If you provide the option `:default_value` for an input in your decanter, the input key will be initialized with the given default value. Input keys not found in the incoming data parameters will be set to the provided default rather than ignoring the missing key. Note: `nil` and empty keys will not be overridden.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
class TripDecanter < Decanter::Base
|
230
|
+
input :name, :string
|
231
|
+
input :destination, :string, default_value: 'Chicago'
|
232
|
+
end
|
233
|
+
|
234
|
+
```
|
235
|
+
|
236
|
+
```
|
237
|
+
TripDecanter.decant({ name: 'Vacation 2020' })
|
238
|
+
=> { name: 'Vacation 2020', destination: 'Chicago' }
|
239
|
+
|
240
|
+
```
|
241
|
+
|
223
242
|
### Global configuration
|
224
243
|
|
225
244
|
You can generate a local copy of the default configuration with `rails generate decanter:install`. This will create an initializer where you can do global configuration:
|
data/decanter.gemspec
CHANGED
@@ -28,12 +28,12 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
30
|
spec.add_dependency 'actionpack', '>= 4.2.10'
|
31
|
-
spec.add_dependency 'activesupport'
|
31
|
+
spec.add_dependency 'activesupport', '~> 5.2'
|
32
32
|
spec.add_dependency 'rails-html-sanitizer', '>= 1.0.4'
|
33
33
|
|
34
34
|
spec.add_development_dependency 'bundler', '~> 1.9'
|
35
35
|
spec.add_development_dependency 'dotenv'
|
36
|
-
spec.add_development_dependency 'rake', '~>
|
37
|
-
spec.add_development_dependency 'rspec-rails'
|
36
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
37
|
+
spec.add_development_dependency 'rspec-rails', '~> 3.9'
|
38
38
|
spec.add_development_dependency 'simplecov', '~> 0.15.1'
|
39
39
|
end
|
data/lib/decanter/core.rb
CHANGED
@@ -1,23 +1,25 @@
|
|
1
1
|
module Decanter
|
2
2
|
module Core
|
3
|
-
|
3
|
+
DEFAULT_VALUE_KEY = :default_value
|
4
|
+
ACTION_CONTROLLER_PARAMETERS_CLASS_NAME = 'ActionController::Parameters'
|
5
|
+
|
4
6
|
def self.included(base)
|
5
7
|
base.extend(ClassMethods)
|
6
8
|
end
|
7
9
|
|
8
10
|
module ClassMethods
|
9
|
-
|
10
|
-
def input(name, parsers=nil, **options)
|
11
11
|
|
12
|
-
|
12
|
+
def input(name, parsers=nil, **options)
|
13
|
+
# Convert all input names to symbols to correctly calculate handled vs. unhandled keys
|
14
|
+
input_names = [name].flatten.map(&:to_sym)
|
13
15
|
|
14
|
-
if
|
16
|
+
if input_names.length > 1 && parsers.blank?
|
15
17
|
raise ArgumentError.new("#{self.name} no parser specified for input with multiple values.")
|
16
18
|
end
|
17
19
|
|
18
|
-
handlers[
|
19
|
-
key: options.fetch(:key,
|
20
|
-
name:
|
20
|
+
handlers[input_names] = {
|
21
|
+
key: options.fetch(:key, input_names.first),
|
22
|
+
name: input_names,
|
21
23
|
options: options,
|
22
24
|
parsers: parsers,
|
23
25
|
type: :input
|
@@ -45,7 +47,7 @@ module Decanter
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def ignore(*args)
|
48
|
-
keys_to_ignore.push(*args)
|
50
|
+
keys_to_ignore.push(*args).map!(&:to_sym)
|
49
51
|
end
|
50
52
|
|
51
53
|
def strict(mode)
|
@@ -56,12 +58,29 @@ module Decanter
|
|
56
58
|
def decant(args)
|
57
59
|
return handle_empty_args if args.blank?
|
58
60
|
return empty_required_input_error unless required_input_keys_present?(args)
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
|
62
|
+
# Convert all params passed to a decanter to a hash with indifferent access to mitigate accessor ambiguity
|
63
|
+
accessible_args = to_indifferent_hash(args)
|
64
|
+
{}.merge( default_keys )
|
65
|
+
.merge( unhandled_keys(accessible_args) )
|
66
|
+
.merge( handled_keys(accessible_args) )
|
62
67
|
end
|
63
68
|
|
64
|
-
def
|
69
|
+
def default_keys
|
70
|
+
# return keys with provided default value when key is not defined within incoming args
|
71
|
+
default_result = default_value_inputs
|
72
|
+
.map { |input| [input[:key], input[:options][DEFAULT_VALUE_KEY]] }
|
73
|
+
.to_h
|
74
|
+
|
75
|
+
# parse default values
|
76
|
+
handled_keys(default_result)
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_value_inputs
|
80
|
+
handlers.values.select { |input| input[:options].key?(DEFAULT_VALUE_KEY) }
|
81
|
+
end
|
82
|
+
|
83
|
+
def handle_empty_args
|
65
84
|
any_inputs_required? ? empty_args_error : {}
|
66
85
|
end
|
67
86
|
|
@@ -73,7 +92,7 @@ module Decanter
|
|
73
92
|
handlers.map do |h|
|
74
93
|
options = h.last[:options]
|
75
94
|
h.first.first if options && options[:required]
|
76
|
-
end
|
95
|
+
end
|
77
96
|
end
|
78
97
|
|
79
98
|
def required_input_keys_present?(args={})
|
@@ -100,11 +119,11 @@ module Decanter
|
|
100
119
|
keys_to_ignore -
|
101
120
|
handlers.values
|
102
121
|
.select { |handler| handler[:type] != :input }
|
103
|
-
.map { |handler| "#{handler[:name]}_attributes".to_sym }
|
122
|
+
.map { |handler| "#{handler[:name]}_attributes".to_sym }
|
104
123
|
|
105
124
|
return {} unless unhandled_keys.any?
|
106
125
|
raise(UnhandledKeysError, "#{self.name} received unhandled keys: #{unhandled_keys.join(', ')}.") if strict_mode
|
107
|
-
args.select { |key| unhandled_keys.include? key }
|
126
|
+
args.select { |key| unhandled_keys.include? key.to_sym }
|
108
127
|
end
|
109
128
|
|
110
129
|
def handled_keys(args)
|
@@ -185,13 +204,13 @@ module Decanter
|
|
185
204
|
def parse(key, parsers, value, options)
|
186
205
|
return { key => value } unless parsers
|
187
206
|
if options[:required] && value_missing?(value)
|
188
|
-
raise ArgumentError.new("No value for required argument: #{key}")
|
207
|
+
raise ArgumentError.new("No value for required argument: #{key}")
|
189
208
|
end
|
190
209
|
parser_classes = Parser.parsers_for(parsers)
|
191
210
|
Parser.compose_parsers(parser_classes).parse(key, value, options)
|
192
211
|
end
|
193
212
|
|
194
|
-
def handlers
|
213
|
+
def handlers
|
195
214
|
@handlers ||= {}
|
196
215
|
end
|
197
216
|
|
@@ -211,6 +230,10 @@ module Decanter
|
|
211
230
|
value.nil? || value == ""
|
212
231
|
end
|
213
232
|
|
233
|
+
def to_indifferent_hash(args)
|
234
|
+
return args.to_unsafe_h if args.class.name == ACTION_CONTROLLER_PARAMETERS_CLASS_NAME
|
235
|
+
args.to_h.with_indifferent_access
|
236
|
+
end
|
214
237
|
end
|
215
238
|
end
|
216
239
|
end
|
data/lib/decanter/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decanter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Francis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-11-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -29,16 +29,16 @@ dependencies:
|
|
29
29
|
name: activesupport
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - "
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '5.2'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - "
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '5.2'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: rails-html-sanitizer
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,28 +87,28 @@ dependencies:
|
|
87
87
|
requirements:
|
88
88
|
- - "~>"
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
90
|
+
version: '12.0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - "~>"
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
97
|
+
version: '12.0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rspec-rails
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- - "
|
102
|
+
- - "~>"
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version: '
|
104
|
+
version: '3.9'
|
105
105
|
type: :development
|
106
106
|
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- - "
|
109
|
+
- - "~>"
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
111
|
+
version: '3.9'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
113
|
name: simplecov
|
114
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,6 +132,7 @@ extensions: []
|
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
134
|
- ".codeclimate.yml"
|
135
|
+
- ".github/CODEOWNERS"
|
135
136
|
- ".github/ISSUE_TEMPLATE/BUG_REPORT.md"
|
136
137
|
- ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md"
|
137
138
|
- ".github/PULL_REQUEST_TEMPLATE.md"
|