Validation Decorators
Express-Cargo uses decorators to validate incoming request data that is bound to a class.
Validation is not performed by a standalone validate function. Instead, it is integrated into the bindingCargo middleware, which automatically validates data during the request lifecycle.
@Enum also checks its field's value, but it belongs to the type-helper category rather than to the validators below. It is documented in Type Helper Decorators, and the difference matters when you reach for @Each.
Number Validators
@Min(value: number)
Validates that a number is greater than or equal to the specified minimum value.
value: The minimum allowed value.
@Max(value: number)
Validates that a number is less than or equal to the specified maximum value.
value: The maximum allowed value.
@Range(min: number, max: number)
Validates that a number is within the specified range, inclusive of the minimum and maximum values.
min: The minimum allowed value.max: The maximum allowed value.
String Validators
@Contains(seed: string)
Validates that the string contains the specified substring.
seed: The substring that must be present in the string.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Prefix(value: string)
Validates that a string starts with the specified prefix.
value: The required starting text.
@Suffix(value: string)
Validates that a string ends with the specified suffix.
value: The required ending text.
@Length(value: number)
Validates that the decorated string’s length is exactly the specified value.
value: The required exact length in characters
@MaxLength(value: number)
Validates that the decorated string’s length does not exceed the specified maximum.
value: The maximum allowed length in characters.
@MinLength(value: number)
Validates that the decorated string’s length is at least the specified minimum.
value: The minimum allowed length in characters.
@Regexp(pattern: RegExp, message?: string)
Validates that the decorated field matches the specified regular expression pattern. This decorator is useful for enforcing format rules such as email, phone numbers, etc.
pattern: A RegExp object used to test the field value. The value is valid if it matches the pattern.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Email()
Validates that the decorated property is a valid email address.
@Alpha(message?: string)
Validates that the decorated field contains alphabetic characters only (uppercase or lowercase English letters, A–Z / a–z).
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Uuid(version?: 'v1' | 'v3' | 'v4' | 'v5', message?: string)
Validates that the decorated field is a valid UUID string, optionally restricted to a specific version (v1, v3, v4, or v5).
version(optional): The specific UUID version to validate against. If omitted, it validates against v1, v3, v4, or v5.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Alphanumeric(message?: string)
Validates that the decorated field contains alphanumeric characters only (English letters and digits, A–Z, a–z, 0–9).
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsUppercase(message?: string)
Validates that the decorated field contains only uppercase characters.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsLowercase(message?: string)
Validates that the decorated field contains only lowercase characters.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsJwt(message?: string)
Validates that the decorated field follows the JWT format (header.payload.signature). Each part must consist of Base64URL characters (A-Z, a-z, 0-9, -, _). This decorator only checks the format — it does not verify the signature or token validity.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsUrl(options?: IsUrlOptions, message?: string)
Validates that the decorated field is a valid URL. By default, http, https, and ftp protocols are allowed.
options(optional):protocols: An array of allowed protocols. Defaults to['http', 'https', 'ftp'].
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsPhoneNumber(region?: CountryCode, message?: string)
Validates that the decorated field is a valid phone number. Uses libphonenumber-js for accurate validation across all countries.
When a region is provided, local formats (without country code) are accepted. When no region is provided, the number must include a country code (e.g., +82). If the number includes a + country code prefix, the region parameter is ignored and the number is validated against its own country code.
region(optional): ISO 3166-1 alpha-2 region code (e.g.,'KR','US'). If omitted, the number must be in international format.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsTimeZone(message?: string)
Validates that the decorated field is a valid IANA timezone identifier (e.g., Asia/Seoul, America/New_York, UTC). Uses the built-in Intl API for validation — no external dependencies required.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsHexColor(message?: string)
Validates that the decorated field is a valid hex color code. Supports #RGB, #RGBA, #RRGGBB, and #RRGGBBAA formats (case-insensitive). The # prefix is required.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsHexadecimal(message?: string)
Validates that the decorated field is a hexadecimal number. The value must contain only characters 0-9 and a-f (case-insensitive). The 0x prefix is also allowed.
message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@IsHash(algorithm: HashAlgorithm, message?: string)
Validates that the decorated field is a valid hash string for the given algorithm. Supported algorithms: md5, sha1, sha256, sha384, sha512, crc32, crc32b. The value must be a hexadecimal string with the exact length required by the algorithm.
algorithm: The hash algorithm to validate against.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Comparison Validators
@Equal(value: any)
Validates that a value is strictly equal (===) to the specified value.
value: The value to compare against.
@NotEqual(value: any)
Validates that a value is strictly not equal (!==) to the specified value.
value: The value to compare against.
@IsTrue()
Validates that the decorated property is true.
@IsFalse()
Validates that the decorated property is false.
@OneOf(values: any[])
Validates that the input value is one of the specified values.
values: The array of allowed values.
@Validate(validateFn: (value: unknown) => boolean, message?: string)
Validates a value using a custom validation function. This decorator provides flexibility to implement validation logic beyond the built-in ones.
validateFn: A function that receives the field value and returns true if valid, false otherwise.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Date Validators
@MinDate(min: Date | (() => Date), message?: string)
Validates that the decorated field is a Date that is on or after the given minimum date. Accepts a fixed Date or a function that returns a Date for dynamic comparison.
min: The minimum allowed date, or a function that returns it.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@MaxDate(max: Date | (() => Date), message?: string)
Validates that the decorated field is a Date that is on or before the given maximum date. Accepts a fixed Date or a function that returns a Date for dynamic comparison.
max: The maximum allowed date, or a function that returns it.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Array Validators
@ListContains(values: any[], comparator?: (expected, actual) => boolean, message?: string)
Validates that the array contains all the specified values. Supports primitive values, objects, Date, and mixed types.
values: The values that must be present in the array.comparator(optional): A custom comparison function(expected, actual) => boolean. When provided, all comparisons are delegated to this function, including primitives.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Warning: Object comparison uses deep equality by default. Performance may degrade when
valuescontains many objects or deeply nested structures. Consider using acomparatorfor more efficient or flexible comparison.
@ListNotContains(values: any[], comparator?: (expected, actual) => boolean, message?: string)
Validates that the array does NOT contain any of the specified values. Supports primitive values, objects, Date, and mixed types.
values: The values that must NOT be present in the array.comparator(optional): A custom comparison function(expected, actual) => boolean. When provided, all comparisons are delegated to this function, including primitives.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Warning: Object comparison uses deep equality by default. Performance may degrade when
valuescontains many objects or deeply nested structures. Consider using acomparatorfor more efficient or flexible comparison.
@ListMaxSize(max: number, message?: string)
Validates that the array contains no more than the specified number of elements.
max: The maximum number of elements allowed in the array.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@ListMinSize(min: number, message?: string)
Validates that the array contains at least the specified number of elements.
min: The minimum number of elements allowed in the array.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Each(...args: (Validator | Function)[])
Validates every individual element within an array. It can accept other validation decorators or custom validation functions.
args: A validation decorator (e.g., @Min(5)) or a custom function (value: any) => boolean.
@Each wraps validation decorators only. Passing a source, type-helper, missing-value, or transform decorator is rejected when the route is registered — @Each(Enum(UserRole)), for instance, fails with @Each cannot wrap type-helper decorator(s): @Enum.
Cross-field Validators
@With(fieldName: string, message?: string)
Validates that if the decorated field has a value, the specified target field (fieldName) must also have a value, establishing a mandatory dependency between the two fields.
fieldName: The name of the target field that must also have a value if the decorated field has a value.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
@Without(fieldName: string, message?: string)
Validates that if the decorated property has a value, the specified target property must NOT have a value, establishing a mutually exclusive relationship between the two properties.
fieldName: The name of the target property that must be empty if the decorated field has a value.message(optional): The error message to display when validation fails. If omitted, a default message will be used.
Usage Example
Here is a complete example of how to use validation decorators within an Express application.
import express, { Request, Response, NextFunction } from 'express'
import { bindingCargo, getCargo, Body, Min, Max, Suffix, CargoValidationError } from 'express-cargo'
// 1. Define a class with source and validation rules
class CreateAssetRequest {
@Body('name')
assetName!: string
@Body('type')
@Suffix('.png')
assetType!: string
@Body('quantity')
@Min(1)
@Max(100)
quantity!: number
}
const app = express()
app.use(express.json())
// 2. Apply the bindingCargo middleware to a route
app.post('/assets', bindingCargo(CreateAssetRequest), (req: Request, res: Response) => {
// 3. If validation succeeds, access the data using getCargo
const assetData = getCargo<CreateAssetRequest>(req)
res.json({
message: 'Asset created successfully!',
data: assetData,
})
})
// 4. Add an error handling middleware to catch validation errors
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof CargoValidationError) {
res.status(400).json({
message: 'Validation Failed',
errors: err.errors.map(e => e.message),
})
} else {
next(err)
}
})
/*
To test this endpoint, send a POST request to /assets.
Example of a VALID request body:
{
"name": "My-Asset",
"type": "icon.png",
"quantity": 10
}
Example of an INVALID request body:
{
"name": "My-Asset",
"type": "icon.jpg", // Fails @Suffix('.png')
"quantity": 101 // Fails @Max(100)
}
*/
Validation failures are raised as a CargoValidationError, as step 4 of the example shows. See Error Handling for the error types, the recommended setCargoErrorHandler route, and example responses.