activesupport 1.2.4 → 8.1.2

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.
Files changed (309) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +505 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +40 -0
  5. data/lib/active_support/actionable_error.rb +50 -0
  6. data/lib/active_support/all.rb +5 -0
  7. data/lib/active_support/array_inquirer.rb +50 -0
  8. data/lib/active_support/backtrace_cleaner.rb +234 -0
  9. data/lib/active_support/benchmark.rb +21 -0
  10. data/lib/active_support/benchmarkable.rb +53 -0
  11. data/lib/active_support/broadcast_logger.rb +238 -0
  12. data/lib/active_support/builder.rb +8 -0
  13. data/lib/active_support/cache/coder.rb +153 -0
  14. data/lib/active_support/cache/entry.rb +134 -0
  15. data/lib/active_support/cache/file_store.rb +244 -0
  16. data/lib/active_support/cache/mem_cache_store.rb +288 -0
  17. data/lib/active_support/cache/memory_store.rb +264 -0
  18. data/lib/active_support/cache/null_store.rb +62 -0
  19. data/lib/active_support/cache/redis_cache_store.rb +498 -0
  20. data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
  21. data/lib/active_support/cache/strategy/local_cache.rb +246 -0
  22. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  23. data/lib/active_support/cache.rb +1170 -0
  24. data/lib/active_support/callbacks.rb +960 -0
  25. data/lib/active_support/class_attribute.rb +33 -0
  26. data/lib/active_support/code_generator.rb +79 -0
  27. data/lib/active_support/concern.rb +217 -0
  28. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
  29. data/lib/active_support/concurrency/null_lock.rb +13 -0
  30. data/lib/active_support/concurrency/share_lock.rb +225 -0
  31. data/lib/active_support/concurrency/thread_monitor.rb +55 -0
  32. data/lib/active_support/configurable.rb +193 -0
  33. data/lib/active_support/configuration_file.rb +60 -0
  34. data/lib/active_support/continuous_integration.rb +145 -0
  35. data/lib/active_support/core_ext/array/access.rb +100 -0
  36. data/lib/active_support/core_ext/array/conversions.rb +209 -26
  37. data/lib/active_support/core_ext/array/extract.rb +21 -0
  38. data/lib/active_support/core_ext/array/extract_options.rb +31 -0
  39. data/lib/active_support/core_ext/array/grouping.rb +109 -0
  40. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  41. data/lib/active_support/core_ext/array/wrap.rb +48 -0
  42. data/lib/active_support/core_ext/array.rb +8 -4
  43. data/lib/active_support/core_ext/benchmark.rb +6 -0
  44. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  45. data/lib/active_support/core_ext/big_decimal.rb +3 -0
  46. data/lib/active_support/core_ext/class/attribute.rb +137 -0
  47. data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
  48. data/lib/active_support/core_ext/class/subclasses.rb +24 -0
  49. data/lib/active_support/core_ext/class.rb +4 -0
  50. data/lib/active_support/core_ext/date/acts_like.rb +10 -0
  51. data/lib/active_support/core_ext/date/blank.rb +18 -0
  52. data/lib/active_support/core_ext/date/calculations.rb +161 -0
  53. data/lib/active_support/core_ext/date/conversions.rb +95 -28
  54. data/lib/active_support/core_ext/date/zones.rb +8 -0
  55. data/lib/active_support/core_ext/date.rb +6 -5
  56. data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
  57. data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
  58. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  59. data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
  60. data/lib/active_support/core_ext/date_time/blank.rb +18 -0
  61. data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
  62. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  63. data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
  64. data/lib/active_support/core_ext/date_time.rb +7 -0
  65. data/lib/active_support/core_ext/digest/uuid.rb +76 -0
  66. data/lib/active_support/core_ext/digest.rb +3 -0
  67. data/lib/active_support/core_ext/enumerable.rb +277 -7
  68. data/lib/active_support/core_ext/erb/util.rb +201 -0
  69. data/lib/active_support/core_ext/file/atomic.rb +72 -0
  70. data/lib/active_support/core_ext/file.rb +3 -0
  71. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  72. data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
  73. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  74. data/lib/active_support/core_ext/hash/except.rb +12 -0
  75. data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
  76. data/lib/active_support/core_ext/hash/keys.rb +134 -44
  77. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
  78. data/lib/active_support/core_ext/hash/slice.rb +27 -0
  79. data/lib/active_support/core_ext/hash.rb +9 -8
  80. data/lib/active_support/core_ext/integer/inflections.rb +29 -13
  81. data/lib/active_support/core_ext/integer/multiple.rb +12 -0
  82. data/lib/active_support/core_ext/integer/time.rb +22 -0
  83. data/lib/active_support/core_ext/integer.rb +4 -6
  84. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  85. data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
  86. data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
  87. data/lib/active_support/core_ext/kernel.rb +4 -78
  88. data/lib/active_support/core_ext/load_error.rb +6 -35
  89. data/lib/active_support/core_ext/module/aliasing.rb +31 -0
  90. data/lib/active_support/core_ext/module/anonymous.rb +30 -0
  91. data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
  92. data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
  93. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
  94. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  95. data/lib/active_support/core_ext/module/delegation.rb +225 -0
  96. data/lib/active_support/core_ext/module/deprecation.rb +25 -0
  97. data/lib/active_support/core_ext/module/introspection.rb +65 -0
  98. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  99. data/lib/active_support/core_ext/module/remove_method.rb +17 -0
  100. data/lib/active_support/core_ext/module.rb +13 -0
  101. data/lib/active_support/core_ext/name_error.rb +59 -0
  102. data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
  103. data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
  104. data/lib/active_support/core_ext/numeric/time.rb +64 -57
  105. data/lib/active_support/core_ext/numeric.rb +4 -6
  106. data/lib/active_support/core_ext/object/acts_like.rb +45 -0
  107. data/lib/active_support/core_ext/object/blank.rb +199 -0
  108. data/lib/active_support/core_ext/object/conversions.rb +6 -0
  109. data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
  110. data/lib/active_support/core_ext/object/duplicable.rb +69 -0
  111. data/lib/active_support/core_ext/object/inclusion.rb +37 -0
  112. data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
  113. data/lib/active_support/core_ext/object/json.rb +267 -0
  114. data/lib/active_support/core_ext/object/to_param.rb +3 -0
  115. data/lib/active_support/core_ext/object/to_query.rb +93 -0
  116. data/lib/active_support/core_ext/object/try.rb +158 -0
  117. data/lib/active_support/core_ext/object/with.rb +46 -0
  118. data/lib/active_support/core_ext/object/with_options.rb +101 -0
  119. data/lib/active_support/core_ext/object.rb +17 -0
  120. data/lib/active_support/core_ext/pathname/blank.rb +20 -0
  121. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  122. data/lib/active_support/core_ext/pathname.rb +4 -0
  123. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  124. data/lib/active_support/core_ext/range/conversions.rb +58 -17
  125. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  126. data/lib/active_support/core_ext/range/sole.rb +17 -0
  127. data/lib/active_support/core_ext/range.rb +5 -4
  128. data/lib/active_support/core_ext/regexp.rb +14 -0
  129. data/lib/active_support/core_ext/securerandom.rb +57 -0
  130. data/lib/active_support/core_ext/string/access.rb +93 -56
  131. data/lib/active_support/core_ext/string/behavior.rb +8 -0
  132. data/lib/active_support/core_ext/string/conversions.rb +57 -16
  133. data/lib/active_support/core_ext/string/exclude.rb +13 -0
  134. data/lib/active_support/core_ext/string/filters.rb +151 -0
  135. data/lib/active_support/core_ext/string/indent.rb +45 -0
  136. data/lib/active_support/core_ext/string/inflections.rb +297 -54
  137. data/lib/active_support/core_ext/string/inquiry.rb +16 -0
  138. data/lib/active_support/core_ext/string/multibyte.rb +67 -0
  139. data/lib/active_support/core_ext/string/output_safety.rb +235 -0
  140. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
  141. data/lib/active_support/core_ext/string/strip.rb +27 -0
  142. data/lib/active_support/core_ext/string/zones.rb +16 -0
  143. data/lib/active_support/core_ext/string.rb +14 -10
  144. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  145. data/lib/active_support/core_ext/symbol.rb +3 -0
  146. data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
  147. data/lib/active_support/core_ext/time/acts_like.rb +10 -0
  148. data/lib/active_support/core_ext/time/calculations.rb +358 -153
  149. data/lib/active_support/core_ext/time/compatibility.rb +15 -0
  150. data/lib/active_support/core_ext/time/conversions.rb +69 -30
  151. data/lib/active_support/core_ext/time/zones.rb +97 -0
  152. data/lib/active_support/core_ext/time.rb +6 -6
  153. data/lib/active_support/core_ext.rb +5 -1
  154. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  155. data/lib/active_support/current_attributes.rb +243 -0
  156. data/lib/active_support/deep_mergeable.rb +53 -0
  157. data/lib/active_support/delegation.rb +183 -0
  158. data/lib/active_support/dependencies/autoload.rb +72 -0
  159. data/lib/active_support/dependencies/interlock.rb +55 -0
  160. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  161. data/lib/active_support/dependencies.rb +84 -222
  162. data/lib/active_support/deprecation/behaviors.rb +148 -0
  163. data/lib/active_support/deprecation/constant_accessor.rb +74 -0
  164. data/lib/active_support/deprecation/deprecators.rb +104 -0
  165. data/lib/active_support/deprecation/disallowed.rb +54 -0
  166. data/lib/active_support/deprecation/method_wrappers.rb +68 -0
  167. data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
  168. data/lib/active_support/deprecation/reporting.rb +162 -0
  169. data/lib/active_support/deprecation.rb +81 -0
  170. data/lib/active_support/deprecator.rb +7 -0
  171. data/lib/active_support/descendants_tracker.rb +112 -0
  172. data/lib/active_support/digest.rb +22 -0
  173. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  174. data/lib/active_support/duration/iso8601_serializer.rb +64 -0
  175. data/lib/active_support/duration.rb +524 -0
  176. data/lib/active_support/editor.rb +70 -0
  177. data/lib/active_support/encrypted_configuration.rb +126 -0
  178. data/lib/active_support/encrypted_file.rb +133 -0
  179. data/lib/active_support/environment_inquirer.rb +40 -0
  180. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  181. data/lib/active_support/error_reporter.rb +318 -0
  182. data/lib/active_support/event_reporter/test_helper.rb +32 -0
  183. data/lib/active_support/event_reporter.rb +592 -0
  184. data/lib/active_support/evented_file_update_checker.rb +185 -0
  185. data/lib/active_support/execution_context/test_helper.rb +13 -0
  186. data/lib/active_support/execution_context.rb +110 -0
  187. data/lib/active_support/execution_wrapper.rb +150 -0
  188. data/lib/active_support/executor/test_helper.rb +7 -0
  189. data/lib/active_support/executor.rb +8 -0
  190. data/lib/active_support/file_update_checker.rb +166 -0
  191. data/lib/active_support/fork_tracker.rb +43 -0
  192. data/lib/active_support/gem_version.rb +17 -0
  193. data/lib/active_support/gzip.rb +41 -0
  194. data/lib/active_support/hash_with_indifferent_access.rb +464 -0
  195. data/lib/active_support/html_safe_translation.rb +56 -0
  196. data/lib/active_support/i18n.rb +17 -0
  197. data/lib/active_support/i18n_railtie.rb +140 -0
  198. data/lib/active_support/inflections.rb +68 -49
  199. data/lib/active_support/inflector/inflections.rb +290 -0
  200. data/lib/active_support/inflector/methods.rb +387 -0
  201. data/lib/active_support/inflector/transliterate.rb +147 -0
  202. data/lib/active_support/inflector.rb +7 -164
  203. data/lib/active_support/isolated_execution_state.rb +76 -0
  204. data/lib/active_support/json/decoding.rb +78 -0
  205. data/lib/active_support/json/encoding.rb +256 -0
  206. data/lib/active_support/json.rb +4 -0
  207. data/lib/active_support/key_generator.rb +66 -0
  208. data/lib/active_support/lazy_load_hooks.rb +107 -0
  209. data/lib/active_support/locale/en.rb +33 -0
  210. data/lib/active_support/locale/en.yml +141 -0
  211. data/lib/active_support/log_subscriber/test_helper.rb +106 -0
  212. data/lib/active_support/log_subscriber.rb +188 -0
  213. data/lib/active_support/logger.rb +55 -0
  214. data/lib/active_support/logger_silence.rb +21 -0
  215. data/lib/active_support/logger_thread_safe_level.rb +50 -0
  216. data/lib/active_support/message_encryptor.rb +374 -0
  217. data/lib/active_support/message_encryptors.rb +193 -0
  218. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  219. data/lib/active_support/message_pack/extensions.rb +310 -0
  220. data/lib/active_support/message_pack/serializer.rb +63 -0
  221. data/lib/active_support/message_pack.rb +50 -0
  222. data/lib/active_support/message_verifier.rb +377 -0
  223. data/lib/active_support/message_verifiers.rb +189 -0
  224. data/lib/active_support/messages/codec.rb +65 -0
  225. data/lib/active_support/messages/metadata.rb +146 -0
  226. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  227. data/lib/active_support/messages/rotation_coordinator.rb +102 -0
  228. data/lib/active_support/messages/rotator.rb +69 -0
  229. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  230. data/lib/active_support/multibyte/chars.rb +188 -0
  231. data/lib/active_support/multibyte/unicode.rb +42 -0
  232. data/lib/active_support/multibyte.rb +27 -0
  233. data/lib/active_support/notifications/fanout.rb +467 -0
  234. data/lib/active_support/notifications/instrumenter.rb +240 -0
  235. data/lib/active_support/notifications.rb +281 -0
  236. data/lib/active_support/number_helper/number_converter.rb +190 -0
  237. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  238. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  239. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  240. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  241. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  242. data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
  243. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  244. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  245. data/lib/active_support/number_helper.rb +479 -0
  246. data/lib/active_support/option_merger.rb +38 -0
  247. data/lib/active_support/ordered_hash.rb +50 -0
  248. data/lib/active_support/ordered_options.rb +141 -25
  249. data/lib/active_support/parameter_filter.rb +157 -0
  250. data/lib/active_support/rails.rb +26 -0
  251. data/lib/active_support/railtie.rb +180 -0
  252. data/lib/active_support/reloader.rb +138 -0
  253. data/lib/active_support/rescuable.rb +176 -0
  254. data/lib/active_support/secure_compare_rotator.rb +58 -0
  255. data/lib/active_support/security_utils.rb +38 -0
  256. data/lib/active_support/string_inquirer.rb +35 -0
  257. data/lib/active_support/structured_event_subscriber.rb +99 -0
  258. data/lib/active_support/subscriber.rb +141 -0
  259. data/lib/active_support/syntax_error_proxy.rb +67 -0
  260. data/lib/active_support/tagged_logging.rb +157 -0
  261. data/lib/active_support/test_case.rb +365 -0
  262. data/lib/active_support/testing/assertions.rb +369 -0
  263. data/lib/active_support/testing/autorun.rb +10 -0
  264. data/lib/active_support/testing/constant_lookup.rb +51 -0
  265. data/lib/active_support/testing/constant_stubbing.rb +54 -0
  266. data/lib/active_support/testing/declarative.rb +28 -0
  267. data/lib/active_support/testing/deprecation.rb +82 -0
  268. data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
  269. data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
  270. data/lib/active_support/testing/file_fixtures.rb +38 -0
  271. data/lib/active_support/testing/isolation.rb +121 -0
  272. data/lib/active_support/testing/method_call_assertions.rb +69 -0
  273. data/lib/active_support/testing/notification_assertions.rb +92 -0
  274. data/lib/active_support/testing/parallelization/server.rb +98 -0
  275. data/lib/active_support/testing/parallelization/worker.rb +107 -0
  276. data/lib/active_support/testing/parallelization.rb +79 -0
  277. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  278. data/lib/active_support/testing/setup_and_teardown.rb +57 -0
  279. data/lib/active_support/testing/stream.rb +41 -0
  280. data/lib/active_support/testing/tagged_logging.rb +27 -0
  281. data/lib/active_support/testing/tests_without_assertions.rb +19 -0
  282. data/lib/active_support/testing/time_helpers.rb +273 -0
  283. data/lib/active_support/time.rb +20 -0
  284. data/lib/active_support/time_with_zone.rb +613 -0
  285. data/lib/active_support/values/time_zone.rb +599 -158
  286. data/lib/active_support/version.rb +7 -6
  287. data/lib/active_support/xml_mini/jdom.rb +175 -0
  288. data/lib/active_support/xml_mini/libxml.rb +80 -0
  289. data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
  290. data/lib/active_support/xml_mini/nokogiri.rb +83 -0
  291. data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
  292. data/lib/active_support/xml_mini/rexml.rb +137 -0
  293. data/lib/active_support/xml_mini.rb +212 -0
  294. data/lib/active_support.rb +122 -10
  295. metadata +524 -93
  296. data/CHANGELOG +0 -283
  297. data/lib/active_support/binding_of_caller.rb +0 -84
  298. data/lib/active_support/breakpoint.rb +0 -523
  299. data/lib/active_support/class_attribute_accessors.rb +0 -57
  300. data/lib/active_support/class_inheritable_attributes.rb +0 -117
  301. data/lib/active_support/clean_logger.rb +0 -36
  302. data/lib/active_support/core_ext/blank.rb +0 -38
  303. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
  304. data/lib/active_support/core_ext/cgi.rb +0 -5
  305. data/lib/active_support/core_ext/exception.rb +0 -29
  306. data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
  307. data/lib/active_support/core_ext/object_and_class.rb +0 -44
  308. data/lib/active_support/module_attribute_accessors.rb +0 -57
  309. data/lib/active_support/whiny_nil.rb +0 -38
