npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-generate-validator

v0.0.10

Published

Task to generate validation functions to check whether JSON data conforms to a schema described as typescript classes

Downloads

30

Readme

Tool for code generation validators by typescript model description

Кодогенерация валидаторов на основе typescript моделей

Содержание:

Мотивация

В ходе анализа популярных библиотек для валидации, таких как:

  • validator.js
  • class-validator
  • yup
  • joi
  • ajv

стало понятно, что все они заставляют разработчика вручную писать валидационную схему. Т.е. во многом дублировать код на typescript.

Поэтому возникла идея сделать кодогенерацию валидации на основании TS описания. По примеру нашей библиотеки https://www.npmjs.com/package/grunt-generate-view-model

Что хотим от валидации:

  1. изоморфность (возможность использования как на клиенте, так и на сервере);
  2. не описывать отдельную схему валидации, а использовать typescript-описание;
  3. для случаев, выходящих за рамки TS (проверка на соотвествие regexp, минимального значения, максимального значения и т.п.) использовать декораторы;
  4. возможность использования кастомной валидации в виде функции, возможно асинхронной;
  5. мультиязычность (вывод ошибок валидации на разных языках);
  6. удобство использования;

Установка

npm install ts-generate-validator -D

Использование

  1. Создать внутри папки src класс-модель на typescript и добавить к этому классу декоратор @Validation:
// src/model.ts
import { Validation } from 'ts-generate-validator';

@Validation
export class User {
  public name: string = '';
  public age: number = 0;
  public website?: string;
}
  1. Добавить в раздел scripts файла package.json инициализирующую команду "generateValidator", например:
  "scripts": {
    "generation": "generateValidator"
  }
  1. Запустить кодогенерацию
npm run generation
  1. В папке src/generated/validators появится новый файл src.model.ts экспортирующий функцию-валидатор userValidator

  2. Использовать валидатор для проверки соответствия данных json схеме, описанной в typescript моделе:

// src/index.ts
import { ValidationException } from 'ts-generate-validator';
import { userValidator } from 'src/generated/validators';

const data = {
  name: 'John',
  age: 30
};

try {
  userValidator(data, { stopAtFirstError: true });
} catch (exception) {
  if (exception instanceof ValidationException) {
    console.log(`Неправильный формат данных`);
    exception.errors.map(({ field, message }) => `[${field}] - ${message}`).forEach((msg) => console.log(msg));
  } else {
    throw exception;
  }
}

Как это работает

Конфигурация кодогенерации

Для изменения конфигурации по умолчанию, создайте файл "ts-generate-validator-config.json" в корне проекта, содержащий объект с любыми из следующих свойств:

inputPath(string) - путь к папке с моделями для которых необходимо сгенерировать валидаторы (по умолчанию "src").

outputPath(string) - путь к папке, в которой появятся сгенерированные валидаторы (по умолчанию "src/generated/validators").

unknownPropertySeverityLevel(number) - уровень проверки неизвестных параметров (параметров, имеющих 1) тип в виде ссылки на другие классы моделей без @Validation декораторов или 2) не поддерживаемые типы без @CustomValidation декораторов). Может иметь следующие значения:

  • 2 (error) - при генерации валидаторов выбрасывается ошибка
  • 1 (warning) - кодогенерация проходит, но в консоли появляется предупреждение об отсутствии валидации
  • 0 (silent) - кодогенерация проходит

по умолчанию: 1 ("warning")

Например:

{
  "inputPath": "src/models",
  "outputPath": "generated/validators",
  "unknownPropertySeverityLevel": 2
}

Конфигурация валидаторов

Конфигурацию валидаторов можно изменить двумя способами

  1. Изменения глобальной конфигурации валидаторов с помощью функции changeConfig:
import { changeConfig } from 'ts-generate-validator';

changeConfig({ stopAtFirstError: true });
  1. Изменение конфигурации только для текущего вызова валидатора:
import { userValidator } from 'src/generated/validators';

userValidator(data, { stopAtFirstError: true });

Следующие параметры могут быть сконфигурированы:

stopAtFirstError(boolean) - не продолжать валидацию после первой найденной ошибки (по умолчанию false).

emailRegExp(RegExp) - заменяет регулярное выражение по умолчанию для проверки email.

messages(object) - словарь с сообщениями об ошибках (по умолчанию используются стандартные сообщения на английском).

Валидатор

Сгенерированная из класса-модели функция-валидатор данных является асинхронной, если хотя бы для одного из свойств в классе-модели добавлен асинхронный custom валидатор. Она принимает в качестве аргументов:

data(any) (обязательный) - JSON данные для проверки

config(object) (необязательный) - объект с параметрами конфигурации

context(any) (необязательный) - любое пользовательское значение, которое будет доступно в пользовательских валидаторах

Результат выполнения: Пустой результат в результате успешной валидации. Если валидация завершилась неудачей, то выбрасывается ValidationException.

Локализация

Сообщения об ошибке по умолчанию на английском языке, но они могут быть заменены на любые другие с помощью декораторов свойств классов-моделей (смотрите раздел декораторы для свойств классов), либо через установку параметра messages в конфигурации валидаторов (смотрите раздел конфигурация валидаторов).

