active_storage_validations 1.3.0 → 1.3.4

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.

Potentially problematic release.


This version of active_storage_validations might be problematic. Click here for more details.

Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -8
  3. data/config/locales/da.yml +0 -1
  4. data/config/locales/de.yml +0 -1
  5. data/config/locales/en.yml +0 -1
  6. data/config/locales/es.yml +0 -1
  7. data/config/locales/fr.yml +0 -1
  8. data/config/locales/it.yml +0 -1
  9. data/config/locales/ja.yml +0 -1
  10. data/config/locales/nl.yml +0 -1
  11. data/config/locales/pl.yml +0 -1
  12. data/config/locales/pt-BR.yml +0 -1
  13. data/config/locales/ru.yml +0 -1
  14. data/config/locales/sv.yml +0 -1
  15. data/config/locales/tr.yml +0 -1
  16. data/config/locales/uk.yml +0 -1
  17. data/config/locales/vi.yml +0 -1
  18. data/config/locales/zh-CN.yml +0 -1
  19. data/lib/active_storage_validations/aspect_ratio_validator.rb +61 -46
  20. data/lib/active_storage_validations/attached_validator.rb +6 -6
  21. data/lib/active_storage_validations/base_size_validator.rb +8 -7
  22. data/lib/active_storage_validations/content_type_spoof_detector.rb +13 -49
  23. data/lib/active_storage_validations/content_type_validator.rb +112 -54
  24. data/lib/active_storage_validations/dimension_validator.rb +11 -10
  25. data/lib/active_storage_validations/limit_validator.rb +9 -8
  26. data/lib/active_storage_validations/marcel_extensor.rb +2 -0
  27. data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +14 -14
  28. data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +12 -12
  29. data/lib/active_storage_validations/matchers/base_size_validator_matcher.rb +14 -14
  30. data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +40 -40
  31. data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +14 -14
  32. data/lib/active_storage_validations/matchers/limit_validator_matcher.rb +14 -14
  33. data/lib/active_storage_validations/matchers/processable_image_validator_matcher.rb +14 -14
  34. data/lib/active_storage_validations/matchers/{concerns/active_storageable.rb → shared/asv_active_storageable.rb} +4 -2
  35. data/lib/active_storage_validations/matchers/{concerns/allow_blankable.rb → shared/asv_allow_blankable.rb} +4 -2
  36. data/lib/active_storage_validations/matchers/{concerns/attachable.rb → shared/asv_attachable.rb} +7 -1
  37. data/lib/active_storage_validations/matchers/{concerns/contextable.rb → shared/asv_contextable.rb} +4 -2
  38. data/lib/active_storage_validations/matchers/{concerns/messageable.rb → shared/asv_messageable.rb} +4 -2
  39. data/lib/active_storage_validations/matchers/{concerns/rspecable.rb → shared/asv_rspecable.rb} +4 -2
  40. data/lib/active_storage_validations/matchers/{concerns/validatable.rb → shared/asv_validatable.rb} +4 -2
  41. data/lib/active_storage_validations/metadata.rb +18 -19
  42. data/lib/active_storage_validations/processable_image_validator.rb +8 -8
  43. data/lib/active_storage_validations/{concerns/active_storageable.rb → shared/asv_active_storageable.rb} +4 -2
  44. data/lib/active_storage_validations/shared/asv_attachable.rb +136 -0
  45. data/lib/active_storage_validations/{concerns/errorable.rb → shared/asv_errorable.rb} +5 -2
  46. data/lib/active_storage_validations/{concerns/loggable.rb → shared/asv_loggable.rb} +3 -1
  47. data/lib/active_storage_validations/shared/asv_optionable.rb +29 -0
  48. data/lib/active_storage_validations/{concerns/symbolizable.rb → shared/asv_symbolizable.rb} +3 -1
  49. data/lib/active_storage_validations/size_validator.rb +2 -2
  50. data/lib/active_storage_validations/total_size_validator.rb +2 -2
  51. data/lib/active_storage_validations/version.rb +1 -1
  52. data/lib/active_storage_validations.rb +0 -1
  53. metadata +65 -25
  54. data/lib/active_storage_validations/concerns/metadatable.rb +0 -31
  55. data/lib/active_storage_validations/option_proc_unfolding.rb +0 -16
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concerns/active_storageable'
4
- require_relative 'concerns/allow_blankable'
5
- require_relative 'concerns/attachable'
6
- require_relative 'concerns/contextable'
7
- require_relative 'concerns/messageable'
8
- require_relative 'concerns/rspecable'
9
- require_relative 'concerns/validatable'
3
+ require_relative 'shared/asv_active_storageable'
4
+ require_relative 'shared/asv_allow_blankable'
5
+ require_relative 'shared/asv_attachable'
6
+ require_relative 'shared/asv_contextable'
7
+ require_relative 'shared/asv_messageable'
8
+ require_relative 'shared/asv_rspecable'
9
+ require_relative 'shared/asv_validatable'
10
10
 