@@ -1,166 +1,9 @@
1
- require 'singleton'
1
+ # frozen_string_literal: true
2
2
 
3
- # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
4
- # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
5
- # in inflections.rb.
6
- module Inflector
7
- # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
8
- # inflection rules. Examples:
9
- #
10
- # Inflector.inflections do |inflect|
11
- # inflect.plural /^(ox)$/i, '\1\2en'
12
- # inflect.singular /^(ox)en/i, '\1'
13
- #
14
- # inflect.irregular 'octopus', 'octopi'
15
- #
16
- # inflect.uncountable "equipment"
17
- # end
18
- #
19
- # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
20
- # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
21
- # already have been loaded.
22
- class Inflections
23
- include Singleton
24
-
25
- attr_reader :plurals, :singulars, :uncountables
26
-
27
- def initialize
28
- @plurals, @singulars, @uncountables = [], [], []
29
- end
30
-
31
- # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
32
- # The replacement should always be a string that may include references to the matched data from the rule.
33
- def plural(rule, replacement)
34
- @plurals.insert(0, [rule, replacement])
35
- end
36
-
37
- # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
38
- # The replacement should always be a string that may include references to the matched data from the rule.
39
- def singular(rule, replacement)
40
- @singulars.insert(0, [rule, replacement])
41
- end
3
+ # in case active_support/inflector is required without the rest of active_support
4
+ require "active_support/inflector/inflections"
5
+ require "active_support/inflector/transliterate"
6
+ require "active_support/inflector/methods"
42
7
 
