activesupport 5.2.4.4 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +327 -408
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -2
- data/lib/active_support.rb +2 -1
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +28 -1
- data/lib/active_support/cache.rb +45 -23
- data/lib/active_support/cache/file_store.rb +22 -22
- data/lib/active_support/cache/mem_cache_store.rb +17 -2
- data/lib/active_support/cache/memory_store.rb +7 -2
- data/lib/active_support/cache/null_store.rb +5 -0
- data/lib/active_support/cache/redis_cache_store.rb +47 -25
- data/lib/active_support/callbacks.rb +16 -5
- data/lib/active_support/concern.rb +24 -1
- data/lib/active_support/configurable.rb +7 -11
- data/lib/active_support/core_ext/array.rb +1 -1
- data/lib/active_support/core_ext/array/access.rb +18 -6
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +2 -6
- data/lib/active_support/core_ext/class/attribute.rb +11 -16
- data/lib/active_support/core_ext/class/subclasses.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +24 -47
- data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +97 -73
- data/lib/active_support/core_ext/hash.rb +1 -2
- data/lib/active_support/core_ext/hash/compact.rb +2 -26
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +0 -29
- data/lib/active_support/core_ext/hash/slice.rb +3 -25
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -29
- data/lib/active_support/core_ext/integer/multiple.rb +1 -1
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +1 -1
- data/lib/active_support/core_ext/module.rb +0 -1
- data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -10
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +13 -19
- data/lib/active_support/core_ext/module/delegation.rb +33 -7
- data/lib/active_support/core_ext/module/introspection.rb +37 -13
- data/lib/active_support/core_ext/module/reachable.rb +1 -6
- data/lib/active_support/core_ext/module/redefine_method.rb +8 -17
- data/lib/active_support/core_ext/numeric.rb +0 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +124 -128
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -25
- data/lib/active_support/core_ext/object/blank.rb +1 -2
- data/lib/active_support/core_ext/object/duplicable.rb +7 -114
- data/lib/active_support/core_ext/object/json.rb +1 -0
- data/lib/active_support/core_ext/object/try.rb +15 -7
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/range/compare_range.rb +22 -13
- data/lib/active_support/core_ext/range/conversions.rb +31 -29
- data/lib/active_support/core_ext/range/include_range.rb +6 -0
- data/lib/active_support/core_ext/regexp.rb +0 -4
- data/lib/active_support/core_ext/securerandom.rb +23 -3
- data/lib/active_support/core_ext/string/access.rb +8 -0
- data/lib/active_support/core_ext/string/filters.rb +42 -1
- data/lib/active_support/core_ext/string/inflections.rb +7 -2
- data/lib/active_support/core_ext/string/multibyte.rb +4 -3
- data/lib/active_support/core_ext/string/output_safety.rb +61 -5
- data/lib/active_support/core_ext/string/strip.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +31 -2
- data/lib/active_support/core_ext/uri.rb +1 -0
- data/lib/active_support/current_attributes.rb +8 -0
- data/lib/active_support/dependencies.rb +69 -16
- data/lib/active_support/dependencies/zeitwerk_integration.rb +110 -0
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/deprecation/method_wrappers.rb +8 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +24 -5
- data/lib/active_support/descendants_tracker.rb +56 -9
- data/lib/active_support/duration.rb +4 -3
- data/lib/active_support/duration/iso8601_parser.rb +2 -3
- data/lib/active_support/duration/iso8601_serializer.rb +3 -4
- data/lib/active_support/encrypted_configuration.rb +0 -4
- data/lib/active_support/encrypted_file.rb +2 -1
- data/lib/active_support/evented_file_update_checker.rb +39 -9
- data/lib/active_support/execution_wrapper.rb +1 -0
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +22 -18
- data/lib/active_support/i18n.rb +1 -0
- data/lib/active_support/i18n_railtie.rb +9 -1
- data/lib/active_support/inflector/inflections.rb +1 -4
- data/lib/active_support/inflector/methods.rb +15 -27
- data/lib/active_support/inflector/transliterate.rb +47 -18
- data/lib/active_support/json/decoding.rb +23 -23
- data/lib/active_support/json/encoding.rb +6 -2
- data/lib/active_support/key_generator.rb +0 -32
- data/lib/active_support/lazy_load_hooks.rb +5 -1
- data/lib/active_support/locale/en.rb +31 -0
- data/lib/active_support/log_subscriber.rb +31 -8
- data/lib/active_support/logger.rb +0 -15
- data/lib/active_support/logger_silence.rb +28 -12
- data/lib/active_support/logger_thread_safe_level.rb +26 -4
- data/lib/active_support/message_encryptor.rb +3 -5
- data/lib/active_support/message_verifier.rb +3 -3
- data/lib/active_support/multibyte/chars.rb +29 -48
- data/lib/active_support/multibyte/unicode.rb +44 -281
- data/lib/active_support/notifications.rb +41 -4
- data/lib/active_support/notifications/fanout.rb +98 -13
- data/lib/active_support/notifications/instrumenter.rb +79 -8
- data/lib/active_support/number_helper.rb +7 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -2
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +5 -3
- data/lib/active_support/ordered_options.rb +1 -1
- data/lib/active_support/parameter_filter.rb +129 -0
- data/lib/active_support/rails.rb +0 -6
- data/lib/active_support/reloader.rb +4 -5
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/subscriber.rb +65 -26
- data/lib/active_support/tagged_logging.rb +13 -4
- data/lib/active_support/test_case.rb +91 -0
- data/lib/active_support/testing/assertions.rb +15 -1
- data/lib/active_support/testing/deprecation.rb +0 -1
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +2 -2
- data/lib/active_support/testing/method_call_assertions.rb +28 -1
- data/lib/active_support/testing/parallelization.rb +128 -0
- data/lib/active_support/testing/stream.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +7 -7
- data/lib/active_support/time_with_zone.rb +15 -5
- data/lib/active_support/values/time_zone.rb +12 -7
- data/lib/active_support/xml_mini.rb +2 -9
- data/lib/active_support/xml_mini/jdom.rb +2 -2
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -4
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -3
- data/lib/active_support/xml_mini/rexml.rb +2 -2
- metadata +34 -9
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -13
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support"
|
4
|
-
require "active_support/file_update_checker"
|
5
4
|
require "active_support/core_ext/array/wrap"
|
6
5
|
|
7
6
|
# :enddoc:
|
@@ -92,6 +91,15 @@ module I18n
|
|
92
91
|
end
|
93
92
|
|
94
93
|
if args.empty? || args.first.is_a?(Hash)
|
94
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
95
|
+
Using I18n fallbacks with an empty `defaults` sets the defaults to
|
96
|
+
include the `default_locale`. This behavior will change in Rails 6.1.
|
97
|
+
If you desire the default locale to be included in the defaults, please
|
98
|
+
explicitly configure it with `config.i18n.fallbacks.defaults =
|
99
|
+
[I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale,
|
100
|
+
{...}]`. If you want to opt-in to the new behavior, use
|
101
|
+
`config.i18n.fallbacks.defaults = [nil, {...}]`.
|
102
|
+
MSG
|
95
103
|
args.unshift I18n.default_locale
|
96
104
|
end
|
97
105
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "concurrent/map"
|
4
|
-
require "active_support/core_ext/array/prepend_and_append"
|
5
|
-
require "active_support/core_ext/regexp"
|
6
4
|
require "active_support/i18n"
|
7
5
|
require "active_support/deprecation"
|
8
6
|
|
@@ -67,8 +65,7 @@ module ActiveSupport
|
|
67
65
|
@__instance__[locale] ||= new
|
68
66
|
end
|
69
67
|
|
70
|
-
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
71
|
-
deprecate :acronym_regex
|
68
|
+
attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
|
72
69
|
|
73
70
|
attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
|
74
71
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/inflections"
|
4
|
-
require "active_support/core_ext/regexp"
|
5
4
|
|
6
5
|
module ActiveSupport
|
7
6
|
# The Inflector transforms words from singular to plural, class names to table
|
@@ -74,7 +73,7 @@ module ActiveSupport
|
|
74
73
|
string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase }
|
75
74
|
end
|
76
75
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
77
|
-
string.gsub!("/"
|
76
|
+
string.gsub!("/", "::")
|
78
77
|
string
|
79
78
|
end
|
80
79
|
|
@@ -91,11 +90,11 @@ module ActiveSupport
|
|
91
90
|
# camelize(underscore('SSLError')) # => "SslError"
|
92
91
|
def underscore(camel_cased_word)
|
93
92
|
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
94
|
-
word = camel_cased_word.to_s.gsub("::"
|
95
|
-
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_'
|
96
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'
|
97
|
-
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'
|
98
|
-
word.tr!("-"
|
93
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
94
|
+
word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
|
95
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
96
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
97
|
+
word.tr!("-", "_")
|
99
98
|
word.downcase!
|
100
99
|
word
|
101
100
|
end
|
@@ -131,11 +130,11 @@ module ActiveSupport
|
|
131
130
|
|
132
131
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
133
132
|
|
134
|
-
result.sub!(/\A_+/, ""
|
133
|
+
result.sub!(/\A_+/, "")
|
135
134
|
unless keep_id_suffix
|
136
|
-
result.sub!(/_id\z/, ""
|
135
|
+
result.sub!(/_id\z/, "")
|
137
136
|
end
|
138
|
-
result.tr!("_"
|
137
|
+
result.tr!("_", " ")
|
139
138
|
|
140
139
|
result.gsub!(/([a-z\d]*)/i) do |match|
|
141
140
|
"#{inflections.acronyms[match.downcase] || match.downcase}"
|
@@ -200,14 +199,14 @@ module ActiveSupport
|
|
200
199
|
# classify('calculus') # => "Calculus"
|
201
200
|
def classify(table_name)
|
202
201
|
# strip out any leading schema name
|
203
|
-
camelize(singularize(table_name.to_s.sub(/.*\./, ""
|
202
|
+
camelize(singularize(table_name.to_s.sub(/.*\./, "")))
|
204
203
|
end
|
205
204
|
|
206
205
|
# Replaces underscores with dashes in the string.
|
207
206
|
#
|
208
207
|
# dasherize('puni_puni') # => "puni-puni"
|
209
208
|
def dasherize(underscored_word)
|
210
|
-
underscored_word.tr("_"
|
209
|
+
underscored_word.tr("_", "-")
|
211
210
|
end
|
212
211
|
|
213
212
|
# Removes the module part from the expression in the string.
|
@@ -270,7 +269,7 @@ module ActiveSupport
|
|
270
269
|
# NameError is raised when the name is not in CamelCase or the constant is
|
271
270
|
# unknown.
|
272
271
|
def constantize(camel_cased_word)
|
273
|
-
names = camel_cased_word.split("::"
|
272
|
+
names = camel_cased_word.split("::")
|
274
273
|
|
275
274
|
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
276
275
|
Object.const_get(camel_cased_word) if names.empty?
|
@@ -343,18 +342,7 @@ module ActiveSupport
|
|
343
342
|
# ordinal(-11) # => "th"
|
344
343
|
# ordinal(-1021) # => "st"
|
345
344
|
def ordinal(number)
|
346
|
-
|
347
|
-
|
348
|
-
if (11..13).include?(abs_number % 100)
|
349
|
-
"th"
|
350
|
-
else
|
351
|
-
case abs_number % 10
|
352
|
-
when 1; "st"
|
353
|
-
when 2; "nd"
|
354
|
-
when 3; "rd"
|
355
|
-
else "th"
|
356
|
-
end
|
357
|
-
end
|
345
|
+
I18n.translate("number.nth.ordinals", number: number)
|
358
346
|
end
|
359
347
|
|
360
348
|
# Turns a number into an ordinal string used to denote the position in an
|
@@ -367,7 +355,7 @@ module ActiveSupport
|
|
367
355
|
# ordinalize(-11) # => "-11th"
|
368
356
|
# ordinalize(-1021) # => "-1021st"
|
369
357
|
def ordinalize(number)
|
370
|
-
"
|
358
|
+
I18n.translate("number.nth.ordinalized", number: number)
|
371
359
|
end
|
372
360
|
|
373
361
|
private
|
@@ -378,7 +366,7 @@ module ActiveSupport
|
|
378
366
|
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
379
367
|
# const_regexp("::") # => "::"
|
380
368
|
def const_regexp(camel_cased_word)
|
381
|
-
parts = camel_cased_word.split("::"
|
369
|
+
parts = camel_cased_word.split("::")
|
382
370
|
|
383
371
|
return Regexp.escape(camel_cased_word) if parts.blank?
|
384
372
|
|
@@ -51,20 +51,45 @@ module ActiveSupport
|
|
51
51
|
#
|
52
52
|
# Now you can have different transliterations for each locale:
|
53
53
|
#
|
54
|
-
#
|
55
|
-
# transliterate('Jürgen')
|
54
|
+
# transliterate('Jürgen', locale: :en)
|
56
55
|
# # => "Jurgen"
|
57
56
|
#
|
58
|
-
#
|
59
|
-
# transliterate('Jürgen')
|
57
|
+
# transliterate('Jürgen', locale: :de)
|
60
58
|
# # => "Juergen"
|
61
|
-
|
59
|
+
#
|
60
|
+
# Transliteration is restricted to UTF-8, US-ASCII and GB18030 strings
|
61
|
+
# Other encodings will raise an ArgumentError.
|
62
|
+
def transliterate(string, replacement = "?", locale: nil)
|
63
|
+
string = string.dup if string.frozen?
|
62
64
|
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
allowed_encodings = [Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030]
|
67
|
+
raise ArgumentError, "Can not transliterate strings with #{string.encoding} encoding" unless allowed_encodings.include?(string.encoding)
|
68
|
+
|
69
|
+
input_encoding = string.encoding
|
70
|
+
|
71
|
+
# US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if
|
72
|
+
# US-ASCII is given. This way we can let tidy_bytes handle the string
|
73
|
+
# in the same way as we do for UTF-8
|
74
|
+
string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII
|
75
|
+
|
76
|
+
# GB18030 is Unicode compatible but is not a direct mapping so needs to be
|
77
|
+
# transcoded. Using invalid/undef :replace will result in loss of data in
|
78
|
+
# the event of invalid characters, but since tidy_bytes will replace
|
79
|
+
# invalid/undef with a "?" we're safe to do the same beforehand
|
80
|
+
string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030
|
81
|
+
|
82
|
+
transliterated = I18n.transliterate(
|
83
|
+
ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
|
84
|
+
replacement: replacement,
|
85
|
+
locale: locale
|
86
|
+
)
|
87
|
+
|
88
|
+
# Restore the string encoding of the input if it was not UTF-8.
|
89
|
+
# Apply invalid/undef :replace as tidy_bytes does
|
90
|
+
transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding
|
91
|
+
|
92
|
+
transliterated
|
68
93
|
end
|
69
94
|
|
70
95
|
# Replaces special characters in a string so that it may be used as part of
|
@@ -75,8 +100,8 @@ module ActiveSupport
|
|
75
100
|
#
|
76
101
|
# To use a custom separator, override the +separator+ argument.
|
77
102
|
#
|
78
|
-
#
|
79
|
-
#
|
103
|
+
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
|
104
|
+
# parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie"
|
80
105
|
#
|
81
106
|
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
82
107
|
#
|
@@ -85,19 +110,23 @@ module ActiveSupport
|
|
85
110
|
#
|
86
111
|
# It preserves dashes and underscores unless they are used as separators:
|
87
112
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
113
|
+
# parameterize("^très|Jolie__ ") # => "tres-jolie__"
|
114
|
+
# parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--"
|
115
|
+
# parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--"
|
91
116
|
#
|
92
|
-
|
117
|
+
# If the optional parameter +locale+ is specified,
|
118
|
+
# the word will be parameterized as a word of that language.
|
119
|
+
# By default, this parameter is set to <tt>nil</tt> and it will use
|
120
|
+
# the configured <tt>I18n.locale<tt>.
|
121
|
+
def parameterize(string, separator: "-", preserve_case: false, locale: nil)
|
93
122
|
# Replace accented chars with their ASCII equivalents.
|
94
|
-
parameterized_string = transliterate(string)
|
123
|
+
parameterized_string = transliterate(string, locale: locale)
|
95
124
|
|
96
125
|
# Turn unwanted chars into the separator.
|
97
126
|
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
|
98
127
|
|
99
128
|
unless separator.nil? || separator.empty?
|
100
|
-
if separator == "-"
|
129
|
+
if separator == "-"
|
101
130
|
re_duplicate_separator = /-{2,}/
|
102
131
|
re_leading_trailing_separator = /^-|-$/i
|
103
132
|
else
|
@@ -108,7 +137,7 @@ module ActiveSupport
|
|
108
137
|
# No more than one of the separator in a row.
|
109
138
|
parameterized_string.gsub!(re_duplicate_separator, separator)
|
110
139
|
# Remove leading/trailing separator.
|
111
|
-
parameterized_string.gsub!(re_leading_trailing_separator, ""
|
140
|
+
parameterized_string.gsub!(re_leading_trailing_separator, "")
|
112
141
|
end
|
113
142
|
|
114
143
|
parameterized_string.downcase! unless preserve_case
|
@@ -45,32 +45,32 @@ module ActiveSupport
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
48
|
+
def convert_dates_from(data)
|
49
|
+
case data
|
50
|
+
when nil
|
51
|
+
nil
|
52
|
+
when DATE_REGEX
|
53
|
+
begin
|
54
|
+
Date.parse(data)
|
55
|
+
rescue ArgumentError
|
56
|
+
data
|
57
|
+
end
|
58
|
+
when DATETIME_REGEX
|
59
|
+
begin
|
60
|
+
Time.zone.parse(data)
|
61
|
+
rescue ArgumentError
|
62
|
+
data
|
63
|
+
end
|
64
|
+
when Array
|
65
|
+
data.map! { |d| convert_dates_from(d) }
|
66
|
+
when Hash
|
67
|
+
data.each do |key, value|
|
68
|
+
data[key] = convert_dates_from(value)
|
69
|
+
end
|
70
|
+
else
|
56
71
|
data
|
57
72
|
end
|
58
|
-
when DATETIME_REGEX
|
59
|
-
begin
|
60
|
-
Time.zone.parse(data)
|
61
|
-
rescue ArgumentError
|
62
|
-
data
|
63
|
-
end
|
64
|
-
when Array
|
65
|
-
data.map! { |d| convert_dates_from(d) }
|
66
|
-
when Hash
|
67
|
-
data.each do |key, value|
|
68
|
-
data[key] = convert_dates_from(value)
|
69
|
-
end
|
70
|
-
else
|
71
|
-
data
|
72
73
|
end
|
73
|
-
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -54,9 +54,13 @@ module ActiveSupport
|
|
54
54
|
class EscapedString < String #:nodoc:
|
55
55
|
def to_json(*)
|
56
56
|
if Encoding.escape_html_entities_in_json
|
57
|
-
|
57
|
+
s = super
|
58
|
+
s.gsub! ESCAPE_REGEX_WITH_HTML_ENTITIES, ESCAPED_CHARS
|
59
|
+
s
|
58
60
|
else
|
59
|
-
|
61
|
+
s = super
|
62
|
+
s.gsub! ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, ESCAPED_CHARS
|
63
|
+
s
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
@@ -38,36 +38,4 @@ module ActiveSupport
|
|
38
38
|
@cache_keys[args.join] ||= @key_generator.generate_key(*args)
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
42
|
-
class LegacyKeyGenerator # :nodoc:
|
43
|
-
SECRET_MIN_LENGTH = 30 # Characters
|
44
|
-
|
45
|
-
def initialize(secret)
|
46
|
-
ensure_secret_secure(secret)
|
47
|
-
@secret = secret
|
48
|
-
end
|
49
|
-
|
50
|
-
def generate_key(salt)
|
51
|
-
@secret
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
# To prevent users from using something insecure like "Password" we make sure that the
|
57
|
-
# secret they've provided is at least 30 characters in length.
|
58
|
-
def ensure_secret_secure(secret)
|
59
|
-
if secret.blank?
|
60
|
-
raise ArgumentError, "A secret is required to generate an integrity hash " \
|
61
|
-
"for cookie session data. Set a secret_key_base of at least " \
|
62
|
-
"#{SECRET_MIN_LENGTH} characters in via `bin/rails credentials:edit`."
|
63
|
-
end
|
64
|
-
|
65
|
-
if secret.length < SECRET_MIN_LENGTH
|
66
|
-
raise ArgumentError, "Secret should be something secure, " \
|
67
|
-
"like \"#{SecureRandom.hex(16)}\". The value you " \
|
68
|
-
"provided, \"#{secret}\", is shorter than the minimum length " \
|
69
|
-
"of #{SECRET_MIN_LENGTH} characters."
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
41
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
{
|
4
|
+
en: {
|
5
|
+
number: {
|
6
|
+
nth: {
|
7
|
+
ordinals: lambda do |_key, number:, **_options|
|
8
|
+
case number
|
9
|
+
when 1; "st"
|
10
|
+
when 2; "nd"
|
11
|
+
when 3; "rd"
|
12
|
+
when 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; "th"
|
13
|
+
else
|
14
|
+
num_modulo = number.to_i.abs % 100
|
15
|
+
num_modulo %= 10 if num_modulo > 13
|
16
|
+
case num_modulo
|
17
|
+
when 1; "st"
|
18
|
+
when 2; "nd"
|
19
|
+
when 3; "rd"
|
20
|
+
else "th"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end,
|
24
|
+
|
25
|
+
ordinalized: lambda do |_key, number:, **_options|
|
26
|
+
"#{number}#{ActiveSupport::Inflector.ordinal(number)}"
|
27
|
+
end
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
@@ -5,8 +5,8 @@ require "active_support/core_ext/class/attribute"
|
|
5
5
|
require "active_support/subscriber"
|
6
6
|
|
7
7
|
module ActiveSupport
|
8
|
-
# ActiveSupport::LogSubscriber is an object set to consume
|
9
|
-
# ActiveSupport::Notifications with the sole purpose of logging them.
|
8
|
+
# <tt>ActiveSupport::LogSubscriber</tt> is an object set to consume
|
9
|
+
# <tt>ActiveSupport::Notifications</tt> with the sole purpose of logging them.
|
10
10
|
# The log subscriber dispatches notifications to a registered object based
|
11
11
|
# on its given namespace.
|
12
12
|
#
|
@@ -16,7 +16,7 @@ module ActiveSupport
|
|
16
16
|
# module ActiveRecord
|
17
17
|
# class LogSubscriber < ActiveSupport::LogSubscriber
|
18
18
|
# def sql(event)
|
19
|
-
# "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
|
19
|
+
# info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
|
20
20
|
# end
|
21
21
|
# end
|
22
22
|
# end
|
@@ -29,13 +29,36 @@ module ActiveSupport
|
|
29
29
|
# subscriber, the line above should be called after your
|
30
30
|
# <tt>ActiveRecord::LogSubscriber</tt> definition.
|
31
31
|
#
|
32
|
-
# After configured, whenever a "sql.active_record" notification is published,
|
33
|
-
# it will properly dispatch the event
|
34
|
-
# the sql method.
|
32
|
+
# After configured, whenever a <tt>"sql.active_record"</tt> notification is published,
|
33
|
+
# it will properly dispatch the event
|
34
|
+
# (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method.
|
35
|
+
#
|
36
|
+
# Being an <tt>ActiveSupport::Notifications</tt> consumer,
|
37
|
+
# <tt>ActiveSupport::LogSubscriber</tt> exposes a simple interface to check if
|
38
|
+
# instrumented code raises an exception. It is common to log a different
|
39
|
+
# message in case of an error, and this can be achieved by extending
|
40
|
+
# the previous example:
|
41
|
+
#
|
42
|
+
# module ActiveRecord
|
43
|
+
# class LogSubscriber < ActiveSupport::LogSubscriber
|
44
|
+
# def sql(event)
|
45
|
+
# exception = event.payload[:exception]
|
46
|
+
#
|
47
|
+
# if exception
|
48
|
+
# exception_object = event.payload[:exception_object]
|
49
|
+
#
|
50
|
+
# error "[ERROR] #{event.payload[:name]}: #{exception.join(', ')} " \
|
51
|
+
# "(#{exception_object.backtrace.first})"
|
52
|
+
# else
|
53
|
+
# # standard logger code
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
35
58
|
#
|
36
59
|
# Log subscriber also has some helpers to deal with logging and automatically
|
37
|
-
# flushes all logs when the request finishes
|
38
|
-
# notification) in a Rails environment.
|
60
|
+
# flushes all logs when the request finishes
|
61
|
+
# (via <tt>action_dispatch.callback</tt> notification) in a Rails environment.
|
39
62
|
class LogSubscriber < Subscriber
|
40
63
|
# Embed in a String to clear all previous ANSI sequences.
|
41
64
|
CLEAR = "\e[0m"
|