Skip to content

Schema (validation)

import: @azure-net/kit

Схемы нужны для валидации ваших реквестов. Есть также две разновидности createSchemaFactory и schema. Разница лишь в наличии предопределенных правил валидации. При создании factory вы создаете экземпляр схемы с правилами, при создании schema вы каждый раз будете импортировать правила.

Пакет содержит немалое количество схем валидации, но сначала по основам.

Создание схемы

typescript
// При создании схемы вы должны передать тип реквеста для типизации
const LoginSchema = schema<ILoginRequest>()
    .rules(() => ({
        // Здесь пишутся правила валидации
    }))
    .transform((request) => (<ILoginRequuestTransformed>{
        // В коллбэке вы получаете ваш  изначальный прилетевший реквест
        // Здесь вы можете преобразовать реквест, при вызове метода json ваш реквест автоматически булдет приведен к тому что вы вернули здесь
        // Трансформация отработает только в случае успешной валидации
    }))
    .with(() => ({
        // В ключах объектов вы можете вернуть кастомные методы нужные вам в схеме, примеры будут ниже
    }))
    .create();

Пример схемы из фабрики

Этот вариант в целом предполагается как основной

typescript
import { createSchemaFactory } from '@azure-net/kit';
// Метод createRules создает праивла валидации с определенными сообщениями
// Сообщений есть 3 вида - validationMessagesI18n, validationMessagesEn, validationMessagesRu
// validationMessagesI18n предполагают использование пакета для переводов (edges-svelte-translations)
// Изначально validationMessagesI18n не имеют переводов и вам придется их добавить
import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';

export const Schema = createSchemaFactory(createRules(validationMessagesI18n));


export const LoginSchema = Schema<ILoginRequest>()
    // Теперь в коллбэке вы получаете правила валидации
    .rules((rules) => ({
        email: [rules.required(), rules.string(), rules.email()],
        password: [rules.required(), rules.password({ length: 6 })]
    }))
    .create();

Примеры использования with

typescript
export const UpdateScriptSchema = Schema<IScriptUpdateRequest>()
    .rules(() => ({
        // Add validation rules here
    }))
    .with(() => ({
        fromScriptModel: (script: IScript) => {
            return <IScriptUpdateRequest>{
                type: script?.type,
                position: script?.position,
                text: script?.text,
                timeout: script?.timeout,
                name: script?.name
            };
        }
    }))
    .create();

// В компоненте вы можете использовать методы из схемы для заполенния реквеста, для чего и создан метод fromScriptModel
const form = createActiveForm((formData: Partial<IScriptUpdateRequest>) => update(data.scriptResource.id, formData), {
    initialData: UpdateScriptSchema.fromScriptModel(data.scriptResource)
});

Правила валидации

string(params?)

Проверяет, что значение — строка, и соответствует ограничениям по длине.

Параметры:

  • length.min — минимальная длина.
  • length.max — максимальная длина.
  • message — переопределение стандартных сообщений (base, min, max).

Пример:

typescript
rules.string({ length: { min: 3, max: 10 } })

number(params?)

Проверяет, что значение — целое число, и входит в диапазон.

Параметры:

  • range.min — минимальное значение.
  • range.max — максимальное значение.
  • message — кастомные тексты ошибок (base, min, max).

Пример:

typescript
rules.number({ range: { min: 1, max: 100 } })

finite(params?)

Проверяет, что значение — конечное число (не NaN, не Infinity) и удовлетворяет ограничениям.

Параметры:

  • range.min / range.max — диапазон допустимых значений.
  • maxDigitsAfterDot — ограничение на количество знаков после запятой.
  • message — объект сообщений (base, min, max, maxDigitsAfterDot).

Пример:

typescript
rules.finite({ range: { min: 0, max: 100 }, maxDigitsAfterDot: 2 })

boolean(params?)

Проверяет, что значение — булево (true/false), и при необходимости совпадает с ожидаемым.

Параметры:

  • expected — если указано, проверяет на равенство true или false.
  • message — сообщения (base, expected).

Пример:

typescript
rules.boolean({ expected: true })

array(params?)

Проверяет, что значение — массив, подходит по длине и может содержать вложенные правила для элементов.

Параметры:

  • length.min / length.max — ограничения по размеру массива.

  • schema — схема валидации элементов:

    • массив правил (для примитивов);
    • объект с наборами правил (для элементов-объектов).
  • message — (base, min, max).

Пример:

typescript
rules.array({
  length: { min: 1 },
  schema: {
    name: [rules.string({ length: { min: 2 } })],
    age: [rules.number({ range: { min: 18 } })]
  }
})

phone(params?)

