hanami-utils 1.3.2 → 1.3.7
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/CHANGELOG.md +28 -0
- data/README.md +2 -3
- data/hanami-utils.gemspec +19 -16
- data/lib/hanami-utils.rb +3 -1
- data/lib/hanami/interactor.rb +57 -31
- data/lib/hanami/logger.rb +12 -12
- data/lib/hanami/logger/colorizer.rb +10 -10
- data/lib/hanami/logger/filter.rb +89 -10
- data/lib/hanami/logger/formatter.rb +4 -4
- data/lib/hanami/utils.rb +12 -10
- data/lib/hanami/utils/basic_object.rb +23 -6
- data/lib/hanami/utils/blank.rb +7 -5
- data/lib/hanami/utils/callbacks.rb +6 -2
- data/lib/hanami/utils/class.rb +8 -8
- data/lib/hanami/utils/class_attribute.rb +4 -2
- data/lib/hanami/utils/deprecation.rb +3 -1
- data/lib/hanami/utils/duplicable.rb +2 -0
- data/lib/hanami/utils/escape.rb +275 -271
- data/lib/hanami/utils/file_list.rb +3 -1
- data/lib/hanami/utils/files.rb +15 -2
- data/lib/hanami/utils/hash.rb +24 -22
- data/lib/hanami/utils/inflector.rb +134 -117
- data/lib/hanami/utils/io.rb +2 -0
- data/lib/hanami/utils/json.rb +5 -3
- data/lib/hanami/utils/kernel.rb +21 -20
- data/lib/hanami/utils/load_paths.rb +6 -4
- data/lib/hanami/utils/path_prefix.rb +6 -4
- data/lib/hanami/utils/query_string.rb +1 -1
- data/lib/hanami/utils/shell_color.rb +9 -9
- data/lib/hanami/utils/string.rb +53 -54
- data/lib/hanami/utils/version.rb +3 -1
- metadata +24 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '02818d90409ea03d89ca587c97fe418bbf17a8694662a2313609c0710466b0f9'
|
4
|
+
data.tar.gz: 973ef420992dd9ea30ab880d43e8cc70eee59cae6fb7b1ba17038c5ce8d536a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d49d6ad21aa25f285c9165c4619d6b2d7fe348513481bf30b8f231211d4e270f7502e2e3594f082789fdf32e9170a33e038329394ae5f43170ab778ebe01892f
|
7
|
+
data.tar.gz: 8b8832a39855525d6818de385212fb1c9d7c5c0f79874f60ead95ee1c592377f6bfec0ade5701a4340b87fe920c495889a9586d81fe2091d8691b52b14f297fa
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
# Hanami::Utils
|
2
2
|
Ruby core extentions and class utilities for Hanami
|
3
3
|
|
4
|
+
## v1.3.7 - 2021-01-04
|
5
|
+
### Added
|
6
|
+
- [Luca Guidi] Official support for Ruby: MRI 3.0
|
7
|
+
- [Khai Le] Allow `Hanami::Logger` to filter sensitive data for an array of hashes
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
- [Hiếu Nguyễn] Ensure `Hanami::Logger` to not mutate `Hash` input when filtering sensitive data
|
11
|
+
|
12
|
+
## v1.3.6 - 2020-01-07
|
13
|
+
### Added
|
14
|
+
- [Luca Guidi] Official support for Ruby: MRI 2.7
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
- [ippachi] `Utils::Files.append`: don't check breakline if file is empty
|
18
|
+
|
19
|
+
## v1.3.5 - 2019-10-25
|
20
|
+
### Fixed
|
21
|
+
- [Ivan Kabluchkov] Ensure `Hanami::Logger` filters to not crash when logger stream is a closed tempfile
|
22
|
+
- [Luca Guidi] Ensure `Utils::Files.append` to append contents properly when existing file doesn't end with a newline
|
23
|
+
|
24
|
+
## v1.3.4 - 2019-09-27
|
25
|
+
### Added
|
26
|
+
- [Luca Guidi] Let `Utils::BasicObject` to lookup constants at the top-level namespace
|
27
|
+
|
28
|
+
## v1.3.3 - 2019-09-13
|
29
|
+
### Fixed
|
30
|
+
- [Mauro Morales] Ensure `Utils::Inflector.pluralize` and `.singularize` to work with words that contain an underscore (`_`)
|
31
|
+
|
4
32
|
## v1.3.2 - 2019-06-21
|
5
33
|
### Added
|
6
34
|
- [Vladislav Yashin & Luca Guidi] Added `Utils::BasicObject#instance_of?`, `#is_a?`, and `#kind_of`
|
data/README.md
CHANGED
@@ -5,8 +5,7 @@ Ruby core extensions and class utilities for [Hanami](http://hanamirb.org)
|
|
5
5
|
## Status
|
6
6
|
|
7
7
|
[](https://badge.fury.io/rb/hanami-utils)
|
8
|
-
[](https://circleci.com/gh/hanami/utils/tree/master)
|
8
|
+
[](https://github.com/hanami/utils/actions?query=workflow%3Aci+branch%3Amaster)
|
10
9
|
[](https://codecov.io/gh/hanami/utils)
|
11
10
|
[](https://depfu.com/github/hanami/utils?project=Bundler)
|
12
11
|
[](http://inch-ci.org/github/hanami/utils)
|
@@ -150,6 +149,6 @@ __Hanami::Utils__ uses [Semantic Versioning 2.0.0](http://semver.org)
|
|
150
149
|
|
151
150
|
## Copyright
|
152
151
|
|
153
|
-
Copyright © 2014-
|
152
|
+
Copyright © 2014-2021 Luca Guidi – Released under MIT License
|
154
153
|
|
155
154
|
This project was formerly known as Lotus (`lotus-utils`).
|
data/hanami-utils.gemspec
CHANGED
@@ -1,27 +1,30 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
5
|
+
require "hanami/utils/version"
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
8
|
+
spec.name = "hanami-utils"
|
7
9
|
spec.version = Hanami::Utils::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
10
|
-
spec.description =
|
11
|
-
spec.summary =
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
10
|
+
spec.authors = ["Luca Guidi"]
|
11
|
+
spec.email = ["me@lucaguidi.com"]
|
12
|
+
spec.description = "Hanami utilities"
|
13
|
+
spec.summary = "Ruby core extentions and Hanami utilities"
|
14
|
+
spec.homepage = "http://hanamirb.org"
|
15
|
+
spec.license = "MIT"
|
14
16
|
|
15
17
|
spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md hanami-utils.gemspec`.split($/)
|
16
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
-
spec.require_paths = [
|
19
|
-
spec.required_ruby_version =
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
spec.required_ruby_version = ">= 2.3.0"
|
20
22
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency "transproc", "~> 1.0"
|
24
|
+
spec.add_dependency "concurrent-ruby", "~> 1.0"
|
23
25
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency "bundler", ">= 1.6", "< 3"
|
27
|
+
spec.add_development_dependency "rake", "~> 13"
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
29
|
+
spec.add_development_dependency "rubocop", "0.81" # rubocop 0.81+ removed support for Ruby 2.3
|
27
30
|
end
|
data/lib/hanami-utils.rb
CHANGED
data/lib/hanami/interactor.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/utils/basic_object"
|
4
|
+
require "hanami/utils/class_attribute"
|
5
|
+
require "hanami/utils/hash"
|
4
6
|
|
5
7
|
module Hanami
|
6
8
|
# Hanami Interactor
|
@@ -17,14 +19,14 @@ module Hanami
|
|
17
19
|
# @api private
|
18
20
|
#
|
19
21
|
# @see Hanami::Interactor::Result#respond_to_missing?
|
20
|
-
METHODS = ::Hash[initialize:
|
21
|
-
success?:
|
22
|
+
METHODS = ::Hash[initialize: true,
|
23
|
+
success?: true,
|
22
24
|
successful?: true,
|
23
|
-
failure?:
|
24
|
-
fail!:
|
25
|
-
prepare!:
|
26
|
-
errors:
|
27
|
-
error:
|
25
|
+
failure?: true,
|
26
|
+
fail!: true,
|
27
|
+
prepare!: true,
|
28
|
+
errors: true,
|
29
|
+
error: true].freeze
|
28
30
|
|
29
31
|
# Initialize a new result
|
30
32
|
#
|
@@ -40,7 +42,7 @@ module Hanami
|
|
40
42
|
@success = true
|
41
43
|
end
|
42
44
|
|
43
|
-
#
|
45
|
+
# Checks if the current status is successful
|
44
46
|
#
|
45
47
|
# @return [TrueClass,FalseClass] the result of the check
|
46
48
|
#
|
@@ -50,9 +52,9 @@ module Hanami
|
|
50
52
|
end
|
51
53
|
|
52
54
|
# @since 0.3.5
|
53
|
-
|
55
|
+
alias_method :success?, :successful?
|
54
56
|
|
55
|
-
#
|
57
|
+
# Checks if the current status is not successful
|
56
58
|
#
|
57
59
|
# @return [TrueClass,FalseClass] the result of the check
|
58
60
|
#
|
@@ -61,7 +63,7 @@ module Hanami
|
|
61
63
|
!successful?
|
62
64
|
end
|
63
65
|
|
64
|
-
#
|
66
|
+
# Forces the status to be a failure
|
65
67
|
#
|
66
68
|
# @since 0.3.5
|
67
69
|
def fail!
|
@@ -104,7 +106,7 @@ module Hanami
|
|
104
106
|
errors.first
|
105
107
|
end
|
106
108
|
|
107
|
-
#
|
109
|
+
# Prepares the result before to be returned
|
108
110
|
#
|
109
111
|
# @param payload [Hash] an updated payload
|
110
112
|
#
|
@@ -351,33 +353,57 @@ module Hanami
|
|
351
353
|
# end
|
352
354
|
#
|
353
355
|
# Signup.new.call # => NoMethodError
|
354
|
-
|
355
|
-
|
356
|
-
|
356
|
+
if RUBY_VERSION >= "3.0"
|
357
|
+
def call(*args, **kwargs)
|
358
|
+
@__result = ::Hanami::Interactor::Result.new
|
359
|
+
_call(*args, **kwargs) { super }
|
360
|
+
end
|
361
|
+
else
|
362
|
+
def call(*args)
|
363
|
+
@__result = ::Hanami::Interactor::Result.new
|
364
|
+
_call(*args) { super }
|
365
|
+
end
|
357
366
|
end
|
358
367
|
|
359
368
|
private
|
360
369
|
|
361
370
|
# @api private
|
362
371
|
# @since 1.1.0
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
372
|
+
if RUBY_VERSION >= "3.0"
|
373
|
+
def _call(*args, **kwargs)
|
374
|
+
catch :fail do
|
375
|
+
validate!(*args, **kwargs)
|
376
|
+
yield
|
377
|
+
end
|
378
|
+
|
379
|
+
_prepare!
|
367
380
|
end
|
381
|
+
else
|
382
|
+
def _call(*args)
|
383
|
+
catch :fail do
|
384
|
+
validate!(*args)
|
385
|
+
yield
|
386
|
+
end
|
368
387
|
|
369
|
-
|
388
|
+
_prepare!
|
389
|
+
end
|
370
390
|
end
|
371
391
|
|
372
392
|
# @since 1.1.0
|
373
|
-
|
374
|
-
|
393
|
+
if RUBY_VERSION >= "3.0"
|
394
|
+
def validate!(*args, **kwargs)
|
395
|
+
fail! unless valid?(*args, **kwargs)
|
396
|
+
end
|
397
|
+
else
|
398
|
+
def validate!(*args)
|
399
|
+
fail! unless valid?(*args)
|
400
|
+
end
|
375
401
|
end
|
376
402
|
end
|
377
403
|
|
378
404
|
private
|
379
405
|
|
380
|
-
#
|
406
|
+
# Checks if proceed with <tt>#call</tt> invocation.
|
381
407
|
# By default it returns <tt>true</tt>.
|
382
408
|
#
|
383
409
|
# Developers can override it.
|
@@ -389,7 +415,7 @@ module Hanami
|
|
389
415
|
true
|
390
416
|
end
|
391
417
|
|
392
|
-
#
|
418
|
+
# Fails and interrupts the current flow.
|
393
419
|
#
|
394
420
|
# @since 0.3.5
|
395
421
|
#
|
@@ -428,7 +454,7 @@ module Hanami
|
|
428
454
|
throw :fail
|
429
455
|
end
|
430
456
|
|
431
|
-
#
|
457
|
+
# Logs an error without interrupting the flow.
|
432
458
|
#
|
433
459
|
# When used, the returned result won't be successful.
|
434
460
|
#
|
@@ -483,7 +509,7 @@ module Hanami
|
|
483
509
|
false
|
484
510
|
end
|
485
511
|
|
486
|
-
#
|
512
|
+
# Logs an error and interrupts the flow.
|
487
513
|
#
|
488
514
|
# When used, the returned result won't be successful.
|
489
515
|
#
|
@@ -579,7 +605,7 @@ module Hanami
|
|
579
605
|
end
|
580
606
|
end
|
581
607
|
|
582
|
-
#
|
608
|
+
# Exposes local instance variables into the returning value of <tt>#call</tt>
|
583
609
|
#
|
584
610
|
# @param instance_variable_names [Symbol,Array<Symbol>] one or more instance
|
585
611
|
# variable names
|
@@ -588,7 +614,7 @@ module Hanami
|
|
588
614
|
#
|
589
615
|
# @see Hanami::Interactor::Result
|
590
616
|
#
|
591
|
-
# @example
|
617
|
+
# @example Exposes instance variable
|
592
618
|
#
|
593
619
|
# class Signup
|
594
620
|
# include Hanami::Interactor
|
data/lib/hanami/logger.rb
CHANGED
@@ -7,7 +7,7 @@ require "hanami/utils/files"
|
|
7
7
|
module Hanami
|
8
8
|
# Hanami logger
|
9
9
|
#
|
10
|
-
#
|
10
|
+
# Implementation with the same interface of Ruby std lib `Logger`.
|
11
11
|
# It uses `STDOUT`, `STDERR`, file name or open file as output stream.
|
12
12
|
#
|
13
13
|
#
|
@@ -16,7 +16,7 @@ module Hanami
|
|
16
16
|
#
|
17
17
|
# This is useful for auto-tagging the output. Eg (`app=Booshelf`).
|
18
18
|
#
|
19
|
-
# When used
|
19
|
+
# When used standalone (eg. `Hanami::Logger.info`), it tags lines with `app=Shared`.
|
20
20
|
#
|
21
21
|
#
|
22
22
|
# The available severity levels are the same of `Logger`:
|
@@ -30,7 +30,7 @@ module Hanami
|
|
30
30
|
#
|
31
31
|
# Those levels are available both as class and instance methods.
|
32
32
|
#
|
33
|
-
# Also Hanami::Logger
|
33
|
+
# Also Hanami::Logger supports different formatters. Now available only two:
|
34
34
|
#
|
35
35
|
# * Formatter (default)
|
36
36
|
# * JSONFormatter
|
@@ -132,11 +132,11 @@ module Hanami
|
|
132
132
|
# @since 0.8.0
|
133
133
|
# @api private
|
134
134
|
LEVELS = ::Hash[
|
135
|
-
"debug"
|
136
|
-
"info"
|
137
|
-
"warn"
|
138
|
-
"error"
|
139
|
-
"fatal"
|
135
|
+
"debug" => DEBUG,
|
136
|
+
"info" => INFO,
|
137
|
+
"warn" => WARN,
|
138
|
+
"error" => ERROR,
|
139
|
+
"fatal" => FATAL,
|
140
140
|
"unknown" => UNKNOWN
|
141
141
|
].freeze
|
142
142
|
|
@@ -279,9 +279,9 @@ module Hanami
|
|
279
279
|
# logger.info "Hello World"
|
280
280
|
#
|
281
281
|
# # => {"app":"Hanami","severity":"DEBUG","time":"2017-03-30T13:57:59Z","message":"Hello World"}
|
282
|
-
# rubocop:disable Lint/
|
282
|
+
# rubocop:disable Lint/SuppressedException
|
283
283
|
# rubocop:disable Metrics/ParameterLists
|
284
|
-
def initialize(application_name = nil, *args, stream: $stdout, level: DEBUG, formatter: nil, filter: [], colorizer: nil)
|
284
|
+
def initialize(application_name = nil, *args, stream: $stdout, level: DEBUG, formatter: nil, filter: [], colorizer: nil) # rubocop:disable Layout/LineLength
|
285
285
|
begin
|
286
286
|
Utils::Files.mkdir_p(stream)
|
287
287
|
rescue TypeError
|
@@ -296,7 +296,7 @@ module Hanami
|
|
296
296
|
end
|
297
297
|
|
298
298
|
# rubocop:enable Metrics/ParameterLists
|
299
|
-
# rubocop:enable Lint/
|
299
|
+
# rubocop:enable Lint/SuppressedException
|
300
300
|
|
301
301
|
# Returns the current application name, this is used for tagging purposes
|
302
302
|
#
|
@@ -313,7 +313,7 @@ module Hanami
|
|
313
313
|
super _level(value)
|
314
314
|
end
|
315
315
|
|
316
|
-
#
|
316
|
+
# Closes the logging stream if this stream isn't an STDOUT
|
317
317
|
#
|
318
318
|
# @since 0.8.0
|
319
319
|
def close
|
@@ -14,9 +14,9 @@ module Hanami
|
|
14
14
|
# @api private
|
15
15
|
def call(app, severity, datetime, _progname)
|
16
16
|
::Hash[
|
17
|
-
app:
|
17
|
+
app: app,
|
18
18
|
severity: severity,
|
19
|
-
time:
|
19
|
+
time: datetime,
|
20
20
|
]
|
21
21
|
end
|
22
22
|
end
|
@@ -44,9 +44,9 @@ module Hanami
|
|
44
44
|
# @return [::Hash] an Hash containing the keys `:app`, `:severity`, and `:time`
|
45
45
|
def call(app, severity, datetime, _progname)
|
46
46
|
::Hash[
|
47
|
-
app:
|
47
|
+
app: app(app),
|
48
48
|
severity: severity(severity),
|
49
|
-
time:
|
49
|
+
time: datetime(datetime),
|
50
50
|
]
|
51
51
|
end
|
52
52
|
|
@@ -57,18 +57,18 @@ module Hanami
|
|
57
57
|
# @since 1.2.0
|
58
58
|
# @api private
|
59
59
|
COLORS = ::Hash[
|
60
|
-
app:
|
60
|
+
app: :blue,
|
61
61
|
datetime: :cyan,
|
62
62
|
].freeze
|
63
63
|
|
64
64
|
# @since 1.2.0
|
65
65
|
# @api private
|
66
66
|
LEVELS = ::Hash[
|
67
|
-
Hanami::Logger::DEBUG
|
68
|
-
Hanami::Logger::INFO
|
69
|
-
Hanami::Logger::WARN
|
70
|
-
Hanami::Logger::ERROR
|
71
|
-
Hanami::Logger::FATAL
|
67
|
+
Hanami::Logger::DEBUG => :cyan,
|
68
|
+
Hanami::Logger::INFO => :magenta,
|
69
|
+
Hanami::Logger::WARN => :yellow,
|
70
|
+
Hanami::Logger::ERROR => :red,
|
71
|
+
Hanami::Logger::FATAL => :red,
|
72
72
|
Hanami::Logger::UNKNOWN => :blue,
|
73
73
|
].freeze
|
74
74
|
|
data/lib/hanami/logger/filter.rb
CHANGED
@@ -9,21 +9,19 @@ module Hanami
|
|
9
9
|
# @since 1.1.0
|
10
10
|
# @api private
|
11
11
|
class Filter
|
12
|
-
# @since 1.
|
12
|
+
# @since 1.3.7
|
13
13
|
# @api private
|
14
|
-
|
14
|
+
FILTERED_VALUE = "[FILTERED]"
|
15
|
+
|
16
|
+
def initialize(filters = [], mask: FILTERED_VALUE)
|
15
17
|
@filters = filters
|
18
|
+
@mask = mask
|
16
19
|
end
|
17
20
|
|
18
21
|
# @since 1.1.0
|
19
22
|
# @api private
|
20
|
-
def call(
|
21
|
-
|
22
|
-
*keys, last = _actual_keys(hash, key.split("."))
|
23
|
-
keys.inject(hash, :fetch)[last] = "[FILTERED]"
|
24
|
-
end
|
25
|
-
|
26
|
-
hash
|
23
|
+
def call(params)
|
24
|
+
_filter(_copy_params(params))
|
27
25
|
end
|
28
26
|
|
29
27
|
private
|
@@ -32,6 +30,29 @@ module Hanami
|
|
32
30
|
# @api private
|
33
31
|
attr_reader :filters
|
34
32
|
|
33
|
+
# @since 1.3.7
|
34
|
+
# @api private
|
35
|
+
attr_reader :mask
|
36
|
+
|
37
|
+
# This is a simple deep merge to merge the original input
|
38
|
+
# with the filtered hash which contains '[FILTERED]' string.
|
39
|
+
#
|
40
|
+
# It only deep-merges if the conflict values are both hashes.
|
41
|
+
#
|
42
|
+
# @since 1.3.7
|
43
|
+
# @api private
|
44
|
+
def _deep_merge(original_hash, filtered_hash)
|
45
|
+
original_hash.merge(filtered_hash) do |_key, original_item, filtered_item|
|
46
|
+
if original_item.is_a?(Hash) && filtered_item.is_a?(Hash)
|
47
|
+
_deep_merge(original_item, filtered_item)
|
48
|
+
elsif filtered_item == FILTERED_VALUE
|
49
|
+
filtered_item
|
50
|
+
else
|
51
|
+
original_item
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
35
56
|
# @since 1.1.0
|
36
57
|
# @api private
|
37
58
|
def _filtered_keys(hash)
|
@@ -42,7 +63,7 @@ module Hanami
|
|
42
63
|
# @api private
|
43
64
|
def _key_paths(hash, base = nil)
|
44
65
|
hash.inject([]) do |results, (k, v)|
|
45
|
-
results + (
|
66
|
+
results + (_key_paths?(v) ? _key_paths(v, _build_path(base, k)) : [_build_path(base, k)])
|
46
67
|
end
|
47
68
|
end
|
48
69
|
|
@@ -63,6 +84,64 @@ module Hanami
|
|
63
84
|
res + [correct_key]
|
64
85
|
end
|
65
86
|
end
|
87
|
+
|
88
|
+
# Check if the given value can be iterated (`Enumerable`) and that isn't a `File`.
|
89
|
+
# This is useful to detect closed `Tempfiles`.
|
90
|
+
#
|
91
|
+
# @since 1.3.5
|
92
|
+
# @api private
|
93
|
+
#
|
94
|
+
# @see https://github.com/hanami/utils/pull/342
|
95
|
+
def _key_paths?(value)
|
96
|
+
value.is_a?(Enumerable) && !value.is_a?(File)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @since 1.3.7
|
100
|
+
# @api private
|
101
|
+
def _deep_dup(hash)
|
102
|
+
hash.map do |key, value|
|
103
|
+
[
|
104
|
+
key,
|
105
|
+
if value.is_a?(Hash)
|
106
|
+
_deep_dup(value)
|
107
|
+
else
|
108
|
+
_key_paths?(value) ? value.dup : value
|
109
|
+
end
|
110
|
+
]
|
111
|
+
end.to_h
|
112
|
+
end
|
113
|
+
|
114
|
+
# @since 1.3.7
|
115
|
+
# @api private
|
116
|
+
def _copy_params(params)
|
117
|
+
case params
|
118
|
+
when Hash
|
119
|
+
_deep_dup(params)
|
120
|
+
when Array
|
121
|
+
params.map { |hash| _deep_dup(hash) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# @since 1.3.7
|
126
|
+
# @api private
|
127
|
+
def _filter_hash(hash)
|
128
|
+
_filtered_keys(hash).each do |key|
|
129
|
+
*keys, last = _actual_keys(hash, key.split("."))
|
130
|
+
keys.inject(hash, :fetch)[last] = mask
|
131
|
+
end
|
132
|
+
hash
|
133
|
+
end
|
134
|
+
|
135
|
+
# @since 1.3.7
|
136
|
+
# @api private
|
137
|
+
def _filter(params)
|
138
|
+
case params
|
139
|
+
when Hash
|
140
|
+
_filter_hash(params)
|
141
|
+
when Array
|
142
|
+
params.map { |hash| _filter_hash(hash) }
|
143
|
+
end
|
144
|
+
end
|
66
145
|
end
|
67
146
|
end
|
68
147
|
end
|