43
- # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
44
- # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
45
- #
46
- # Examples:
47
- # irregular 'octopus', 'octopi'
48
- # irregular 'person', 'people'
49
- def irregular(singular, plural)
50
- plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
51
- singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
52
- end
53
-
54
- # Add uncountable words that shouldn't be attempted inflected.
55
- #
56
- # Examples:
57
- # uncountable "money"
58
- # uncountable "money", "information"
59
- # uncountable %w( money information rice )
60
- def uncountable(*words)
61
- (@uncountables << words).flatten!
62
- end
63
-
64
- # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
65
- # the options are: :plurals, :singulars, :uncountables
66
- #
67
- # Examples:
68
- # clear :all
69
- # clear :plurals
70
- def clear(scope = :all)
71
- case scope
72
- when :all
73
- @plurals, @singulars, @uncountables = [], [], []
74
- else
75
- instance_variable_set "@#{scope}", []
76
- end
77
- end
78
- end
79
-
80
- extend self
81
-
82
- def inflections
83
- if block_given?
84
- yield Inflections.instance
85
- else
86
- Inflections.instance
87
- end
88
- end
89
-
90
- def pluralize(word)
91
- result = word.to_s.dup
92
-
93
- if inflections.uncountables.include?(result.downcase)
94
- result
95
- else
96
- inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
97
- result
98
- end
99
- end
100
-
101
- def singularize(word)
102
- result = word.to_s.dup
103
-
104
- if inflections.uncountables.include?(result.downcase)
105
- result
106
- else
107
- inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
108
- result
109
- end
110
- end
111
-
112
- def camelize(lower_case_and_underscored_word)
113
- lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
114
- end
115
-
116
- def titleize(word)
117
- humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize }
118
- end
119
-
120
- def underscore(camel_cased_word)
121
- camel_cased_word.to_s.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
122
- end
123
-
124
- def humanize(lower_case_and_underscored_word)
125
- lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
126
- end
127
-
128
- def demodulize(class_name_in_module)
129
- class_name_in_module.to_s.gsub(/^.*::/, '')
130
- end
131
-
132
- def tableize(class_name)
133
- pluralize(underscore(class_name))
134
- end
135
-
136
- def classify(table_name)
137
- camelize(singularize(table_name))
138
- end
139
-
140
- def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
141
- underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
142
- end
143
-
144
- def constantize(camel_cased_word)
145
- raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!" unless
146
- camel_cased_word.split("::").all? { |part| /^[A-Z]\w*$/ =~ part }
147
-
148
- camel_cased_word = "::#{camel_cased_word}" unless camel_cased_word[0, 2] == '::'
149
- Object.module_eval(camel_cased_word, __FILE__, __LINE__)
150
- end
151
-
152
- def ordinalize(number)
153
- if (11..13).include?(number.to_i % 100)
154
- "#{number}th"
155
- else
156
- case number.to_i % 10
157
- when 1: "#{number}st"
158
- when 2: "#{number}nd"
159
- when 3: "#{number}rd"
160
- else "#{number}th"
161
- end
162
- end
163
- end
164
- end
165
-
166
- require File.dirname(__FILE__) + '/inflections'
8
+ require "active_support/inflections"
9
+ require "active_support/core_ext/string/inflections"
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module IsolatedExecutionState # :nodoc:
5
+ @isolation_level = nil
6
+
7
+ Thread.attr_accessor :active_support_execution_state
8
+ Fiber.attr_accessor :active_support_execution_state
9
+
10
+ class << self
11
+ attr_reader :isolation_level, :scope
12
+
13
+ def isolation_level=(level)
14
+ return if level == @isolation_level
15
+
16
+ unless %i(thread fiber).include?(level)
17
+ raise ArgumentError, "isolation_level must be `:thread` or `:fiber`, got: `#{level.inspect}`"
18
+ end
19
+
20
+ clear if @isolation_level
21
+
22
+ @scope =
23
+ case level
24
+ when :thread; Thread
25
+ when :fiber; Fiber
26
+ end
27
+
28
+ @isolation_level = level
29
+ end
30
+
31
+ def [](key)
32
+ if state = @scope.current.active_support_execution_state
33
+ state[key]
34
+ end
35
+ end
36
+
37
+ def []=(key, value)
38
+ state = (@scope.current.active_support_execution_state ||= {})
39
+ state[key] = value
40
+ end
41
+
42
+ def key?(key)
43
+ @scope.current.active_support_execution_state&.key?(key)
44
+ end
45
+
46
+ def delete(key)
47
+ @scope.current.active_support_execution_state&.delete(key)
48
+ end
49
+
50
+ def clear
51
+ @scope.current.active_support_execution_state&.clear
52
+ end
53
+
54
+ def context
55
+ scope.current
56
+ end
57
+
58
+ def share_with(other, except: [], &block)
59
+ # Action Controller streaming spawns a new thread and copy thread locals.
60
+ # We do the same here for backward compatibility, but this is very much a hack
61
+ # and streaming should be rethought.
62
+ if state = other.active_support_execution_state
63
+ copied_state = state.dup
64
+ Array(except).each { |key| copied_state.delete(key) }
65
+ end
66
+
67
+ old_state, context.active_support_execution_state = context.active_support_execution_state, copied_state
68
+ block.call
69
+ ensure
70
+ context.active_support_execution_state = old_state
71
+ end
72
+ end
73
+
74
+ self.isolation_level = :thread
75
+ end
76
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+ require "active_support/core_ext/module/delegation"
5
+ require "json"
6
+
7
+ module ActiveSupport
8
+ # Look for and parse JSON strings that look like ISO 8601 times.
9
+ mattr_accessor :parse_json_times
10
+
11
+ module JSON
12
+ # matches YAML-formatted dates
13
+ DATE_REGEX = /\A\d{4}-\d{2}-\d{2}\z/
14
+ DATETIME_REGEX = /\A(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)\z/
15
+
16
+ class << self
17
+ # Parses a JSON string (JavaScript Object Notation) into a Ruby object.
18
+ # See http://www.json.org for more info.
19
+ #
20
+ # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
21
+ # # => {"team" => "rails", "players" => "36"}
22
+ # ActiveSupport::JSON.decode("2.39")
23
+ # # => 2.39
24
+ def decode(json, options = {})
25
+ data = ::JSON.parse(json, options)
26
+
27
+ if ActiveSupport.parse_json_times
28
+ convert_dates_from(data)
29
+ else
30
+ data
31
+ end
32
+ end
33
+ alias_method :load, :decode
34
+
35
+ # Returns the class of the error that will be raised when there is an
36
+ # error in decoding JSON. Using this method means you won't directly
37
+ # depend on the ActiveSupport's JSON implementation, in case it changes
38
+ # in the future.
39
+ #
40
+ # begin
41
+ # obj = ActiveSupport::JSON.decode(some_string)
42
+ # rescue ActiveSupport::JSON.parse_error
43
+ # Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}")
44
+ # end
45
+ def parse_error
46
+ ::JSON::ParserError
47
+ end
48
+
49
+ private
50
+ def convert_dates_from(data)
51
+ case data
52
+ when nil
53
+ nil
54
+ when DATE_REGEX
55
+ begin
56
+ Date.parse(data)
57
+ rescue ArgumentError
58
+ data
59
+ end
60
+ when DATETIME_REGEX
61
+ begin
62
+ Time.zone.parse(data)
63
+ rescue ArgumentError
64
+ data
65
+ end
66
+ when Array
67
+ data.map! { |d| convert_dates_from(d) }
68
+ when Hash
69
+ data.transform_values! do |value|
70
+ convert_dates_from(value)
71
+ end
72
+ else
73
+ data
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/json"
4
+ require "active_support/core_ext/module/delegation"
5
+
6
+ module ActiveSupport
7
+ class << self
8
+ delegate :use_standard_json_time_format, :use_standard_json_time_format=,
9
+ :time_precision, :time_precision=,
10
+ :escape_html_entities_in_json, :escape_html_entities_in_json=,
11
+ :escape_js_separators_in_json, :escape_js_separators_in_json=,
12
+ :json_encoder, :json_encoder=,
13
+ to: :'ActiveSupport::JSON::Encoding'
14
+ end
15
+
16
+ module JSON
17
+ class << self
18
+ # Dumps objects in JSON (JavaScript Object Notation).
19
+ # See http://www.json.org for more info.
20
+ #
21
+ # ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
22
+ # # => "{\"team\":\"rails\",\"players\":\"36\"}"
23
+ #
24
+ # By default, it generates JSON that is safe to include in JavaScript, as
25
+ # it escapes U+2028 (Line Separator) and U+2029 (Paragraph Separator):
26
+ #
27
+ # ActiveSupport::JSON.encode({ key: "\u2028" })
28
+ # # => "{\"key\":\"\\u2028\"}"
29
+ #
30
+ # By default, it also generates JSON that is safe to include in HTML, as
31
+ # it escapes <tt><</tt>, <tt>></tt>, and <tt>&</tt>:
32
+ #
33
+ # ActiveSupport::JSON.encode({ key: "<>&" })
34
+ # # => "{\"key\":\"\\u003c\\u003e\\u0026\"}"
35
+ #
36
+ # This behavior can be changed with the +escape_html_entities+ option, or the
37
+ # global escape_html_entities_in_json configuration option.
38
+ #
39
+ # ActiveSupport::JSON.encode({ key: "<>&" }, escape_html_entities: false)
40
+ # # => "{\"key\":\"<>&\"}"
41
+ #
42
+ # For performance reasons, you can set the +escape+ option to false,
43
+ # which will skip all escaping:
44
+ #
45
+ # ActiveSupport::JSON.encode({ key: "\u2028<>&" }, escape: false)
46
+ # # => "{\"key\":\"\u2028<>&\"}"
47
+ def encode(value, options = nil)
48
+ if options.nil? || options.empty?
49
+ Encoding.encode_without_options(value)
50
+ elsif options == { escape: false }.freeze
51
+ Encoding.encode_without_escape(value)
52
+ else
53
+ Encoding.json_encoder.new(options).encode(value)
54
+ end
55
+ end
56
+ alias_method :dump, :encode
57
+ end
58
+
59
+ module Encoding # :nodoc:
60
+ U2028 = -"\u2028".b
61
+ U2029 = -"\u2029".b
62
+
63
+ ESCAPED_CHARS = {
64
+ U2028 => '\u2028'.b,
65
+ U2029 => '\u2029'.b,
66
+ ">".b => '\u003e'.b,
67
+ "<".b => '\u003c'.b,
68
+ "&".b => '\u0026'.b,
69
+ }
70
+
71
+ HTML_ENTITIES_REGEX = Regexp.union(*(ESCAPED_CHARS.keys - [U2028, U2029]))
72
+ FULL_ESCAPE_REGEX = Regexp.union(*ESCAPED_CHARS.keys)
73
+ JS_SEPARATORS_REGEX = Regexp.union(U2028, U2029)
74
+
75
+ class JSONGemEncoder # :nodoc:
76
+ attr_reader :options
77
+
78
+ def initialize(options = nil)
79
+ @options = options || {}
80
+ end
81
+
82
+ # Encode the given object into a JSON string
83
+ def encode(value)
84
+ unless options.empty?
85
+ value = value.as_json(options.dup.freeze)
86
+ end
87
+ json = stringify(jsonify(value))
88
+
89
+ return json unless @options.fetch(:escape, true)
90
+
91
+ json.force_encoding(::Encoding::BINARY)
92
+ if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json)
93
+ if Encoding.escape_js_separators_in_json
94
+ json.gsub!(FULL_ESCAPE_REGEX, ESCAPED_CHARS)
95
+ else
96
+ json.gsub!(HTML_ENTITIES_REGEX, ESCAPED_CHARS)
97
+ end
98
+ elsif Encoding.escape_js_separators_in_json
99
+ json.gsub!(JS_SEPARATORS_REGEX, ESCAPED_CHARS)
100
+ end
101
+ json.force_encoding(::Encoding::UTF_8)
102
+ end
103
+
104
+ private
105
+ # Convert an object into a "JSON-ready" representation composed of
106
+ # primitives like Hash, Array, String, Symbol, Numeric,
107
+ # and +true+/+false+/+nil+.
108
+ # Recursively calls #as_json to the object to recursively build a
109
+ # fully JSON-ready object.
110
+ #
111
+ # This allows developers to implement #as_json without having to
112
+ # worry about what base types of objects they are allowed to return
113
+ # or having to remember to call #as_json recursively.
114
+ #
115
+ # Note: the +options+ hash passed to +object.to_json+ is only passed
116
+ # to +object.as_json+, not any of this method's recursive +#as_json+
117
+ # calls.
118
+ def jsonify(value)
119
+ case value
120
+ when String, Integer, Symbol, nil, true, false
121
+ value
122
+ when Numeric
123
+ value.as_json
124
+ when Hash
125
+ result = {}
126
+ value.each do |k, v|
127
+ k = k.to_s unless Symbol === k || String === k
128
+ result[k] = jsonify(v)
129
+ end
130
+ result
131
+ when Array
132
+ value.map { |v| jsonify(v) }
133
+ else
134
+ if defined?(::JSON::Fragment) && ::JSON::Fragment === value
135
+ value
136
+ else
137
+ jsonify value.as_json
138
+ end
139
+ end
140
+ end
141
+
142
+ # Encode a "jsonified" Ruby data structure using the JSON gem
143
+ def stringify(jsonified)
144
+ ::JSON.generate(jsonified)
145
+ end
146
+ end
147
+
148
+ # ruby/json 2.14.x yields non-String keys but doesn't let us know it's a key
149
+ if defined?(::JSON::Coder) && Gem::Version.new(::JSON::VERSION) >= Gem::Version.new("2.15.2")
150
+ class JSONGemCoderEncoder # :nodoc:
151
+ JSON_NATIVE_TYPES = [Hash, Array, Float, String, Symbol, Integer, NilClass, TrueClass, FalseClass, ::JSON::Fragment].freeze
152
+ CODER = ::JSON::Coder.new do |value, is_key|
153
+ json_value = value.as_json
154
+ # Keep compatibility by calling to_s on non-String keys
155
+ next json_value.to_s if is_key
156
+ # Handle objects returning self from as_json
157
+ if json_value.equal?(value)
158
+ next ::JSON::Fragment.new(::JSON.generate(json_value))
159
+ end
160
+ # Handle objects not returning JSON-native types from as_json
161
+ count = 5
162
+ until JSON_NATIVE_TYPES.include?(json_value.class)
163
+ raise SystemStackError if count == 0
164
+ json_value = json_value.as_json
165
+ count -= 1
166
+ end
167
+ json_value
168
+ end
169
+
170
+
171
+ def initialize(options = nil)
172
+ if options
173
+ options = options.dup
174
+ @escape = options.delete(:escape) { true }
175
+ @options = options.freeze
176
+ else
177
+ @escape = true
178
+ @options = {}.freeze
179
+ end
180
+ end
181
+
182
+ # Encode the given object into a JSON string
183
+ def encode(value)
184
+ value = value.as_json(@options) unless @options.empty?
185
+
186
+ json = CODER.dump(value)
187
+
188
+ return json unless @escape
189
+
190
+ json.force_encoding(::Encoding::BINARY)
191
+ if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json)
192
+ if Encoding.escape_js_separators_in_json
193
+ json.gsub!(FULL_ESCAPE_REGEX, ESCAPED_CHARS)
194
+ else
195
+ json.gsub!(HTML_ENTITIES_REGEX, ESCAPED_CHARS)
196
+ end
197
+ elsif Encoding.escape_js_separators_in_json
198
+ json.gsub!(JS_SEPARATORS_REGEX, ESCAPED_CHARS)
199
+ end
200
+ json.force_encoding(::Encoding::UTF_8)
201
+ end
202
+ end
203
+ end
204
+
205
+ class << self
206
+ # If true, use ISO 8601 format for dates and times. Otherwise, fall back
207
+ # to the Active Support legacy format.
208
+ attr_accessor :use_standard_json_time_format
209
+
210
+ # If true, encode >, <, & as escaped unicode sequences (e.g. > as \u003e)
211
+ # as a safety measure.
212
+ attr_accessor :escape_html_entities_in_json
213
+
214
+ # If true, encode LINE SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029)
215
+ # as escaped unicode sequences ('\u2028' and '\u2029').
216
+ # Historically these characters were not valid inside JavaScript strings
217
+ # but that changed in ECMAScript 2019. As such it's no longer a concern in
218
+ # modern browsers: https://caniuse.com/mdn-javascript_builtins_json_json_superset.
219
+ attr_accessor :escape_js_separators_in_json
220
+
221
+ # Sets the precision of encoded time values.
222
+ # Defaults to 3 (equivalent to millisecond precision)
223
+ attr_accessor :time_precision
224
+
225
+ # Sets the encoder used by \Rails to encode Ruby objects into JSON strings
226
+ # in +Object#to_json+ and +ActiveSupport::JSON.encode+.
227
+ attr_reader :json_encoder
228
+
229
+ def json_encoder=(encoder)
230
+ @json_encoder = encoder
231
+ @encoder_without_options = encoder.new
232
+ @encoder_without_escape = encoder.new(escape: false)
233
+ end
234
+
235
+ def encode_without_options(value) # :nodoc:
236
+ @encoder_without_options.encode(value)
237
+ end
238
+
239
+ def encode_without_escape(value) # :nodoc:
240
+ @encoder_without_escape.encode(value)
241
+ end
242
+ end
243
+
244
+ self.use_standard_json_time_format = true
245
+ self.escape_html_entities_in_json = true
246
+ self.escape_js_separators_in_json = true
247
+ self.json_encoder =
248
+ if defined?(JSONGemCoderEncoder)
249
+ JSONGemCoderEncoder
250
+ else
251
+ JSONGemEncoder
252
+ end
253
+ self.time_precision = 3
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/json/decoding"
4
+ require "active_support/json/encoding"
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+ require "openssl"
5
+
6
+ module ActiveSupport
7
+ # = Key Generator
8
+ #
9
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2.
10
+ # It can be used to derive a number of keys for various purposes from a given secret.
11
+ # This lets \Rails applications have a single secure secret, but avoid reusing that
12
+ # key in multiple incompatible contexts.
13
+ class KeyGenerator
14
+ class << self
15
+ def hash_digest_class=(klass)
16
+ if klass.kind_of?(Class) && klass < OpenSSL::Digest
17
+ @hash_digest_class = klass
18
+ else
19
+ raise ArgumentError, "#{klass} is expected to be an OpenSSL::Digest subclass"
20
+ end
21
+ end
22
+
23
+ def hash_digest_class
24
+ @hash_digest_class ||= OpenSSL::Digest::SHA1
25
+ end
26
+ end
27
+
28
+ def initialize(secret, options = {})
29
+ @secret = secret
30
+ # The default iterations are higher than required for our key derivation uses
31
+ # on the off chance someone uses this for password storage
32
+ @iterations = options[:iterations] || 2**16
33
+ # Also allow configuration here so people can use this to build a rotation
34
+ # scheme when switching the digest class.
35
+ @hash_digest_class = options[:hash_digest_class] || self.class.hash_digest_class
36
+ end
37
+
38
+ # Returns a derived key suitable for use. The default +key_size+ is chosen
39
+ # to be compatible with the default settings of ActiveSupport::MessageVerifier.
40
+ # i.e. <tt>OpenSSL::Digest::SHA1#block_length</tt>
41
+ def generate_key(salt, key_size = 64)
42
+ OpenSSL::PKCS5.pbkdf2_hmac(@secret, salt, @iterations, key_size, @hash_digest_class.new)
43
+ end
44
+
45
+ def inspect # :nodoc:
46
+ "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>"
47
+ end
48
+ end
49
+
50
+ # = Caching Key Generator
51
+ #
52
+ # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
53
+ # re-executing the key generation process when it's called using the same +salt+ and
54
+ # +key_size+.
55
+ class CachingKeyGenerator
56
+ def initialize(key_generator)
57
+ @key_generator = key_generator
58
+ @cache_keys = Concurrent::Map.new
59
+ end
60
+
61
+ # Returns a derived key suitable for use.
62
+ def generate_key(*args)
63
+ @cache_keys[args.join("|")] ||= @key_generator.generate_key(*args)
64
+ end
65
+ end
66
+ end