Библиотека Validator.js предоставляет широкий набор предопределённых функций для проверки строковых значений: email, URL, длина, числовые диапазоны, форматы дат и множество других сценариев. Однако прикладные задачи редко ограничиваются стандартным набором правил. В реальных системах возникает необходимость в создании собственных проверок, учитывающих бизнес-логику, структуру данных и доменные ограничения.
Кастомные методы в контексте Validator.js представляют собой либо обёртки над существующими функциями, либо полностью самостоятельные функции проверки, интегрированные в общий поток валидации.
Основой кастомной проверки является функция, принимающая значение и возвращающая результат логической проверки. В простейшем виде она строится следующим образом:
function isValidPostalCode(value) {
return /^[0-9]{6}$/.test(value);
}
Такой подход позволяет создавать атомарные правила, которые легко комбинируются с функциями Validator.js:
import validator from 'validator';
function isCorporateEmail(email) {
if (!validator.isEmail(email)) {
return false;
}
return email.endsWith('@company.com');
}
В данном случае стандартная проверка email используется как базовый слой, а затем добавляется доменное ограничение.
Кастомные методы редко существуют изолированно. Чаще они представляют
собой композицию нескольких правил, объединённых логикой
AND или OR.
function isStrongUsername(username) {
return (
validator.isLength(username, { min: 6, max: 20 }) &&
/^[a-zA-Z0-9_]+$/.test(username) &&
!username.includes('admin')
);
}
Подобная структура делает правила читаемыми и повторно используемыми. Каждая часть отвечает за отдельный аспект проверки: длину, допустимые символы и запрещённые значения.
При увеличении количества проверок возникает необходимость в их структурировании. Кастомные методы выделяются в отдельные модули, формируя библиотеку доменных валидаторов.
// validators/userValidators.js
import validator from 'validator';
export function isValidLogin(login) {
return validator.isAlphanumeric(login) && validator.isLength(login, { min: 4, max: 16 });
}
export function isValidPassword(password) {
return (
validator.isLength(password, { min: 8 }) &&
/[A-Z]/.test(password) &&
/[0-9]/.test(password)
);
}
Такой подход упрощает сопровождение кода и снижает дублирование логики.
В системах, использующих цепочки вызовов (например, при построении middleware-валидации), кастомные методы подключаются как часть общего потока.
function validateUser(data) {
const errors = [];
if (!isValidLogin(data.login)) {
errors.push('Некорректный логин');
}
if (!isValidPassword(data.password)) {
errors.push('Слабый пароль');
}
return errors;
}
Здесь кастомные функции выступают как строительные блоки более сложной логики проверки.
Иногда требуется не просто новая проверка, а модификация поведения существующих методов Validator.js. В таких случаях создаются обёртки:
function isRequiredEmail(value) {
return value && validator.isEmail(value);
}
Такая конструкция добавляет обязательность поля поверх стандартной проверки email.
Более гибкий вариант предполагает параметризацию:
function isEmailDomain(email, domain) {
return validator.isEmail(email) && email.endsWith(`@${domain}`);
}
При масштабировании системы проверки часто превращаются в конфигурируемые фабрики:
function createLengthValidator(min, max) {
return function (value) {
return validator.isLength(value, { min, max });
};
}
const isUsernameValid = createLengthValidator(5, 15);
const isTagValid = createLengthValidator(1, 10);
Фабричный подход снижает дублирование и делает правила декларативными.
Кастомные методы часто применяются не только к строкам, но и к объектам данных, где каждая проверка отвечает за отдельное поле:
function validateProfile(profile) {
return (
validator.isLength(profile.name, { min: 2 }) &&
validator.isEmail(profile.email) &&
typeof profile.age === 'number' &&
profile.age >= 18
);
}
Такая проверка объединяет разные типы условий в единый контракт.
В сложных системах кастомные методы группируются в наборы правил, отражающих бизнес-области:
const paymentValidators = {
isValidCardNumber(value) {
return validator.isCreditCard(value);
},
isValidAmount(value) {
return validator.isFloat(value, { min: 0.01 });
}
};
Это позволяет логически разделять ответственность между модулями.
Некоторые сценарии требуют обращения к внешним источникам данных. В таких случаях кастомный метод становится асинхронным:
async function isUniqueEmail(email, db) {
const user = await db.findUserByEmail(email);
return !user;
}
Асинхронные проверки особенно важны при работе с базами данных, где необходимо гарантировать уникальность значений.
Для масштабируемости важно стандартизировать возвращаемые значения кастомных методов. Вместо простого boolean часто используется структура результата:
function validateAge(age) {
if (!validator.isInt(age.toString())) {
return { valid: false, error: 'Возраст должен быть числом' };
}
if (age < 18) {
return { valid: false, error: 'Минимальный возраст 18 лет' };
}
return { valid: true };
}
Такой подход позволяет централизованно обрабатывать ошибки и формировать сообщения для интерфейса.
Кастомные методы могут учитывать внешний контекст:
function isValidDiscount(price, discount, userType) {
if (userType === 'premium') {
return discount <= price * 0.5;
}
return discount <= price * 0.2;
}
Здесь логика проверки зависит от роли пользователя, что выходит за рамки стандартных функций Validator.js.
При росте проекта кастомные методы объединяются в архитектурно выверенную структуру:
Такое разделение упрощает сопровождение и масштабирование системы валидации без зависимости от внутренних ограничений стандартной библиотеки.