decanter 3.4.1 → 3.6.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/Gemfile.lock +1 -1
- data/README.md +9 -1
- data/lib/decanter/base.rb +2 -0
- data/lib/decanter/collection_detection.rb +26 -0
- data/lib/decanter/configuration.rb +2 -1
- data/lib/decanter/core.rb +24 -6
- data/lib/decanter/extensions.rb +2 -19
- data/lib/decanter/version.rb +1 -1
- data/lib/decanter.rb +2 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 697f969bd6cdcac1487d237135cd4f1860ff9aa79abece975305d7ca7f0d5504
|
4
|
+
data.tar.gz: 7ab9d647d3c90e9c5186f4f0b486115b3d17f3107990a7984827d87e2f4843f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 286e79ac8ebdbd3b75cc667fadd77b2fc6966f54274f06e282fc9d94250cf3075eb2f6a9e31295f1d51efb50b1b5757507de98cc6816a23b9871af7c3e32ab2a
|
7
|
+
data.tar.gz: b4cfff1c6ba4acc7f3244674e6d2a741dfbee1d5e03cdf392365bcbe4ba684f4592e1921143e7041e28d600b67cc1814110ac973c809bbea5c076a872092c652
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -101,6 +101,7 @@ If this option is not provided, autodetect logic is used to determine if the pro
|
|
101
101
|
- `nil` or not provided: will try to autodetect single vs collection
|
102
102
|
- `true` will always treat the incoming params args as *collection*
|
103
103
|
- `false` will always treat incoming params args as *single object*
|
104
|
+
- `truthy` will raise an error
|
104
105
|
|
105
106
|
### Nested resources
|
106
107
|
|
@@ -144,7 +145,11 @@ input :start_date, :date, parse_format: '%Y-%m-%d'
|
|
144
145
|
|
145
146
|
### Exceptions
|
146
147
|
|
147
|
-
By default, `Decanter#decant` will raise an exception when unexpected parameters are passed. To override this behavior, you can
|
148
|
+
By default, `Decanter#decant` will raise an exception when unexpected parameters are passed. To override this behavior, you can change the strict mode option to one of:
|
149
|
+
|
150
|
+
- `true` (default): unhandled keys will raise an unexpected parameters exception
|
151
|
+
- `false`: all parameter key-value pairs will be included in the result
|
152
|
+
- `:ignore`: unhandled keys will be excluded from the decanted result
|
148
153
|
|
149
154
|
```ruby
|
150
155
|
class TripDecanter < Decanter::Base
|
@@ -275,11 +280,14 @@ TripDecanter.decant({ name: 'Vacation 2020' })
|
|
275
280
|
|
276
281
|
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:
|
277
282
|
|
283
|
+
Setting strict mode to :ignore will log out any unhandled keys. To avoid excessive logging, the global configuration can be set to `log_unhandled_keys = false`
|
284
|
+
|
278
285
|
```ruby
|
279
286
|
# ./config/initializers/decanter.rb
|
280
287
|
|
281
288
|
Decanter.config do |config|
|
282
289
|
config.strict = false
|
290
|
+
config.log_unhandled_keys = false
|
283
291
|
end
|
284
292
|
```
|
285
293
|
|
data/lib/decanter/base.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Decanter
|
2
|
+
module CollectionDetection
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def decant(args, **options)
|
9
|
+
return super(args) unless collection?(args, options[:is_collection])
|
10
|
+
|
11
|
+
args.map { |resource| super(resource) }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# leveraging the approach used in the [fast JSON API gem](https://github.com/Netflix/fast_jsonapi#collection-serialization)
|
17
|
+
def collection?(args, collection_option = nil)
|
18
|
+
raise(ArgumentError, "#{name}: Unknown collection option value: #{collection_option}") unless [true, false, nil].include? collection_option
|
19
|
+
|
20
|
+
return collection_option unless collection_option.nil?
|
21
|
+
|
22
|
+
args.respond_to?(:size) && !args.respond_to?(:each_pair)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/decanter/core.rb
CHANGED
@@ -50,10 +50,15 @@ module Decanter
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def strict(mode)
|
53
|
-
raise(ArgumentError, "#{self.name}: Unknown strict value #{mode}") unless [true, false].include? mode
|
53
|
+
raise(ArgumentError, "#{self.name}: Unknown strict value #{mode}") unless [:ignore, true, false].include? mode
|
54
54
|
@strict_mode = mode
|
55
55
|
end
|
56
56
|
|
57
|
+
def log_unhandled_keys(mode)
|
58
|
+
raise(ArgumentError, "#{self.name}: Unknown log_unhandled_keys value #{mode}") unless [true, false].include? mode
|
59
|
+
@log_unhandled_keys_mode = mode
|
60
|
+
end
|
61
|
+
|
57
62
|
def decant(args)
|
58
63
|
return handle_empty_args if args.blank?
|
59
64
|
return empty_required_input_error unless required_input_keys_present?(args)
|
@@ -71,8 +76,9 @@ module Decanter
|
|
71
76
|
.map { |input| [input[:key], input[:options][DEFAULT_VALUE_KEY]] }
|
72
77
|
.to_h
|
73
78
|
|
74
|
-
# parse default values
|
75
|
-
handled_keys
|
79
|
+
# parse handled default values, including keys
|
80
|
+
# with defaults not already managed by handled_keys
|
81
|
+
default_result.merge(handled_keys(default_result))
|
76
82
|
end
|
77
83
|
|
78
84
|
def default_value_inputs
|
@@ -121,14 +127,21 @@ module Decanter
|
|
121
127
|
.map { |handler| "#{handler[:name]}_attributes".to_sym }
|
122
128
|
|
123
129
|
return {} unless unhandled_keys.any?
|
124
|
-
|
125
|
-
|
130
|
+
|
131
|
+
case strict_mode
|
132
|
+
when :ignore
|
133
|
+
p "#{self.name} ignoring unhandled keys: #{unhandled_keys.join(', ')}." if log_unhandled_keys_mode
|
134
|
+
{}
|
135
|
+
when true
|
136
|
+
raise(UnhandledKeysError, "#{self.name} received unhandled keys: #{unhandled_keys.join(', ')}.")
|
137
|
+
else
|
138
|
+
args.select { |key| unhandled_keys.include? key.to_sym }
|
139
|
+
end
|
126
140
|
end
|
127
141
|
|
128
142
|
def handled_keys(args)
|
129
143
|
arg_keys = args.keys.map(&:to_sym)
|
130
144
|
inputs, assocs = handlers.values.partition { |handler| handler[:type] == :input }
|
131
|
-
|
132
145
|
{}.merge(
|
133
146
|
# Inputs
|
134
147
|
inputs.select { |handler| (arg_keys & handler[:name]).any? }
|
@@ -221,6 +234,11 @@ module Decanter
|
|
221
234
|
@strict_mode.nil? ? Decanter.configuration.strict : @strict_mode
|
222
235
|
end
|
223
236
|
|
237
|
+
def log_unhandled_keys_mode
|
238
|
+
return !!(Decanter.configuration.log_unhandled_keys) if @log_unhandled_keys_mode.nil?
|
239
|
+
!!@log_unhandled_keys_mode
|
240
|
+
end
|
241
|
+
|
224
242
|
# Helpers
|
225
243
|
|
226
244
|
private
|
data/lib/decanter/extensions.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Decanter
|
2
2
|
module Extensions
|
3
|
-
|
4
3
|
def self.included(base)
|
5
4
|
base.extend(ClassMethods)
|
6
5
|
end
|
@@ -34,29 +33,13 @@ module Decanter
|
|
34
33
|
.save!(context: options[:context])
|
35
34
|
end
|
36
35
|
|
37
|
-
def decant(args, options={})
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
def decant_collection(args, options)
|
42
|
-
args.map { |resource| decant_args(resource, options) }
|
43
|
-
end
|
44
|
-
|
45
|
-
def decant_args(args, options)
|
46
|
-
if specified_decanter = options[:decanter]
|
36
|
+
def decant(args, options = {})
|
37
|
+
if (specified_decanter = options[:decanter])
|
47
38
|
Decanter.decanter_from(specified_decanter)
|
48
39
|
else
|
49
40
|
Decanter.decanter_for(self)
|
50
41
|
end.decant(args)
|
51
42
|
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
# leveraging the approach used in the [fast JSON API gem](https://github.com/Netflix/fast_jsonapi#collection-serialization)
|
56
|
-
def is_collection?(args, collection_option=nil)
|
57
|
-
return collection_option[:is_collection] unless collection_option.nil?
|
58
|
-
args.respond_to?(:size) && !args.respond_to?(:each_pair)
|
59
|
-
end
|
60
43
|
end
|
61
44
|
|
62
45
|
module ActiveRecordExtensions
|
data/lib/decanter/version.rb
CHANGED
data/lib/decanter.rb
CHANGED
@@ -13,7 +13,7 @@ module Decanter
|
|
13
13
|
klass_or_sym.to_s.singularize.camelize
|
14
14
|
else
|
15
15
|
raise ArgumentError.new("cannot lookup decanter for #{klass_or_sym} with class #{klass_or_sym.class}")
|
16
|
-
end
|
16
|
+
end + 'Decanter'
|
17
17
|
begin
|
18
18
|
decanter_name.constantize
|
19
19
|
rescue
|
@@ -57,9 +57,8 @@ end
|
|
57
57
|
|
58
58
|
require 'decanter/version'
|
59
59
|
require 'decanter/configuration'
|
60
|
-
require 'decanter/core'
|
61
60
|
require 'decanter/base'
|
62
61
|
require 'decanter/extensions'
|
63
62
|
require 'decanter/exceptions'
|
64
63
|
require 'decanter/parser'
|
65
|
-
require 'decanter/railtie' if defined?(::Rails)
|
64
|
+
require 'decanter/railtie' if defined?(::Rails)
|
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.6.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:
|
12
|
+
date: 2021-09-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -152,6 +152,7 @@ files:
|
|
152
152
|
- decanter.gemspec
|
153
153
|
- lib/decanter.rb
|
154
154
|
- lib/decanter/base.rb
|
155
|
+
- lib/decanter/collection_detection.rb
|
155
156
|
- lib/decanter/configuration.rb
|
156
157
|
- lib/decanter/core.rb
|
157
158
|
- lib/decanter/exceptions.rb
|