The om-data-mapper валидация module provides a высокопроизводительный, class-валидатор-compatible API for validating objects using декораторs. It's разработан как прямая замена for class-validator with 10x better performance through JIT-компиляция.
npm install om-data-mapper
# or
pnpm add om-data-mapper
# or
yarn add om-data-mapperНе требуются дополнительные зависимости - unlike class-валидатор, you don't need reflect-metadata.
import { IsString, IsEmail, MinLength, validate } from 'om-data-mapper/class-validator-compat';
class UserDto {
@IsString()
@MinLength(3)
name: string;
@IsEmail()
email: string;
}
const user = new UserDto();
user.name = 'Jo'; // Too short
user.email = 'invalid-email';
const errors = await validate(user);
console.log(errors);
// [
// {
// property: 'name',
// constraints: { minLength: 'name должно быть at least 3 characters' }
// },
// {
// property: 'email',
// constraints: { isEmail: 'email должно быть a valid email' }
// }
// ]// Import from class-валидатор-compat submodule
import {
validate,
validateSync,
IsString,
IsNumber,
MinLength,
// ... other валидаторs
} from 'om-data-mapper/class-validator-compat';Асинхронно валидирует an object. Supports async custom валидаторs.
const errors = await validate(userDto);
if (errors.length > 0) {
console.log('Validation failed:', errors);
}Синхронно валидирует an object. Не поддерживает async валидаторs.
const errors = validateSync(userDto);
if (errors.length > 0) {
console.log('Validation failed:', errors);
}Валидирует и выбрасывает an error if валидация fails.
try {
await validateOrReject(userDto);
console.log('Validation passed!');
} catch (errors) {
console.log('Validation failed:', errors);
}Synchronous Версия of validateOrReject.
try {
validateOrRejectSync(userDto);
console.log('Validation passed!');
} catch (errors) {
console.log('Validation failed:', errors);
}Валидирует массив of objects.
const users = [user1, user2, user3];
const allErrors = await validateMany(users);
// Возвращает: ValidationError[][]Synchronous Версия of validateMany.
const allErrors = validateManySync(users);interface ValidatorOptions {
skipMissingProperties?: boolean; // Skip undefined properties
skipNullProperties?: boolean; // Skip null properties
skipUndefinedProperties?: boolean; // Skip undefined properties
groups?: string[]; // Validation groups
always?: boolean; // Always validate
stopAtFirstError?: boolean; // Stop at first error
forbidUnknownValues?: boolean; // Forbid unknown values
whitelist?: boolean; // Remove unknown properties
forbidNonWhitelisted?: boolean; // Throw on unknown properties
}const errors = await validate(user, {
skipMissingProperties: true,
groups: ['create'],
stopAtFirstError: true
});Помечает свойство как необязательное - skips валидация if unОпределитьd.
class UserDto {
@IsOptional()
@IsString()
middleName?: string;
}Проверяет, является ли значение Определитьd (not unОпределитьd).
class UserDto {
@IsDefined()
name: string;
}Проверяет, является ли значение not empty.
class UserDto {
@IsNotEmpty()
name: string;
}Проверяет, является ли значение equals the specified value.
class ConfigDto {
@Equals('production')
environment: string;
}Проверяет, является ли значение does not equal the specified value.
class UserDto {
@NotEquals('admin')
role: string;
}Проверяет, является ли значение in an array of allowed values.
class UserDto {
@IsIn(['admin', 'user', 'guest'])
role: string;
}Проверяет, является ли значение not in an array of disallowed values.
class UserDto {
@IsNotIn(['root', 'administrator'])
username: string;
}Проверяет, является ли значение a string.
class UserDto {
@IsString()
name: string;
}Checks if string length is at least min.
class UserDto {
@MinLength(3)
username: string;
}Checks if string length is at most max.
class UserDto {
@MaxLength(50)
name: string;
}Checks if string length is between min and max.
class UserDto {
@Length(3, 20)
username: string;
}Проверяет, является ли значение a valid email.
class UserDto {
@IsEmail()
email: string;
}Проверяет, является ли значение a valid URL.
class UserDto {
@IsURL()
website: string;
}Проверяет, является ли значение a valid UUID.
class UserDto {
@IsUUID()
id: string;
}Проверяет, является ли значение valid JSON.
class ConfigDto {
@IsJSON()
settings: string;
}Checks if string contains only letters.
class UserDto {
@IsAlpha()
firstName: string;
}Checks if string contains only letters and numbers.
class UserDto {
@IsAlphanumeric()
username: string;
}Проверяет, является ли значение a valid hex color.
class ThemeDto {
@IsHexColor()
primaryColor: string;
}Проверяет, является ли значение a valid IP address.
class ServerDto {
@IsIP()
ipAddress: string;
}Проверяет, является ли значение a valid credit card number.
class PaymentDto {
@IsCreditCard()
cardNumber: string;
}Проверяет, является ли значение a valid ISBN.
class BookDto {
@IsISBN()
isbn: string;
}Проверяет, является ли значение a valid phone number.
class UserDto {
@IsPhoneNumber('US')
phone: string;
}Checks if string contains the seed.
class UserDto {
@Contains('@')
email: string;
}Checks if string does not contain the seed.
class UserDto {
@NotContains('admin')
username: string;
}Checks if string is lowercase.
class UserDto {
@IsLowercase()
username: string;
}Checks if string is uppercase.
class CodeDto {
@IsUppercase()
countryCode: string;
}Checks if string matches a regex pattern.
class UserDto {
@Matches(/^[a-zA-Z0-9]+$/)
username: string;
}Проверяет, является ли значение полным доменным именем (FQDN).
class WebsiteDto {
@IsFQDN()
domain: string; // 'example.com', 'subdomain.example.com'
}Проверяет, является ли значение валидной датой в формате ISO 8601.
class EventDto {
@IsISO8601()
startDate: string; // '2024-01-15T10:30:00Z', '2024-01-15'
}Алиас для @IsISO8601(). Проверяет, является ли значение валидной датой в формате ISO 8601.
class EventDto {
@IsDateString()
createdAt: string; // '2024-01-15T10:30:00Z'
}Проверяет, является ли значение валидным номером мобильного телефона. Поддерживает валидацию для конкретных локалей.
class UserDto {
@IsMobilePhone('en-US')
phone: string; // '+1-555-123-4567', '555-123-4567'
}
// Без указания локали (принимает различные форматы)
class ContactDto {
@IsMobilePhone()
mobile: string;
}Проверяет, является ли значение валидным почтовым индексом. Поддерживает локали US, RU и GB.
class AddressDto {
@IsPostalCode('US')
zipCode: string; // '12345', '12345-6789'
}
class RussianAddressDto {
@IsPostalCode('RU')
postalCode: string; // '123456'
}Проверяет, является ли значение валидным MongoDB ObjectId (24-символьная шестнадцатеричная строка).
class DocumentDto {
@IsMongoId()
id: string; // '507f1f77bcf86cd799439011'
}Проверяет, является ли значение валидным JWT токеном.
class AuthDto {
@IsJWT()
token: string; // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U'
}Проверяет, является ли значение надежным паролем (минимум 8 символов, заглавные и строчные буквы, цифры, спецсимволы).
class UserDto {
@IsStrongPassword()
password: string; // 'MyP@ssw0rd123'
}Проверяет, является ли значение валидным номером порта (0-65535).
class ServerDto {
@IsPort()
port: string; // '8080', '3000', '443'
}Проверяет, является ли значение валидным MAC-адресом.
class DeviceDto {
@IsMACAddress()
macAddress: string; // '00:1B:44:11:3A:B7', '00-1B-44-11-3A-B7'
}Проверяет, является ли значение валидной строкой в кодировке base64.
class FileDto {
@IsBase64()
content: string; // 'SGVsbG8gV29ybGQ=', 'SGVsbG8gV29ybGQ'
}Проверяет, является ли значение валидным международным номером банковского счета (IBAN).
class BankAccountDto {
@IsIBAN()
iban: string; // 'GB82WEST12345698765432', 'DE89370400440532013000'
}Проверяет, является ли значение валидным банковским идентификационным кодом (BIC/SWIFT).
class BankDto {
@IsBIC()
swiftCode: string; // 'DEUTDEFF', 'DEUTDEFF500'
}Проверяет, является ли значение валидной денежной суммой.
class PaymentDto {
@IsCurrency()
amount: string; // '$100.00', '€50.99', '¥1000'
}Проверяет, является ли значение валидным кодом валюты по стандарту ISO 4217.
class TransactionDto {
@IsISO4217CurrencyCode()
currency: string; // 'USD', 'EUR', 'RUB', 'GBP'
}Проверяет, является ли значение валидным адресом Ethereum.
class WalletDto {
@IsEthereumAddress()
address: string; // '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb'
}Проверяет, является ли значение валидным адресом Bitcoin (legacy или SegWit).
class CryptoDto {
@IsBtcAddress()
btcAddress: string; // '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'
}Проверяет, является ли значение валидным номером паспорта. Поддерживает валидацию для конкретных локалей.
class TravelDto {
@IsPassportNumber('US')
passport: string; // '123456789'
}
class InternationalDto {
@IsPassportNumber()
passportNumber: string; // Принимает различные форматы
}Проверяет, является ли значение валидным номером удостоверения личности.
class IdentityDto {
@IsIdentityCard('ES')
idCard: string; // 'AB12345678'
}Проверяет, является ли значение валидным европейским артикульным номером (EAN-8 или EAN-13).
class ProductDto {
@IsEAN()
barcode: string; // '12345678' (EAN-8), '1234567890123' (EAN-13)
}Проверяет, является ли значение валидным международным идентификационным номером ценной бумаги (ISIN).
class SecurityDto {
@IsISIN()
isin: string; // 'US0378331005'
}Проверяет, является ли значение валидным Magnet URI.
class TorrentDto {
@IsMagnetURI()
magnetLink: string; // 'magnet:?xt=urn:btih:c12fe1c06bba254a9dc9f519b335aa7c1367a88a'
}Проверяет, является ли значение валидным Data URI.
class ImageDto {
@IsDataURI()
dataUri: string; // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA'
}Проверяет, является ли значение валидным двухбуквенным кодом страны по стандарту ISO 3166-1 alpha-2.
class AddressDto {
@IsISO31661Alpha2()
countryCode: string; // 'US', 'RU', 'GB', 'FR'
}Проверяет, является ли значение валидным трёхбуквенным кодом страны по стандарту ISO 3166-1 alpha-3.
class CountryDto {
@IsISO31661Alpha3()
code: string; // 'USA', 'RUS', 'GBR', 'FRA'
}Проверяет, является ли значение валидным кодом локали.
class UserDto {
@IsLocale()
locale: string; // 'en-US', 'ru-RU', 'fr-FR', 'en'
}Проверяет, является ли значение валидной семантической версией.
class PackageDto {
@IsSemVer()
version: string; // '1.2.3', '2.0.0-beta.1', '1.0.0+20130313144700'
}Проверяет, является ли значение валидным MIME-типом.
class FileDto {
@IsMimeType()
contentType: string; // 'text/html', 'application/json', 'image/png'
}Проверяет, является ли значение валидным часовым поясом.
class EventDto {
@IsTimeZone()
timezone: string; // 'America/New_York', 'Europe/Moscow', 'UTC'
}Проверяет, является ли значение валидной датой в формате RFC 3339.
class TimestampDto {
@IsRFC3339()
timestamp: string; // '2024-01-15T10:30:00Z', '2024-01-15T10:30:00+03:00'
}Проверяет, является ли значение a number.
class ProductDto {
@IsNumber()
price: number;
}Проверяет, является ли значение an integer.
class ProductDto {
@IsInt()
quantity: number;
}Checks if number is at least min.
class ProductDto {
@Min(0)
price: number;
}Checks if number is at most max.
class ProductDto {
@Max(100)
discount: number;
}Checks if number is positive.
class ProductDto {
@IsPositive()
price: number;
}Checks if number is negative.
class TransactionDto {
@IsNegative()
debit: number;
}Checks if number is divisible by num.
class ProductDto {
@IsDivisibleBy(5)
quantity: number;
}Проверяет, является ли значение a decimal number.
class ProductDto {
@IsDecimal()
price: number;
}Checks if date is after or equal to the specified date.
class EventDto {
@MinDate(new Date('2024-01-01'))
startDate: Date;
}Checks if date is before or equal to the specified date.
class EventDto {
@MaxDate(new Date('2024-12-31'))
endDate: Date;
}Проверяет, является ли значение an array.
class ProductDto {
@IsArray()
tags: string[];
}Checks if array is not empty.
class ProductDto {
@ArrayNotEmpty()
tags: string[];
}Checks if array has at least min elements.
class ProductDto {
@ArrayMinSize(1)
images: string[];
}Checks if array has at most max elements.
class ProductDto {
@ArrayMaxSize(10)
tags: string[];
}Checks if array contains all specified values.
class ProductDto {
@ArrayContains(['featured'])
tags: string[];
}Checks if array does not contain any of the specified values.
class ProductDto {
@ArrayNotContains(['banned'])
tags: string[];
}Checks if all array elements are unique.
class ProductDto {
@ArrayUnique()
tags: string[];
}Проверяет, является ли значение a boolean.
class UserDto {
@IsBoolean()
isActive: boolean;
}Проверяет, является ли значение a Date object.
class EventDto {
@IsDate()
startDate: Date;
}Проверяет, является ли значение an object.
class UserDto {
@IsObject()
metadata: object;
}Проверяет, является ли значение a valid enum value.
enum UserRole {
Admin = 'admin',
User = 'user',
Guest = 'guest'
}
class UserDto {
@IsEnum(UserRole)
role: UserRole;
}Проверяет, является ли значение an instance of a class.
class UserDto {
@IsInstance(Date)
createdAt: Date;
}Проверяет, является ли значение a non-empty object.
class UserDto {
@IsNotEmptyObject()
settings: object;
}Проверяет, является ли значение a valid latitude-longitude pair.
class LocationDto {
@IsLatLong()
coordinates: string; // "40.7128,-74.0060"
}Проверяет, является ли значение a valid latitude.
class LocationDto {
@IsLatitude()
lat: string;
}Проверяет, является ли значение a valid longitude.
class LocationDto {
@IsLongitude()
lng: string;
}Use @ValidateNested() to validate nested objects.
import { ValidateNested, IsString } from 'om-data-mapper/class-validator-compat';
import { Type } from 'om-data-mapper/class-transformer-compat';
class Address {
@IsString()
street: string;
@IsString()
city: string;
}
class UserDto {
@IsString()
name: string;
@ValidateNested()
@Type(() => Address)
address: Address;
}
const user = new UserDto();
user.name = 'John';
user.address = new Address();
user.address.street = ''; // Invalid
const errors = await validate(user);
// Errors will include nested валидация errorsUse @ValidateIf() to conditionally validate properties.
import { ValidateIf, IsString } from 'om-data-mapper/class-validator-compat';
class UserDto {
@IsString()
accountType: string;
@ValidateIf(o => o.accountType === 'premium')
@IsString()
premiumFeature?: string;
}Use groups to validate different scenarios.
class UserDto {
@IsString({ groups: ['create', 'update'] })
name: string;
@IsString({ groups: ['create'] })
password: string;
@IsString({ groups: ['update'] })
@IsOptional()
newPassword?: string;
}
// Validate for Создать
const createErrors = await validate(user, { groups: ['create'] });
// Validate for update
const updateErrors = await validate(user, { groups: ['update'] });Provide custom error messages for валидаторs.
class UserDto {
@IsString({ message: 'Please provide a valid name' })
@MinLength(3, { message: 'Name must be at least 3 characters long' })
name: string;
@IsEmail({ message: 'Please provide a valid email address' })
email: string;
}Use functions for dynamic error messages.
class UserDto {
@MinLength(3, {
message: (args) => `${args.property} is too short. Minimum length is ${args.constraints[0]}`
})
name: string;
}Создать custom валидаторs for complex валидация logic.
import {
ValidatorConstraint,
ValidatorConstraintInterface,
ValidationArguments,
Validate
} from 'om-data-mapper/class-validator-compat';
@ValidatorConstraint({ name: 'isStrongPassword', async: false })
class IsStrongPasswordConstraint implements ValidatorConstraintInterface {
validate(value: any, args: ValidationArguments): boolean {
if (typeof value !== 'string') return false;
const hasUpperCase = /[A-Z]/.test(value);
const hasLowerCase = /[a-z]/.test(value);
const hasNumber = /[0-9]/.test(value);
const hasSpecialChar = /[!@#$%^&*]/.test(value);
return hasUpperCase && hasLowerCase && hasNumber && hasSpecialChar && value.length >= 8;
}
defaultMessage(args: ValidationArguments): string {
return 'Password must contain uppercase, lowercase, number, special character, and be at least 8 characters';
}
}
class UserDto {
@Validate(IsStrongPasswordConstraint)
password: string;
}@ValidatorConstraint({ name: 'isUserAlreadyExist', async: true })
class IsUserAlreadyExistConstraint implements ValidatorConstraintInterface {
async validate(value: any, args: ValidationArguments): Promise<boolean> {
// Check database
const user = await database.findUserByEmail(value);
return !user; // Return false if user exists
}
defaultMessage(args: ValidationArguments): string {
return 'User with this email already exists';
}
}
class CreateUserDto {
@Validate(IsUserAlreadyExistConstraint)
email: string;
}
// Must use async validate
const errors = await validate(dto);// ✅ Faster
const errors = validateSync(dto);
// ❌ Slower (unless you have async валидаторs)
const errors = await validate(dto);class UserDto {
@IsString()
@MinLength(3)
@MaxLength(20)
@Matches(/^[a-zA-Z0-9]+$/)
username: string;
}// Different валидация rules for different scenarios
class UserDto {
@IsString({ groups: ['create'] })
password: string;
@IsString({ groups: ['update'] })
@IsOptional()
newPassword?: string;
}class UserDto {
@IsString()
name: string;
@IsOptional()
@IsString()
middleName?: string; // Only validated if provided
}// Instead of multiple декораторs, Создать a custom валидатор
@Validate(IsComplexBusinessRuleConstraint)
complexField: string;The API is 100% compatible with class-валидатор. Simply change the import:
// Before
import { validate, IsString } from 'class-validator';
// After
import { validate, IsString } from 'om-data-mapper/class-validator-compat';No other changes needed! Your existing code will work with 10x better performance.
- Reuse DTOs: Создать DTO instances once and reuse them
- Use validateSync: When you don't need async валидаторs
- Limit Nested Depth: Deep nesting impacts performance
- Use Groups: Validate only what you need
- Cache Validators: The first валидация compiles the валидатор, subsequent calls are cached
validate(object, options?)- Async валидацияvalidateSync(object, options?)- Sync валидацияvalidateOrReject(object, options?)- Async валидация with throwvalidateOrRejectSync(object, options?)- Sync валидация with throwvalidateMany(objects, options?)- Validate array asyncvalidateManySync(objects, options?)- Validate array sync
- Common:
@IsOptional(),@IsDefined(),@IsNotEmpty(),@Equals(),@NotEquals(),@IsIn(),@IsNotIn() - String:
@IsString(),@MinLength(),@MaxLength(),@Length(),@IsEmail(),@IsURL(),@IsUUID(),@Matches() - Number:
@IsNumber(),@IsInt(),@Min(),@Max(),@IsPositive(),@IsNegative() - Date:
@MinDate(),@MaxDate() - Array:
@IsArray(),@ArrayNotEmpty(),@ArrayMinSize(),@ArrayMaxSize(),@ArrayUnique() - Type:
@IsBoolean(),@IsDate(),@IsObject(),@IsEnum(),@IsInstance() - Nested:
@ValidateNested(),@ValidateIf(),@ValidatePromise() - Custom:
@Validate(),@ValidateBy(),@ValidatorConstraint()
The валидация module provides:
- ✅ 10x faster than class-валидатор
- ✅ 100% API compatible - прямая замена
- ✅ No dependencies - no reflect-metadata needed
- ✅ Type-safe - full TypeScript support
- ✅ Extensible - custom валидаторs supported
Start validating with confidence! 🚀