11
11
  module ActiveStorageValidations
12
12
  module Matchers
@@ -15,13 +15,13 @@ module ActiveStorageValidations
15
15
  end
16
16
 
17
17
  class LimitValidatorMatcher
18
- include ActiveStorageable
19
- include AllowBlankable
20
- include Attachable
21
- include Contextable
22
- include Messageable
23
- include Rspecable
24
- include Validatable
18
+ include ASVActiveStorageable
19
+ include ASVAllowBlankable
20
+ include ASVAttachable
21
+ include ASVContextable
22
+ include ASVMessageable
23
+ include ASVRspecable
24
+ include ASVValidatable
25
25
 
26
26
  def initialize(attribute_name)
27
27
  initialize_allow_blankable
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concerns/active_storageable.rb'
4
- require_relative 'concerns/allow_blankable.rb'
5
- require_relative 'concerns/attachable.rb'
6
- require_relative 'concerns/contextable.rb'
7
- require_relative 'concerns/messageable.rb'
8
- require_relative 'concerns/rspecable.rb'
9
- require_relative 'concerns/validatable.rb'
3
+ require_relative 'shared/asv_active_storageable'
4
+ require_relative 'shared/asv_allow_blankable'
5
+ require_relative 'shared/asv_attachable'
6
+ require_relative 'shared/asv_contextable'
7
+ require_relative 'shared/asv_messageable'
8
+ require_relative 'shared/asv_rspecable'
9
+ require_relative 'shared/asv_validatable'
10
10
 
11
11
  module ActiveStorageValidations
12
12
  module Matchers
@@ -15,13 +15,13 @@ module ActiveStorageValidations
15
15
  end
16
16
 
17
17
  class ProcessableImageValidatorMatcher
18
- include ActiveStorageable
19
- include AllowBlankable
20
- include Attachable
21
- include Contextable
22
- include Messageable
23
- include Rspecable
24
- include Validatable
18
+ include ASVActiveStorageable
19
+ include ASVAllowBlankable
20
+ include ASVAttachable
21
+ include ASVContextable
22
+ include ASVMessageable
23
+ include ASVRspecable
24
+ include ASVValidatable
25
25
 
26
26
  def initialize(attribute_name)
27
27
  initialize_allow_blankable
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module ActiveStorageable
7
+ module ASVActiveStorageable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  private
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module AllowBlankable
7
+ module ASVAllowBlankable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  def initialize_allow_blankable
@@ -1,6 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
1
5
  module ActiveStorageValidations
2
6
  module Matchers
3
- module Attachable
7
+ module ASVAttachable
8
+ extend ActiveSupport::Concern
9
+
4
10
  private
5
11
 
6
12
  def attach_file(file = dummy_file)
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module Contextable
7
+ module ASVContextable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  def initialize_contextable
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module Messageable
7
+ module ASVMessageable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  def initialize_messageable
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module Rspecable
7
+ module ASVRspecable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  def initialize_rspecable
@@ -1,8 +1,10 @@
1
- require "active_support/concern"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
2
4
 
3
5
  module ActiveStorageValidations
4
6
  module Matchers
5
- module Validatable
7
+ module ASVValidatable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  private
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concerns/loggable'
3
+ require_relative 'shared/asv_loggable'
4
4
 
5
5
  module ActiveStorageValidations
6
6
  class Metadata
7
- include Loggable
7
+ include ASVLoggable
8
8
 
9
9
  class InvalidImageError < StandardError; end
10
10
 
