Как стать автором
Обновить

Комментарии 14

По моему, единственная причина использование "min|max число, максимальная длинна… и пр. — это случай, когда эти условия задаются не в коде, а в настройках. Да еще настройка рассчитана на людей, который понятия не имеют о regexp.
В коде, лично мне, проще регулярные выражения писать, чем такую лапшу из проверок.

Регэкспы могут быть абсолютно нечитабельны.

Могут быть… На первый взгляд.


Но когда с ними часто работаешь, то наступает просветление.
Очень формальный и простой язык описания. Нужно только научится мыслить как парсер и просветление наступит.
Но для тех кто код будет смотреть ВСЕГДА оставляю комментарий что данный regexp делает.

Ничто не мешает брать список валидаторов и параметры для них хоть из конфигов, хоть из базы. Ошибки будут накапливаться.

Проверка "3 условия из 4х" реализована как-нибудь?

нет. неожиданный кейс… но впринципе это легко реализуемо уже на клиенте проверкой кол-ва ошибок
validate(string)
   .rule1()
   .rule2()
   .rule3()
   .rule4()
   .errors.length < 2;
Если честно, API мне кажется не очень удачным. Сложно реюзать. Я б его инвертировал:

passwordRules = new Validator()
  .hasLettersLatin()
  .hasNumbers();

passwordRules.validate(password1);
passwordRules.validate(password2);
import {composeRules, minLength, maxLength, has} from '...';

const passwordRule = composeRules(
   minLength(6),
   maxLength(32),
   has(/[0-9]/, 'numbers'),
   has(/^[a-z]+$/i, 'only-latin'),
);

const result = passwordRule(inputPass.value);
а чем плох:
const validatePassword = pass => validate(pass)
  .hasLettersLatin()
  .hasNumbers();

validatePassword(password1);
validatePassword(password2);
если мы говорим про валидацию, которая выполняется на каждый чих пользователя, то ответ: ВСЕМ.
можно как-то более развёрнуто?

Плохо тем, что на каждый чих вместо уже подготовленной (возможно оптимальной под конкретный паттерн) функции (которую барузер успешно заJITит), будет создаваться новый объект, методы которого вдобавок завраплены, т.е. как не крути, это всё оверхед.


Ок, допустим он небольшой, но всё равно остаётся проблема повторного использования, да, можно завернуть это в метод, как вы написали, но это нужно догадаться, без шуток.


Кроме этого, если оформить в функциональном стиле, мы получим достаточно гибкую штуку и комбинации правил, типа


import {validate, compose, minLength, regExp} import '...';

const emailRule = compose('email', [
  minLength(6),
  regExp(/^.+@.+\.[a-z]+$/),
]);
const onlyGmail = compose('only-gmail', [
  emailRule(),
  regExp(/@gmail.com$/),
]);

validate(onlyGmail, input.value);

Думаю этот спор всё-равно ни к чему не приведёт, но я не вижу тут оверхеда...


В чём конкретно проблема того что ассерты завраплены? С клиентской стороны этого не видно, а для разработки это проще. Не приходится тащить кусок ядра в каждый ассерт в отличае от вашей идеи.


Объект создаётся только потому что с ним работать удобнее. В нём не лежит ни одной функции, и он легко сериализуется в JSON. Все ассерты находятся в прототипе который JS движок не будет пересоздавать на каждый чих.


Да, функциональщина это круто. Но тут получается функциональщина ради функциональщины.


Кроме этого, если оформить в функциональном стиле, мы получим ...

… усложнение кода библиотеки, повышение порога вход, усложнение кода клиента и стоимости его поддержки, без выйгрыша в чём либо.
Теоретически compose вместе с хитрым createComplexRule могут дать какой-то прирост в производительности по сравнению с runAssertAsMethod. Но это уж точно выглядит оверхедом и преждевременной оптимизацией

Хотя думаю погорячился, так что всё это ИМХО, просто у себя я именно так и сделал, вот:


Правила
export function minLength(min: number): ValidateRule {
    return ({value}) => value.length >= min ? null : {
        id: 'minLength',
        detail: {
            min,
        },
    };
}

export function required(): ValidateRule {
    return createComplexRule('required', {}, [minLength(1)]);
}

export function email(): ValidateRule {
    return createComplexRule('email', {}, [regexp(/^.+@.+\..+$/)]);
}

export function password(additionalRules: ValidateRule[] = []): ValidateRule {
    return createComplexRule('password', {}, [
        required(),
        minLength(6),
    ].concat(additionalRules));
}

Результат вылидации
const validaty = password()({value: "123"});
// {
//   id: 'password',
//   detail: {},
//   nested: {
//     id: 'minLength',
//     detail: {min: 6},
//   },
// }
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории