reslib 1.0.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.
- package/README.md +298 -0
- package/build/auth/index.d.ts +2034 -0
- package/build/auth/index.js +5 -0
- package/build/auth/types.d.ts +465 -0
- package/build/auth/types.js +1 -0
- package/build/countries/countries.d.ts +1454 -0
- package/build/countries/countries.js +1 -0
- package/build/countries/index.d.ts +159 -0
- package/build/countries/index.js +5 -0
- package/build/countries/types.d.ts +65 -0
- package/build/countries/types.js +1 -0
- package/build/currency/currencies.d.ts +8 -0
- package/build/currency/currencies.js +1 -0
- package/build/currency/index.d.ts +51 -0
- package/build/currency/index.js +5 -0
- package/build/currency/session.d.ts +23 -0
- package/build/currency/session.js +5 -0
- package/build/currency/types.d.ts +1039 -0
- package/build/currency/types.js +1 -0
- package/build/currency/utils.d.ts +25 -0
- package/build/currency/utils.js +1 -0
- package/build/i18n/index.d.ts +640 -0
- package/build/i18n/index.js +5 -0
- package/build/inputFormatter/index.d.ts +396 -0
- package/build/inputFormatter/index.js +5 -0
- package/build/inputFormatter/types.d.ts +544 -0
- package/build/inputFormatter/types.js +1 -0
- package/build/logger/index.d.ts +235 -0
- package/build/logger/index.js +5 -0
- package/build/observable/index.d.ts +329 -0
- package/build/observable/index.js +1 -0
- package/build/platform/index.d.ts +32 -0
- package/build/platform/index.js +1 -0
- package/build/resources/ResourcePaginationHelper.d.ts +537 -0
- package/build/resources/ResourcePaginationHelper.js +2 -0
- package/build/resources/decorators/create.decorator.d.ts +20 -0
- package/build/resources/decorators/create.decorator.js +1 -0
- package/build/resources/decorators/index.d.ts +41 -0
- package/build/resources/decorators/index.js +1 -0
- package/build/resources/fields/index.d.ts +33 -0
- package/build/resources/fields/index.js +1 -0
- package/build/resources/filters.d.ts +62 -0
- package/build/resources/filters.js +1 -0
- package/build/resources/index.d.ts +854 -0
- package/build/resources/index.js +6 -0
- package/build/resources/types/filters.d.ts +508 -0
- package/build/resources/types/filters.js +1 -0
- package/build/resources/types/index.d.ts +4138 -0
- package/build/resources/types/index.js +1 -0
- package/build/session/index.d.ts +1474 -0
- package/build/session/index.js +1 -0
- package/build/translations/auth.en.d.ts +3 -0
- package/build/translations/auth.en.js +1 -0
- package/build/translations/countries.en.d.ts +6 -0
- package/build/translations/countries.en.js +1 -0
- package/build/translations/currencies.en.d.ts +5 -0
- package/build/translations/currencies.en.js +1 -0
- package/build/translations/date.en.d.ts +19 -0
- package/build/translations/date.en.js +1 -0
- package/build/translations/index.d.ts +1583 -0
- package/build/translations/index.js +5 -0
- package/build/translations/resources.en.d.ts +6 -0
- package/build/translations/resources.en.js +1 -0
- package/build/translations/validator.en.d.ts +104 -0
- package/build/translations/validator.en.js +5 -0
- package/build/types/date.d.ts +44 -0
- package/build/types/date.js +1 -0
- package/build/types/dictionary.d.ts +29 -0
- package/build/types/dictionary.js +1 -0
- package/build/types/i18n.d.ts +121 -0
- package/build/types/i18n.js +1 -0
- package/build/types/index.d.ts +145 -0
- package/build/types/index.js +1 -0
- package/build/utils/areEquals.d.ts +19 -0
- package/build/utils/areEquals.js +1 -0
- package/build/utils/date/dateHelper.d.ts +371 -0
- package/build/utils/date/dateHelper.js +5 -0
- package/build/utils/date/index.d.ts +212 -0
- package/build/utils/date/index.js +5 -0
- package/build/utils/date/isDateObj.d.ts +14 -0
- package/build/utils/date/isDateObj.js +1 -0
- package/build/utils/debounce.d.ts +52 -0
- package/build/utils/debounce.js +1 -0
- package/build/utils/defaultArray.d.ts +18 -0
- package/build/utils/defaultArray.js +1 -0
- package/build/utils/defaultBool.d.ts +14 -0
- package/build/utils/defaultBool.js +1 -0
- package/build/utils/defaultStr.d.ts +17 -0
- package/build/utils/defaultStr.js +1 -0
- package/build/utils/defaultVal.d.ts +18 -0
- package/build/utils/defaultVal.js +1 -0
- package/build/utils/dom/index.d.ts +65 -0
- package/build/utils/dom/index.js +1 -0
- package/build/utils/dom/isDOMElement.d.ts +11 -0
- package/build/utils/dom/isDOMElement.js +1 -0
- package/build/utils/file/index.d.ts +26 -0
- package/build/utils/file/index.js +1 -0
- package/build/utils/global.d.ts +53 -0
- package/build/utils/global.js +1 -0
- package/build/utils/image.d.ts +56 -0
- package/build/utils/image.js +1 -0
- package/build/utils/index.d.ts +39 -0
- package/build/utils/index.js +6 -0
- package/build/utils/interpolate.d.ts +105 -0
- package/build/utils/interpolate.js +1 -0
- package/build/utils/isEmail.d.ts +57 -0
- package/build/utils/isEmail.js +1 -0
- package/build/utils/isEmpty.d.ts +18 -0
- package/build/utils/isEmpty.js +1 -0
- package/build/utils/isNonNullString.d.ts +17 -0
- package/build/utils/isNonNullString.js +1 -0
- package/build/utils/isNullable.d.ts +7 -0
- package/build/utils/isNullable.js +1 -0
- package/build/utils/isNumber.d.ts +36 -0
- package/build/utils/isNumber.js +1 -0
- package/build/utils/isPrimitive.d.ts +16 -0
- package/build/utils/isPrimitive.js +1 -0
- package/build/utils/isPromise.d.ts +14 -0
- package/build/utils/isPromise.js +1 -0
- package/build/utils/isRegex.d.ts +15 -0
- package/build/utils/isRegex.js +1 -0
- package/build/utils/isTime.d.ts +18 -0
- package/build/utils/isTime.js +1 -0
- package/build/utils/json.d.ts +224 -0
- package/build/utils/json.js +1 -0
- package/build/utils/numbers.d.ts +148 -0
- package/build/utils/numbers.js +5 -0
- package/build/utils/object.d.ts +567 -0
- package/build/utils/object.js +1 -0
- package/build/utils/sort.d.ts +67 -0
- package/build/utils/sort.js +1 -0
- package/build/utils/string.d.ts +165 -0
- package/build/utils/string.js +1 -0
- package/build/utils/stringify.d.ts +23 -0
- package/build/utils/stringify.js +1 -0
- package/build/utils/uniqid.d.ts +18 -0
- package/build/utils/uniqid.js +1 -0
- package/build/utils/uri/index.d.ts +333 -0
- package/build/utils/uri/index.js +2 -0
- package/build/validator/index.d.ts +4 -0
- package/build/validator/index.js +6 -0
- package/build/validator/rules/array.d.ts +848 -0
- package/build/validator/rules/array.js +5 -0
- package/build/validator/rules/boolean.d.ts +87 -0
- package/build/validator/rules/boolean.js +5 -0
- package/build/validator/rules/date.d.ts +551 -0
- package/build/validator/rules/date.js +5 -0
- package/build/validator/rules/default.d.ts +367 -0
- package/build/validator/rules/default.js +5 -0
- package/build/validator/rules/enum.d.ts +155 -0
- package/build/validator/rules/enum.js +5 -0
- package/build/validator/rules/file.d.ts +356 -0
- package/build/validator/rules/file.js +5 -0
- package/build/validator/rules/format.d.ts +2825 -0
- package/build/validator/rules/format.js +6 -0
- package/build/validator/rules/index.d.ts +16 -0
- package/build/validator/rules/index.js +6 -0
- package/build/validator/rules/multiRules.d.ts +475 -0
- package/build/validator/rules/multiRules.js +5 -0
- package/build/validator/rules/numeric.d.ts +1135 -0
- package/build/validator/rules/numeric.js +5 -0
- package/build/validator/rules/string.d.ts +504 -0
- package/build/validator/rules/string.js +5 -0
- package/build/validator/rules/target.d.ts +137 -0
- package/build/validator/rules/target.js +5 -0
- package/build/validator/rules/utils.d.ts +1 -0
- package/build/validator/rules/utils.js +1 -0
- package/build/validator/rulesMarkers.d.ts +11 -0
- package/build/validator/rulesMarkers.js +1 -0
- package/build/validator/types.d.ts +2906 -0
- package/build/validator/types.js +1 -0
- package/build/validator/validator.d.ts +3692 -0
- package/build/validator/validator.js +5 -0
- package/lib/cjs/auth.js +1 -0
- package/lib/cjs/countries.js +1 -0
- package/lib/cjs/currency.js +1 -0
- package/lib/cjs/i18n.js +1 -0
- package/lib/cjs/inputFormatter.js +1 -0
- package/lib/cjs/logger.js +1 -0
- package/lib/cjs/observable.js +1 -0
- package/lib/cjs/platform.js +1 -0
- package/lib/cjs/resources.js +1 -0
- package/lib/cjs/session.js +1 -0
- package/lib/cjs/types.js +1 -0
- package/lib/cjs/utils.js +1 -0
- package/lib/cjs/validator.js +1 -0
- package/lib/esm/auth.mjs +1 -0
- package/lib/esm/countries.mjs +1 -0
- package/lib/esm/currency.mjs +1 -0
- package/lib/esm/i18n.mjs +1 -0
- package/lib/esm/inputFormatter.mjs +1 -0
- package/lib/esm/logger.mjs +1 -0
- package/lib/esm/observable.mjs +1 -0
- package/lib/esm/platform.mjs +1 -0
- package/lib/esm/resources.mjs +1 -0
- package/lib/esm/session.mjs +1 -0
- package/lib/esm/types.mjs +1 -0
- package/lib/esm/utils.mjs +1 -0
- package/lib/esm/validator.mjs +1 -0
- package/package.json +244 -0
|
@@ -0,0 +1,2825 @@
|
|
|
1
|
+
import { CountryCode } from '../../countries/types';
|
|
2
|
+
import { IsEmailOptions } from '../../utils/isEmail';
|
|
3
|
+
import { IsUrlOptions } from '../../utils/uri';
|
|
4
|
+
/**
|
|
5
|
+
* @summary IsEmail Decorator
|
|
6
|
+
*
|
|
7
|
+
* @description Validates that a property value is a properly formatted email address according to RFC 5322 standards.
|
|
8
|
+
* This decorator performs comprehensive email validation including:
|
|
9
|
+
*
|
|
10
|
+
* - **Local part validation**: Checks the part before @ for valid characters, proper dot placement, and quoted strings
|
|
11
|
+
* - **Domain validation**: Validates domain structure, TLD requirements, and supports international domains (IDN)
|
|
12
|
+
* - **IP address domains**: Supports [IPv4] and [IPv6] bracketed formats
|
|
13
|
+
* - **Length constraints**: Configurable limits for total length, local part, domain, and domain labels
|
|
14
|
+
* - **Edge case handling**: Consecutive dots, leading/trailing dots, escaped characters in quoted strings
|
|
15
|
+
*
|
|
16
|
+
* The validation is based on RFC 5321 (SMTP) and RFC 5322 (Internet Message Format) specifications,
|
|
17
|
+
* ensuring compatibility with modern email systems while being strict enough to catch common typos.
|
|
18
|
+
*
|
|
19
|
+
* #### Configuration Options
|
|
20
|
+
*
|
|
21
|
+
* The decorator accepts an optional configuration object to customize validation constraints:
|
|
22
|
+
*
|
|
23
|
+
* - `maxTotalLength`: Maximum total email length (default: 320 characters, per RFC 5321)
|
|
24
|
+
* - `maxLocalPartLength`: Maximum local part length (default: 64 characters, per RFC 5321)
|
|
25
|
+
* - `maxDomainLength`: Maximum domain length (default: 255 characters, per RFC 1035)
|
|
26
|
+
* - `maxDomainLabelLength`: Maximum individual domain label length (default: 63 characters, per RFC 1035)
|
|
27
|
+
*
|
|
28
|
+
* #### Usage Examples
|
|
29
|
+
*
|
|
30
|
+
* **Basic usage (default settings):**
|
|
31
|
+
* ```typescript
|
|
32
|
+
* class User {
|
|
33
|
+
* @IsRequired()
|
|
34
|
+
* @IsEmail()
|
|
35
|
+
* email: string;
|
|
36
|
+
*
|
|
37
|
+
* @IsEmail() // Optional email field
|
|
38
|
+
* backupEmail?: string;
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* // Valid examples
|
|
42
|
+
* const user1 = { email: "user@example.com" }; // ✓ Valid
|
|
43
|
+
* const user2 = { email: "test.email+tag@subdomain.example.co.uk" }; // ✓ Valid
|
|
44
|
+
* const user3 = { email: "\"quoted.name\"@example.com" }; // ✓ Valid (quoted local part)
|
|
45
|
+
* const user4 = { email: "user@[192.168.1.1]" }; // ✓ Valid (IP domain)
|
|
46
|
+
*
|
|
47
|
+
* // Invalid examples
|
|
48
|
+
* const invalid1 = { email: "not-an-email" }; // ✗ Missing @
|
|
49
|
+
* const invalid2 = { email: "@example.com" }; // ✗ Empty local part
|
|
50
|
+
* const invalid3 = { email: "user@" }; // ✗ Empty domain
|
|
51
|
+
* const invalid4 = { email: "user..name@example.com" }; // ✗ Consecutive dots
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* **Custom length constraints:**
|
|
55
|
+
* ```typescript
|
|
56
|
+
* class StrictUser {
|
|
57
|
+
* @IsEmail({
|
|
58
|
+
* maxTotalLength: 100, // Shorter total limit
|
|
59
|
+
* maxLocalPartLength: 32, // Shorter local part
|
|
60
|
+
* maxDomainLength: 50 // Shorter domain
|
|
61
|
+
* })
|
|
62
|
+
* email: string;
|
|
63
|
+
* }
|
|
64
|
+
*
|
|
65
|
+
* // Valid with custom limits
|
|
66
|
+
* const user = { email: "short@example.com" }; // ✓ Valid (under limits)
|
|
67
|
+
*
|
|
68
|
+
* // Invalid with custom limits
|
|
69
|
+
* const tooLong = { email: "very.long.local.part.that.exceeds.limits@example.com" }; // ✗ Too long
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* **Integration with other validators:**
|
|
73
|
+
* ```typescript
|
|
74
|
+
* class ContactForm {
|
|
75
|
+
* @IsRequired()
|
|
76
|
+
* @IsEmail()
|
|
77
|
+
* @MaxLength(254) // Additional length check
|
|
78
|
+
* email: string;
|
|
79
|
+
*
|
|
80
|
+
* @IsOptional()
|
|
81
|
+
* @IsEmail({
|
|
82
|
+
* maxTotalLength: 320,
|
|
83
|
+
* maxLocalPartLength: 64
|
|
84
|
+
* })
|
|
85
|
+
* ccEmail?: string;
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* #### Validation Behavior
|
|
90
|
+
*
|
|
91
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
92
|
+
* - **Non-string values**: Returns validation error message
|
|
93
|
+
* - **Invalid format**: Returns localized error message from i18n system
|
|
94
|
+
* - **Valid emails**: Returns `true`
|
|
95
|
+
*
|
|
96
|
+
* #### Performance Considerations
|
|
97
|
+
*
|
|
98
|
+
* - Email validation is computationally lightweight and suitable for high-throughput validation
|
|
99
|
+
* - The regex-based validation is optimized for common email patterns
|
|
100
|
+
* - Custom length constraints are checked first for early rejection of obviously invalid inputs
|
|
101
|
+
* - Supports both simple and complex email formats without performance degradation
|
|
102
|
+
*
|
|
103
|
+
* #### Internationalization Support
|
|
104
|
+
*
|
|
105
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
106
|
+
* The default error key is `'validator.email'` and supports interpolation with field names and values.
|
|
107
|
+
*
|
|
108
|
+
* #### Common Validation Scenarios
|
|
109
|
+
*
|
|
110
|
+
* **User registration:**
|
|
111
|
+
* ```typescript
|
|
112
|
+
* class RegisterUser {
|
|
113
|
+
* @IsRequired()
|
|
114
|
+
* @IsEmail()
|
|
115
|
+
* email: string;
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* **Contact forms:**
|
|
120
|
+
* ```typescript
|
|
121
|
+
* class Contact {
|
|
122
|
+
* @IsEmail()
|
|
123
|
+
* email?: string; // Optional contact email
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* **API data validation:**
|
|
128
|
+
* ```typescript
|
|
129
|
+
* class APIUser {
|
|
130
|
+
* @IsEmail({
|
|
131
|
+
* maxTotalLength: 254, // RFC 3696 recommendation
|
|
132
|
+
* maxLocalPartLength: 64,
|
|
133
|
+
* maxDomainLength: 255
|
|
134
|
+
* })
|
|
135
|
+
* email: string;
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*
|
|
139
|
+
* @param {TOptions} [options] - Optional configuration object for email validation constraints
|
|
140
|
+
* @param {number} [options.maxTotalLength=320] - Maximum total email length in characters
|
|
141
|
+
* @param {number} [options.maxLocalPartLength=64] - Maximum local part length in characters
|
|
142
|
+
* @param {number} [options.maxDomainLength=255] - Maximum domain length in characters
|
|
143
|
+
* @param {number} [options.maxDomainLabelLength=63] - Maximum domain label length in characters
|
|
144
|
+
*
|
|
145
|
+
* @returns {PropertyDecorator} A property decorator that validates email format
|
|
146
|
+
*
|
|
147
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* // Basic usage
|
|
152
|
+
* class User {
|
|
153
|
+
* @IsEmail()
|
|
154
|
+
* email: string;
|
|
155
|
+
* }
|
|
156
|
+
*
|
|
157
|
+
* // With custom options
|
|
158
|
+
* class StrictUser {
|
|
159
|
+
* @IsEmail({
|
|
160
|
+
* maxTotalLength: 100,
|
|
161
|
+
* maxLocalPartLength: 32
|
|
162
|
+
* })
|
|
163
|
+
* email: string;
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @decorator
|
|
168
|
+
* @public
|
|
169
|
+
*/
|
|
170
|
+
export declare const IsEmail: (options?: IsEmailOptions | undefined) => PropertyDecorator;
|
|
171
|
+
/**
|
|
172
|
+
* @summary IsUrl Decorator
|
|
173
|
+
*
|
|
174
|
+
* @description Validates that a property value is a properly formatted URL. Checks for
|
|
175
|
+
* valid URL structure including protocol, domain, and optional path components.
|
|
176
|
+
* This decorator provides comprehensive URL validation with configurable options
|
|
177
|
+
* for protocol requirements and allowed protocols.
|
|
178
|
+
*
|
|
179
|
+
* #### Configuration Options
|
|
180
|
+
*
|
|
181
|
+
* The decorator accepts an optional configuration object to customize validation behavior:
|
|
182
|
+
*
|
|
183
|
+
* - `requireHost`: If true, only allows protocols that require a hostname (http, https, ftp, etc.).
|
|
184
|
+
* If false, allows all valid protocols including mailto, tel, data, etc. (default: true)
|
|
185
|
+
* - `allowedProtocols`: List of allowed protocols. If provided, only URLs with these protocols are considered valid.
|
|
186
|
+
* Protocols should be specified without the trailing colon (e.g., 'http', not 'http:').
|
|
187
|
+
*
|
|
188
|
+
* #### Validation Logic
|
|
189
|
+
*
|
|
190
|
+
* - **Protocol validation**: Ensures URL starts with a valid protocol
|
|
191
|
+
* - **Host requirements**: Can require or allow hostless protocols (mailto, tel, data)
|
|
192
|
+
* - **Protocol filtering**: Optional whitelist of allowed protocols
|
|
193
|
+
* - **Structure validation**: Validates overall URL format and components
|
|
194
|
+
*
|
|
195
|
+
* #### Usage Examples
|
|
196
|
+
*
|
|
197
|
+
* **Basic usage (default settings):**
|
|
198
|
+
* ```typescript
|
|
199
|
+
* class Website {
|
|
200
|
+
* @IsRequired()
|
|
201
|
+
* @IsUrl()
|
|
202
|
+
* homepage: string;
|
|
203
|
+
*
|
|
204
|
+
* @IsUrl() // Optional URL field
|
|
205
|
+
* blogUrl?: string;
|
|
206
|
+
* }
|
|
207
|
+
*
|
|
208
|
+
* // Valid examples
|
|
209
|
+
* const site1 = { homepage: "https://example.com" }; // ✓ Valid
|
|
210
|
+
* const site2 = { homepage: "https://example.com/path?query=value#fragment" }; // ✓ Valid
|
|
211
|
+
* const site3 = { homepage: "ftp://ftp.example.com/file.txt" }; // ✓ Valid
|
|
212
|
+
*
|
|
213
|
+
* // Invalid examples
|
|
214
|
+
* const invalid1 = { homepage: "not-a-url" }; // ✗ Missing protocol
|
|
215
|
+
* const invalid2 = { homepage: "example.com" }; // ✗ Missing protocol
|
|
216
|
+
* const invalid3 = { homepage: "mailto:user@example.com" }; // ✗ Requires host by default
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* **Custom protocol requirements:**
|
|
220
|
+
* ```typescript
|
|
221
|
+
* class FlexibleSite {
|
|
222
|
+
* @IsUrl({ requireHost: false }) // Allow mailto, tel, data, etc.
|
|
223
|
+
* contactUrl?: string;
|
|
224
|
+
*
|
|
225
|
+
* @IsUrl({ allowedProtocols: ['https'] }) // Only HTTPS allowed
|
|
226
|
+
* secureUrl: string;
|
|
227
|
+
*
|
|
228
|
+
* @IsUrl({ allowedProtocols: ['http', 'https', 'ftp'] }) // Multiple protocols
|
|
229
|
+
* resourceUrl: string;
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* // Valid with custom settings
|
|
233
|
+
* const flexible = {
|
|
234
|
+
* contactUrl: "mailto:user@example.com", // ✓ Valid (host not required)
|
|
235
|
+
* secureUrl: "https://secure.example.com", // ✓ Valid (HTTPS allowed)
|
|
236
|
+
* resourceUrl: "ftp://ftp.example.com/file.txt" // ✓ Valid (FTP allowed)
|
|
237
|
+
* };
|
|
238
|
+
*
|
|
239
|
+
* // Invalid with custom settings
|
|
240
|
+
* const invalid = {
|
|
241
|
+
* contactUrl: "https://example.com", // ✗ Would be valid but not testing here
|
|
242
|
+
* secureUrl: "http://insecure.example.com", // ✗ HTTP not in allowed protocols
|
|
243
|
+
* resourceUrl: "file:///local/path" // ✗ file protocol not allowed
|
|
244
|
+
* };
|
|
245
|
+
* ```
|
|
246
|
+
*
|
|
247
|
+
* **Integration with other validators:**
|
|
248
|
+
* ```typescript
|
|
249
|
+
* class WebResource {
|
|
250
|
+
* @IsRequired()
|
|
251
|
+
* @IsUrl()
|
|
252
|
+
* @MaxLength(2048) // Reasonable URL length limit
|
|
253
|
+
* url: string;
|
|
254
|
+
*
|
|
255
|
+
* @IsOptional()
|
|
256
|
+
* @IsUrl({ requireHost: false })
|
|
257
|
+
* callbackUrl?: string;
|
|
258
|
+
* }
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* #### Validation Behavior
|
|
262
|
+
*
|
|
263
|
+
* - **Empty/null values**: Considered valid (use `@IsRequired()` for mandatory fields)
|
|
264
|
+
* - **Non-string values**: Considered valid (other validators should handle type checking)
|
|
265
|
+
* - **Invalid URLs**: Returns localized error message from i18n system
|
|
266
|
+
* - **Valid URLs**: Returns `true`
|
|
267
|
+
*
|
|
268
|
+
* #### Performance Considerations
|
|
269
|
+
*
|
|
270
|
+
* - URL validation is computationally lightweight using efficient regex patterns
|
|
271
|
+
* - Protocol filtering is performed early for fast rejection of invalid protocols
|
|
272
|
+
* - Suitable for high-throughput validation scenarios
|
|
273
|
+
*
|
|
274
|
+
* #### Internationalization Support
|
|
275
|
+
*
|
|
276
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
277
|
+
* The default error key is `'validator.url'` and supports interpolation with field names and values.
|
|
278
|
+
*
|
|
279
|
+
* #### Common Validation Scenarios
|
|
280
|
+
*
|
|
281
|
+
* **Web application URLs:**
|
|
282
|
+
* ```typescript
|
|
283
|
+
* class WebApp {
|
|
284
|
+
* @IsRequired()
|
|
285
|
+
* @IsUrl({ allowedProtocols: ['https'] })
|
|
286
|
+
* apiUrl: string;
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* **Contact information:**
|
|
291
|
+
* ```typescript
|
|
292
|
+
* class Contact {
|
|
293
|
+
* @IsUrl({ requireHost: false })
|
|
294
|
+
* website?: string; // Allow mailto:, tel:, etc.
|
|
295
|
+
* }
|
|
296
|
+
* ```
|
|
297
|
+
*
|
|
298
|
+
* **Resource links:**
|
|
299
|
+
* ```typescript
|
|
300
|
+
* class Resource {
|
|
301
|
+
* @IsUrl({ allowedProtocols: ['http', 'https', 'ftp'] })
|
|
302
|
+
* downloadUrl: string;
|
|
303
|
+
* }
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @param options - Optional configuration object for URL validation
|
|
307
|
+
* @param options.requireHost - Whether to require protocols that need a hostname (default: true)
|
|
308
|
+
* @param options.allowedProtocols - Array of allowed protocols without colons
|
|
309
|
+
* @returns A property decorator that validates URL format
|
|
310
|
+
*
|
|
311
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* // Basic usage
|
|
316
|
+
* class Website {
|
|
317
|
+
* @IsUrl()
|
|
318
|
+
* homepage: string;
|
|
319
|
+
* }
|
|
320
|
+
*
|
|
321
|
+
* // With custom options
|
|
322
|
+
* class SecureSite {
|
|
323
|
+
* @IsUrl({ allowedProtocols: ['https'] })
|
|
324
|
+
* secureUrl: string;
|
|
325
|
+
* }
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* @decorator
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
331
|
+
export declare const IsUrl: (options?: IsUrlOptions | undefined) => PropertyDecorator;
|
|
332
|
+
/**
|
|
333
|
+
* @summary IsPhoneNumber Decorator
|
|
334
|
+
*
|
|
335
|
+
* @description Validates that a property value is a valid phone number. This decorator uses
|
|
336
|
+
* the InputFormatter's comprehensive phone number validation which supports
|
|
337
|
+
* international phone numbers with automatic country code detection and validation
|
|
338
|
+
* against specific country formats.
|
|
339
|
+
*
|
|
340
|
+
* #### Configuration Options
|
|
341
|
+
*
|
|
342
|
+
* The decorator accepts an optional configuration object:
|
|
343
|
+
*
|
|
344
|
+
* - `countryCode`: Optional country code to validate against a specific country's format.
|
|
345
|
+
* If not provided, automatic country detection is used based on the phone number format.
|
|
346
|
+
*
|
|
347
|
+
* #### Validation Logic
|
|
348
|
+
*
|
|
349
|
+
* - **International format support**: Validates E.164 international format (+country code)
|
|
350
|
+
* - **National format support**: Validates local/national phone number formats
|
|
351
|
+
* - **Country-specific validation**: Can enforce validation against specific country rules
|
|
352
|
+
* - **Format normalization**: Accepts various input formats (spaces, dashes, parentheses)
|
|
353
|
+
* - **Length validation**: Ensures phone numbers meet minimum/maximum length requirements
|
|
354
|
+
* - **Digit validation**: Ensures only valid phone number characters and patterns
|
|
355
|
+
*
|
|
356
|
+
* #### Usage Examples
|
|
357
|
+
*
|
|
358
|
+
* **Basic usage (automatic country detection):**
|
|
359
|
+
* ```typescript
|
|
360
|
+
* class Contact {
|
|
361
|
+
* @IsRequired()
|
|
362
|
+
* @IsPhoneNumber()
|
|
363
|
+
* phone: string;
|
|
364
|
+
*
|
|
365
|
+
* @IsPhoneNumber() // Optional phone field
|
|
366
|
+
* mobile?: string;
|
|
367
|
+
* }
|
|
368
|
+
*
|
|
369
|
+
* // Valid examples (automatic detection)
|
|
370
|
+
* const contact1 = { phone: "+1234567890" }; // ✓ Valid (US/CA format)
|
|
371
|
+
* const contact2 = { phone: "(555) 123-4567" }; // ✓ Valid (US national format)
|
|
372
|
+
* const contact3 = { phone: "+44 20 7123 4567" }; // ✓ Valid (UK format)
|
|
373
|
+
* const contact4 = { phone: "+33 1 23 45 67 89" }; // ✓ Valid (France format)
|
|
374
|
+
*
|
|
375
|
+
* // Invalid examples
|
|
376
|
+
* const invalid1 = { phone: "not-a-phone-number" }; // ✗ Invalid format
|
|
377
|
+
* const invalid2 = { phone: "123" }; // ✗ Too short
|
|
378
|
+
* const invalid3 = { phone: "" }; // ✗ Empty string
|
|
379
|
+
* ```
|
|
380
|
+
*
|
|
381
|
+
* **Country-specific validation:**
|
|
382
|
+
* ```typescript
|
|
383
|
+
* class LocalizedContact {
|
|
384
|
+
* @IsPhoneNumber({ countryCode: 'US' }) // US format only
|
|
385
|
+
* usPhone: string;
|
|
386
|
+
*
|
|
387
|
+
* @IsPhoneNumber({ countryCode: 'GB' }) // UK format only
|
|
388
|
+
* ukPhone: string;
|
|
389
|
+
*
|
|
390
|
+
* @IsPhoneNumber({ countryCode: 'FR' }) // France format only
|
|
391
|
+
* frPhone: string;
|
|
392
|
+
* }
|
|
393
|
+
*
|
|
394
|
+
* // Valid with country constraints
|
|
395
|
+
* const localized = {
|
|
396
|
+
* usPhone: "(555) 123-4567", // ✓ Valid for US
|
|
397
|
+
* ukPhone: "+44 20 7123 4567", // ✓ Valid for UK
|
|
398
|
+
* frPhone: "+33 1 23 45 67 89" // ✓ Valid for France
|
|
399
|
+
* };
|
|
400
|
+
*
|
|
401
|
+
* // Invalid with country constraints
|
|
402
|
+
* const invalidLocalized = {
|
|
403
|
+
* usPhone: "+44 20 7123 4567", // ✗ UK number for US field
|
|
404
|
+
* ukPhone: "(555) 123-4567", // ✗ US number for UK field
|
|
405
|
+
* };
|
|
406
|
+
* ```
|
|
407
|
+
*
|
|
408
|
+
* **Integration with other validators:**
|
|
409
|
+
* ```typescript
|
|
410
|
+
* class UserRegistration {
|
|
411
|
+
* @IsRequired()
|
|
412
|
+
* @IsPhoneNumber()
|
|
413
|
+
* @MaxLength(20) // Reasonable phone length limit
|
|
414
|
+
* phoneNumber: string;
|
|
415
|
+
*
|
|
416
|
+
* @IsOptional()
|
|
417
|
+
* @IsPhoneNumber({ countryCode: 'US' })
|
|
418
|
+
* backupPhone?: string;
|
|
419
|
+
* }
|
|
420
|
+
* ```
|
|
421
|
+
*
|
|
422
|
+
* #### Validation Behavior
|
|
423
|
+
*
|
|
424
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
425
|
+
* - **Non-string values**: Returns validation error message
|
|
426
|
+
* - **Invalid phone numbers**: Returns localized error message from i18n system
|
|
427
|
+
* - **Valid phone numbers**: Returns `true`
|
|
428
|
+
*
|
|
429
|
+
* #### Performance Considerations
|
|
430
|
+
*
|
|
431
|
+
* - Phone number validation uses efficient pattern matching and country detection algorithms
|
|
432
|
+
* - Country-specific validation is optimized for common phone number formats
|
|
433
|
+
* - Suitable for high-throughput validation with minimal performance impact
|
|
434
|
+
*
|
|
435
|
+
* #### Internationalization Support
|
|
436
|
+
*
|
|
437
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
438
|
+
* The default error key is `'validator.phoneNumber'` and supports interpolation with field names and values.
|
|
439
|
+
*
|
|
440
|
+
* #### Common Validation Scenarios
|
|
441
|
+
*
|
|
442
|
+
* **User registration:**
|
|
443
|
+
* ```typescript
|
|
444
|
+
* class RegisterUser {
|
|
445
|
+
* @IsRequired()
|
|
446
|
+
* @IsPhoneNumber()
|
|
447
|
+
* phoneNumber: string;
|
|
448
|
+
* }
|
|
449
|
+
* ```
|
|
450
|
+
*
|
|
451
|
+
* **Contact forms:**
|
|
452
|
+
* ```typescript
|
|
453
|
+
* class ContactForm {
|
|
454
|
+
* @IsPhoneNumber()
|
|
455
|
+
* phone?: string; // Optional contact phone
|
|
456
|
+
* }
|
|
457
|
+
* ```
|
|
458
|
+
*
|
|
459
|
+
* **Country-specific applications:**
|
|
460
|
+
* ```typescript
|
|
461
|
+
* class USApplication {
|
|
462
|
+
* @IsRequired()
|
|
463
|
+
* @IsPhoneNumber({ countryCode: 'US' })
|
|
464
|
+
* phoneNumber: string;
|
|
465
|
+
* }
|
|
466
|
+
* ```
|
|
467
|
+
*
|
|
468
|
+
* @param options - Optional configuration object for phone number validation
|
|
469
|
+
* @param options.countryCode - Country code to validate against specific country's format
|
|
470
|
+
* @returns A property decorator that validates phone number format
|
|
471
|
+
*
|
|
472
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* ```typescript
|
|
476
|
+
* // Basic usage
|
|
477
|
+
* class Contact {
|
|
478
|
+
* @IsPhoneNumber()
|
|
479
|
+
* phone: string;
|
|
480
|
+
* }
|
|
481
|
+
*
|
|
482
|
+
* // With country code
|
|
483
|
+
* class USContact {
|
|
484
|
+
* @IsPhoneNumber({ countryCode: 'US' })
|
|
485
|
+
* phone: string;
|
|
486
|
+
* }
|
|
487
|
+
* ```
|
|
488
|
+
*
|
|
489
|
+
* @decorator
|
|
490
|
+
* @public
|
|
491
|
+
*/
|
|
492
|
+
export declare const IsPhoneNumber: (countryCode?: "AF" | "AL" | "DZ" | "AS" | "AD" | "AO" | "AI" | "AG" | "AR" | "AM" | "AW" | "AU" | "AT" | "AZ" | "BS" | "BH" | "BD" | "BB" | "BY" | "BE" | "BZ" | "BJ" | "BM" | "BT" | "BO" | "BA" | "BW" | "BR" | "IO" | "VG" | "BN" | "BG" | "BF" | "BI" | "KH" | "CM" | "CA" | "CV" | "BQ" | "KY" | "CF" | "TD" | "CL" | "CN" | "CX" | "CC" | "CO" | "KM" | "CD" | "CG" | "CK" | "CR" | "CI" | "HR" | "CU" | "CW" | "CY" | "CZ" | "DK" | "DJ" | "DM" | "DO" | "EC" | "EG" | "SV" | "GQ" | "ER" | "EE" | "ET" | "FK" | "FO" | "FJ" | "FI" | "FR" | "GF" | "PF" | "GA" | "GM" | "GE" | "DE" | "GH" | "GI" | "GR" | "GL" | "GD" | "GP" | "GU" | "GT" | "GG" | "GN" | "GW" | "GY" | "HT" | "HN" | "HK" | "HU" | "IS" | "IN" | "ID" | "IR" | "IQ" | "IE" | "IM" | "IL" | "IT" | "JM" | "JP" | "JE" | "JO" | "KZ" | "KE" | "KI" | "KW" | "KG" | "LA" | "LV" | "LB" | "LS" | "LR" | "LY" | "LI" | "LT" | "LU" | "MO" | "MK" | "MG" | "MW" | "MY" | "MV" | "ML" | "MT" | "MH" | "MQ" | "MR" | "MU" | "YT" | "MX" | "FM" | "MD" | "MC" | "MN" | "ME" | "MS" | "MA" | "MZ" | "MM" | "NA" | "NR" | "NP" | "NL" | "NC" | "NZ" | "NI" | "NE" | "NG" | "NU" | "NF" | "KP" | "MP" | "NO" | "OM" | "PK" | "PW" | "PS" | "PA" | "PG" | "PY" | "PE" | "PH" | "PL" | "PT" | "PR" | "QA" | "RE" | "RO" | "RU" | "RW" | "BL" | "SH" | "KN" | "LC" | "MF" | "PM" | "VC" | "WS" | "SM" | "ST" | "SA" | "SN" | "RS" | "SC" | "SL" | "SG" | "SX" | "SK" | "SI" | "SB" | "SO" | "ZA" | "KR" | "SS" | "ES" | "LK" | "SD" | "SR" | "SJ" | "SZ" | "SE" | "CH" | "SY" | "TW" | "TJ" | "TZ" | "TH" | "TL" | "TG" | "TK" | "TO" | "TT" | "TN" | "TR" | "TM" | "TC" | "TV" | "VI" | "UG" | "UA" | "AE" | "GB" | "US" | "UY" | "UZ" | "VU" | "VA" | "VE" | "VN" | "WF" | "EH" | "YE" | "ZM" | "ZW" | "AX" | undefined) => PropertyDecorator;
|
|
493
|
+
/**
|
|
494
|
+
* @summary IsEmailOrPhone Decorator
|
|
495
|
+
*
|
|
496
|
+
* @description Validates that a property value is either a valid email address or a valid phone number.
|
|
497
|
+
* This decorator provides flexible validation for contact information fields that can accept
|
|
498
|
+
* either email or phone number formats, automatically detecting and validating the appropriate type.
|
|
499
|
+
*
|
|
500
|
+
* #### Configuration Options
|
|
501
|
+
*
|
|
502
|
+
* The decorator accepts an optional configuration object with separate options for email and phone validation:
|
|
503
|
+
*
|
|
504
|
+
* - `email`: Email validation options (same as IsEmail rule - maxTotalLength, maxLocalPartLength, etc.)
|
|
505
|
+
* - `phoneNumber`: Phone number validation options with country code
|
|
506
|
+
*
|
|
507
|
+
* #### Validation Logic
|
|
508
|
+
*
|
|
509
|
+
* - **Automatic type detection**: Attempts email validation first, then phone validation if email fails
|
|
510
|
+
* - **Email validation**: Full RFC 5322 compliant email validation with configurable constraints
|
|
511
|
+
* - **Phone validation**: International phone number validation with country code support
|
|
512
|
+
* - **Flexible input**: Accepts various email and phone number formats
|
|
513
|
+
* - **Fallback behavior**: If neither validation passes, returns appropriate error message
|
|
514
|
+
*
|
|
515
|
+
* #### Usage Examples
|
|
516
|
+
*
|
|
517
|
+
* **Basic usage (automatic detection):**
|
|
518
|
+
* ```typescript
|
|
519
|
+
* class Contact {
|
|
520
|
+
* @IsRequired()
|
|
521
|
+
* @IsEmailOrPhone()
|
|
522
|
+
* contactInfo: string;
|
|
523
|
+
*
|
|
524
|
+
* @IsEmailOrPhone() // Optional contact field
|
|
525
|
+
* backupContact?: string;
|
|
526
|
+
* }
|
|
527
|
+
*
|
|
528
|
+
* // Valid examples (either email or phone)
|
|
529
|
+
* const contact1 = { contactInfo: "user@example.com" }; // ✓ Valid (email)
|
|
530
|
+
* const contact2 = { contactInfo: "+1234567890" }; // ✓ Valid (phone)
|
|
531
|
+
* const contact3 = { contactInfo: "(555) 123-4567" }; // ✓ Valid (phone)
|
|
532
|
+
* const contact4 = { contactInfo: "test.email+tag@subdomain.example.co.uk" }; // ✓ Valid (email)
|
|
533
|
+
*
|
|
534
|
+
* // Invalid examples
|
|
535
|
+
* const invalid1 = { contactInfo: "not-valid-contact" }; // ✗ Neither valid email nor phone
|
|
536
|
+
* const invalid2 = { contactInfo: "@example.com" }; // ✗ Invalid email, not a phone
|
|
537
|
+
* const invalid3 = { contactInfo: "123" }; // ✗ Too short for phone, not email
|
|
538
|
+
* const invalid4 = { contactInfo: "" }; // ✗ Empty string
|
|
539
|
+
* ```
|
|
540
|
+
*
|
|
541
|
+
* **Custom validation constraints:**
|
|
542
|
+
* ```typescript
|
|
543
|
+
* class FlexibleContact {
|
|
544
|
+
* @IsEmailOrPhone({
|
|
545
|
+
* email: { maxTotalLength: 100 },
|
|
546
|
+
* phoneNumber: { countryCode: 'US' }
|
|
547
|
+
* })
|
|
548
|
+
* contact: string;
|
|
549
|
+
*
|
|
550
|
+
* @IsEmailOrPhone({
|
|
551
|
+
* email: { maxLocalPartLength: 32 },
|
|
552
|
+
* phoneNumber: { countryCode: 'GB' }
|
|
553
|
+
* })
|
|
554
|
+
* internationalContact: string;
|
|
555
|
+
* }
|
|
556
|
+
*
|
|
557
|
+
* // Valid with custom constraints
|
|
558
|
+
* const flexible = {
|
|
559
|
+
* contact: "user@example.com", // ✓ Valid email (under length limit)
|
|
560
|
+
* internationalContact: "+44 20 7123 4567" // ✓ Valid UK phone
|
|
561
|
+
* };
|
|
562
|
+
*
|
|
563
|
+
* // Invalid with custom constraints
|
|
564
|
+
* const invalidFlexible = {
|
|
565
|
+
* contact: "very.long.email.address.that.exceeds.limit@example.com", // ✗ Email too long
|
|
566
|
+
* internationalContact: "(555) 123-4567" // ✗ US phone for UK field
|
|
567
|
+
* };
|
|
568
|
+
* ```
|
|
569
|
+
*
|
|
570
|
+
* **Integration with other validators:**
|
|
571
|
+
* ```typescript
|
|
572
|
+
* class UserContact {
|
|
573
|
+
* @IsRequired()
|
|
574
|
+
* @IsEmailOrPhone()
|
|
575
|
+
* @MaxLength(254) // Reasonable contact length limit
|
|
576
|
+
* primaryContact: string;
|
|
577
|
+
*
|
|
578
|
+
* @IsOptional()
|
|
579
|
+
* @IsEmailOrPhone({
|
|
580
|
+
* email: { maxTotalLength: 320 },
|
|
581
|
+
* phoneNumber: { countryCode: 'US' }
|
|
582
|
+
* })
|
|
583
|
+
* secondaryContact?: string;
|
|
584
|
+
* }
|
|
585
|
+
* ```
|
|
586
|
+
*
|
|
587
|
+
* #### Validation Behavior
|
|
588
|
+
*
|
|
589
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
590
|
+
* - **Non-string values**: Returns validation error message
|
|
591
|
+
* - **Valid email or phone**: Returns `true`
|
|
592
|
+
* - **Invalid input**: Returns localized error message indicating neither email nor phone format is valid
|
|
593
|
+
*
|
|
594
|
+
* #### Performance Considerations
|
|
595
|
+
*
|
|
596
|
+
* - Efficient validation with early rejection for obviously invalid inputs
|
|
597
|
+
* - Email validation attempted first (typically faster regex-based)
|
|
598
|
+
* - Phone validation only performed if email validation fails
|
|
599
|
+
* - Suitable for contact form validation with good performance characteristics
|
|
600
|
+
*
|
|
601
|
+
* #### Internationalization Support
|
|
602
|
+
*
|
|
603
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
604
|
+
* The default error key is `'validator.emailOrPhoneNumber'` and supports interpolation with field names and values.
|
|
605
|
+
*
|
|
606
|
+
* #### Common Validation Scenarios
|
|
607
|
+
*
|
|
608
|
+
* **User registration with flexible contact:**
|
|
609
|
+
* ```typescript
|
|
610
|
+
* class RegisterUser {
|
|
611
|
+
* @IsRequired()
|
|
612
|
+
* @IsEmailOrPhone()
|
|
613
|
+
* usernameOrEmailOrPhone: string;
|
|
614
|
+
* }
|
|
615
|
+
* ```
|
|
616
|
+
*
|
|
617
|
+
* **Contact forms:**
|
|
618
|
+
* ```typescript
|
|
619
|
+
* class ContactForm {
|
|
620
|
+
* @IsEmailOrPhone()
|
|
621
|
+
* preferredContact?: string; // User can provide either email or phone
|
|
622
|
+
* }
|
|
623
|
+
* ```
|
|
624
|
+
*
|
|
625
|
+
* **Multi-channel communication:**
|
|
626
|
+
* ```typescript
|
|
627
|
+
* class NotificationSettings {
|
|
628
|
+
* @IsRequired()
|
|
629
|
+
* @IsEmailOrPhone()
|
|
630
|
+
* contactMethod: string; // Email or SMS capable number
|
|
631
|
+
* }
|
|
632
|
+
* ```
|
|
633
|
+
*
|
|
634
|
+
* @param options - Optional configuration object for email and phone validation
|
|
635
|
+
* @param options.email - Email validation options (maxTotalLength, maxLocalPartLength, etc.)
|
|
636
|
+
* @param options.phoneNumber - Phone validation options with country code
|
|
637
|
+
* @returns A property decorator that validates email or phone number format
|
|
638
|
+
*
|
|
639
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* ```typescript
|
|
643
|
+
* // Basic usage
|
|
644
|
+
* class Contact {
|
|
645
|
+
* @IsEmailOrPhone()
|
|
646
|
+
* contactInfo: string;
|
|
647
|
+
* }
|
|
648
|
+
*
|
|
649
|
+
* // With custom options
|
|
650
|
+
* class FlexibleContact {
|
|
651
|
+
* @IsEmailOrPhone({
|
|
652
|
+
* email: { maxTotalLength: 100 },
|
|
653
|
+
* phoneNumber: { countryCode: 'US' }
|
|
654
|
+
* })
|
|
655
|
+
* contact: string;
|
|
656
|
+
* }
|
|
657
|
+
* ```
|
|
658
|
+
*
|
|
659
|
+
* @decorator
|
|
660
|
+
* @public
|
|
661
|
+
*/
|
|
662
|
+
export declare const IsEmailOrPhone: (options?: {
|
|
663
|
+
email?: IsEmailOptions;
|
|
664
|
+
phoneNumber?: {
|
|
665
|
+
countryCode?: CountryCode;
|
|
666
|
+
} | undefined;
|
|
667
|
+
} | undefined) => PropertyDecorator;
|
|
668
|
+
/**
|
|
669
|
+
* ### IsFileName Decorator
|
|
670
|
+
*
|
|
671
|
+
* Validates that a property value is a valid file name. This decorator checks for
|
|
672
|
+
* forbidden characters and reserved names that cannot be used as file names across
|
|
673
|
+
* different operating systems (Windows, macOS, Linux).
|
|
674
|
+
*
|
|
675
|
+
* #### Validation Logic
|
|
676
|
+
*
|
|
677
|
+
* - **Forbidden characters**: Blocks \ / : * ? " < > | which are invalid in file names
|
|
678
|
+
* - **Starting character**: Cannot start with a dot (.) to prevent hidden files
|
|
679
|
+
* - **Reserved names**: Blocks Windows reserved names (nul, prn, con, lpt[0-9], com[0-9])
|
|
680
|
+
* - **Case insensitive**: Reserved name checks are case-insensitive
|
|
681
|
+
* - **Cross-platform**: Validates against restrictions from multiple operating systems
|
|
682
|
+
*
|
|
683
|
+
* #### Usage Examples
|
|
684
|
+
*
|
|
685
|
+
* **Basic usage:**
|
|
686
|
+
* ```typescript
|
|
687
|
+
* class FileUpload {
|
|
688
|
+
* @IsRequired()
|
|
689
|
+
* @IsFileName()
|
|
690
|
+
* fileName: string;
|
|
691
|
+
*
|
|
692
|
+
* @IsFileName() // Optional file name field
|
|
693
|
+
* displayName?: string;
|
|
694
|
+
* }
|
|
695
|
+
*
|
|
696
|
+
* // Valid file names
|
|
697
|
+
* const upload1 = { fileName: "document.txt" }; // ✓ Valid
|
|
698
|
+
* const upload2 = { fileName: "my-file_123.pdf" }; // ✓ Valid
|
|
699
|
+
* const upload3 = { fileName: "file with spaces.jpg" }; // ✓ Valid
|
|
700
|
+
* const upload4 = { fileName: "résumé.docx" }; // ✓ Valid (Unicode supported)
|
|
701
|
+
* const upload5 = { fileName: "file-name.tar.gz" }; // ✓ Valid
|
|
702
|
+
*
|
|
703
|
+
* // Invalid examples
|
|
704
|
+
* const invalid1 = { fileName: "file:with:colons.txt" }; // ✗ Contains forbidden characters
|
|
705
|
+
* const invalid2 = { fileName: "con" }; // ✗ Reserved name (Windows)
|
|
706
|
+
* const invalid3 = { fileName: ".hidden" }; // ✗ Starts with dot
|
|
707
|
+
* const invalid4 = { fileName: "file<name>.txt" }; // ✗ Contains < >
|
|
708
|
+
* const invalid5 = { fileName: "file|name.txt" }; // ✗ Contains |
|
|
709
|
+
* const invalid6 = { fileName: "" }; // ✗ Empty string
|
|
710
|
+
* ```
|
|
711
|
+
*
|
|
712
|
+
* **Integration with file upload:**
|
|
713
|
+
* ```typescript
|
|
714
|
+
* class FileMetadata {
|
|
715
|
+
* @IsRequired()
|
|
716
|
+
* @IsFileName()
|
|
717
|
+
* @MaxLength(255) // Reasonable file name length
|
|
718
|
+
* originalName: string;
|
|
719
|
+
*
|
|
720
|
+
* @IsOptional()
|
|
721
|
+
* @IsFileName()
|
|
722
|
+
* displayName?: string;
|
|
723
|
+
* }
|
|
724
|
+
* ```
|
|
725
|
+
*
|
|
726
|
+
* #### Validation Behavior
|
|
727
|
+
*
|
|
728
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
729
|
+
* - **Non-string values**: Returns validation error message
|
|
730
|
+
* - **Invalid file names**: Returns localized error message from i18n system
|
|
731
|
+
* - **Valid file names**: Returns `true`
|
|
732
|
+
*
|
|
733
|
+
* #### Performance Considerations
|
|
734
|
+
*
|
|
735
|
+
* - File name validation uses efficient regex patterns for character validation
|
|
736
|
+
* - Reserved name checking is optimized with case-insensitive string comparison
|
|
737
|
+
* - Suitable for high-throughput file upload validation
|
|
738
|
+
*
|
|
739
|
+
* #### Internationalization Support
|
|
740
|
+
*
|
|
741
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
742
|
+
* The default error key is `'validator.fileName'` and supports interpolation with field names and values.
|
|
743
|
+
*
|
|
744
|
+
* #### Common Validation Scenarios
|
|
745
|
+
*
|
|
746
|
+
* **File upload forms:**
|
|
747
|
+
* ```typescript
|
|
748
|
+
* class UploadForm {
|
|
749
|
+
* @IsRequired()
|
|
750
|
+
* @IsFileName()
|
|
751
|
+
* fileName: string;
|
|
752
|
+
* }
|
|
753
|
+
* ```
|
|
754
|
+
*
|
|
755
|
+
* **Document management:**
|
|
756
|
+
* ```typescript
|
|
757
|
+
* class Document {
|
|
758
|
+
* @IsRequired()
|
|
759
|
+
* @IsFileName()
|
|
760
|
+
* fileName: string;
|
|
761
|
+
*
|
|
762
|
+
* @IsFileName()
|
|
763
|
+
* alias?: string;
|
|
764
|
+
* }
|
|
765
|
+
* ```
|
|
766
|
+
*
|
|
767
|
+
* **Asset naming:**
|
|
768
|
+
* ```typescript
|
|
769
|
+
* class Asset {
|
|
770
|
+
* @IsRequired()
|
|
771
|
+
* @IsFileName()
|
|
772
|
+
* @Matches('^[a-zA-Z0-9._-]+$', {message: 'asset.invalidChars'})
|
|
773
|
+
* name: string;
|
|
774
|
+
* }
|
|
775
|
+
* ```
|
|
776
|
+
*
|
|
777
|
+
* #### Security Considerations
|
|
778
|
+
*
|
|
779
|
+
* - Prevents path traversal attacks by blocking directory separators
|
|
780
|
+
* - Blocks reserved names that could cause system conflicts
|
|
781
|
+
* - Helps prevent filesystem-related security vulnerabilities
|
|
782
|
+
*
|
|
783
|
+
* @returns A property decorator that validates file name format
|
|
784
|
+
*
|
|
785
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```typescript
|
|
789
|
+
* // Basic usage
|
|
790
|
+
* class FileUpload {
|
|
791
|
+
* @IsFileName()
|
|
792
|
+
* fileName: string;
|
|
793
|
+
* }
|
|
794
|
+
*
|
|
795
|
+
* // With additional constraints
|
|
796
|
+
* class StrictFileUpload {
|
|
797
|
+
* @IsFileName()
|
|
798
|
+
* @MaxLength(100)
|
|
799
|
+
* @Matches('^[a-zA-Z0-9._-]+$', {message: 'filename.invalid'})
|
|
800
|
+
* fileName: string;
|
|
801
|
+
* }
|
|
802
|
+
* ```
|
|
803
|
+
*
|
|
804
|
+
* @decorator
|
|
805
|
+
* @public
|
|
806
|
+
*/
|
|
807
|
+
export declare const IsFileName: () => PropertyDecorator;
|
|
808
|
+
/**
|
|
809
|
+
* ### IsUUID Decorator
|
|
810
|
+
*
|
|
811
|
+
* Validates that a property value is a valid Universally Unique Identifier (UUID).
|
|
812
|
+
* This decorator validates UUIDs according to RFC 4122 standards, supporting all
|
|
813
|
+
* UUID versions (v1-v5) with proper format and variant validation.
|
|
814
|
+
*
|
|
815
|
+
* #### Validation Logic
|
|
816
|
+
*
|
|
817
|
+
* - **Format validation**: Ensures UUID follows the standard 8-4-4-4-12 hexadecimal format
|
|
818
|
+
* - **Version support**: Accepts UUIDs of any version (1-5) as indicated by version bits
|
|
819
|
+
* - **Variant validation**: Ensures correct UUID variant (RFC 4122 variant)
|
|
820
|
+
* - **Case insensitive**: Accepts both uppercase and lowercase hexadecimal digits
|
|
821
|
+
* - **Hyphen requirements**: Requires proper hyphen placement between groups
|
|
822
|
+
*
|
|
823
|
+
* #### UUID Format
|
|
824
|
+
*
|
|
825
|
+
* UUIDs must follow the pattern: `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
|
826
|
+
* where each `x` is a hexadecimal digit (0-9, a-f, A-F).
|
|
827
|
+
*
|
|
828
|
+
* #### Usage Examples
|
|
829
|
+
*
|
|
830
|
+
* **Basic usage:**
|
|
831
|
+
* ```typescript
|
|
832
|
+
* class Entity {
|
|
833
|
+
* @IsRequired()
|
|
834
|
+
* @IsUUID()
|
|
835
|
+
* id: string;
|
|
836
|
+
*
|
|
837
|
+
* @IsUUID() // Optional UUID field
|
|
838
|
+
* parentId?: string;
|
|
839
|
+
* }
|
|
840
|
+
*
|
|
841
|
+
* // Valid UUIDs (all versions)
|
|
842
|
+
* const entity1 = { id: "550e8400-e29b-41d4-a716-446655440000" }; // ✓ Valid (v4)
|
|
843
|
+
* const entity2 = { id: "6ba7b810-9dad-11d1-80b4-00c04fd430c8" }; // ✓ Valid (v1)
|
|
844
|
+
* const entity3 = { id: "550E8400-E29B-41D4-A716-446655440000" }; // ✓ Valid (uppercase)
|
|
845
|
+
* const entity4 = { id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" }; // ✓ Valid (v4)
|
|
846
|
+
*
|
|
847
|
+
* // Invalid examples
|
|
848
|
+
* const invalid1 = { id: "not-a-uuid" }; // ✗ Invalid format
|
|
849
|
+
* const invalid2 = { id: "550e8400-e29b-41d4-a716" }; // ✗ Too short
|
|
850
|
+
* const invalid3 = { id: "550e8400-e29b-41d4-a716-446655440000-extra" }; // ✗ Too long
|
|
851
|
+
* const invalid4 = { id: "550e8400e29b41d4a716446655440000" }; // ✗ Missing hyphens
|
|
852
|
+
* const invalid5 = { id: "550e8400-e29b-41d4-a716-44665544000g" }; // ✗ Invalid character (g)
|
|
853
|
+
* const invalid6 = { id: "" }; // ✗ Empty string
|
|
854
|
+
* ```
|
|
855
|
+
*
|
|
856
|
+
* **Integration with database entities:**
|
|
857
|
+
* ```typescript
|
|
858
|
+
* class DatabaseEntity {
|
|
859
|
+
* @IsRequired()
|
|
860
|
+
* @IsUUID()
|
|
861
|
+
* @MaxLength(36) // UUIDs are always 36 characters
|
|
862
|
+
* id: string;
|
|
863
|
+
*
|
|
864
|
+
* @IsOptional()
|
|
865
|
+
* @IsUUID()
|
|
866
|
+
* tenantId?: string;
|
|
867
|
+
* }
|
|
868
|
+
* ```
|
|
869
|
+
*
|
|
870
|
+
* #### Validation Behavior
|
|
871
|
+
*
|
|
872
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
873
|
+
* - **Non-string values**: Returns validation error message
|
|
874
|
+
* - **Invalid UUIDs**: Returns localized error message from i18n system
|
|
875
|
+
* - **Valid UUIDs**: Returns `true` (asynchronous validation)
|
|
876
|
+
*
|
|
877
|
+
* #### Performance Considerations
|
|
878
|
+
*
|
|
879
|
+
* - UUID validation uses efficient regex pattern matching
|
|
880
|
+
* - Asynchronous validation allows for non-blocking validation in high-throughput scenarios
|
|
881
|
+
* - Regex is optimized for the specific UUID format requirements
|
|
882
|
+
*
|
|
883
|
+
* #### Internationalization Support
|
|
884
|
+
*
|
|
885
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
886
|
+
* The default error key is `'validator.uuid'` and supports interpolation with field names and values.
|
|
887
|
+
*
|
|
888
|
+
* #### Common Validation Scenarios
|
|
889
|
+
*
|
|
890
|
+
* **Database primary keys:**
|
|
891
|
+
* ```typescript
|
|
892
|
+
* class Model {
|
|
893
|
+
* @IsRequired()
|
|
894
|
+
* @IsUUID()
|
|
895
|
+
* id: string;
|
|
896
|
+
* }
|
|
897
|
+
* ```
|
|
898
|
+
*
|
|
899
|
+
* **API resource identifiers:**
|
|
900
|
+
* ```typescript
|
|
901
|
+
* class APIResource {
|
|
902
|
+
* @IsRequired()
|
|
903
|
+
* @IsUUID()
|
|
904
|
+
* resourceId: string;
|
|
905
|
+
* }
|
|
906
|
+
* ```
|
|
907
|
+
*
|
|
908
|
+
* **Session tokens:**
|
|
909
|
+
* ```typescript
|
|
910
|
+
* class Session {
|
|
911
|
+
* @IsRequired()
|
|
912
|
+
* @IsUUID()
|
|
913
|
+
* sessionId: string;
|
|
914
|
+
* }
|
|
915
|
+
* ```
|
|
916
|
+
*
|
|
917
|
+
* #### Standards Compliance
|
|
918
|
+
*
|
|
919
|
+
* - **RFC 4122**: Compliant with UUID standard format and variant requirements
|
|
920
|
+
* - **Version agnostic**: Accepts UUIDs of all versions (v1-v5)
|
|
921
|
+
* - **Case insensitive**: Follows RFC guidelines for hexadecimal representation
|
|
922
|
+
*
|
|
923
|
+
* @returns A property decorator that validates UUID format
|
|
924
|
+
*
|
|
925
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
926
|
+
*
|
|
927
|
+
* @example
|
|
928
|
+
* ```typescript
|
|
929
|
+
* // Basic usage
|
|
930
|
+
* class Entity {
|
|
931
|
+
* @IsUUID()
|
|
932
|
+
* id: string;
|
|
933
|
+
* }
|
|
934
|
+
*
|
|
935
|
+
* // With additional constraints
|
|
936
|
+
* class StrictEntity {
|
|
937
|
+
* @IsUUID()
|
|
938
|
+
* @MaxLength(36)
|
|
939
|
+
* id: string;
|
|
940
|
+
* }
|
|
941
|
+
* ```
|
|
942
|
+
*
|
|
943
|
+
* @decorator
|
|
944
|
+
* @public
|
|
945
|
+
*/
|
|
946
|
+
export declare const IsUUID: () => PropertyDecorator;
|
|
947
|
+
/**
|
|
948
|
+
* ### IsJSON Decorator
|
|
949
|
+
*
|
|
950
|
+
* Validates that a property value is valid JSON (JavaScript Object Notation).
|
|
951
|
+
* This decorator attempts to parse the string value as JSON and validates that
|
|
952
|
+
* it conforms to proper JSON syntax and structure.
|
|
953
|
+
*
|
|
954
|
+
* #### Validation Logic
|
|
955
|
+
*
|
|
956
|
+
* - **Syntax validation**: Ensures the string is valid JSON syntax
|
|
957
|
+
* - **Structure validation**: Validates that the JSON represents valid data structures
|
|
958
|
+
* - **Encoding**: Assumes UTF-8 encoding for the JSON string
|
|
959
|
+
* - **Parsing**: Uses native JSON.parse() for validation
|
|
960
|
+
* - **Error handling**: Catches and reports JSON parsing errors
|
|
961
|
+
*
|
|
962
|
+
* #### Supported JSON Types
|
|
963
|
+
*
|
|
964
|
+
* - Objects: `{"key": "value", "number": 123}`
|
|
965
|
+
* - Arrays: `[1, 2, 3, "string"]`
|
|
966
|
+
* - Strings: `"Hello World"`
|
|
967
|
+
* - Numbers: `123`, `123.45`, `-123`
|
|
968
|
+
* - Booleans: `true`, `false`
|
|
969
|
+
* - null: `null`
|
|
970
|
+
* - Nested structures: Objects and arrays can be nested
|
|
971
|
+
*
|
|
972
|
+
* #### Usage Examples
|
|
973
|
+
*
|
|
974
|
+
* **Basic usage:**
|
|
975
|
+
* ```typescript
|
|
976
|
+
* class Config {
|
|
977
|
+
* @IsRequired()
|
|
978
|
+
* @IsJSON()
|
|
979
|
+
* settings: string;
|
|
980
|
+
*
|
|
981
|
+
* @IsJSON() // Optional JSON field
|
|
982
|
+
* metadata?: string;
|
|
983
|
+
* }
|
|
984
|
+
*
|
|
985
|
+
* // Valid JSON strings
|
|
986
|
+
* const config1 = { settings: '{"name": "John", "age": 30}' }; // ✓ Valid object
|
|
987
|
+
* const config2 = { settings: '[1, 2, 3]' }; // ✓ Valid array
|
|
988
|
+
* const config3 = { settings: '"Hello World"' }; // ✓ Valid string
|
|
989
|
+
* const config4 = { settings: '123' }; // ✓ Valid number
|
|
990
|
+
* const config5 = { settings: 'true' }; // ✓ Valid boolean
|
|
991
|
+
* const config6 = { settings: 'null' }; // ✓ Valid null
|
|
992
|
+
*
|
|
993
|
+
* // Invalid examples
|
|
994
|
+
* const invalid1 = { settings: '{"name": "John", "age": }' }; // ✗ Invalid JSON (trailing comma)
|
|
995
|
+
* const invalid2 = { settings: '{"name": "John", "age": 30' }; // ✗ Missing closing brace
|
|
996
|
+
* const invalid3 = { settings: '[1, 2, 3' }; // ✗ Missing closing bracket
|
|
997
|
+
* const invalid4 = { settings: '{"name": "John" "age": 30}' }; // ✗ Missing comma
|
|
998
|
+
* const invalid5 = { settings: 'undefined' }; // ✗ undefined is not valid JSON
|
|
999
|
+
* const invalid6 = { settings: '{name: "John"}' }; // ✗ Unquoted keys
|
|
1000
|
+
* const invalid7 = { settings: "" }; // ✗ Empty string
|
|
1001
|
+
* ```
|
|
1002
|
+
*
|
|
1003
|
+
* **Configuration storage:**
|
|
1004
|
+
* ```typescript
|
|
1005
|
+
* class AppConfig {
|
|
1006
|
+
* @IsRequired()
|
|
1007
|
+
* @IsJSON()
|
|
1008
|
+
* @MaxLength(10000) // Reasonable JSON size limit
|
|
1009
|
+
* configData: string;
|
|
1010
|
+
*
|
|
1011
|
+
* @IsOptional()
|
|
1012
|
+
* @IsJSON()
|
|
1013
|
+
* userPreferences?: string;
|
|
1014
|
+
* }
|
|
1015
|
+
* ```
|
|
1016
|
+
*
|
|
1017
|
+
* #### Validation Behavior
|
|
1018
|
+
*
|
|
1019
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1020
|
+
* - **Non-string values**: Returns validation error message
|
|
1021
|
+
* - **Invalid JSON**: Returns localized error message from i18n system
|
|
1022
|
+
* - **Valid JSON**: Returns `true` (asynchronous validation)
|
|
1023
|
+
*
|
|
1024
|
+
* #### Performance Considerations
|
|
1025
|
+
*
|
|
1026
|
+
* - JSON validation uses native browser/Node.js JSON.parse() which is highly optimized
|
|
1027
|
+
* - Asynchronous validation allows for non-blocking validation of large JSON strings
|
|
1028
|
+
* - Suitable for configuration and data validation scenarios
|
|
1029
|
+
*
|
|
1030
|
+
* #### Internationalization Support
|
|
1031
|
+
*
|
|
1032
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1033
|
+
* The default error key is `'validator.json'` and supports interpolation with field names and values.
|
|
1034
|
+
*
|
|
1035
|
+
* #### Common Validation Scenarios
|
|
1036
|
+
*
|
|
1037
|
+
* **Configuration files:**
|
|
1038
|
+
* ```typescript
|
|
1039
|
+
* class Configuration {
|
|
1040
|
+
* @IsRequired()
|
|
1041
|
+
* @IsJSON()
|
|
1042
|
+
* appConfig: string;
|
|
1043
|
+
* }
|
|
1044
|
+
* ```
|
|
1045
|
+
*
|
|
1046
|
+
* **API responses:**
|
|
1047
|
+
* ```typescript
|
|
1048
|
+
* class APIResponse {
|
|
1049
|
+
* @IsRequired()
|
|
1050
|
+
* @IsJSON()
|
|
1051
|
+
* data: string;
|
|
1052
|
+
* }
|
|
1053
|
+
* ```
|
|
1054
|
+
*
|
|
1055
|
+
* **User preferences:**
|
|
1056
|
+
* ```typescript
|
|
1057
|
+
* class UserSettings {
|
|
1058
|
+
* @IsJSON()
|
|
1059
|
+
* preferences?: string;
|
|
1060
|
+
* }
|
|
1061
|
+
* ```
|
|
1062
|
+
*
|
|
1063
|
+
* #### Security Considerations
|
|
1064
|
+
*
|
|
1065
|
+
* - JSON validation helps prevent malformed data from being processed
|
|
1066
|
+
* - Does not execute JavaScript code (safe for untrusted input)
|
|
1067
|
+
* - Validates structure but does not validate content semantics
|
|
1068
|
+
*
|
|
1069
|
+
* @returns A property decorator that validates JSON format
|
|
1070
|
+
*
|
|
1071
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* ```typescript
|
|
1075
|
+
* // Basic usage
|
|
1076
|
+
* class Config {
|
|
1077
|
+
* @IsJSON()
|
|
1078
|
+
* settings: string;
|
|
1079
|
+
* }
|
|
1080
|
+
*
|
|
1081
|
+
* // With size constraints
|
|
1082
|
+
* class LimitedConfig {
|
|
1083
|
+
* @IsJSON()
|
|
1084
|
+
* @MaxLength(5000)
|
|
1085
|
+
* settings: string;
|
|
1086
|
+
* }
|
|
1087
|
+
* ```
|
|
1088
|
+
*
|
|
1089
|
+
* @decorator
|
|
1090
|
+
* @public
|
|
1091
|
+
*/
|
|
1092
|
+
export declare const IsJSON: () => PropertyDecorator;
|
|
1093
|
+
/**
|
|
1094
|
+
* ### IsBase64 Decorator
|
|
1095
|
+
*
|
|
1096
|
+
* Validates that a property value is a valid Base64 encoded string.
|
|
1097
|
+
* This decorator checks that the string conforms to Base64 encoding standards,
|
|
1098
|
+
* ensuring it can be properly decoded and contains only valid Base64 characters.
|
|
1099
|
+
*
|
|
1100
|
+
* #### Validation Logic
|
|
1101
|
+
*
|
|
1102
|
+
* - **Character validation**: Ensures only valid Base64 characters (A-Z, a-z, 0-9, +, /, =)
|
|
1103
|
+
* - **Length validation**: Checks that length is appropriate for Base64 encoding
|
|
1104
|
+
* - **Padding validation**: Validates proper padding with = characters
|
|
1105
|
+
* - **Format compliance**: Ensures the string follows Base64 encoding rules
|
|
1106
|
+
* - **Decodability**: Validates that the string can be properly decoded
|
|
1107
|
+
*
|
|
1108
|
+
* #### Base64 Format
|
|
1109
|
+
*
|
|
1110
|
+
* Base64 encoding represents binary data as ASCII text using 64 different characters.
|
|
1111
|
+
* Valid characters are: A-Z, a-z, 0-9, +, / with = used for padding.
|
|
1112
|
+
*
|
|
1113
|
+
* #### Usage Examples
|
|
1114
|
+
*
|
|
1115
|
+
* **Basic usage:**
|
|
1116
|
+
* ```typescript
|
|
1117
|
+
* class ImageData {
|
|
1118
|
+
* @IsRequired()
|
|
1119
|
+
* @IsBase64()
|
|
1120
|
+
* data: string;
|
|
1121
|
+
*
|
|
1122
|
+
* @IsBase64() // Optional Base64 field
|
|
1123
|
+
* thumbnail?: string;
|
|
1124
|
+
* }
|
|
1125
|
+
*
|
|
1126
|
+
* // Valid Base64 strings
|
|
1127
|
+
* const image1 = { data: "SGVsbG8gV29ybGQ=" }; // ✓ Valid ("Hello World")
|
|
1128
|
+
* const image2 = { data: "dGVzdA==" }; // ✓ Valid ("test")
|
|
1129
|
+
* const image3 = { data: "UGF5bG9hZA==" }; // ✓ Valid ("Payload")
|
|
1130
|
+
* const image4 = { data: "YWJjZGVmZ2hpams=" }; // ✓ Valid (longer string)
|
|
1131
|
+
*
|
|
1132
|
+
* // Invalid examples
|
|
1133
|
+
* const invalid1 = { data: "not-base64!" }; // ✗ Invalid characters
|
|
1134
|
+
* const invalid2 = { data: "SGVsbG8gV29ybGQ" }; // ✗ Missing padding
|
|
1135
|
+
* const invalid3 = { data: "SGVsbG8gV29ybGQ==" }; // ✗ Incorrect padding
|
|
1136
|
+
* const invalid4 = { data: "SGVsbG8gV29ybGQ===" }; // ✗ Too much padding
|
|
1137
|
+
* const invalid5 = { data: "" }; // ✗ Empty string
|
|
1138
|
+
* ```
|
|
1139
|
+
*
|
|
1140
|
+
* **File upload validation:**
|
|
1141
|
+
* ```typescript
|
|
1142
|
+
* class FileUpload {
|
|
1143
|
+
* @IsRequired()
|
|
1144
|
+
* @IsBase64()
|
|
1145
|
+
* @MaxLength(1048576) // 1MB Base64 limit
|
|
1146
|
+
* fileData: string;
|
|
1147
|
+
*
|
|
1148
|
+
* @IsOptional()
|
|
1149
|
+
* @IsBase64()
|
|
1150
|
+
* previewData?: string;
|
|
1151
|
+
* }
|
|
1152
|
+
* ```
|
|
1153
|
+
*
|
|
1154
|
+
* #### Validation Behavior
|
|
1155
|
+
*
|
|
1156
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1157
|
+
* - **Non-string values**: Returns validation error message
|
|
1158
|
+
* - **Invalid Base64**: Returns localized error message from i18n system
|
|
1159
|
+
* - **Valid Base64**: Returns `true` (asynchronous validation)
|
|
1160
|
+
*
|
|
1161
|
+
* #### Performance Considerations
|
|
1162
|
+
*
|
|
1163
|
+
* - Base64 validation uses efficient regex pattern matching
|
|
1164
|
+
* - Asynchronous validation allows for non-blocking validation of large Base64 strings
|
|
1165
|
+
* - Regex is optimized for Base64 character and format validation
|
|
1166
|
+
*
|
|
1167
|
+
* #### Internationalization Support
|
|
1168
|
+
*
|
|
1169
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1170
|
+
* The default error key is `'validator.base64'` and supports interpolation with field names and values.
|
|
1171
|
+
*
|
|
1172
|
+
* #### Common Validation Scenarios
|
|
1173
|
+
*
|
|
1174
|
+
* **Image data:**
|
|
1175
|
+
* ```typescript
|
|
1176
|
+
* class Image {
|
|
1177
|
+
* @IsRequired()
|
|
1178
|
+
* @IsBase64()
|
|
1179
|
+
* base64Data: string;
|
|
1180
|
+
* }
|
|
1181
|
+
* ```
|
|
1182
|
+
*
|
|
1183
|
+
* **File uploads:**
|
|
1184
|
+
* ```typescript
|
|
1185
|
+
* class Upload {
|
|
1186
|
+
* @IsRequired()
|
|
1187
|
+
* @IsBase64()
|
|
1188
|
+
* fileContent: string;
|
|
1189
|
+
* }
|
|
1190
|
+
* ```
|
|
1191
|
+
*
|
|
1192
|
+
* **Binary data:**
|
|
1193
|
+
* ```typescript
|
|
1194
|
+
* class BinaryData {
|
|
1195
|
+
* @IsBase64()
|
|
1196
|
+
* encodedData?: string;
|
|
1197
|
+
* }
|
|
1198
|
+
* ```
|
|
1199
|
+
*
|
|
1200
|
+
* #### Standards Compliance
|
|
1201
|
+
*
|
|
1202
|
+
* - **RFC 4648**: Compliant with Base64 encoding standard
|
|
1203
|
+
* - **RFC 2045**: Compatible with MIME Base64 encoding
|
|
1204
|
+
* - **Padding**: Properly validates padding requirements
|
|
1205
|
+
* - **Alphabet**: Uses standard Base64 alphabet (A-Z, a-z, 0-9, +, /)
|
|
1206
|
+
*
|
|
1207
|
+
* @returns A property decorator that validates Base64 format
|
|
1208
|
+
*
|
|
1209
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1210
|
+
*
|
|
1211
|
+
* @example
|
|
1212
|
+
* ```typescript
|
|
1213
|
+
* // Basic usage
|
|
1214
|
+
* class ImageData {
|
|
1215
|
+
* @IsBase64()
|
|
1216
|
+
* data: string;
|
|
1217
|
+
* }
|
|
1218
|
+
*
|
|
1219
|
+
* // With size constraints
|
|
1220
|
+
* class LimitedImageData {
|
|
1221
|
+
* @IsBase64()
|
|
1222
|
+
* @MaxLength(100000)
|
|
1223
|
+
* data: string;
|
|
1224
|
+
* }
|
|
1225
|
+
* ```
|
|
1226
|
+
*
|
|
1227
|
+
* @decorator
|
|
1228
|
+
* @public
|
|
1229
|
+
*/
|
|
1230
|
+
export declare const IsBase64: () => PropertyDecorator;
|
|
1231
|
+
/**
|
|
1232
|
+
* ### IsHexColor Decorator
|
|
1233
|
+
*
|
|
1234
|
+
* Validates that a property value is a valid hexadecimal color code.
|
|
1235
|
+
* This decorator supports various hexadecimal color formats including
|
|
1236
|
+
* 3-digit, 4-digit, 6-digit, and 8-digit hex colors with optional alpha channels.
|
|
1237
|
+
*
|
|
1238
|
+
* #### Supported Formats
|
|
1239
|
+
*
|
|
1240
|
+
* - **3-digit**: `#RGB` (e.g., `#F00`, `#ABC`)
|
|
1241
|
+
* - **4-digit**: `#RGBA` (e.g., `#F00A`, `#ABCD`) - with alpha
|
|
1242
|
+
* - **6-digit**: `#RRGGBB` (e.g., `#FF0000`, `#3366CC`)
|
|
1243
|
+
* - **8-digit**: `#RRGGBBAA` (e.g., `#FF000080`, `#3366CCFF`) - with alpha
|
|
1244
|
+
*
|
|
1245
|
+
* #### Validation Logic
|
|
1246
|
+
*
|
|
1247
|
+
* - **Format validation**: Ensures proper # prefix and valid hex digits
|
|
1248
|
+
* - **Length validation**: Accepts only valid lengths (4, 5, 7, or 9 characters)
|
|
1249
|
+
* - **Character validation**: Ensures only valid hexadecimal characters (0-9, A-F, a-f)
|
|
1250
|
+
* - **Case insensitive**: Accepts both uppercase and lowercase hex digits
|
|
1251
|
+
* - **Alpha support**: Supports alpha channel in 4-digit and 8-digit formats
|
|
1252
|
+
*
|
|
1253
|
+
* #### Usage Examples
|
|
1254
|
+
*
|
|
1255
|
+
* **Basic usage:**
|
|
1256
|
+
* ```typescript
|
|
1257
|
+
* class Theme {
|
|
1258
|
+
* @IsRequired()
|
|
1259
|
+
* @IsHexColor()
|
|
1260
|
+
* primaryColor: string;
|
|
1261
|
+
*
|
|
1262
|
+
* @IsHexColor() // Optional color field
|
|
1263
|
+
* secondaryColor?: string;
|
|
1264
|
+
* }
|
|
1265
|
+
*
|
|
1266
|
+
* // Valid hex colors
|
|
1267
|
+
* const theme1 = { primaryColor: "#FF0000" }; // ✓ Valid (6-digit red)
|
|
1268
|
+
* const theme2 = { primaryColor: "#3366cc" }; // ✓ Valid (6-digit blue)
|
|
1269
|
+
* const theme3 = { primaryColor: "#abc" }; // ✓ Valid (3-digit)
|
|
1270
|
+
* const theme4 = { primaryColor: "#FF000080" }; // ✓ Valid (8-digit with alpha)
|
|
1271
|
+
* const theme5 = { primaryColor: "#F00A" }; // ✓ Valid (4-digit with alpha)
|
|
1272
|
+
* const theme6 = { primaryColor: "#ABCDEF" }; // ✓ Valid (uppercase)
|
|
1273
|
+
*
|
|
1274
|
+
* // Invalid examples
|
|
1275
|
+
* const invalid1 = { primaryColor: "#GGG" }; // ✗ Invalid characters
|
|
1276
|
+
* const invalid2 = { primaryColor: "#12" }; // ✗ Too short
|
|
1277
|
+
* const invalid3 = { primaryColor: "#12345" }; // ✗ Invalid length
|
|
1278
|
+
* const invalid4 = { primaryColor: "FF0000" }; // ✗ Missing #
|
|
1279
|
+
* const invalid5 = { primaryColor: "#FF0000FF0" }; // ✗ Too long
|
|
1280
|
+
* const invalid6 = { primaryColor: "" }; // ✗ Empty string
|
|
1281
|
+
* ```
|
|
1282
|
+
*
|
|
1283
|
+
* **CSS/styling validation:**
|
|
1284
|
+
* ```typescript
|
|
1285
|
+
* class Stylesheet {
|
|
1286
|
+
* @IsRequired()
|
|
1287
|
+
* @IsHexColor()
|
|
1288
|
+
* @MaxLength(9) // Max hex color length
|
|
1289
|
+
* backgroundColor: string;
|
|
1290
|
+
*
|
|
1291
|
+
* @IsOptional()
|
|
1292
|
+
* @IsHexColor()
|
|
1293
|
+
* borderColor?: string;
|
|
1294
|
+
* }
|
|
1295
|
+
* ```
|
|
1296
|
+
*
|
|
1297
|
+
* #### Validation Behavior
|
|
1298
|
+
*
|
|
1299
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1300
|
+
* - **Non-string values**: Returns validation error message
|
|
1301
|
+
* - **Invalid hex colors**: Returns localized error message from i18n system
|
|
1302
|
+
* - **Valid hex colors**: Returns `true`
|
|
1303
|
+
*
|
|
1304
|
+
* #### Performance Considerations
|
|
1305
|
+
*
|
|
1306
|
+
* - Hex color validation uses efficient regex pattern matching
|
|
1307
|
+
* - Synchronous validation for fast color validation in UI contexts
|
|
1308
|
+
* - Regex is optimized for hex color format validation
|
|
1309
|
+
*
|
|
1310
|
+
* #### Internationalization Support
|
|
1311
|
+
*
|
|
1312
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1313
|
+
* The default error key is `'validator.hexColor'` and supports interpolation with field names and values.
|
|
1314
|
+
*
|
|
1315
|
+
* #### Common Validation Scenarios
|
|
1316
|
+
*
|
|
1317
|
+
* **Theme configuration:**
|
|
1318
|
+
* ```typescript
|
|
1319
|
+
* class ThemeConfig {
|
|
1320
|
+
* @IsRequired()
|
|
1321
|
+
* @IsHexColor()
|
|
1322
|
+
* primaryColor: string;
|
|
1323
|
+
* }
|
|
1324
|
+
* ```
|
|
1325
|
+
*
|
|
1326
|
+
* **CSS properties:**
|
|
1327
|
+
* ```typescript
|
|
1328
|
+
* class CSSProperties {
|
|
1329
|
+
* @IsHexColor()
|
|
1330
|
+
* color?: string;
|
|
1331
|
+
* }
|
|
1332
|
+
* ```
|
|
1333
|
+
*
|
|
1334
|
+
* **Design systems:**
|
|
1335
|
+
* ```typescript
|
|
1336
|
+
* class ColorPalette {
|
|
1337
|
+
* @IsHexColor()
|
|
1338
|
+
* brandColor?: string;
|
|
1339
|
+
* }
|
|
1340
|
+
* ```
|
|
1341
|
+
*
|
|
1342
|
+
* #### Standards Compliance
|
|
1343
|
+
*
|
|
1344
|
+
* - **CSS Color Module Level 4**: Supports modern CSS color formats
|
|
1345
|
+
* - **HTML5**: Compatible with HTML color input validation
|
|
1346
|
+
* - **Web standards**: Follows web color specification standards
|
|
1347
|
+
* - **Alpha channels**: Supports CSS rgba equivalent in hex format
|
|
1348
|
+
*
|
|
1349
|
+
* @returns A property decorator that validates hexadecimal color format
|
|
1350
|
+
*
|
|
1351
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1352
|
+
*
|
|
1353
|
+
* @example
|
|
1354
|
+
* ```typescript
|
|
1355
|
+
* // Basic usage
|
|
1356
|
+
* class Theme {
|
|
1357
|
+
* @IsHexColor()
|
|
1358
|
+
* primaryColor: string;
|
|
1359
|
+
* }
|
|
1360
|
+
*
|
|
1361
|
+
* // With length constraints
|
|
1362
|
+
* class StrictTheme {
|
|
1363
|
+
* @IsHexColor()
|
|
1364
|
+
* @MaxLength(7) // 6-digit colors only
|
|
1365
|
+
* primaryColor: string;
|
|
1366
|
+
* }
|
|
1367
|
+
* ```
|
|
1368
|
+
*
|
|
1369
|
+
* @decorator
|
|
1370
|
+
* @public
|
|
1371
|
+
*/
|
|
1372
|
+
export declare const IsHexColor: () => PropertyDecorator;
|
|
1373
|
+
/**
|
|
1374
|
+
* @summary IsCreditCard Decorator
|
|
1375
|
+
*
|
|
1376
|
+
* @description Validates that a property value is a valid credit card number using the Luhn algorithm.
|
|
1377
|
+
* This decorator checks the format and performs mathematical validation to ensure
|
|
1378
|
+
* the credit card number follows proper checksum rules used by major card networks.
|
|
1379
|
+
*
|
|
1380
|
+
* #### Validation Logic
|
|
1381
|
+
*
|
|
1382
|
+
* - **Format validation**: Removes spaces and dashes, checks for valid digits only
|
|
1383
|
+
* - **Length validation**: Ensures 13-19 digits (standard credit card length range)
|
|
1384
|
+
* - **Luhn algorithm**: Performs mathematical checksum validation
|
|
1385
|
+
* - **Character filtering**: Accepts spaces, dashes, and digits in input
|
|
1386
|
+
* - **Card type agnostic**: Works with all major credit card types (Visa, Mastercard, etc.)
|
|
1387
|
+
*
|
|
1388
|
+
* #### Luhn Algorithm
|
|
1389
|
+
*
|
|
1390
|
+
* The Luhn algorithm (mod 10) is a checksum formula used to validate credit card numbers:
|
|
1391
|
+
* 1. Double every second digit from right to left
|
|
1392
|
+
* 2. If doubling results in a two-digit number, add the digits
|
|
1393
|
+
* 3. Sum all the digits
|
|
1394
|
+
* 4. If the total modulo 10 is 0, the number is valid
|
|
1395
|
+
*
|
|
1396
|
+
* #### Usage Examples
|
|
1397
|
+
*
|
|
1398
|
+
* **Basic usage:**
|
|
1399
|
+
* ```typescript
|
|
1400
|
+
* class Payment {
|
|
1401
|
+
* @IsRequired()
|
|
1402
|
+
* @IsCreditCard()
|
|
1403
|
+
* cardNumber: string;
|
|
1404
|
+
*
|
|
1405
|
+
* @IsCreditCard() // Optional card field
|
|
1406
|
+
* backupCard?: string;
|
|
1407
|
+
* }
|
|
1408
|
+
*
|
|
1409
|
+
* // Valid credit card numbers
|
|
1410
|
+
* const payment1 = { cardNumber: "4532015112830366" }; // ✓ Valid Visa test number
|
|
1411
|
+
* const payment2 = { cardNumber: "4532-0151-1283-0366" }; // ✓ Valid with dashes
|
|
1412
|
+
* const payment3 = { cardNumber: "4532 0151 1283 0366" }; // ✓ Valid with spaces
|
|
1413
|
+
* const payment4 = { cardNumber: "5555555555554444" }; // ✓ Valid Mastercard test number
|
|
1414
|
+
* const payment5 = { cardNumber: "4111111111111111" }; // ✓ Valid Visa test number
|
|
1415
|
+
*
|
|
1416
|
+
* // Invalid examples
|
|
1417
|
+
* const invalid1 = { cardNumber: "4532015112830367" }; // ✗ Invalid checksum
|
|
1418
|
+
* const invalid2 = { cardNumber: "123" }; // ✗ Too short
|
|
1419
|
+
* const invalid3 = { cardNumber: "45320151128303664532015112830366" }; // ✗ Too long
|
|
1420
|
+
* const invalid4 = { cardNumber: "453201511283036a" }; // ✗ Contains letters
|
|
1421
|
+
* const invalid5 = { cardNumber: "" }; // ✗ Empty string
|
|
1422
|
+
* ```
|
|
1423
|
+
*
|
|
1424
|
+
* **Payment processing:**
|
|
1425
|
+
* ```typescript
|
|
1426
|
+
* class Transaction {
|
|
1427
|
+
* @IsRequired()
|
|
1428
|
+
* @IsCreditCard()
|
|
1429
|
+
* @MaxLength(19) // Standard card number length
|
|
1430
|
+
* cardNumber: string;
|
|
1431
|
+
*
|
|
1432
|
+
* @IsOptional()
|
|
1433
|
+
* @IsCreditCard()
|
|
1434
|
+
* previousCard?: string;
|
|
1435
|
+
* }
|
|
1436
|
+
* ```
|
|
1437
|
+
*
|
|
1438
|
+
* #### Validation Behavior
|
|
1439
|
+
*
|
|
1440
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1441
|
+
* - **Non-string values**: Returns validation error message
|
|
1442
|
+
* - **Invalid card numbers**: Returns localized error message from i18n system
|
|
1443
|
+
* - **Valid card numbers**: Returns `true`
|
|
1444
|
+
*
|
|
1445
|
+
* #### Performance Considerations
|
|
1446
|
+
*
|
|
1447
|
+
* - Credit card validation uses efficient mathematical operations
|
|
1448
|
+
* - Synchronous validation for fast payment processing validation
|
|
1449
|
+
* - Luhn algorithm is computationally lightweight
|
|
1450
|
+
*
|
|
1451
|
+
* #### Internationalization Support
|
|
1452
|
+
*
|
|
1453
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1454
|
+
* The default error key is `'validator.creditCard'` and supports interpolation with field names and values.
|
|
1455
|
+
*
|
|
1456
|
+
* #### Common Validation Scenarios
|
|
1457
|
+
*
|
|
1458
|
+
* **Payment forms:**
|
|
1459
|
+
* ```typescript
|
|
1460
|
+
* class PaymentForm {
|
|
1461
|
+
* @IsRequired()
|
|
1462
|
+
* @IsCreditCard()
|
|
1463
|
+
* cardNumber: string;
|
|
1464
|
+
* }
|
|
1465
|
+
* ```
|
|
1466
|
+
*
|
|
1467
|
+
* **Billing information:**
|
|
1468
|
+
* ```typescript
|
|
1469
|
+
* class Billing {
|
|
1470
|
+
* @IsCreditCard()
|
|
1471
|
+
* cardNumber?: string;
|
|
1472
|
+
* }
|
|
1473
|
+
* ```
|
|
1474
|
+
*
|
|
1475
|
+
* **Subscription services:**
|
|
1476
|
+
* ```typescript
|
|
1477
|
+
* class Subscription {
|
|
1478
|
+
* @IsRequired()
|
|
1479
|
+
* @IsCreditCard()
|
|
1480
|
+
* paymentMethod: string;
|
|
1481
|
+
* }
|
|
1482
|
+
* ```
|
|
1483
|
+
*
|
|
1484
|
+
* #### Security Considerations
|
|
1485
|
+
*
|
|
1486
|
+
* - **Client-side only**: This validation should be complemented with server-side validation
|
|
1487
|
+
* - **No card type detection**: Only validates mathematical correctness, not card type
|
|
1488
|
+
* - **Test cards**: Accepts test card numbers commonly used in development
|
|
1489
|
+
* - **Tokenization**: Consider using tokenized card numbers for enhanced security
|
|
1490
|
+
*
|
|
1491
|
+
* #### Standards Compliance
|
|
1492
|
+
*
|
|
1493
|
+
* - **ISO/IEC 7812**: Compatible with credit card numbering standards
|
|
1494
|
+
* - **Luhn algorithm**: Implements standard checksum validation
|
|
1495
|
+
* - **Major card networks**: Works with Visa, Mastercard, American Express, Discover, etc.
|
|
1496
|
+
*
|
|
1497
|
+
* @returns A property decorator that validates credit card number format and checksum
|
|
1498
|
+
*
|
|
1499
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* ```typescript
|
|
1503
|
+
* // Basic usage
|
|
1504
|
+
* class Payment {
|
|
1505
|
+
* @IsCreditCard()
|
|
1506
|
+
* cardNumber: string;
|
|
1507
|
+
* }
|
|
1508
|
+
*
|
|
1509
|
+
* // With additional constraints
|
|
1510
|
+
* class SecurePayment {
|
|
1511
|
+
* @IsCreditCard()
|
|
1512
|
+
* @MaxLength(19)
|
|
1513
|
+
* cardNumber: string;
|
|
1514
|
+
* }
|
|
1515
|
+
* ```
|
|
1516
|
+
*
|
|
1517
|
+
* @decorator
|
|
1518
|
+
* @public
|
|
1519
|
+
*/
|
|
1520
|
+
export declare const IsCreditCard: () => PropertyDecorator;
|
|
1521
|
+
/**
|
|
1522
|
+
* @summary IsIP Decorator
|
|
1523
|
+
*
|
|
1524
|
+
* @description Validates that a property value is a valid IP (Internet Protocol) address.
|
|
1525
|
+
* This decorator supports both IPv4 and IPv6 address validation with configurable
|
|
1526
|
+
* version restrictions, ensuring proper network address format compliance.
|
|
1527
|
+
*
|
|
1528
|
+
* #### Validation Logic
|
|
1529
|
+
*
|
|
1530
|
+
* - **Version support**: Accepts IPv4, IPv6, or both (configurable)
|
|
1531
|
+
* - **IPv4 validation**: Validates dotted decimal format (0.0.0.0 to 255.255.255.255)
|
|
1532
|
+
* - **IPv6 validation**: Validates hexadecimal format with colon separation
|
|
1533
|
+
* - **Format compliance**: Ensures proper octet/hexadecimal group structure
|
|
1534
|
+
* - **Leading zeros**: Allows but validates proper range limits
|
|
1535
|
+
* - **Compressed notation**: Supports IPv6 compression (::) and leading zero compression
|
|
1536
|
+
*
|
|
1537
|
+
* #### IP Address Formats
|
|
1538
|
+
*
|
|
1539
|
+
* **IPv4**: `192.168.1.1`, `10.0.0.1`, `172.16.0.0`
|
|
1540
|
+
* **IPv6**: `2001:0db8:85a3:0000:0000:8a2e:0370:7334`, `::1`, `::ffff:192.0.2.1`
|
|
1541
|
+
*
|
|
1542
|
+
* #### Usage Examples
|
|
1543
|
+
*
|
|
1544
|
+
* **Basic usage:**
|
|
1545
|
+
* ```typescript
|
|
1546
|
+
* class NetworkConfig {
|
|
1547
|
+
* @IsRequired()
|
|
1548
|
+
* @IsIP() // Accepts both IPv4 and IPv6
|
|
1549
|
+
* serverAddress: string;
|
|
1550
|
+
*
|
|
1551
|
+
* @IsIP() // Optional IP field
|
|
1552
|
+
* gatewayAddress?: string;
|
|
1553
|
+
* }
|
|
1554
|
+
*
|
|
1555
|
+
* // Valid IP addresses
|
|
1556
|
+
* const config1 = { serverAddress: "192.168.1.1" }; // ✓ Valid IPv4
|
|
1557
|
+
* const config2 = { serverAddress: "2001:0db8:85a3::8a2e:0370:7334" }; // ✓ Valid IPv6
|
|
1558
|
+
* const config3 = { serverAddress: "::1" }; // ✓ Valid IPv6 loopback
|
|
1559
|
+
* const config4 = { serverAddress: "10.0.0.1" }; // ✓ Valid IPv4
|
|
1560
|
+
* const config5 = { serverAddress: "::ffff:192.0.2.1" }; // ✓ Valid IPv4-mapped IPv6
|
|
1561
|
+
*
|
|
1562
|
+
* // Invalid examples
|
|
1563
|
+
* const invalid1 = { serverAddress: "256.1.1.1" }; // ✗ Invalid IPv4 (octet > 255)
|
|
1564
|
+
* const invalid2 = { serverAddress: "192.168.1" }; // ✗ Invalid IPv4 (missing octet)
|
|
1565
|
+
* const invalid3 = { serverAddress: "2001:0db8:85a3:0000:0000:8a2e:0370" }; // ✗ Invalid IPv6 (incomplete)
|
|
1566
|
+
* const invalid4 = { serverAddress: "not-an-ip" }; // ✗ Invalid format
|
|
1567
|
+
* const invalid5 = { serverAddress: "" }; // ✗ Empty string
|
|
1568
|
+
* ```
|
|
1569
|
+
*
|
|
1570
|
+
* **Version-specific validation:**
|
|
1571
|
+
* ```typescript
|
|
1572
|
+
* class StrictNetworkConfig {
|
|
1573
|
+
* @IsRequired()
|
|
1574
|
+
* @IsIP(['4']) // IPv4 only
|
|
1575
|
+
* ipv4Address: string;
|
|
1576
|
+
*
|
|
1577
|
+
* @IsRequired()
|
|
1578
|
+
* @IsIP(['6']) // IPv6 only
|
|
1579
|
+
* ipv6Address: string;
|
|
1580
|
+
*
|
|
1581
|
+
* @IsIP() // Both versions allowed
|
|
1582
|
+
* flexibleAddress?: string;
|
|
1583
|
+
* }
|
|
1584
|
+
* ```
|
|
1585
|
+
*
|
|
1586
|
+
* #### Validation Behavior
|
|
1587
|
+
*
|
|
1588
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1589
|
+
* - **Non-string values**: Returns validation error message
|
|
1590
|
+
* - **Invalid IP addresses**: Returns localized error message from i18n system
|
|
1591
|
+
* - **Valid IP addresses**: Returns `true`
|
|
1592
|
+
*
|
|
1593
|
+
* #### Performance Considerations
|
|
1594
|
+
*
|
|
1595
|
+
* - IP validation uses efficient regular expressions optimized for each IP version
|
|
1596
|
+
* - Synchronous validation for fast network configuration validation
|
|
1597
|
+
* - Regex patterns are pre-compiled and cached for repeated use
|
|
1598
|
+
*
|
|
1599
|
+
* #### Internationalization Support
|
|
1600
|
+
*
|
|
1601
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1602
|
+
* The default error key is `'validator.ip'` and supports interpolation with field names, values, and IP version.
|
|
1603
|
+
*
|
|
1604
|
+
* #### Common Validation Scenarios
|
|
1605
|
+
*
|
|
1606
|
+
* **Network configuration:**
|
|
1607
|
+
* ```typescript
|
|
1608
|
+
* class NetworkSettings {
|
|
1609
|
+
* @IsRequired()
|
|
1610
|
+
* @IsIP(['4'])
|
|
1611
|
+
* ipAddress: string;
|
|
1612
|
+
*
|
|
1613
|
+
* @IsIP(['4'])
|
|
1614
|
+
* subnetMask?: string;
|
|
1615
|
+
*
|
|
1616
|
+
* @IsIP(['4'])
|
|
1617
|
+
* gateway?: string;
|
|
1618
|
+
* }
|
|
1619
|
+
* ```
|
|
1620
|
+
*
|
|
1621
|
+
* **Server configuration:**
|
|
1622
|
+
* ```typescript
|
|
1623
|
+
* class ServerConfig {
|
|
1624
|
+
* @IsRequired()
|
|
1625
|
+
* @IsIP() // Accepts both IPv4 and IPv6
|
|
1626
|
+
* bindAddress: string;
|
|
1627
|
+
*
|
|
1628
|
+
* @IsIP()
|
|
1629
|
+
* allowedHosts?: string[];
|
|
1630
|
+
* }
|
|
1631
|
+
* ```
|
|
1632
|
+
*
|
|
1633
|
+
* **DNS and networking:**
|
|
1634
|
+
* ```typescript
|
|
1635
|
+
* class DNSRecord {
|
|
1636
|
+
* @IsRequired()
|
|
1637
|
+
* @IsIP()
|
|
1638
|
+
* address: string;
|
|
1639
|
+
*
|
|
1640
|
+
* @IsIP(['6'])
|
|
1641
|
+
* ipv6Address?: string;
|
|
1642
|
+
* }
|
|
1643
|
+
* ```
|
|
1644
|
+
*
|
|
1645
|
+
* #### Standards Compliance
|
|
1646
|
+
*
|
|
1647
|
+
* - **RFC 791**: IPv4 address format compliance
|
|
1648
|
+
* - **RFC 4291**: IPv6 address format compliance
|
|
1649
|
+
* - **RFC 5952**: IPv6 text representation recommendations
|
|
1650
|
+
* - **RFC 3986**: URI address literal format support
|
|
1651
|
+
*
|
|
1652
|
+
* #### Security Considerations
|
|
1653
|
+
*
|
|
1654
|
+
* - Validates address format but does not check for reserved/private addresses
|
|
1655
|
+
* - Does not perform reachability or routing validation
|
|
1656
|
+
* - Suitable for format validation in network configuration contexts
|
|
1657
|
+
* - Consider additional validation for security-critical applications
|
|
1658
|
+
*
|
|
1659
|
+
* @param ruleParams - Optional array specifying IP version(s) to validate
|
|
1660
|
+
* @param ruleParams[0] - IP version: "4" (IPv4 only), "6" (IPv6 only), or "4/6" (both, default)
|
|
1661
|
+
* @returns A property decorator that validates IP address format
|
|
1662
|
+
*
|
|
1663
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1664
|
+
*
|
|
1665
|
+
* @example
|
|
1666
|
+
* ```typescript
|
|
1667
|
+
* // Basic usage (accepts both IPv4 and IPv6)
|
|
1668
|
+
* class NetworkDevice {
|
|
1669
|
+
* @IsIP()
|
|
1670
|
+
* ipAddress: string;
|
|
1671
|
+
* }
|
|
1672
|
+
*
|
|
1673
|
+
* // IPv4 only
|
|
1674
|
+
* class IPv4Device {
|
|
1675
|
+
* @IsIP(['4'])
|
|
1676
|
+
* ipv4Address: string;
|
|
1677
|
+
* }
|
|
1678
|
+
*
|
|
1679
|
+
* // IPv6 only
|
|
1680
|
+
* class IPv6Device {
|
|
1681
|
+
* @IsIP(['6'])
|
|
1682
|
+
* ipv6Address: string;
|
|
1683
|
+
* }
|
|
1684
|
+
* ```
|
|
1685
|
+
*
|
|
1686
|
+
* @decorator
|
|
1687
|
+
* @public
|
|
1688
|
+
*/
|
|
1689
|
+
export declare const IsIP: (...ruleParameters: string[]) => PropertyDecorator;
|
|
1690
|
+
/**
|
|
1691
|
+
* @summary IsMACAddress Decorator
|
|
1692
|
+
*
|
|
1693
|
+
* @description Validates that a property value is a valid Media Access Control (MAC) address.
|
|
1694
|
+
* This decorator supports multiple common MAC address formats used in networking,
|
|
1695
|
+
* ensuring proper hardware address format compliance for network device identification.
|
|
1696
|
+
*
|
|
1697
|
+
* #### Validation Logic
|
|
1698
|
+
*
|
|
1699
|
+
* - **Format support**: Accepts colon-separated, dash-separated, and compact hexadecimal formats
|
|
1700
|
+
* - **Character validation**: Ensures only valid hexadecimal characters (0-9, A-F, a-f)
|
|
1701
|
+
* - **Length validation**: Validates proper 48-bit (6-byte) MAC address length
|
|
1702
|
+
* - **Case insensitive**: Accepts both uppercase and lowercase hexadecimal digits
|
|
1703
|
+
* - **Separator validation**: Supports standard networking separators (: and -)
|
|
1704
|
+
*
|
|
1705
|
+
* #### MAC Address Formats
|
|
1706
|
+
*
|
|
1707
|
+
* - **Colon-separated**: `00:1B:44:11:3A:B7` (most common)
|
|
1708
|
+
* - **Dash-separated**: `00-1B-44-11-3A-B7` (Windows format)
|
|
1709
|
+
* - **Compact**: `001B44113AB7` (12 hexadecimal digits, no separators)
|
|
1710
|
+
*
|
|
1711
|
+
* #### Usage Examples
|
|
1712
|
+
*
|
|
1713
|
+
* **Basic usage:**
|
|
1714
|
+
* ```typescript
|
|
1715
|
+
* class NetworkDevice {
|
|
1716
|
+
* @IsRequired()
|
|
1717
|
+
* @IsMACAddress()
|
|
1718
|
+
* macAddress: string;
|
|
1719
|
+
*
|
|
1720
|
+
* @IsMACAddress() // Optional MAC field
|
|
1721
|
+
* backupMac?: string;
|
|
1722
|
+
* }
|
|
1723
|
+
*
|
|
1724
|
+
* // Valid MAC addresses
|
|
1725
|
+
* const device1 = { macAddress: "00:1B:44:11:3A:B7" }; // ✓ Valid (colon-separated)
|
|
1726
|
+
* const device2 = { macAddress: "00-1B-44-11-3A-B7" }; // ✓ Valid (dash-separated)
|
|
1727
|
+
* const device3 = { macAddress: "001B44113AB7" }; // ✓ Valid (compact)
|
|
1728
|
+
* const device4 = { macAddress: "a1:b2:c3:d4:e5:f6" }; // ✓ Valid (lowercase)
|
|
1729
|
+
* const device5 = { macAddress: "FF:FF:FF:FF:FF:FF" }; // ✓ Valid (broadcast)
|
|
1730
|
+
* const device6 = { macAddress: "00:00:00:00:00:00" }; // ✓ Valid (null address)
|
|
1731
|
+
*
|
|
1732
|
+
* // Invalid examples
|
|
1733
|
+
* const invalid1 = { macAddress: "00:1B:44:11:3A" }; // ✗ Invalid (too short)
|
|
1734
|
+
* const invalid2 = { macAddress: "00:1B:44:11:3A:B7:extra" }; // ✗ Invalid (too long)
|
|
1735
|
+
* const invalid3 = { macAddress: "GG:1B:44:11:3A:B7" }; // ✗ Invalid (non-hex character)
|
|
1736
|
+
* const invalid4 = { macAddress: "00:1B:44:11:3A:B" }; // ✗ Invalid (incomplete byte)
|
|
1737
|
+
* const invalid5 = { macAddress: "001B44113AB" }; // ✗ Invalid (too short)
|
|
1738
|
+
* const invalid6 = { macAddress: "" }; // ✗ Empty string
|
|
1739
|
+
* ```
|
|
1740
|
+
*
|
|
1741
|
+
* **Network device configuration:**
|
|
1742
|
+
* ```typescript
|
|
1743
|
+
* class RouterConfig {
|
|
1744
|
+
* @IsRequired()
|
|
1745
|
+
* @IsMACAddress()
|
|
1746
|
+
* @MaxLength(17) // Standard MAC address length
|
|
1747
|
+
* deviceMac: string;
|
|
1748
|
+
*
|
|
1749
|
+
* @IsOptional()
|
|
1750
|
+
* @IsMACAddress()
|
|
1751
|
+
* gatewayMac?: string;
|
|
1752
|
+
* }
|
|
1753
|
+
* ```
|
|
1754
|
+
*
|
|
1755
|
+
* #### Validation Behavior
|
|
1756
|
+
*
|
|
1757
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1758
|
+
* - **Non-string values**: Returns validation error message
|
|
1759
|
+
* - **Invalid MAC addresses**: Returns localized error message from i18n system
|
|
1760
|
+
* - **Valid MAC addresses**: Returns `true`
|
|
1761
|
+
*
|
|
1762
|
+
* #### Performance Considerations
|
|
1763
|
+
*
|
|
1764
|
+
* - MAC address validation uses efficient regular expressions
|
|
1765
|
+
* - Synchronous validation for fast network device validation
|
|
1766
|
+
* - Regex patterns are optimized for common MAC address formats
|
|
1767
|
+
*
|
|
1768
|
+
* #### Internationalization Support
|
|
1769
|
+
*
|
|
1770
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1771
|
+
* The default error key is `'validator.macAddress'` and supports interpolation with field names and values.
|
|
1772
|
+
*
|
|
1773
|
+
* #### Common Validation Scenarios
|
|
1774
|
+
*
|
|
1775
|
+
* **Network hardware:**
|
|
1776
|
+
* ```typescript
|
|
1777
|
+
* class NetworkInterface {
|
|
1778
|
+
* @IsRequired()
|
|
1779
|
+
* @IsMACAddress()
|
|
1780
|
+
* physicalAddress: string;
|
|
1781
|
+
* }
|
|
1782
|
+
* ```
|
|
1783
|
+
*
|
|
1784
|
+
* **Device management:**
|
|
1785
|
+
* ```typescript
|
|
1786
|
+
* class Device {
|
|
1787
|
+
* @IsRequired()
|
|
1788
|
+
* @IsMACAddress()
|
|
1789
|
+
* macAddress: string;
|
|
1790
|
+
*
|
|
1791
|
+
* @IsMACAddress()
|
|
1792
|
+
* bluetoothMac?: string;
|
|
1793
|
+
* }
|
|
1794
|
+
* ```
|
|
1795
|
+
*
|
|
1796
|
+
* **Access control:**
|
|
1797
|
+
* ```typescript
|
|
1798
|
+
* class AccessList {
|
|
1799
|
+
* @IsMACAddress()
|
|
1800
|
+
* allowedMacs?: string[];
|
|
1801
|
+
* }
|
|
1802
|
+
* ```
|
|
1803
|
+
*
|
|
1804
|
+
* #### Standards Compliance
|
|
1805
|
+
*
|
|
1806
|
+
* - **IEEE 802**: Compliant with IEEE 802 MAC address standards
|
|
1807
|
+
* - **EUI-48**: Supports Extended Unique Identifier (48-bit) format
|
|
1808
|
+
* - **RFC 2469**: Compatible with IPv6 interface identifiers
|
|
1809
|
+
* - **RFC 7042**: Supports various MAC address text representations
|
|
1810
|
+
*
|
|
1811
|
+
* #### Security Considerations
|
|
1812
|
+
*
|
|
1813
|
+
* - **Format validation only**: Validates address format but does not check for reserved addresses
|
|
1814
|
+
* - **No uniqueness validation**: Does not verify MAC address uniqueness in networks
|
|
1815
|
+
* - **Privacy considerations**: MAC addresses can be used for device tracking
|
|
1816
|
+
* - **Access control**: Consider additional validation for security-critical applications
|
|
1817
|
+
*
|
|
1818
|
+
* @returns A property decorator that validates MAC address format
|
|
1819
|
+
*
|
|
1820
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1821
|
+
*
|
|
1822
|
+
* @example
|
|
1823
|
+
* ```typescript
|
|
1824
|
+
* // Basic usage
|
|
1825
|
+
* class NetworkDevice {
|
|
1826
|
+
* @IsMACAddress()
|
|
1827
|
+
* macAddress: string;
|
|
1828
|
+
* }
|
|
1829
|
+
*
|
|
1830
|
+
* // With additional constraints
|
|
1831
|
+
* class StrictNetworkDevice {
|
|
1832
|
+
* @IsMACAddress()
|
|
1833
|
+
* @MaxLength(17) // Enforce colon-separated format
|
|
1834
|
+
* macAddress: string;
|
|
1835
|
+
* }
|
|
1836
|
+
* ```
|
|
1837
|
+
*
|
|
1838
|
+
* @decorator
|
|
1839
|
+
* @public
|
|
1840
|
+
*/
|
|
1841
|
+
export declare const IsMACAddress: () => PropertyDecorator;
|
|
1842
|
+
/**
|
|
1843
|
+
* @summary Matches Decorator
|
|
1844
|
+
*
|
|
1845
|
+
* @description Validates that a property value matches a specified regular expression pattern.
|
|
1846
|
+
* This decorator provides flexible pattern-based validation using JavaScript regular expressions,
|
|
1847
|
+
* allowing for complex string validation requirements beyond built-in format validators.
|
|
1848
|
+
*
|
|
1849
|
+
* #### Validation Logic
|
|
1850
|
+
*
|
|
1851
|
+
* - **Pattern matching**: Uses JavaScript RegExp for flexible pattern validation
|
|
1852
|
+
* - **Custom patterns**: Accepts any valid regular expression pattern
|
|
1853
|
+
* - **Case sensitivity**: Respects regex flags (case-insensitive with /i flag)
|
|
1854
|
+
* - **Error customization**: Supports custom error messages via i18n keys
|
|
1855
|
+
* - **Pattern validation**: Validates regex syntax before testing
|
|
1856
|
+
*
|
|
1857
|
+
* #### Pattern Format
|
|
1858
|
+
*
|
|
1859
|
+
* Patterns can be provided as:
|
|
1860
|
+
* - **String patterns**: `'^[a-z]+$'` (converted to RegExp)
|
|
1861
|
+
* - **RegExp objects**: `/^[a-z]+$/i` (direct RegExp usage)
|
|
1862
|
+
*
|
|
1863
|
+
* #### Usage Examples
|
|
1864
|
+
*
|
|
1865
|
+
* **Basic usage:**
|
|
1866
|
+
* ```typescript
|
|
1867
|
+
* class User {
|
|
1868
|
+
* @IsRequired()
|
|
1869
|
+
* @Matches('^[a-zA-Z0-9_]+$', {message: 'username.invalid'})
|
|
1870
|
+
* username: string;
|
|
1871
|
+
*
|
|
1872
|
+
* @Matches('^\\+?[1-9]\\d{1,14}$') // E.164 phone pattern
|
|
1873
|
+
* phoneNumber?: string;
|
|
1874
|
+
* }
|
|
1875
|
+
*
|
|
1876
|
+
* // Valid matches
|
|
1877
|
+
* const user1 = { username: "john_doe123" }; // ✓ Valid (alphanumeric + underscore)
|
|
1878
|
+
* const user2 = { username: "testUser" }; // ✓ Valid (letters and numbers)
|
|
1879
|
+
* const user3 = { phoneNumber: "+1234567890" }; // ✓ Valid (E.164 format)
|
|
1880
|
+
* const user4 = { phoneNumber: "1234567890" }; // ✓ Valid (without country code)
|
|
1881
|
+
*
|
|
1882
|
+
* // Invalid examples
|
|
1883
|
+
* const invalid1 = { username: "user-name" }; // ✗ Invalid (contains hyphen)
|
|
1884
|
+
* const invalid2 = { username: "user@domain" }; // ✗ Invalid (contains @)
|
|
1885
|
+
* const invalid3 = { username: "" }; // ✗ Invalid (empty string)
|
|
1886
|
+
* const invalid4 = { phoneNumber: "abc123" }; // ✗ Invalid (non-numeric)
|
|
1887
|
+
* ```
|
|
1888
|
+
*
|
|
1889
|
+
* **Advanced patterns:**
|
|
1890
|
+
* ```typescript
|
|
1891
|
+
* class ValidationExamples {
|
|
1892
|
+
* @Matches('^[A-Z][a-z]+$', {message: 'name.capitalized'})
|
|
1893
|
+
* firstName: string; // Must start with capital letter
|
|
1894
|
+
*
|
|
1895
|
+
* @Matches('^\\d{5}(-\\d{4})?$', {message: 'zipcode.invalid'})
|
|
1896
|
+
* zipCode: string; // US ZIP code format
|
|
1897
|
+
*
|
|
1898
|
+
* @Matches('^(http|https)://[^\\s/$.?#].[^\\s]*$', {message: 'url.invalid'})
|
|
1899
|
+
* website?: string; // Basic URL pattern
|
|
1900
|
+
*
|
|
1901
|
+
* @Matches('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$', {message: 'uuid.invalid'})
|
|
1902
|
+
* customId?: string; // UUID pattern
|
|
1903
|
+
* }
|
|
1904
|
+
* ```
|
|
1905
|
+
*
|
|
1906
|
+
* #### Validation Behavior
|
|
1907
|
+
*
|
|
1908
|
+
* - **Empty/null values**: Returns validation error message (use `@IsOptional()` for optional fields)
|
|
1909
|
+
* - **Non-string values**: Returns validation error message
|
|
1910
|
+
* - **Invalid patterns**: Returns error for malformed regex patterns
|
|
1911
|
+
* - **No pattern provided**: Returns parameter validation error
|
|
1912
|
+
* - **Pattern mismatch**: Returns localized error message from i18n system
|
|
1913
|
+
* - **Valid matches**: Returns `true`
|
|
1914
|
+
*
|
|
1915
|
+
* #### Performance Considerations
|
|
1916
|
+
*
|
|
1917
|
+
* - Regex compilation happens on each validation (consider caching for high-frequency patterns)
|
|
1918
|
+
* - Synchronous validation for immediate pattern matching
|
|
1919
|
+
* - Complex regex patterns may impact performance with large input strings
|
|
1920
|
+
* - Simple patterns are highly optimized by JavaScript engines
|
|
1921
|
+
*
|
|
1922
|
+
* #### Internationalization Support
|
|
1923
|
+
*
|
|
1924
|
+
* Error messages are fully internationalized and can be customized through the validator's i18n system.
|
|
1925
|
+
* Supports both default error key `'validator.matches'` and custom error message keys.
|
|
1926
|
+
* The default error key supports interpolation with field names, values, and pattern information.
|
|
1927
|
+
*
|
|
1928
|
+
* #### Common Validation Scenarios
|
|
1929
|
+
*
|
|
1930
|
+
* **Username validation:**
|
|
1931
|
+
* ```typescript
|
|
1932
|
+
* class UserAccount {
|
|
1933
|
+
* @IsRequired()
|
|
1934
|
+
* @Matches('^[a-zA-Z0-9_]{3,20}$', {message: 'username.invalid'})
|
|
1935
|
+
* username: string;
|
|
1936
|
+
* }
|
|
1937
|
+
* ```
|
|
1938
|
+
*
|
|
1939
|
+
* **Password complexity:**
|
|
1940
|
+
* ```typescript
|
|
1941
|
+
* class SecureAccount {
|
|
1942
|
+
* @Matches('(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}', {message: 'password.weak'})
|
|
1943
|
+
* password?: string; // At least 1 lowercase, 1 uppercase, 1 digit, 1 special char, 8+ chars
|
|
1944
|
+
* }
|
|
1945
|
+
* ```
|
|
1946
|
+
*
|
|
1947
|
+
* **Custom formats:**
|
|
1948
|
+
* ```typescript
|
|
1949
|
+
* class Product {
|
|
1950
|
+
* @Matches('^[A-Z]{2}-\\d{4}$', {message: 'productCode.invalid'})
|
|
1951
|
+
* productCode: string; // Format: AB-1234
|
|
1952
|
+
*
|
|
1953
|
+
* @Matches('^v\\d+\\.\\d+\\.\\d+$', {message: 'version.invalid'})
|
|
1954
|
+
* version?: string; // Semantic versioning: v1.2.3
|
|
1955
|
+
* }
|
|
1956
|
+
* ```
|
|
1957
|
+
*
|
|
1958
|
+
* #### Security Considerations
|
|
1959
|
+
*
|
|
1960
|
+
* - **ReDoS vulnerability**: Complex regex patterns can be vulnerable to Regular Expression Denial of Service
|
|
1961
|
+
* - **Input validation**: Always validate input length before regex matching
|
|
1962
|
+
* - **Pattern complexity**: Avoid overly complex patterns that may cause performance issues
|
|
1963
|
+
* - **User input in patterns**: Never allow user-provided regex patterns in production code
|
|
1964
|
+
* - **Sanitization**: Ensure patterns don't contain malicious regex constructs
|
|
1965
|
+
*
|
|
1966
|
+
* #### Best Practices
|
|
1967
|
+
*
|
|
1968
|
+
* - **Pattern testing**: Thoroughly test regex patterns with various inputs
|
|
1969
|
+
* - **Anchors**: Use `^` and `$` anchors to match entire strings
|
|
1970
|
+
* - **Escaping**: Properly escape special regex characters in patterns
|
|
1971
|
+
* - **Alternatives**: Consider built-in validators for common patterns (email, URL, etc.)
|
|
1972
|
+
* - **Documentation**: Document complex patterns for maintainability
|
|
1973
|
+
* - **Performance**: Profile regex performance with expected input sizes
|
|
1974
|
+
*
|
|
1975
|
+
* @param ruleParams - Array containing regex pattern and optional error message
|
|
1976
|
+
* @param ruleParams[0] - Regular expression pattern as string or RegExp object (required)
|
|
1977
|
+
* @param ruleParams[1] - Optional custom error message key for i18n translation
|
|
1978
|
+
* @returns A property decorator that validates string patterns using regular expressions
|
|
1979
|
+
*
|
|
1980
|
+
* @throws {ValidationError} When validation fails, containing localized error message
|
|
1981
|
+
*
|
|
1982
|
+
* @example
|
|
1983
|
+
* ```typescript
|
|
1984
|
+
* // Basic pattern matching
|
|
1985
|
+
* class Validation {
|
|
1986
|
+
* @Matches('^[a-z]+$', {message: 'lowercase.required'})
|
|
1987
|
+
* lowercaseOnly: string;
|
|
1988
|
+
* }
|
|
1989
|
+
*
|
|
1990
|
+
* // With custom error message
|
|
1991
|
+
* class CustomValidation {
|
|
1992
|
+
* @Matches('^\\d{3}-\\d{2}-\\d{4}$', {message: 'ssn.invalid'})
|
|
1993
|
+
* socialSecurity: string;
|
|
1994
|
+
* }
|
|
1995
|
+
*
|
|
1996
|
+
* // Complex validation
|
|
1997
|
+
* class AdvancedValidation {
|
|
1998
|
+
* @Matches('(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}', {message: 'password.complexity'})
|
|
1999
|
+
* strongPassword: string;
|
|
2000
|
+
* }
|
|
2001
|
+
* ```
|
|
2002
|
+
*
|
|
2003
|
+
* @decorator
|
|
2004
|
+
* @public
|
|
2005
|
+
*/
|
|
2006
|
+
export declare const Matches: (pattern: string | RegExp, options?: {
|
|
2007
|
+
message?: string;
|
|
2008
|
+
} | undefined) => PropertyDecorator;
|
|
2009
|
+
declare module '../types' {
|
|
2010
|
+
interface ValidatorRuleParamTypes {
|
|
2011
|
+
/**
|
|
2012
|
+
* @summary Url Rule
|
|
2013
|
+
*
|
|
2014
|
+
* @description Validates that the field under validation is a properly formatted URL.
|
|
2015
|
+
* This rule checks for valid URL structure including protocol, domain, and optional path components.
|
|
2016
|
+
*
|
|
2017
|
+
* #### Configuration Options
|
|
2018
|
+
*
|
|
2019
|
+
* The rule accepts an optional configuration object to customize validation behavior:
|
|
2020
|
+
*
|
|
2021
|
+
* - `requireHost`: If true, only allows protocols that require a hostname (http, https, ftp, etc.).
|
|
2022
|
+
* If false, allows all valid protocols including mailto, tel, data, etc. (default: true)
|
|
2023
|
+
* - `allowedProtocols`: List of allowed protocols. If provided, only URLs with these protocols are considered valid.
|
|
2024
|
+
* Protocols should be specified without the trailing colon (e.g., 'http', not 'http:').
|
|
2025
|
+
*
|
|
2026
|
+
* @example
|
|
2027
|
+
* ```typescript
|
|
2028
|
+
* // Valid URLs
|
|
2029
|
+
* await Validator.validate({
|
|
2030
|
+
* value: 'https://example.com',
|
|
2031
|
+
* rules: ['Url']
|
|
2032
|
+
* }); // ✓ Valid
|
|
2033
|
+
*
|
|
2034
|
+
* await Validator.validate({
|
|
2035
|
+
* value: 'https://example.com/path?query=value#fragment',
|
|
2036
|
+
* rules: ['Url']
|
|
2037
|
+
* }); // ✓ Valid
|
|
2038
|
+
*
|
|
2039
|
+
* await Validator.validate({
|
|
2040
|
+
* value: 'ftp://ftp.example.com/file.txt',
|
|
2041
|
+
* rules: ['Url']
|
|
2042
|
+
* }); // ✓ Valid
|
|
2043
|
+
*
|
|
2044
|
+
* // Invalid examples
|
|
2045
|
+
* await Validator.validate({
|
|
2046
|
+
* value: 'not-a-url',
|
|
2047
|
+
* rules: ['Url']
|
|
2048
|
+
* }); // ✗ Invalid (missing protocol)
|
|
2049
|
+
*
|
|
2050
|
+
* await Validator.validate({
|
|
2051
|
+
* value: 'example.com',
|
|
2052
|
+
* rules: ['Url']
|
|
2053
|
+
* }); // ✗ Invalid (missing protocol)
|
|
2054
|
+
*
|
|
2055
|
+
* await Validator.validate({
|
|
2056
|
+
* value: 'mailto:user@example.com',
|
|
2057
|
+
* rules: ['Url']
|
|
2058
|
+
* }); // ✗ Invalid (default requires host)
|
|
2059
|
+
*
|
|
2060
|
+
* await Validator.validate({
|
|
2061
|
+
* value: 123,
|
|
2062
|
+
* rules: ['Url']
|
|
2063
|
+
* }); // ✗ Invalid (not a string)
|
|
2064
|
+
*
|
|
2065
|
+
* // Class validation with custom options
|
|
2066
|
+
* class Website {
|
|
2067
|
+
* @IsUrl() // Default: requires host
|
|
2068
|
+
* homepage: string;
|
|
2069
|
+
*
|
|
2070
|
+
* @IsUrl({ requireHost: false }) // Allow mailto, tel, etc.
|
|
2071
|
+
* contactUrl?: string;
|
|
2072
|
+
*
|
|
2073
|
+
* @IsUrl({ allowedProtocols: ['https'] }) // Only HTTPS
|
|
2074
|
+
* secureUrl: string;
|
|
2075
|
+
* }
|
|
2076
|
+
* ```
|
|
2077
|
+
*
|
|
2078
|
+
* @param options - Optional configuration object for URL validation
|
|
2079
|
+
* @param options.requireHost - Whether to require protocols that need a hostname (default: true)
|
|
2080
|
+
* @param options.allowedProtocols - Array of allowed protocols without colons
|
|
2081
|
+
* @returns true if valid URL, rejecting with error message if invalid
|
|
2082
|
+
*
|
|
2083
|
+
* @public
|
|
2084
|
+
*/
|
|
2085
|
+
Url: ValidatorRuleParams<[options?: IsUrlOptions]>;
|
|
2086
|
+
/**
|
|
2087
|
+
* @summary FileName Rule
|
|
2088
|
+
*
|
|
2089
|
+
* @description Validates that the field under validation is a valid file name.
|
|
2090
|
+
* This rule checks for forbidden characters and reserved names that cannot be used as file names
|
|
2091
|
+
* across different operating systems (Windows, macOS, Linux).
|
|
2092
|
+
*
|
|
2093
|
+
* #### Validation Logic
|
|
2094
|
+
* - Forbids characters: \ / : * ? " < > |
|
|
2095
|
+
* - Cannot start with a dot (.)
|
|
2096
|
+
* - Cannot be reserved names: nul, prn, con, lpt[0-9], com[0-9]
|
|
2097
|
+
* - Case-insensitive checks for reserved names
|
|
2098
|
+
*
|
|
2099
|
+
* @example
|
|
2100
|
+
* ```typescript
|
|
2101
|
+
* // Valid file names
|
|
2102
|
+
* await Validator.validate({
|
|
2103
|
+
* value: 'document.txt',
|
|
2104
|
+
* rules: ['FileName']
|
|
2105
|
+
* }); // ✓ Valid
|
|
2106
|
+
*
|
|
2107
|
+
* await Validator.validate({
|
|
2108
|
+
* value: 'my-file_123.pdf',
|
|
2109
|
+
* rules: ['FileName']
|
|
2110
|
+
* }); // ✓ Valid
|
|
2111
|
+
*
|
|
2112
|
+
* await Validator.validate({
|
|
2113
|
+
* value: 'file with spaces.jpg',
|
|
2114
|
+
* rules: ['FileName']
|
|
2115
|
+
* }); // ✓ Valid
|
|
2116
|
+
*
|
|
2117
|
+
* // Invalid examples
|
|
2118
|
+
* await Validator.validate({
|
|
2119
|
+
* value: 'file:with:colons.txt',
|
|
2120
|
+
* rules: ['FileName']
|
|
2121
|
+
* }); // ✗ Invalid (contains forbidden characters)
|
|
2122
|
+
*
|
|
2123
|
+
* await Validator.validate({
|
|
2124
|
+
* value: 'con',
|
|
2125
|
+
* rules: ['FileName']
|
|
2126
|
+
* }); // ✗ Invalid (reserved name)
|
|
2127
|
+
*
|
|
2128
|
+
* await Validator.validate({
|
|
2129
|
+
* value: '.hidden',
|
|
2130
|
+
* rules: ['FileName']
|
|
2131
|
+
* }); // ✗ Invalid (starts with dot)
|
|
2132
|
+
*
|
|
2133
|
+
* await Validator.validate({
|
|
2134
|
+
* value: 'file<name>.txt',
|
|
2135
|
+
* rules: ['FileName']
|
|
2136
|
+
* }); // ✗ Invalid (contains < >)
|
|
2137
|
+
*
|
|
2138
|
+
* await Validator.validate({
|
|
2139
|
+
* value: 123,
|
|
2140
|
+
* rules: ['FileName']
|
|
2141
|
+
* }); // ✗ Invalid (not a string)
|
|
2142
|
+
*
|
|
2143
|
+
* // Class validation
|
|
2144
|
+
* class FileUpload {
|
|
2145
|
+
* @IsRequired()
|
|
2146
|
+
* @IsFileName
|
|
2147
|
+
* fileName: string;
|
|
2148
|
+
*
|
|
2149
|
+
* @IsOptional()
|
|
2150
|
+
* @IsFileName
|
|
2151
|
+
* displayName?: string;
|
|
2152
|
+
* }
|
|
2153
|
+
* ```
|
|
2154
|
+
*
|
|
2155
|
+
* @returns true if valid file name, rejecting with error message if invalid
|
|
2156
|
+
*
|
|
2157
|
+
* @public
|
|
2158
|
+
*/
|
|
2159
|
+
FileName: ValidatorRuleParams<[]>;
|
|
2160
|
+
/**
|
|
2161
|
+
* @summary PhoneNumber Rule
|
|
2162
|
+
*
|
|
2163
|
+
* @description Validates that the field under validation is a valid phone number.
|
|
2164
|
+
* This rule uses the InputFormatter's phone number validation which supports
|
|
2165
|
+
* international phone numbers with country code detection.
|
|
2166
|
+
*
|
|
2167
|
+
* #### Parameters
|
|
2168
|
+
* - `countryCode`: Optional country code to validate against a specific country's format
|
|
2169
|
+
*
|
|
2170
|
+
* @example
|
|
2171
|
+
* ```typescript
|
|
2172
|
+
* // Valid phone numbers
|
|
2173
|
+
* await Validator.validate({
|
|
2174
|
+
* value: '+1234567890',
|
|
2175
|
+
* rules: ['PhoneNumber']
|
|
2176
|
+
* }); // ✓ Valid (international format)
|
|
2177
|
+
*
|
|
2178
|
+
* await Validator.validate({
|
|
2179
|
+
* value: '(555) 123-4567',
|
|
2180
|
+
* rules: ['PhoneNumber']
|
|
2181
|
+
* }); // ✓ Valid (US format)
|
|
2182
|
+
*
|
|
2183
|
+
* await Validator.validate({
|
|
2184
|
+
* value: '+44 20 7123 4567',
|
|
2185
|
+
* rules: ['PhoneNumber']
|
|
2186
|
+
* }); // ✓ Valid (UK format)
|
|
2187
|
+
*
|
|
2188
|
+
* // Invalid examples
|
|
2189
|
+
* await Validator.validate({
|
|
2190
|
+
* value: 'not-a-phone-number',
|
|
2191
|
+
* rules: ['PhoneNumber']
|
|
2192
|
+
* }); // ✗ Invalid (invalid format)
|
|
2193
|
+
*
|
|
2194
|
+
* await Validator.validate({
|
|
2195
|
+
* value: '123',
|
|
2196
|
+
* rules: ['PhoneNumber']
|
|
2197
|
+
* }); // ✗ Invalid (too short)
|
|
2198
|
+
*
|
|
2199
|
+
* await Validator.validate({
|
|
2200
|
+
* value: 1234567890,
|
|
2201
|
+
* rules: ['PhoneNumber']
|
|
2202
|
+
* }); // ✗ Invalid (not a string)
|
|
2203
|
+
*
|
|
2204
|
+
* // Class validation
|
|
2205
|
+
* class Contact {
|
|
2206
|
+
* @IsRequired()
|
|
2207
|
+
* @IsPhoneNumber() // Auto-detect country
|
|
2208
|
+
* phone: string;
|
|
2209
|
+
*
|
|
2210
|
+
* @IsPhoneNumber({ countryCode: 'US' }) // US format only
|
|
2211
|
+
* usPhone?: string;
|
|
2212
|
+
* }
|
|
2213
|
+
* ```
|
|
2214
|
+
*
|
|
2215
|
+
* @param options - Optional configuration object
|
|
2216
|
+
* @param options.countryCode - Country code to validate against specific country's format
|
|
2217
|
+
* @returns true if valid phone number, rejecting with error message if invalid
|
|
2218
|
+
*
|
|
2219
|
+
* @public
|
|
2220
|
+
*/
|
|
2221
|
+
PhoneNumber: ValidatorRuleParams<[countryCode?: CountryCode]>;
|
|
2222
|
+
/**
|
|
2223
|
+
* @summary EmailOrPhoneNumber Rule
|
|
2224
|
+
*
|
|
2225
|
+
* @description Validates that the field under validation is either a valid email address or a valid phone number.
|
|
2226
|
+
* This rule provides flexible validation for contact information fields that can accept either format.
|
|
2227
|
+
*
|
|
2228
|
+
* #### Configuration Options
|
|
2229
|
+
*
|
|
2230
|
+
* The rule accepts an optional configuration object with separate options for email and phone validation:
|
|
2231
|
+
*
|
|
2232
|
+
* - `email`: Email validation options (same as IsEmail rule)
|
|
2233
|
+
* - `phoneNumber`: Phone number validation options with country code
|
|
2234
|
+
*
|
|
2235
|
+
* @example
|
|
2236
|
+
* ```typescript
|
|
2237
|
+
* // Valid examples (either email or phone)
|
|
2238
|
+
* await Validator.validate({
|
|
2239
|
+
* value: 'user@example.com',
|
|
2240
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2241
|
+
* }); // ✓ Valid (email)
|
|
2242
|
+
*
|
|
2243
|
+
* await Validator.validate({
|
|
2244
|
+
* value: '+1234567890',
|
|
2245
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2246
|
+
* }); // ✓ Valid (phone)
|
|
2247
|
+
*
|
|
2248
|
+
* await Validator.validate({
|
|
2249
|
+
* value: '(555) 123-4567',
|
|
2250
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2251
|
+
* }); // ✓ Valid (phone)
|
|
2252
|
+
*
|
|
2253
|
+
* // Invalid examples
|
|
2254
|
+
* await Validator.validate({
|
|
2255
|
+
* value: 'not-valid-contact',
|
|
2256
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2257
|
+
* }); // ✗ Invalid (neither valid email nor phone)
|
|
2258
|
+
*
|
|
2259
|
+
* await Validator.validate({
|
|
2260
|
+
* value: '@example.com',
|
|
2261
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2262
|
+
* }); // ✗ Invalid (invalid email, not a phone)
|
|
2263
|
+
*
|
|
2264
|
+
* await Validator.validate({
|
|
2265
|
+
* value: '123',
|
|
2266
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2267
|
+
* }); // ✗ Invalid (too short for phone, not email)
|
|
2268
|
+
*
|
|
2269
|
+
* await Validator.validate({
|
|
2270
|
+
* value: 1234567890,
|
|
2271
|
+
* rules: ['EmailOrPhoneNumber']
|
|
2272
|
+
* }); // ✗ Invalid (not a string)
|
|
2273
|
+
*
|
|
2274
|
+
* // Class validation
|
|
2275
|
+
* class ContactForm {
|
|
2276
|
+
* @IsRequired()
|
|
2277
|
+
* @IsEmailOrPhoneNumber() // Either email or phone
|
|
2278
|
+
* contact: string;
|
|
2279
|
+
*
|
|
2280
|
+
* @IsEmailOrPhoneNumber({
|
|
2281
|
+
* email: { maxTotalLength: 100 },
|
|
2282
|
+
* phoneNumber: { countryCode: 'US' }
|
|
2283
|
+
* })
|
|
2284
|
+
* flexibleContact?: string;
|
|
2285
|
+
* }
|
|
2286
|
+
* ```
|
|
2287
|
+
*
|
|
2288
|
+
* @param options - Optional configuration object for email and phone validation
|
|
2289
|
+
* @param options.email - Email validation options (maxTotalLength, etc.)
|
|
2290
|
+
* @param options.phoneNumber - Phone validation options with country code
|
|
2291
|
+
* @returns true if valid email or phone, rejecting with error message if invalid
|
|
2292
|
+
*
|
|
2293
|
+
* @public
|
|
2294
|
+
*/
|
|
2295
|
+
EmailOrPhoneNumber: ValidatorRuleParams<[
|
|
2296
|
+
options?: {
|
|
2297
|
+
email?: IsEmailOptions;
|
|
2298
|
+
phoneNumber?: {
|
|
2299
|
+
countryCode?: CountryCode;
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
]>;
|
|
2303
|
+
/**
|
|
2304
|
+
* @summary Email Rule
|
|
2305
|
+
*
|
|
2306
|
+
* @description Validates that the field under validation is a properly formatted email address according to RFC 5322 standards.
|
|
2307
|
+
* This decorator performs comprehensive email validation including local part validation, domain validation,
|
|
2308
|
+
* international domains (IDN), IP address domains, and configurable length constraints.
|
|
2309
|
+
*
|
|
2310
|
+
* #### Configuration Options
|
|
2311
|
+
*
|
|
2312
|
+
* The rule accepts an optional configuration object to customize validation constraints:
|
|
2313
|
+
*
|
|
2314
|
+
* - `maxTotalLength`: Maximum total email length (default: 320 characters, per RFC 5321)
|
|
2315
|
+
* - `maxLocalPartLength`: Maximum local part length (default: 64 characters, per RFC 5321)
|
|
2316
|
+
* - `maxDomainLength`: Maximum domain length (default: 255 characters, per RFC 1035)
|
|
2317
|
+
* - `maxDomainLabelLength`: Maximum individual domain label length (default: 63 characters, per RFC 1035)
|
|
2318
|
+
*
|
|
2319
|
+
* @example
|
|
2320
|
+
* ```typescript
|
|
2321
|
+
* // Valid emails
|
|
2322
|
+
* await Validator.validate({
|
|
2323
|
+
* value: 'user@example.com',
|
|
2324
|
+
* rules: ['Email']
|
|
2325
|
+
* }); // ✓ Valid
|
|
2326
|
+
*
|
|
2327
|
+
* await Validator.validate({
|
|
2328
|
+
* value: 'test.email+tag@subdomain.example.co.uk',
|
|
2329
|
+
* rules: ['Email']
|
|
2330
|
+
* }); // ✓ Valid
|
|
2331
|
+
*
|
|
2332
|
+
* await Validator.validate({
|
|
2333
|
+
* value: '"quoted.name"@example.com',
|
|
2334
|
+
* rules: ['Email']
|
|
2335
|
+
* }); // ✓ Valid (quoted local part)
|
|
2336
|
+
*
|
|
2337
|
+
* await Validator.validate({
|
|
2338
|
+
* value: 'user@[192.168.1.1]',
|
|
2339
|
+
* rules: ['Email']
|
|
2340
|
+
* }); // ✓ Valid (IP domain)
|
|
2341
|
+
*
|
|
2342
|
+
* // Invalid examples
|
|
2343
|
+
* await Validator.validate({
|
|
2344
|
+
* value: 'not-an-email',
|
|
2345
|
+
* rules: ['Email']
|
|
2346
|
+
* }); // ✗ Invalid (missing @)
|
|
2347
|
+
*
|
|
2348
|
+
* await Validator.validate({
|
|
2349
|
+
* value: '@example.com',
|
|
2350
|
+
* rules: ['Email']
|
|
2351
|
+
* }); // ✗ Invalid (empty local part)
|
|
2352
|
+
*
|
|
2353
|
+
* await Validator.validate({
|
|
2354
|
+
* value: 'user@',
|
|
2355
|
+
* rules: ['Email']
|
|
2356
|
+
* }); // ✗ Invalid (empty domain)
|
|
2357
|
+
*
|
|
2358
|
+
* await Validator.validate({
|
|
2359
|
+
* value: 'user..name@example.com',
|
|
2360
|
+
* rules: ['Email']
|
|
2361
|
+
* }); // ✗ Invalid (consecutive dots)
|
|
2362
|
+
*
|
|
2363
|
+
* await Validator.validate({
|
|
2364
|
+
* value: 123,
|
|
2365
|
+
* rules: ['Email']
|
|
2366
|
+
* }); // ✗ Invalid (not a string)
|
|
2367
|
+
*
|
|
2368
|
+
* // Class validation with custom options
|
|
2369
|
+
* class User {
|
|
2370
|
+
* @IsRequired()
|
|
2371
|
+
* @IsEmail() // Default settings
|
|
2372
|
+
* email: string;
|
|
2373
|
+
*
|
|
2374
|
+
* @IsEmail({
|
|
2375
|
+
* maxTotalLength: 100,
|
|
2376
|
+
* maxLocalPartLength: 32
|
|
2377
|
+
* }) // Custom constraints
|
|
2378
|
+
* backupEmail?: string;
|
|
2379
|
+
* }
|
|
2380
|
+
* ```
|
|
2381
|
+
*
|
|
2382
|
+
* @param options - Optional configuration object for email validation constraints
|
|
2383
|
+
* @param options.maxTotalLength - Maximum total email length in characters (default: 320)
|
|
2384
|
+
* @param options.maxLocalPartLength - Maximum local part length in characters (default: 64)
|
|
2385
|
+
* @param options.maxDomainLength - Maximum domain length in characters (default: 255)
|
|
2386
|
+
* @param options.maxDomainLabelLength - Maximum domain label length in characters (default: 63)
|
|
2387
|
+
* @returns true if valid email, rejecting with error message if invalid
|
|
2388
|
+
*
|
|
2389
|
+
* @public
|
|
2390
|
+
*/
|
|
2391
|
+
Email: ValidatorRuleParams<[options?: IsEmailOptions]>;
|
|
2392
|
+
/**
|
|
2393
|
+
* @summary UUID Rule
|
|
2394
|
+
*
|
|
2395
|
+
* @description Validates that the field under validation is a valid UUID (v1-v5).
|
|
2396
|
+
*
|
|
2397
|
+
* @example
|
|
2398
|
+
* ```typescript
|
|
2399
|
+
* // Valid UUIDs
|
|
2400
|
+
* await Validator.validate({
|
|
2401
|
+
* value: '550e8400-e29b-41d4-a716-446655440000',
|
|
2402
|
+
* rules: ['UUID']
|
|
2403
|
+
* }); // ✓ Valid
|
|
2404
|
+
*
|
|
2405
|
+
* await Validator.validate({
|
|
2406
|
+
* value: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
2407
|
+
* rules: ['UUID']
|
|
2408
|
+
* }); // ✓ Valid
|
|
2409
|
+
*
|
|
2410
|
+
* // Invalid examples
|
|
2411
|
+
* await Validator.validate({
|
|
2412
|
+
* value: 'not-a-uuid',
|
|
2413
|
+
* rules: ['UUID']
|
|
2414
|
+
* }); // ✗ Invalid
|
|
2415
|
+
*
|
|
2416
|
+
* await Validator.validate({
|
|
2417
|
+
* value: '550e8400-e29b-41d4-a716', // Too short
|
|
2418
|
+
* rules: ['UUID']
|
|
2419
|
+
* }); // ✗ Invalid
|
|
2420
|
+
*
|
|
2421
|
+
* await Validator.validate({
|
|
2422
|
+
* value: 123,
|
|
2423
|
+
* rules: ['UUID']
|
|
2424
|
+
* }); // ✗ Invalid
|
|
2425
|
+
*
|
|
2426
|
+
* // Class validation
|
|
2427
|
+
* class Entity {
|
|
2428
|
+
* @IsRequired()
|
|
2429
|
+
* @IsUUID()
|
|
2430
|
+
* id: string;
|
|
2431
|
+
* }
|
|
2432
|
+
* ```
|
|
2433
|
+
*
|
|
2434
|
+
* @param options - Validation options containing value and context
|
|
2435
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2436
|
+
*
|
|
2437
|
+
* @public
|
|
2438
|
+
*/
|
|
2439
|
+
UUID: ValidatorRuleParams<[]>;
|
|
2440
|
+
/**
|
|
2441
|
+
* @summary JSON Rule
|
|
2442
|
+
*
|
|
2443
|
+
* @description Validates that the field under validation is valid JSON.
|
|
2444
|
+
*
|
|
2445
|
+
* @example
|
|
2446
|
+
* ```typescript
|
|
2447
|
+
* // Valid JSON strings
|
|
2448
|
+
* await Validator.validate({
|
|
2449
|
+
* value: '{"name": "John", "age": 30}',
|
|
2450
|
+
* rules: ['JSON']
|
|
2451
|
+
* }); // ✓ Valid
|
|
2452
|
+
*
|
|
2453
|
+
* await Validator.validate({
|
|
2454
|
+
* value: '[1, 2, 3]',
|
|
2455
|
+
* rules: ['JSON']
|
|
2456
|
+
* }); // ✓ Valid
|
|
2457
|
+
*
|
|
2458
|
+
* // Invalid examples
|
|
2459
|
+
* await Validator.validate({
|
|
2460
|
+
* value: '{"name": "John", "age": }', // Invalid JSON
|
|
2461
|
+
* rules: ['JSON']
|
|
2462
|
+
* }); // ✗ Invalid
|
|
2463
|
+
*
|
|
2464
|
+
* await Validator.validate({
|
|
2465
|
+
* value: 123,
|
|
2466
|
+
* rules: ['JSON']
|
|
2467
|
+
* }); // ✗ Invalid
|
|
2468
|
+
*
|
|
2469
|
+
* // Class validation
|
|
2470
|
+
* class Config {
|
|
2471
|
+
* @IsRequired()
|
|
2472
|
+
* @IsJSON()
|
|
2473
|
+
* settings: string;
|
|
2474
|
+
* }
|
|
2475
|
+
* ```
|
|
2476
|
+
*
|
|
2477
|
+
* @param options - Validation options containing value and context
|
|
2478
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2479
|
+
*
|
|
2480
|
+
* @public
|
|
2481
|
+
*/
|
|
2482
|
+
JSON: ValidatorRuleParams<[]>;
|
|
2483
|
+
/**
|
|
2484
|
+
* @summary Base64 Rule
|
|
2485
|
+
*
|
|
2486
|
+
* @description Validates that the field under validation is valid Base64 encoded string.
|
|
2487
|
+
*
|
|
2488
|
+
* @example
|
|
2489
|
+
* ```typescript
|
|
2490
|
+
* // Valid Base64 strings
|
|
2491
|
+
* await Validator.validate({
|
|
2492
|
+
* value: 'SGVsbG8gV29ybGQ=', // "Hello World"
|
|
2493
|
+
* rules: ['Base64']
|
|
2494
|
+
* }); // ✓ Valid
|
|
2495
|
+
*
|
|
2496
|
+
* await Validator.validate({
|
|
2497
|
+
* value: 'dGVzdA==', // "test"
|
|
2498
|
+
* rules: ['Base64']
|
|
2499
|
+
* }); // ✓ Valid
|
|
2500
|
+
*
|
|
2501
|
+
* // Invalid examples
|
|
2502
|
+
* await Validator.validate({
|
|
2503
|
+
* value: 'not-base64!',
|
|
2504
|
+
* rules: ['Base64']
|
|
2505
|
+
* }); // ✗ Invalid
|
|
2506
|
+
*
|
|
2507
|
+
* await Validator.validate({
|
|
2508
|
+
* value: 123,
|
|
2509
|
+
* rules: ['Base64']
|
|
2510
|
+
* }); // ✗ Invalid
|
|
2511
|
+
*
|
|
2512
|
+
* // Class validation
|
|
2513
|
+
* class ImageData {
|
|
2514
|
+
* @IsRequired()
|
|
2515
|
+
* @IsBase64()
|
|
2516
|
+
* data: string;
|
|
2517
|
+
* }
|
|
2518
|
+
* ```
|
|
2519
|
+
*
|
|
2520
|
+
* @param options - Validation options containing value and context
|
|
2521
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2522
|
+
*
|
|
2523
|
+
* @public
|
|
2524
|
+
*/
|
|
2525
|
+
Base64: ValidatorRuleParams<[]>;
|
|
2526
|
+
/**
|
|
2527
|
+
* @summary HexColor Rule
|
|
2528
|
+
*
|
|
2529
|
+
* @description Validates that the field under validation is a valid hexadecimal color code.
|
|
2530
|
+
*
|
|
2531
|
+
* @example
|
|
2532
|
+
* ```typescript
|
|
2533
|
+
* // Valid hex colors
|
|
2534
|
+
* await Validator.validate({
|
|
2535
|
+
* value: '#FF0000',
|
|
2536
|
+
* rules: ['HexColor']
|
|
2537
|
+
* }); // ✓ Valid
|
|
2538
|
+
*
|
|
2539
|
+
* await Validator.validate({
|
|
2540
|
+
* value: '#3366cc',
|
|
2541
|
+
* rules: ['HexColor']
|
|
2542
|
+
* }); // ✓ Valid
|
|
2543
|
+
*
|
|
2544
|
+
* await Validator.validate({
|
|
2545
|
+
* value: '#abc', // Short format
|
|
2546
|
+
* rules: ['HexColor']
|
|
2547
|
+
* }); // ✓ Valid
|
|
2548
|
+
*
|
|
2549
|
+
* await Validator.validate({
|
|
2550
|
+
* value: '#FF000080', // With alpha
|
|
2551
|
+
* rules: ['HexColor']
|
|
2552
|
+
* }); // ✓ Valid
|
|
2553
|
+
*
|
|
2554
|
+
* // Invalid examples
|
|
2555
|
+
* await Validator.validate({
|
|
2556
|
+
* value: '#GGG', // Invalid characters
|
|
2557
|
+
* rules: ['HexColor']
|
|
2558
|
+
* }); // ✗ Invalid
|
|
2559
|
+
*
|
|
2560
|
+
* await Validator.validate({
|
|
2561
|
+
* value: '#12', // Too short
|
|
2562
|
+
* rules: ['HexColor']
|
|
2563
|
+
* }); // ✗ Invalid
|
|
2564
|
+
*
|
|
2565
|
+
* await Validator.validate({
|
|
2566
|
+
* value: 123,
|
|
2567
|
+
* rules: ['HexColor']
|
|
2568
|
+
* }); // ✗ Invalid
|
|
2569
|
+
*
|
|
2570
|
+
* // Class validation
|
|
2571
|
+
* class Theme {
|
|
2572
|
+
* @IsRequired()
|
|
2573
|
+
* @IsHexColor()
|
|
2574
|
+
* primaryColor: string;
|
|
2575
|
+
* }
|
|
2576
|
+
* ```
|
|
2577
|
+
*
|
|
2578
|
+
* @param options - Validation options containing value and context
|
|
2579
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2580
|
+
*
|
|
2581
|
+
* @public
|
|
2582
|
+
*/
|
|
2583
|
+
HexColor: ValidatorRuleParams<[]>;
|
|
2584
|
+
/**
|
|
2585
|
+
* @summary CreditCard Rule
|
|
2586
|
+
*
|
|
2587
|
+
* @description Validates that the field under validation is a valid credit card number using Luhn algorithm.
|
|
2588
|
+
*
|
|
2589
|
+
* @example
|
|
2590
|
+
* ```typescript
|
|
2591
|
+
* // Valid credit card numbers
|
|
2592
|
+
* await Validator.validate({
|
|
2593
|
+
* value: '4532015112830366', // Visa test number
|
|
2594
|
+
* rules: ['CreditCard']
|
|
2595
|
+
* }); // ✓ Valid
|
|
2596
|
+
*
|
|
2597
|
+
* await Validator.validate({
|
|
2598
|
+
* value: '4532-0151-1283-0366', // With dashes
|
|
2599
|
+
* rules: ['CreditCard']
|
|
2600
|
+
* }); // ✓ Valid
|
|
2601
|
+
*
|
|
2602
|
+
* // Invalid examples
|
|
2603
|
+
* await Validator.validate({
|
|
2604
|
+
* value: '4532015112830367', // Invalid checksum
|
|
2605
|
+
* rules: ['CreditCard']
|
|
2606
|
+
* }); // ✗ Invalid
|
|
2607
|
+
*
|
|
2608
|
+
* await Validator.validate({
|
|
2609
|
+
* value: '123',
|
|
2610
|
+
* rules: ['CreditCard']
|
|
2611
|
+
* }); // ✗ Invalid
|
|
2612
|
+
*
|
|
2613
|
+
* await Validator.validate({
|
|
2614
|
+
* value: 4532015112830366,
|
|
2615
|
+
* rules: ['CreditCard']
|
|
2616
|
+
* }); // ✗ Invalid
|
|
2617
|
+
*
|
|
2618
|
+
* // Class validation
|
|
2619
|
+
* class Payment {
|
|
2620
|
+
* @IsRequired()
|
|
2621
|
+
* @IsCreditCard()
|
|
2622
|
+
* cardNumber: string;
|
|
2623
|
+
* }
|
|
2624
|
+
* ```
|
|
2625
|
+
*
|
|
2626
|
+
* @param options - Validation options containing value and context
|
|
2627
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2628
|
+
*
|
|
2629
|
+
* @public
|
|
2630
|
+
*/
|
|
2631
|
+
CreditCard: ValidatorRuleParams<[]>;
|
|
2632
|
+
/**
|
|
2633
|
+
* @summary IP Rule
|
|
2634
|
+
*
|
|
2635
|
+
* @description Validates that the field under validation is a valid IP address.
|
|
2636
|
+
*
|
|
2637
|
+
* #### Parameters
|
|
2638
|
+
* - IP version: "4", "6", or "4/6" (default: "4/6")
|
|
2639
|
+
*
|
|
2640
|
+
* @example
|
|
2641
|
+
* ```typescript
|
|
2642
|
+
* // Valid IP addresses
|
|
2643
|
+
* await Validator.validate({
|
|
2644
|
+
* value: '192.168.1.1',
|
|
2645
|
+
* rules: ['IP', '4']
|
|
2646
|
+
* }); // ✓ Valid IPv4
|
|
2647
|
+
*
|
|
2648
|
+
* await Validator.validate({
|
|
2649
|
+
* value: '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
|
|
2650
|
+
* rules: ['IP', '6']
|
|
2651
|
+
* }); // ✓ Valid IPv6
|
|
2652
|
+
*
|
|
2653
|
+
* await Validator.validate({
|
|
2654
|
+
* value: '192.168.1.1',
|
|
2655
|
+
* rules: ['IP'] // Default allows both
|
|
2656
|
+
* }); // ✓ Valid
|
|
2657
|
+
*
|
|
2658
|
+
* // Invalid examples
|
|
2659
|
+
* await Validator.validate({
|
|
2660
|
+
* value: '256.1.1.1', // Invalid IPv4
|
|
2661
|
+
* rules: ['IP', '4']
|
|
2662
|
+
* }); // ✗ Invalid
|
|
2663
|
+
*
|
|
2664
|
+
* await Validator.validate({
|
|
2665
|
+
* value: '192.168.1.1',
|
|
2666
|
+
* rules: ['IP', '6'] // IPv4 not valid for IPv6 only
|
|
2667
|
+
* }); // ✗ Invalid
|
|
2668
|
+
*
|
|
2669
|
+
* await Validator.validate({
|
|
2670
|
+
* value: 123,
|
|
2671
|
+
* rules: ['IP']
|
|
2672
|
+
* }); // ✗ Invalid
|
|
2673
|
+
*
|
|
2674
|
+
* // Class validation
|
|
2675
|
+
* class Server {
|
|
2676
|
+
* @IsIP(['4']) // IPv4 only
|
|
2677
|
+
* ipv4Address: string;
|
|
2678
|
+
*
|
|
2679
|
+
* @IsIP(['6']) // IPv6 only
|
|
2680
|
+
* ipv6Address: string;
|
|
2681
|
+
*
|
|
2682
|
+
* @IsIP() // IPv4 or IPv6
|
|
2683
|
+
* ipAddress: string;
|
|
2684
|
+
* }
|
|
2685
|
+
* ```
|
|
2686
|
+
*
|
|
2687
|
+
* @param options - Validation options with rule parameters
|
|
2688
|
+
* @param options.ruleParams - Array containing IP version ("4", "6", or "4/6")
|
|
2689
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2690
|
+
*
|
|
2691
|
+
* @public
|
|
2692
|
+
*/
|
|
2693
|
+
IP: ValidatorRuleParams<string[]>;
|
|
2694
|
+
/**
|
|
2695
|
+
* @summary MACAddress Rule
|
|
2696
|
+
*
|
|
2697
|
+
* @description Validates that the field under validation is a valid MAC address.
|
|
2698
|
+
*
|
|
2699
|
+
* @example
|
|
2700
|
+
* ```typescript
|
|
2701
|
+
* // Valid MAC addresses
|
|
2702
|
+
* await Validator.validate({
|
|
2703
|
+
* value: '00:1B:44:11:3A:B7',
|
|
2704
|
+
* rules: ['MACAddress']
|
|
2705
|
+
* }); // ✓ Valid
|
|
2706
|
+
*
|
|
2707
|
+
* await Validator.validate({
|
|
2708
|
+
* value: '00-1B-44-11-3A-B7',
|
|
2709
|
+
* rules: ['MACAddress']
|
|
2710
|
+
* }); // ✓ Valid
|
|
2711
|
+
*
|
|
2712
|
+
* await Validator.validate({
|
|
2713
|
+
* value: '001B44113AB7',
|
|
2714
|
+
* rules: ['MACAddress']
|
|
2715
|
+
* }); // ✓ Valid
|
|
2716
|
+
*
|
|
2717
|
+
* // Invalid examples
|
|
2718
|
+
* await Validator.validate({
|
|
2719
|
+
* value: '00:1B:44:11:3A', // Too short
|
|
2720
|
+
* rules: ['MACAddress']
|
|
2721
|
+
* }); // ✗ Invalid
|
|
2722
|
+
*
|
|
2723
|
+
* await Validator.validate({
|
|
2724
|
+
* value: 'GG:1B:44:11:3A:B7', // Invalid characters
|
|
2725
|
+
* rules: ['MACAddress']
|
|
2726
|
+
* }); // ✗ Invalid
|
|
2727
|
+
*
|
|
2728
|
+
* await Validator.validate({
|
|
2729
|
+
* value: 123,
|
|
2730
|
+
* rules: ['MACAddress']
|
|
2731
|
+
* }); // ✗ Invalid
|
|
2732
|
+
*
|
|
2733
|
+
* // Class validation
|
|
2734
|
+
* class NetworkDevice {
|
|
2735
|
+
* @IsRequired()
|
|
2736
|
+
* @IsMACAddress()
|
|
2737
|
+
* macAddress: string;
|
|
2738
|
+
* }
|
|
2739
|
+
* ```
|
|
2740
|
+
*
|
|
2741
|
+
* @param options - Validation options containing value and context
|
|
2742
|
+
* @returns true if valid, rejecting with error message if invalid
|
|
2743
|
+
*
|
|
2744
|
+
* @public
|
|
2745
|
+
*/
|
|
2746
|
+
MACAddress: ValidatorRuleParams<[]>;
|
|
2747
|
+
/**
|
|
2748
|
+
* @summary Matches Rule
|
|
2749
|
+
*
|
|
2750
|
+
* @description Validates that the field under validation matches a regular expression pattern.
|
|
2751
|
+
* This rule provides flexible pattern-based validation using JavaScript regular expressions.
|
|
2752
|
+
*
|
|
2753
|
+
* #### Parameters
|
|
2754
|
+
* - `pattern`: Regular expression pattern to match against (required)
|
|
2755
|
+
* - `errorMessage`: Optional custom error message key for i18n translation
|
|
2756
|
+
*
|
|
2757
|
+
* #### Pattern Format
|
|
2758
|
+
* The pattern can be provided as a string that will be converted to a RegExp,
|
|
2759
|
+
* or as a RegExp object directly.
|
|
2760
|
+
*
|
|
2761
|
+
* @example
|
|
2762
|
+
* ```typescript
|
|
2763
|
+
* // Valid matches
|
|
2764
|
+
* await Validator.validate({
|
|
2765
|
+
* value: 'abc123',
|
|
2766
|
+
* rules: ['Matches', '/^[a-z]+\\d+$/']
|
|
2767
|
+
* }); // ✓ Valid (letters followed by numbers)
|
|
2768
|
+
*
|
|
2769
|
+
* await Validator.validate({
|
|
2770
|
+
* value: 'test@example.com',
|
|
2771
|
+
* rules: ['Matches', '/^[\\w.-]+@[\\w.-]+\\.\\w+$/']
|
|
2772
|
+
* }); // ✓ Valid (simple email pattern)
|
|
2773
|
+
*
|
|
2774
|
+
* await Validator.validate({
|
|
2775
|
+
* value: 'Hello World',
|
|
2776
|
+
* rules: ['Matches', '/^Hello/']
|
|
2777
|
+
* }); // ✓ Valid (starts with "Hello")
|
|
2778
|
+
*
|
|
2779
|
+
* // Invalid examples
|
|
2780
|
+
* await Validator.validate({
|
|
2781
|
+
* value: '123abc',
|
|
2782
|
+
* rules: ['Matches', '/^[a-z]+\\d+$/']
|
|
2783
|
+
* }); // ✗ Invalid (numbers before letters)
|
|
2784
|
+
*
|
|
2785
|
+
* await Validator.validate({
|
|
2786
|
+
* value: 'hello world',
|
|
2787
|
+
* rules: ['Matches', '/^Hello/']
|
|
2788
|
+
* }); // ✗ Invalid (case sensitive)
|
|
2789
|
+
*
|
|
2790
|
+
* await Validator.validate({
|
|
2791
|
+
* value: 123,
|
|
2792
|
+
* rules: ['Matches', '/^\\d+$/']
|
|
2793
|
+
* }); // ✗ Invalid (not a string)
|
|
2794
|
+
*
|
|
2795
|
+
* await Validator.validate({
|
|
2796
|
+
* value: 'test',
|
|
2797
|
+
* rules: ['Matches', '/^$/']
|
|
2798
|
+
* }); // ✗ Invalid (empty pattern)
|
|
2799
|
+
*
|
|
2800
|
+
* // Class validation
|
|
2801
|
+
* class User {
|
|
2802
|
+
* @IsRequired()
|
|
2803
|
+
* @Matches('^[a-zA-Z0-9_]+$', {message: 'username.invalid'})
|
|
2804
|
+
* username: string;
|
|
2805
|
+
*
|
|
2806
|
+
* @Matches('^\\+?[1-9]\\d{1,14}$') // E.164 phone pattern
|
|
2807
|
+
* phoneNumber?: string;
|
|
2808
|
+
* }
|
|
2809
|
+
* ```
|
|
2810
|
+
*
|
|
2811
|
+
* @param ruleParams - Array containing pattern and optional error message
|
|
2812
|
+
* @param ruleParams[0] - Regular expression pattern as string or RegExp object
|
|
2813
|
+
* @param ruleParams[1] - Optional custom error message key for i18n
|
|
2814
|
+
* @returns true if pattern matches, rejecting with error message if invalid
|
|
2815
|
+
*
|
|
2816
|
+
* @public
|
|
2817
|
+
*/
|
|
2818
|
+
Matches: ValidatorRuleParams<[
|
|
2819
|
+
pattern: string | RegExp,
|
|
2820
|
+
options?: {
|
|
2821
|
+
message?: string;
|
|
2822
|
+
}
|
|
2823
|
+
]>;
|
|
2824
|
+
}
|
|
2825
|
+
}
|