11
- attr_reader :file
11
+ attr_reader :attachable
12
12
 
13
13
  DEFAULT_IMAGE_PROCESSOR = :mini_magick.freeze
14
14
 
15
- def initialize(file)
15
+ def initialize(attachable)
16
16
  require_image_processor
17
- @file = file
17
+ @attachable = attachable
18
18
  end
19
19
 
20
20
  def valid?
@@ -64,14 +64,9 @@ module ActiveStorageValidations
64
64
  end
65
65
 
66
66
  def read_image
67
- is_string = file.is_a?(String)
68
- if is_string || file.is_a?(ActiveStorage::Blob)
69
- blob =
70
- if is_string
71
- ActiveStorage::Blob.find_signed!(file)
72
- else
73
- file
74
- end
67
+ is_string = attachable.is_a?(String)
68
+ if is_string || attachable.is_a?(ActiveStorage::Blob)
69
+ blob = is_string ? ActiveStorage::Blob.find_signed!(attachable) : attachable
75
70
 
76
71
  tempfile = Tempfile.new(["ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter])
77
72
  tempfile.binmode
@@ -107,9 +102,9 @@ module ActiveStorageValidations
107
102
  begin
108
103
  Vips::Image.new_from_file(path)
109
104
  rescue exception_class
110
- # We handle cases where an error is raised when reading the file
105
+ # We handle cases where an error is raised when reading the attachable
111
106
  # because Vips can throw errors rather than returning false
112
- # We stumble upon this issue while reading 0 byte size file
107
+ # We stumble upon this issue while reading 0 byte size attachable
113
108
  # https://github.com/janko/image_processing/issues/97
114
109
  false
115
110
  end
@@ -156,13 +151,13 @@ module ActiveStorageValidations
156
151
  end
157
152
 
158
153
  def read_file_path
159
- case file
154
+ case attachable
160
155
  when ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile
161
- file.path
156
+ attachable.path
162
157
  when Hash
163
- io = file.fetch(:io)
158
+ io = attachable.fetch(:io)
164
159
  if io.is_a?(StringIO)
165
- tempfile = Tempfile.new([File.basename(file[:filename], '.*'), File.extname(file[:filename])])
160
+ tempfile = Tempfile.new([File.basename(attachable[:filename], '.*'), File.extname(attachable[:filename])])
166
161
  tempfile.binmode
167
162
  IO.copy_stream(io, tempfile)
168
163
  io.rewind
@@ -172,6 +167,10 @@ module ActiveStorageValidations
172
167
  else
173
168
  File.open(io).path
174
169
  end
170
+ when File
171
+ attachable.path
172
+ when Pathname
173
+ attachable.to_s
175
174
  else
176
175
  raise "Something wrong with params."
177
176
  end
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concerns/active_storageable.rb'
4
- require_relative 'concerns/errorable.rb'
5
- require_relative 'concerns/metadatable.rb'
6
- require_relative 'concerns/symbolizable.rb'
3
+ require_relative 'shared/asv_active_storageable'
4
+ require_relative 'shared/asv_attachable'
5
+ require_relative 'shared/asv_errorable'
6
+ require_relative 'shared/asv_symbolizable'
7
7
 
8
8
  module ActiveStorageValidations
9
9
  class ProcessableImageValidator < ActiveModel::EachValidator # :nodoc
10
- include ActiveStorageable
11
- include Errorable
12
- include Metadatable
13
- include Symbolizable
10
+ include ASVActiveStorageable
11
+ include ASVAttachable
12
+ include ASVErrorable
13
+ include ASVSymbolizable
14
14
 
15
15
  ERROR_TYPES = %i[
16
16
  image_not_processable
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveStorageValidations
2
- # ActiveStorageValidations::ActiveStorageable
4
+ # ActiveStorageValidations::ASVActiveStorageable
3
5
  #
4
6
  # Validator helper methods to make our code more explicit.
5
- module ActiveStorageable
7
+ module ASVActiveStorageable
6
8
  extend ActiveSupport::Concern
7
9
 
8
10
  private
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../metadata"
4
+
5
+ module ActiveStorageValidations
6
+ # ActiveStorageValidations::ASVAttachable
7
+ #
8
+ # Validator methods for analyzing attachable.
9
+ #
10
+ # An attachable is a file representation such as ActiveStorage::Blob,
11
+ # ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile, Hash, String,
12
+ # File or Pathname
13
+ module ASVAttachable
14
+ extend ActiveSupport::Concern
15
+
16
+ private
17
+
18
+ # Loop through the newly submitted attachables to validate them. Using
19
+ # attachables is the only way to get the attached file io that is necessary
20
+ # to perform file analyses.
21
+ def validate_changed_files_from_metadata(record, attribute)
22
+ attachables_from_changes(record, attribute).each do |attachable|
23
+ is_valid?(record, attribute, attachable, Metadata.new(attachable).metadata)
24
+ end
25
+ end
26
+
27
+ # Retrieve an array of newly submitted attachables. Some file could be passed
28
+ # several times, we just need to perform the analysis once on the file,
29
+ # therefore the use of #uniq.
30
+ def attachables_from_changes(record, attribute)
31
+ changes = record.attachment_changes[attribute.to_s]
32
+ return [] if changes.blank?
33
+
34
+ Array.wrap(
35
+ changes.is_a?(ActiveStorage::Attached::Changes::CreateMany) ? changes.attachables : changes.attachable
36
+ ).uniq
37
+ end
38
+
39
+ # Retrieve the full declared content_type from attachable.
40
+ def full_attachable_content_type(attachable)
41
+ case attachable
42
+ when ActiveStorage::Blob
43
+ attachable.content_type
44
+ when ActionDispatch::Http::UploadedFile
45
+ attachable.content_type
46
+ when Rack::Test::UploadedFile
47
+ attachable.content_type
48
+ when String
49
+ blob = ActiveStorage::Blob.find_signed!(attachable)
50
+ blob.content_type
51
+ when Hash
52
+ attachable[:content_type]
53
+ when File
54
+ supports_file_attachment? ? marcel_content_type_from_filename(attachable) : raise_rails_like_error(attachable)
55
+ when Pathname
56
+ supports_pathname_attachment? ? marcel_content_type_from_filename(attachable) : raise_rails_like_error(attachable)
57
+ else
58
+ raise_rails_like_error(attachable)
59
+ end
60
+ end
61
+
62
+ # Retrieve the declared content_type from attachable without potential mime
63
+ # type parameters (e.g. 'application/x-rar-compressed;version=5')
64
+ def attachable_content_type(attachable)
65
+ full_attachable_content_type(attachable) && full_attachable_content_type(attachable).downcase.split(/[;,\s]/, 2).first
66
+ end
67
+
68
+ # Retrieve the io from attachable.
69
+ def attachable_io(attachable)
70
+ case attachable
71
+ when ActiveStorage::Blob
72
+ attachable.download
73
+ when ActionDispatch::Http::UploadedFile
74
+ attachable.read
75
+ when Rack::Test::UploadedFile
76
+ attachable.read
77
+ when String
78
+ blob = ActiveStorage::Blob.find_signed!(attachable)
79
+ blob.download
80
+ when Hash
81
+ attachable[:io].read
82
+ when File
83
+ supports_file_attachment? ? attachable : raise_rails_like_error(attachable)
84
+ when Pathname
85
+ supports_pathname_attachment? ? attachable.read : raise_rails_like_error(attachable)
86
+ else
87
+ raise_rails_like_error(attachable)
88
+ end
89
+ end
90
+
91
+ # Retrieve the declared filename from attachable.
92
+ def attachable_filename(attachable)
93
+ case attachable
94
+ when ActiveStorage::Blob
95
+ attachable.filename
96
+ when ActionDispatch::Http::UploadedFile
97
+ attachable.original_filename
98
+ when Rack::Test::UploadedFile
99
+ attachable.original_filename
100
+ when String
101
+ blob = ActiveStorage::Blob.find_signed!(attachable)
102
+ blob.filename
103
+ when Hash
104
+ attachable[:filename]
105
+ when File
106
+ supports_file_attachment? ? File.basename(attachable) : raise_rails_like_error(attachable)
107
+ when Pathname
108
+ supports_pathname_attachment? ? File.basename(attachable) : raise_rails_like_error(attachable)
109
+ else
110
+ raise_rails_like_error(attachable)
111
+ end
112
+ end
113
+
114
+ # Raise the same Rails error for not-implemented file representations.
115
+ def raise_rails_like_error(attachable)
116
+ raise(
117
+ ArgumentError,
118
+ "Could not find or build blob: expected attachable, " \
119
+ "got #{attachable.inspect}"
120
+ )
121
+ end
122
+
123
+ # Check if the current Rails version supports File or Pathname attachment
124
+ #
125
+ # https://github.com/rails/rails/blob/7-1-stable/activestorage/CHANGELOG.md#rails-710rc1-september-27-2023
126
+ def supports_file_attachment?
127
+ Rails.gem_version >= Gem::Version.new('7.1.0.rc1')
128
+ end
129
+ alias :supports_pathname_attachment? :supports_file_attachment?
130
+
131
+ # Retrieve the content_type from the file name only
132
+ def marcel_content_type_from_filename(attachable)
133
+ Marcel::MimeType.for(name: attachable_filename(attachable).to_s)
134
+ end
135
+ end
136
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveStorageValidations
2
- module Errorable
4
+ module ASVErrorable
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  def initialize_error_options(options, file = nil)
@@ -30,8 +32,9 @@ module ActiveStorageValidations
30
32
 
31
33
  case file
32
34
  when ActiveStorage::Attached, ActiveStorage::Attachment then file.blob&.filename&.to_s
35
+ when ActiveStorage::Blob then file.filename
33
36
  when Hash then file[:filename]
34
- end
37
+ end.to_s
35
38
  end
36
39
  end
37
40
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveStorageValidations
2
- module Loggable
4
+ module ASVLoggable
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  def logger
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorageValidations
4
+ # ActiveStorageValidations::ASVOptionable
5
+ #
6
+ # Helper method to flatten the validator options.
7
+ module ASVOptionable
8
+ extend ActiveSupport::Concern
9
+
10
+ private
11
+
12
+ def set_flat_options(record)
13
+ flatten_options(record, self.options)
14
+ end
15
+
16
+ def flatten_options(record, options, available_checks = self.class::AVAILABLE_CHECKS)
17
+ case options
18
+ when Hash
19
+ options.merge(options) do |key, value|
20
+ available_checks&.exclude?(key) ? {} : flatten_options(record, value, nil)
21
+ end
22
+ when Array
23
+ options.map { |option| flatten_options(record, option, available_checks) }
24
+ else
25
+ options.is_a?(Proc) ? options.call(record) : options
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveStorageValidations
2
- module Symbolizable
4
+ module ASVSymbolizable
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  class_methods do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base_size_validator.rb'
3
+ require_relative 'base_size_validator'
4
4
 
5
5
  module ActiveStorageValidations
6
6
  class SizeValidator < BaseSizeValidator
@@ -15,7 +15,7 @@ module ActiveStorageValidations
15
15
  def validate_each(record, attribute, _value)
16
16
  return if no_attachments?(record, attribute)
17
17
 
18
- flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
18
+ flat_options = set_flat_options(record)
19
19
 
20
20
  attached_files(record, attribute).each do |file|
21
21
  next if is_valid?(file.blob.byte_size, flat_options)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'base_size_validator.rb'
3
+ require_relative 'base_size_validator'
4
4
 
5
5
  module ActiveStorageValidations
6
6
  class TotalSizeValidator < BaseSizeValidator
@@ -18,7 +18,7 @@ module ActiveStorageValidations
18
18
  return if no_attachments?(record, attribute)
19
19
 
20
20
  total_file_size = attached_files(record, attribute).sum { |file| file.blob.byte_size }
21
- flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
21
+ flat_options = set_flat_options(record)
22
22
 
23
23
  return if is_valid?(total_file_size, flat_options)
24
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageValidations
4
- VERSION = '1.3.0'
4
+ VERSION = '1.3.4'
5
5
  end
@@ -5,7 +5,6 @@ require 'active_support/concern'
5
5
 
6
6
  require 'active_storage_validations/railtie'
7
7
  require 'active_storage_validations/engine'
8
- require 'active_storage_validations/option_proc_unfolding'
9
8
  require 'active_storage_validations/attached_validator'
10
9
  require 'active_storage_validations/content_type_validator'
11
10
  require 'active_storage_validations/limit_validator'