interactor-validation 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/README.md +176 -85
- data/benchmark/validation_benchmark.rb +227 -0
- data/lib/interactor/validation/configuration.rb +9 -4
- data/lib/interactor/validation/error_codes.rb +51 -0
- data/lib/interactor/validation/validates.rb +460 -44
- data/lib/interactor/validation/version.rb +1 -1
- data/lib/interactor/validation.rb +1 -0
- metadata +3 -1
|
@@ -4,15 +4,20 @@ module Interactor
|
|
|
4
4
|
module Validation
|
|
5
5
|
# Configuration class for interactor validation behavior
|
|
6
6
|
class Configuration
|
|
7
|
-
attr_accessor :halt_on_first_error
|
|
7
|
+
attr_accessor :halt_on_first_error, :regex_timeout, :max_array_size,
|
|
8
|
+
:enable_instrumentation, :cache_regex_patterns
|
|
8
9
|
attr_reader :error_mode
|
|
9
10
|
|
|
10
11
|
# Available error modes:
|
|
11
|
-
# - :default - Uses ActiveModel-style human-readable messages
|
|
12
|
-
# - :code - Returns structured error codes (e.g., USERNAME_IS_REQUIRED)
|
|
12
|
+
# - :default - Uses ActiveModel-style human-readable messages [DEFAULT]
|
|
13
|
+
# - :code - Returns structured error codes (e.g., USERNAME_IS_REQUIRED)
|
|
13
14
|
def initialize
|
|
14
|
-
@error_mode = :
|
|
15
|
+
@error_mode = :default
|
|
15
16
|
@halt_on_first_error = false
|
|
17
|
+
@regex_timeout = 0.1 # 100ms timeout for regex matching (ReDoS protection)
|
|
18
|
+
@max_array_size = 1000 # Maximum array size for nested validation (memory protection)
|
|
19
|
+
@enable_instrumentation = false # ActiveSupport::Notifications instrumentation
|
|
20
|
+
@cache_regex_patterns = true # Cache compiled regex patterns for performance
|
|
16
21
|
end
|
|
17
22
|
|
|
18
23
|
def error_mode=(mode)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Interactor
|
|
4
|
+
module Validation
|
|
5
|
+
# Error code constants for structured error messages
|
|
6
|
+
module ErrorCodes
|
|
7
|
+
REQUIRED = "IS_REQUIRED"
|
|
8
|
+
MUST_BE_BOOLEAN = "MUST_BE_BOOLEAN"
|
|
9
|
+
INVALID_FORMAT = "INVALID_FORMAT"
|
|
10
|
+
NOT_IN_ALLOWED_VALUES = "NOT_IN_ALLOWED_VALUES"
|
|
11
|
+
MUST_BE_A_NUMBER = "MUST_BE_A_NUMBER"
|
|
12
|
+
INVALID_TYPE = "INVALID_TYPE"
|
|
13
|
+
REGEX_TIMEOUT = "REGEX_TIMEOUT"
|
|
14
|
+
ARRAY_TOO_LARGE = "ARRAY_TOO_LARGE"
|
|
15
|
+
|
|
16
|
+
# Generate length error codes
|
|
17
|
+
def self.exceeds_max_length(count)
|
|
18
|
+
"EXCEEDS_MAX_LENGTH_#{count}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.below_min_length(count)
|
|
22
|
+
"BELOW_MIN_LENGTH_#{count}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.must_be_length(count)
|
|
26
|
+
"MUST_BE_LENGTH_#{count}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Generate numeric comparison error codes
|
|
30
|
+
def self.must_be_greater_than(count)
|
|
31
|
+
"MUST_BE_GREATER_THAN_#{count}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.must_be_at_least(count)
|
|
35
|
+
"MUST_BE_AT_LEAST_#{count}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.must_be_less_than(count)
|
|
39
|
+
"MUST_BE_LESS_THAN_#{count}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.must_be_at_most(count)
|
|
43
|
+
"MUST_BE_AT_MOST_#{count}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.must_be_equal_to(count)
|
|
47
|
+
"MUST_BE_EQUAL_TO_#{count}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|