Проверяет, что строка является корректным телефонным номером с допустимым кодом страны.

Параметры:

  • message — функция для текста ошибки. Использует внутренний список кодов из masks.

Пример:

typescript
rules.phone()

email(params?)

Проверяет, что строка соответствует формату электронной почты.

Параметры:

  • message — функция для текста ошибки.

Пример:

typescript
rules.email()

lettersOnly(params?)

Проверяет, что строка содержит только буквы (латиница и кириллица). Может разрешать пробелы.

Параметры:

  • whiteSpaces — разрешать ли пробелы.
  • message — функция с аргументом whiteSpaces.

Пример:

typescript
rules.lettersOnly({ whiteSpaces: true })

allowedOnly(params?)

Проверяет, что значение входит в список допустимых.

Параметры:

  • allowed — массив допустимых значений.
  • message — функция с аргументом allowed.join(', ').

Пример:

typescript
rules.allowedOnly({ allowed: ['A', 'B', 'C'] })

sameAs(params)

Проверяет, что значение совпадает с другим полем формы/объекта.

Параметры:

  • key — ключ (имя поля), с которым нужно сравнивать.
  • message — функция, принимает имя ключа.

Пример:

typescript
rules.sameAs({ key: 'password' })

notSameAs(params)

Противоположность sameAs. Проверяет, что значение не совпадает с указанным полем.

Параметры:

  • key — имя поля для сравнения.
  • message — функция, принимает имя ключа.

Пример:

typescript
rules.notSameAs({ key: 'oldPassword' })

required(params?)

Проверяет, что значение существует и не пустое. Можно задавать условие, при котором поле обязательно.

Параметры:

  • byCondition — функция, возвращающая true/false (когда применять правило).
  • message — функция без аргументов.

Пример:

typescript
rules.required({
  byCondition: ({ listValues }) => listValues?.hasDelivery === true
})

password(params?)

Проверяет сложность пароля по нескольким критериям.

Параметры:

  • length — минимальная длина (по умолчанию 8).
  • specialChars — требовать спецсимволы (true/число).
  • numbers — требовать цифры (true/число).
  • lowerUpperCasePattern — требовать сочетание верхнего и нижнего регистра.
  • message — объект с функциями (length, specialChars, numbers, lowerUpperCasePattern).

Пример:

typescript
rules.password({
  length: 10,
  specialChars: 2,
  numbers: true,
  lowerUpperCasePattern: true
})

Примеры полноценных схем

typescript
export const LoginSchema = Schema<ILoginRequest>()
    .rules((rules) => ({
        email: [rules.required(), rules.string(), rules.email()],
        password: [rules.required(), rules.password({ length: 6 })]
    }))
    .create();


export const CreateJobRequestSchema = Schema<IJobRequestCreateRequest>()
    .rules((rules) => ({
        title: [rules.required(), rules.string()],
        contact_info: [rules.required(), rules.string()],
        price: [rules.finite({ maxDigitsAfterDot: 2 })],
        benefits: [rules.string()],
        deadline_at: [rules.string()],
        description: [rules.string()],
        full_description: [rules.string()],
        request_type: [
            rules.string(),
            rules.allowedOnly({
                allowed: [JobRequestType.CONSULTATION, JobRequestType.INVESTMENT, JobRequestType.OTHER, JobRequestType.SERVICE, JobRequestType.PARTNERSHIP]
            })
        ],
        other_type: [rules.string()],
        currency: [rules.string()]
    }))
    .transform((req) => ({ ...req, price: Number(req.price) }))
    .create();

Валидация

Для валидации схемы есть несколько вариантов. Сначала вам нужно отдать ваш реквест схеме с помощью метода from.

typescript
LoginSchema.from(data)

Далее вам доступны 3 метода

  • json автоматически валидирует и вызовет transform на ваш реквест в случае успеха, отдаст вам данные в виде json даже если вы туда отдали FormData
  • formData тажке автоматически валидирует и вызовет transform на ваш реквест в случае успеха, но отдаст вам данные в виде formData
  • validated() проведет валидауция и отдаст вам информацию о валиадации
typescript
LoginSchema.from(data).json() // Валидация плюс данные в json, в случае падения выдаст исключение в виде SchemaFail которые автоматом обработает crateAsyncAction и отдаст ошибки в error.fields
LoginSchema.from(data).formData() // Валидация плюс данные в formdData
const {valid, errors, json, formData} = LoginSchema.from(data).validated()

validated отдает 4 ключа

  • json и formData повторяют логику тех что описапны выше и просто позволят после валидации трансфомировать данные
  • valid - boolean прошел ли валидацию реквест
  • errors - список ошибок по полям если реквест валидацию не прошел