Декораторы

Декораторы могут быть применены на классах, и на свойствах классов.

Для классов

  • @Validation(config?: ValidationConfig) - помечает класс, как требующий генерации функции-валидатора.

  • @RequiredOneOfValidation(fields: string[], message?: Message) - добавляет к нескольким свойствам класса, перечисленным в первом аргументе fields, валидатор, проверяющий заполненность как минимум одного из указанных полей.

Для свойств классов

  • all supported types (смотрите поддерживаемые типы)

    • @TypeValidation(message: Message) - заменяет стандартное сообщение об ошибке для валидатора типа.
  • all types

    • @CustomValidation(validator: CustomValidator, message: Message) - добавляет к свойству пользовательскую функцию-валидатор, которая принимает в качестве первого аргумента объект со следующими свойствами:

      property(any) - значение свойства для валидации

      propertyName(string) - имя свойства для валидации

      data(object) - объект с JSON данными для валидации

      config(object) - объект с текущей конфигурацией валидаторов

      context(any) - пользовательский контекст, переданный в сгенерированную функцию-валидатор

      Возвращаемое значение: в случае успешной валидации - ничего не возвращает, в случае когда данные не соответствуют типу - должна выбрасываться ошибка ValidationError, например:

      import { ValidationError } from 'ts-generate-validator';
      
      ({ property, propertyName }) => {
        const allowedValues = [1, 4, 9];
        if (!allowedValues.includes(property)) {
          throw new ValidationError(propertyName, 'is invalid');
        }
      };
    • @IgnoreValidation - помечает свойство как игнорируемое в функции-валидаторе - оно не будет проверяться на соответствие типу, а любые примененные декораторы для дополнительной валидацией будут проигнорированы.

  • boolean, number, string, null, enum, union(boolean, number, string, null), array(boolean, number, string, null)

    • @EqualValidation(value: EqualToValue, message?: Message) - добавляет валидатор, который проверяет соответствие значения свойства - значению, переданному в первом аргументе (в первом аргументе допускаются любые уровни вложенности в массивах).

    • @EqualToValidation(propName: string, message?: Message) - добавляет валидатор, который проверяет соответствие значения свойства, на котором был использован декоратор - свойству, содержащемуся в свойстве propName.

  • number, number[]

    • @MinValidation(threshold: number, message?: Message) - добавляет валидатор, который проверяет число на соответствие минимальному значению threshold(включительно).

    • @MaxValidation(threshold: number, message?: Message) - добавляет валидатор, который проверяет число на соответствие максимальному значению threshold(включительно).

    • @NegativeValidation(message?: Message) - добавляет валидатор, который проверяет - является ли число отрицательным.

    • @PositiveValidation(message?: Message) - добавляет валидатор, который проверяет - является ли число положительным.

    • @IntegerValidation(message?: Message) - добавляет валидатор, который проверяет - является ли число целым.

    • @FloatValidation(message?: Message) - добавляет валидатор, который проверяет - содержит ли число плавающую точку.

    • @LessThanValidation(propName: string, message?: Message) - добавляет валидатор, который проверяет - является ли число меньшим, чем число в свойстве propName.

    • @MoreThanValidation(propName: string, message?: Message) - добавляет валидатор, который проверяет - является ли число большим, чем число в свойстве propName.

  • string, string[]

    • @TrimValidation(message?: Message) - добавляет валидатор, который проверяет отсутствие пробелов в начале и конце строки.

    • @LowercaseValidation(message?: Message) - добавляет валидатор, который проверяет отсутствие заглавных букв в строке.

    • @UppercaseValidation(message?: Message) - добавляет валидатор, который проверяет отсутствие строчных букв в строке.

    • @MinLengthValidation(threshold: number, message?: Message) - добавляет валидатор, который проверяет длину строки на соответствие максимальному значению threshold(включительно).

    • @maxLength(threshold: number, message?: Message) - добавляет валидатор, который проверяет длину строки на соответствие максимальному значению threshold(включительно).

    • @EmailValidation(message?: Message) - добавляет валидатор, который проверяет - является ли строка корректным email адресом.

    • @UrlValidation(message?: Message) - добавляет валидатор, который проверяет - является ли строка корректным url адресом.

    • @MatchValidation(regexp: RegExp, message?: Message) - добавляет валидатор, который проверяет строку на соответствие регулярному выражению, переданному в первом аргументе.

Поддерживаемые типы

| Тип | Поддержка | Определение типа по значению | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | | boolean | Да | Да | | number | Да | Да | | string | Да | Да | | null | Да | Да | | undefined | Нет | Нет | | enum | Да | Нет | | array | Частично (поддерживаются только массивы, элементы которых являются поддерживаемыми типами) | Нет | | union | Частично (поддерживаются только объединения из свойств, имеющих поддерживаемый тип) | Нет | | class | Частично (поддерживаются только классы, имеющие декоратор @Validation и находящиеся в каталогах, доступных для генерации валидаций - смотрите в конфигурации кодогенерации свойство inputPath) | Нет | | interface | Нет | Нет | | type | Нет (кастомные typescript типы не поддерживаются) | Нет | | typeof | Нет | Нет |

Лицензия

MIT License