@astral/validations 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/array/array.d.ts +1 -8
- package/boolean/boolean.d.ts +1 -8
- package/core/composeAsync/composeAsync.d.ts +6 -0
- package/core/composeAsync/composeAsync.js +24 -0
- package/core/composeAsync/index.d.ts +1 -0
- package/core/composeAsync/index.js +1 -0
- package/core/errors/constants.d.ts +2 -0
- package/core/errors/constants.js +5 -0
- package/core/errors/index.d.ts +1 -0
- package/core/errors/index.js +1 -0
- package/core/guard/createGuard/createGuard.d.ts +21 -24
- package/core/guard/createGuard/createGuard.js +8 -27
- package/core/guard/types.d.ts +18 -0
- package/core/guard/types.js +1 -0
- package/core/index.d.ts +1 -0
- package/core/index.js +1 -0
- package/core/logger/index.d.ts +1 -0
- package/core/logger/index.js +1 -0
- package/core/logger/logger.d.ts +6 -0
- package/core/logger/logger.js +9 -0
- package/core/rule/callAsyncRule/callAsyncRule.d.ts +8 -0
- package/core/rule/callAsyncRule/callAsyncRule.js +25 -0
- package/core/rule/callAsyncRule/index.d.ts +1 -0
- package/core/rule/callAsyncRule/index.js +1 -0
- package/core/rule/index.d.ts +1 -0
- package/core/rule/index.js +1 -0
- package/core/rule/types.d.ts +8 -0
- package/date/date.d.ts +1 -8
- package/index.d.ts +2 -2
- package/index.js +2 -2
- package/max/max.d.ts +2 -2
- package/min/min.d.ts +2 -2
- package/number/number.d.ts +1 -8
- package/object/index.d.ts +1 -0
- package/object/index.js +1 -0
- package/object/object.d.ts +1 -8
- package/object/objectAsync/index.d.ts +1 -0
- package/object/objectAsync/index.js +1 -0
- package/object/objectAsync/objectAsync.d.ts +61 -0
- package/object/objectAsync/objectAsync.js +71 -0
- package/package.json +1 -1
- package/partial/partial.d.ts +3 -10
- package/string/index.d.ts +1 -0
- package/string/index.js +1 -0
- package/string/string.d.ts +1 -8
- package/string/string.js +2 -1
- package/string/stringAsync/index.d.ts +1 -0
- package/string/stringAsync/index.js +1 -0
- package/string/stringAsync/stringAsync.d.ts +6 -0
- package/string/stringAsync/stringAsync.js +23 -0
- package/string/utils/index.d.ts +1 -0
- package/string/utils/index.js +1 -0
- package/string/utils/isString/index.d.ts +1 -0
- package/string/utils/isString/index.js +1 -0
- package/string/utils/isString/isString.d.ts +1 -0
- package/string/utils/isString/isString.js +1 -0
package/README.md
CHANGED
@@ -65,6 +65,7 @@
|
|
65
65
|
- [when. Условная валидация](#when-условная-валидация)
|
66
66
|
- [transform](#transform)
|
67
67
|
- [or](#or)
|
68
|
+
- [Async](#async)
|
68
69
|
- [Integrations](#integrations)
|
69
70
|
- [react-hook-form](#react-hook-form)
|
70
71
|
- [Guides](#guides)
|
@@ -1464,6 +1465,45 @@ validate(new Date())
|
|
1464
1465
|
|
1465
1466
|
---
|
1466
1467
|
|
1468
|
+
# Async
|
1469
|
+
Пакет поддерживает асинхронную валидацию.
|
1470
|
+
|
1471
|
+
Guard, поддерживающие асинхронную валидацию имеют постфиксы ```async```:
|
1472
|
+
- ```objectAsync```
|
1473
|
+
- ```stringAsync```
|
1474
|
+
|
1475
|
+
Пример:
|
1476
|
+
|
1477
|
+
```ts
|
1478
|
+
type Values = {
|
1479
|
+
nickname: string;
|
1480
|
+
phone: string;
|
1481
|
+
};
|
1482
|
+
|
1483
|
+
const validate = objectAsync<Values>({
|
1484
|
+
phone: string(),
|
1485
|
+
nickname: stringAsync(min(3), async (value, ctx) => {
|
1486
|
+
const nicknameIsAvailable = await checkNickname(value);
|
1487
|
+
|
1488
|
+
if (nicknameIsAvailable) {
|
1489
|
+
return undefined;
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
return ctx.createError({
|
1493
|
+
code: 'nickname-available',
|
1494
|
+
message: 'Nickname занят',
|
1495
|
+
});
|
1496
|
+
}),
|
1497
|
+
});
|
1498
|
+
|
1499
|
+
const result = await validate({ phone: '79308999999', nickname: 'Vasya' });
|
1500
|
+
|
1501
|
+
// { nickname: 'Nickname занят' }
|
1502
|
+
toPrettyError(result);
|
1503
|
+
```
|
1504
|
+
|
1505
|
+
---
|
1506
|
+
|
1467
1507
|
# Integrations
|
1468
1508
|
|
1469
1509
|
## react-hook-form
|
package/array/array.d.ts
CHANGED
@@ -12,11 +12,4 @@ import { ValidationRule } from '../core';
|
|
12
12
|
* validateArray(value);
|
13
13
|
* ```
|
14
14
|
*/
|
15
|
-
export declare const array: <TItem extends unknown, TLastSchemaValues extends Record<string, unknown> = {}>(...rules: ValidationRule<TItem[], TLastSchemaValues>[]) => {
|
16
|
-
(value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
17
|
-
define(overridesDefOptions: Partial<{}> & {
|
18
|
-
requiredErrorMessage?: string | undefined;
|
19
|
-
typeErrorMessage?: string | undefined;
|
20
|
-
isOptional?: boolean | undefined;
|
21
|
-
}): any;
|
22
|
-
};
|
15
|
+
export declare const array: <TItem extends unknown, TLastSchemaValues extends Record<string, unknown> = {}>(...rules: ValidationRule<TItem[], TLastSchemaValues>[]) => import("../core").Guard<TLastSchemaValues, {}>;
|
package/boolean/boolean.d.ts
CHANGED
@@ -10,11 +10,4 @@ import { ValidationRule } from '../core';
|
|
10
10
|
* validate(true);
|
11
11
|
* ```
|
12
12
|
*/
|
13
|
-
export declare const boolean: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<boolean, TLastSchemaValues>[]) => {
|
14
|
-
(value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
15
|
-
define(overridesDefOptions: Partial<{}> & {
|
16
|
-
requiredErrorMessage?: string | undefined;
|
17
|
-
typeErrorMessage?: string | undefined;
|
18
|
-
isOptional?: boolean | undefined;
|
19
|
-
}): any;
|
20
|
-
};
|
13
|
+
export declare const boolean: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<boolean, TLastSchemaValues>[]) => import("../core").Guard<TLastSchemaValues, {}>;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { AsyncIndependentValidationRule, AsyncValidationRule, IndependentValidationRule, ValidationRule } from '../rule';
|
2
|
+
/**
|
3
|
+
* Объединяет переданные асинхронные правила в цепочку правил, останавливает выполнение цепочки, если появилась ошибка. Выполняет правила слева направо
|
4
|
+
* @example composeAsync(stringAsync(), max());
|
5
|
+
*/
|
6
|
+
export declare const composeAsync: <ValidationType, TLastSchemaValues extends Record<string, unknown>>(...rules: (IndependentValidationRule<ValidationType, TLastSchemaValues> | AsyncIndependentValidationRule<ValidationType, TLastSchemaValues> | ValidationRule<ValidationType, TLastSchemaValues> | AsyncValidationRule<ValidationType, TLastSchemaValues>)[]) => AsyncIndependentValidationRule<ValidationType, Record<string, unknown>>;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import { callAsyncRule, } from '../rule';
|
11
|
+
/**
|
12
|
+
* Объединяет переданные асинхронные правила в цепочку правил, останавливает выполнение цепочки, если появилась ошибка. Выполняет правила слева направо
|
13
|
+
* @example composeAsync(stringAsync(), max());
|
14
|
+
*/
|
15
|
+
export const composeAsync = (...rules) => (value, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
16
|
+
let result;
|
17
|
+
for (const rule of rules) {
|
18
|
+
result = yield callAsyncRule(rule, value, ctx);
|
19
|
+
if (result) {
|
20
|
+
break;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
return result;
|
24
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './composeAsync';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './composeAsync';
|
package/core/errors/index.d.ts
CHANGED
package/core/errors/index.js
CHANGED
@@ -1,23 +1,6 @@
|
|
1
1
|
import { ValidationResult } from '../../types';
|
2
2
|
import { ValidationContext } from '../../context';
|
3
|
-
|
4
|
-
/**
|
5
|
-
* @description Переопределяет дефолтное сообщения ошибки для required
|
6
|
-
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
7
|
-
*/
|
8
|
-
requiredErrorMessage?: string;
|
9
|
-
/**
|
10
|
-
* @description Переопределяет сообщение об ошибке типа
|
11
|
-
* @example string.define({ typeErrorMessage: 'ИНН не может быть числом' })(inn())
|
12
|
-
*/
|
13
|
-
typeErrorMessage?: string;
|
14
|
-
/**
|
15
|
-
* @description Позволяет выключать проверку на required
|
16
|
-
* @default false
|
17
|
-
*/
|
18
|
-
isOptional?: boolean;
|
19
|
-
};
|
20
|
-
type GuardValue = unknown;
|
3
|
+
import { GuardDefOptions, GuardValue } from '../types';
|
21
4
|
/**
|
22
5
|
* @description Интерфейс функции guard, которая в прототипе содержит метод define
|
23
6
|
*/
|
@@ -28,12 +11,28 @@ export interface Guard<TLastSchemaValues extends Record<string, unknown> = {}, A
|
|
28
11
|
* @param options - параметры, позволяющие переопределить дефолтные настройки guard
|
29
12
|
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
30
13
|
*/
|
31
|
-
define(options:
|
14
|
+
define(options: GuardDefOptions<AddDefOptions>): Guard<TLastSchemaValues, AddDefOptions>;
|
15
|
+
}
|
16
|
+
/**
|
17
|
+
* @description Интерфейс асинхронной функции guard, которая в прототипе содержит метод define
|
18
|
+
*/
|
19
|
+
export interface AsyncGuard<TLastSchemaValues extends Record<string, unknown> = {}, AddDefOptions extends Record<string, unknown> = {}> {
|
20
|
+
(value: GuardValue, ctx?: ValidationContext<TLastSchemaValues>): Promise<ValidationResult>;
|
21
|
+
/**
|
22
|
+
* @description Функция для создания нового guard с переопределенными дефолтными параметрами. Возвращает новый guard
|
23
|
+
* @param options - параметры, позволяющие переопределить дефолтные настройки guard
|
24
|
+
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
25
|
+
*/
|
26
|
+
define(options: GuardDefOptions<AddDefOptions>): AsyncGuard<TLastSchemaValues, AddDefOptions>;
|
32
27
|
}
|
33
28
|
/**
|
34
29
|
* @description Функция, которая позволяет определять частную логику для guard
|
35
30
|
*/
|
36
|
-
type GuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<Record<string, unknown>>, defOptions:
|
31
|
+
type GuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<Record<string, unknown>>, defOptions: GuardDefOptions<AddDefOptions>) => ValidationResult;
|
32
|
+
/**
|
33
|
+
* @description Функция, которая позволяет определять частную логику для guard
|
34
|
+
*/
|
35
|
+
type AsyncGuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<Record<string, unknown>>, defOptions: GuardDefOptions<AddDefOptions>) => Promise<ValidationResult>;
|
37
36
|
/**
|
38
37
|
* @description Создает guard. Guard - функция, проверяющая тип значения
|
39
38
|
* По-дефолту проверяет value на required. Для выключения required необходимо использовать optional().
|
@@ -50,8 +49,6 @@ type GuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unkn
|
|
50
49
|
* });
|
51
50
|
* ```
|
52
51
|
*/
|
53
|
-
export declare
|
54
|
-
|
55
|
-
define(overridesDefOptions: DefOptions<AddDefOptions>): any;
|
56
|
-
};
|
52
|
+
export declare function createGuard<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown> = {}>(executor: GuardExecutor<AddDefOptions>): Guard<TLastSchemaValues, AddDefOptions>;
|
53
|
+
export declare function createGuard<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown> = {}>(executor: AsyncGuardExecutor<AddDefOptions>): AsyncGuard<TLastSchemaValues, AddDefOptions>;
|
57
54
|
export {};
|
@@ -1,41 +1,22 @@
|
|
1
|
-
import {
|
1
|
+
import { required } from '../../rule';
|
2
2
|
import { createContext } from '../../context';
|
3
|
-
|
4
|
-
/**
|
5
|
-
* @description Создает guard. Guard - функция, проверяющая тип значения
|
6
|
-
* По-дефолту проверяет value на required. Для выключения required необходимо использовать optional().
|
7
|
-
* После первого вызова guard в прототипу функции становится доступен метод define, который позволяет переопределить дефолтное поведение guard (например, изменить текст для required правила)
|
8
|
-
* @example
|
9
|
-
* ```ts
|
10
|
-
* const string = <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<string, TValues>[]) =>
|
11
|
-
* createGuard<string, TValues>((value, ctx) => {
|
12
|
-
* if (typeof value !== 'string') {
|
13
|
-
* return ctx.createError({ code: 'custom error', message: 'Не строка' });
|
14
|
-
* }
|
15
|
-
*
|
16
|
-
* return compose<string, TValues>(...rules)(value, ctx);
|
17
|
-
* });
|
18
|
-
* ```
|
19
|
-
*/
|
20
|
-
export const createGuard = (executeGuard) => {
|
3
|
+
export function createGuard(executor) {
|
21
4
|
// выделено в отдельную именованную функцию для того, чтобы ее можно было рекурсивно вызывать в define
|
22
5
|
const createInnerGuard = (defOptions = {}) => {
|
23
6
|
const guard = (value, prevCtx) => {
|
24
7
|
const ctx = createContext(prevCtx,
|
25
8
|
// при создании контекста сейчас не имеет значение какого типа будет ctx.values
|
26
9
|
value);
|
27
|
-
const
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if ((defOptions === null || defOptions === void 0 ? void 0 : defOptions.isOptional) &&
|
32
|
-
(validationResult === null || validationResult === void 0 ? void 0 : validationResult.cause.code) === REQUIRED_ERROR_INFO.code) {
|
10
|
+
const requiredResult = required({
|
11
|
+
message: defOptions === null || defOptions === void 0 ? void 0 : defOptions.requiredErrorMessage,
|
12
|
+
})(value, ctx);
|
13
|
+
if ((defOptions === null || defOptions === void 0 ? void 0 : defOptions.isOptional) && requiredResult) {
|
33
14
|
return undefined;
|
34
15
|
}
|
35
|
-
return
|
16
|
+
return requiredResult || executor(value, ctx, defOptions);
|
36
17
|
};
|
37
18
|
guard.define = (overridesDefOptions) => createInnerGuard(overridesDefOptions);
|
38
19
|
return guard;
|
39
20
|
};
|
40
21
|
return createInnerGuard();
|
41
|
-
}
|
22
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
export type GuardDefOptions<AddDefOptions extends Record<string, unknown>> = Partial<AddDefOptions> & {
|
2
|
+
/**
|
3
|
+
* @description Переопределяет дефолтное сообщения ошибки для required
|
4
|
+
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
5
|
+
*/
|
6
|
+
requiredErrorMessage?: string;
|
7
|
+
/**
|
8
|
+
* @description Переопределяет сообщение об ошибке типа
|
9
|
+
* @example string.define({ typeErrorMessage: 'ИНН не может быть числом' })(inn())
|
10
|
+
*/
|
11
|
+
typeErrorMessage?: string;
|
12
|
+
/**
|
13
|
+
* @description Позволяет выключать проверку на required
|
14
|
+
* @default false
|
15
|
+
*/
|
16
|
+
isOptional?: boolean;
|
17
|
+
};
|
18
|
+
export type GuardValue = unknown;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/core/index.d.ts
CHANGED
package/core/index.js
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './logger';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './logger';
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { AsyncValidationRule, ValidationRule } from '../types';
|
2
|
+
import { ValidationResult } from '../../types';
|
3
|
+
import { ValidationContext } from '../../context';
|
4
|
+
/**
|
5
|
+
* Позволяет рекурсивно вызывать асинхронные правила. Rule может возвращать другой rule
|
6
|
+
* Если один из rule выбросит exception, то функция его обработает и вернет дефолтную ошибку
|
7
|
+
*/
|
8
|
+
export declare const callAsyncRule: <TValue, TLastSchemaValues extends Record<string, unknown>>(rule: ValidationRule<TValue, TLastSchemaValues> | AsyncValidationRule<TValue, TLastSchemaValues>, value: TValue, ctx: ValidationContext<TLastSchemaValues>) => ValidationResult | Promise<ValidationResult>;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { REJECT_PROMISE_ERROR_INFO } from '../../errors';
|
2
|
+
import { logger } from '../../logger';
|
3
|
+
/**
|
4
|
+
* Позволяет рекурсивно вызывать асинхронные правила. Rule может возвращать другой rule
|
5
|
+
* Если один из rule выбросит exception, то функция его обработает и вернет дефолтную ошибку
|
6
|
+
*/
|
7
|
+
export const callAsyncRule = (rule, value, ctx) => {
|
8
|
+
const ruleResult = rule(value, ctx);
|
9
|
+
if (ruleResult && 'then' in ruleResult) {
|
10
|
+
return ruleResult
|
11
|
+
.then((result) => {
|
12
|
+
if (typeof result === 'function') {
|
13
|
+
return callAsyncRule(result, value, ctx);
|
14
|
+
}
|
15
|
+
return result;
|
16
|
+
})
|
17
|
+
.catch((err) => {
|
18
|
+
logger.error('Ошибка при выполнении асинхронного правила', err);
|
19
|
+
return ctx.createError(REJECT_PROMISE_ERROR_INFO);
|
20
|
+
});
|
21
|
+
}
|
22
|
+
return typeof ruleResult === 'function'
|
23
|
+
? callAsyncRule(ruleResult, value, ctx)
|
24
|
+
: ruleResult;
|
25
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './callAsyncRule';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './callAsyncRule';
|
package/core/rule/index.d.ts
CHANGED
package/core/rule/index.js
CHANGED
package/core/rule/types.d.ts
CHANGED
@@ -4,10 +4,18 @@ import { ValidationResult } from '../types';
|
|
4
4
|
* @description Самостоятельное правило для валидации. Может использоваться вне guard'ов
|
5
5
|
*/
|
6
6
|
export type IndependentValidationRule<TValue, TLastSchemaValues extends Record<string, unknown>> = (value: TValue, ctx?: ValidationContext<TLastSchemaValues>) => ValidationResult;
|
7
|
+
/**
|
8
|
+
* @description Самостоятельное асинхронное правило для валидации. Может использоваться вне guard'ов
|
9
|
+
*/
|
10
|
+
export type AsyncIndependentValidationRule<TValue, TLastSchemaValues extends Record<string, unknown>> = (value: TValue, ctx?: ValidationContext<TLastSchemaValues>) => Promise<ValidationResult>;
|
7
11
|
/**
|
8
12
|
* @description Правило для валидации, работающее исключительно с guard'ами
|
9
13
|
*/
|
10
14
|
export type ValidationRule<TValue, TLastSchemaValues extends Record<string, unknown> = {}> = (value: TValue, ctx: ValidationContext<TLastSchemaValues>) => ValidationResult | ValidationRule<TValue, TLastSchemaValues>;
|
15
|
+
/**
|
16
|
+
* @description Асинхронное правило для валидации, работающее исключительно с guard'ами
|
17
|
+
*/
|
18
|
+
export type AsyncValidationRule<TValue, TLastSchemaValues extends Record<string, unknown> = {}> = (value: TValue, ctx: ValidationContext<TLastSchemaValues>) => Promise<ValidationResult | AsyncValidationRule<TValue, TLastSchemaValues> | ValidationRule<TValue, TLastSchemaValues>>;
|
11
19
|
/**
|
12
20
|
* @description Композиционное правило валидации, умеющее работать с любыми значениями.
|
13
21
|
* В основном используется для композиционных правил, которые принимают rule, умеющие валидировать разные значения (optional, transform...)
|
package/date/date.d.ts
CHANGED
@@ -15,12 +15,5 @@ type AdditionalDefOptions = {
|
|
15
15
|
* validate(new Date('22.22.2022'));
|
16
16
|
* ```
|
17
17
|
*/
|
18
|
-
export declare const date: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<Date, TLastSchemaValues>[]) =>
|
19
|
-
(value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
20
|
-
define(overridesDefOptions: Partial<AdditionalDefOptions> & {
|
21
|
-
requiredErrorMessage?: string | undefined;
|
22
|
-
typeErrorMessage?: string | undefined;
|
23
|
-
isOptional?: boolean | undefined;
|
24
|
-
}): any;
|
25
|
-
};
|
18
|
+
export declare const date: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<Date, TLastSchemaValues>[]) => import("../core").Guard<TLastSchemaValues, AdditionalDefOptions>;
|
26
19
|
export {};
|
package/index.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
export { object, OBJECT_TYPE_ERROR_INFO, type Schema, type SchemaValue, type ObjectGuard, } from './object';
|
1
|
+
export { object, objectAsync, OBJECT_TYPE_ERROR_INFO, type Schema, type SchemaValue, type ObjectGuard, type ObjectAsyncGuard, } from './object';
|
2
2
|
export { optional } from './optional';
|
3
|
-
export { string, STRING_TYPE_ERROR_INFO } from './string';
|
3
|
+
export { string, STRING_TYPE_ERROR_INFO, stringAsync } from './string';
|
4
4
|
export { date, INVALID_DATE_ERROR_INFO, DATE_TYPE_ERROR_INFO } from './date';
|
5
5
|
export { number, NAN_NUMBER_ERROR_INFO, NUMBER_TYPE_ERROR_INFO, INFINITY_NUMBER_ERROR_INFO, } from './number';
|
6
6
|
export { boolean, BOOLEAN_TYPE_ERROR_INFO } from './boolean';
|
package/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
export { object, OBJECT_TYPE_ERROR_INFO, } from './object';
|
1
|
+
export { object, objectAsync, OBJECT_TYPE_ERROR_INFO, } from './object';
|
2
2
|
export { optional } from './optional';
|
3
|
-
export { string, STRING_TYPE_ERROR_INFO } from './string';
|
3
|
+
export { string, STRING_TYPE_ERROR_INFO, stringAsync } from './string';
|
4
4
|
export { date, INVALID_DATE_ERROR_INFO, DATE_TYPE_ERROR_INFO } from './date';
|
5
5
|
export { number, NAN_NUMBER_ERROR_INFO, NUMBER_TYPE_ERROR_INFO, INFINITY_NUMBER_ERROR_INFO, } from './number';
|
6
6
|
export { boolean, BOOLEAN_TYPE_ERROR_INFO } from './boolean';
|
package/max/max.d.ts
CHANGED
@@ -21,6 +21,6 @@ type MaxParams<ValidationType> = {
|
|
21
21
|
* date(max(new Date())));
|
22
22
|
* ```
|
23
23
|
*/
|
24
|
-
export declare function max<ValidationType extends Date>(threshold: Date, params?: MaxParams<ValidationType>): ReturnType<typeof createRule<Date>>;
|
25
|
-
export declare function max<ValidationType extends BaseMaxValidationTypes>(threshold: number, params?: MaxParams<ValidationType>): ReturnType<typeof createRule<BaseMaxValidationTypes>>;
|
24
|
+
export declare function max<ValidationType extends Date, TLastSchemaValues extends Record<string, unknown> = {}>(threshold: Date, params?: MaxParams<ValidationType>): ReturnType<typeof createRule<Date, TLastSchemaValues>>;
|
25
|
+
export declare function max<ValidationType extends BaseMaxValidationTypes, TLastSchemaValues extends Record<string, unknown> = {}>(threshold: number, params?: MaxParams<ValidationType>): ReturnType<typeof createRule<BaseMaxValidationTypes, TLastSchemaValues>>;
|
26
26
|
export {};
|
package/min/min.d.ts
CHANGED
@@ -21,6 +21,6 @@ type MinParams<ValidationType> = {
|
|
21
21
|
* date(min(new Date())));
|
22
22
|
* ```
|
23
23
|
*/
|
24
|
-
export declare function min<ValidationType extends Date>(threshold: Date, params?: MinParams<ValidationType>): ReturnType<typeof createRule<Date>>;
|
25
|
-
export declare function min<ValidationType extends BaseMinValidationTypes>(threshold: number, params?: MinParams<ValidationType>): ReturnType<typeof createRule<BaseMinValidationTypes>>;
|
24
|
+
export declare function min<ValidationType extends Date, TLastSchemaValues extends Record<string, unknown> = {}>(threshold: Date, params?: MinParams<ValidationType>): ReturnType<typeof createRule<Date, TLastSchemaValues>>;
|
25
|
+
export declare function min<ValidationType extends BaseMinValidationTypes, TLastSchemaValues extends Record<string, unknown> = {}>(threshold: number, params?: MinParams<ValidationType>): ReturnType<typeof createRule<BaseMinValidationTypes, TLastSchemaValues>>;
|
26
26
|
export {};
|
package/number/number.d.ts
CHANGED
@@ -15,12 +15,5 @@ type AdditionalDefOptions = {
|
|
15
15
|
* validate(24);
|
16
16
|
* ```
|
17
17
|
*/
|
18
|
-
export declare const number: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<number, TLastSchemaValues>[]) =>
|
19
|
-
(value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
20
|
-
define(overridesDefOptions: Partial<AdditionalDefOptions> & {
|
21
|
-
requiredErrorMessage?: string | undefined;
|
22
|
-
typeErrorMessage?: string | undefined;
|
23
|
-
isOptional?: boolean | undefined;
|
24
|
-
}): any;
|
25
|
-
};
|
18
|
+
export declare const number: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<number, TLastSchemaValues>[]) => import("../core").Guard<TLastSchemaValues, AdditionalDefOptions>;
|
26
19
|
export {};
|
package/object/index.d.ts
CHANGED
package/object/index.js
CHANGED
package/object/object.d.ts
CHANGED
@@ -44,13 +44,6 @@ export type Schema<TValue extends Record<string, unknown>> = Record<keyof TValue
|
|
44
44
|
* });
|
45
45
|
* ```
|
46
46
|
*/
|
47
|
-
export declare const object: <TValue extends Record<string, unknown>, TLastSchemaValues extends Record<string, unknown> = {}>(schema: Schema<TValue>) =>
|
48
|
-
(value: unknown, prevCtx?: ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
49
|
-
define(overridesDefOptions: Partial<AdditionalDefOptions> & {
|
50
|
-
requiredErrorMessage?: string | undefined;
|
51
|
-
typeErrorMessage?: string | undefined;
|
52
|
-
isOptional?: boolean | undefined;
|
53
|
-
}): any;
|
54
|
-
};
|
47
|
+
export declare const object: <TValue extends Record<string, unknown>, TLastSchemaValues extends Record<string, unknown> = {}>(schema: Schema<TValue>) => Guard<TLastSchemaValues, AdditionalDefOptions>;
|
55
48
|
export type ObjectGuard<TValue extends Record<string, unknown>> = ReturnType<typeof object<TValue>>;
|
56
49
|
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './objectAsync';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './objectAsync';
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { AsyncGuard, AsyncValidationRule, Guard, ValidationContext, ValidationRule } from '../../core';
|
2
|
+
/**
|
3
|
+
* @description Специальный итерфейс Guard для object. В данном интерфейсе ctx required
|
4
|
+
* Переопределение необходимо для того, чтобы ts показывал, что ctx required в кастомных правилах
|
5
|
+
*/
|
6
|
+
interface ObjectPropGuard<TLastSchemaValues extends Record<string, unknown>> {
|
7
|
+
(value: Parameters<Guard<TLastSchemaValues>>[0], ctx: ValidationContext<TLastSchemaValues>): ReturnType<Guard<TLastSchemaValues>>;
|
8
|
+
define: Guard<TLastSchemaValues>['define'];
|
9
|
+
}
|
10
|
+
interface AsyncObjectPropGuard<TLastSchemaValues extends Record<string, unknown>> {
|
11
|
+
(value: Parameters<Guard<TLastSchemaValues>>[0], ctx: ValidationContext<TLastSchemaValues>): ReturnType<AsyncGuard<TLastSchemaValues>>;
|
12
|
+
define: AsyncGuard<TLastSchemaValues>['define'];
|
13
|
+
}
|
14
|
+
type AdditionalDefOptions = {
|
15
|
+
/**
|
16
|
+
* @description Делает все свойства объекта partial
|
17
|
+
*/
|
18
|
+
isPartial?: boolean;
|
19
|
+
};
|
20
|
+
/**
|
21
|
+
* @description Возможные значения, принимаемые схемой
|
22
|
+
*/
|
23
|
+
export type AsyncSchemaValue<TValue extends Record<string, unknown>> = ObjectPropGuard<TValue> | AsyncObjectPropGuard<TValue> | ValidationRule<unknown, TValue> | AsyncValidationRule<unknown, TValue>;
|
24
|
+
/**
|
25
|
+
* @description Схема правил валдиации для объекта
|
26
|
+
*/
|
27
|
+
export type AsyncSchema<TValue extends Record<string, unknown>> = Record<keyof TValue, AsyncSchemaValue<TValue>>;
|
28
|
+
/**
|
29
|
+
* @description Guard для объекта, который поддерживает асинхронную валидацию
|
30
|
+
* @example
|
31
|
+
* ```ts
|
32
|
+
* type Values = {
|
33
|
+
* name: string;
|
34
|
+
* age?: number;
|
35
|
+
* info: { surname: string };
|
36
|
+
* };
|
37
|
+
*
|
38
|
+
* const values: Values = { name: 'Vasya', info: { surname: 'Vasin' } };
|
39
|
+
*
|
40
|
+
* const validateObject = objectAsync<Values>({
|
41
|
+
* name: string(min(2), async (value, ctx) => {
|
42
|
+
* const result = await validateName(value);
|
43
|
+
*
|
44
|
+
* return result.isInvalid
|
45
|
+
* ? ctx.createError({
|
46
|
+
* message: 'Имя занято',
|
47
|
+
* code: 'name-is-not-available',
|
48
|
+
* })
|
49
|
+
* : undefined;
|
50
|
+
* }),
|
51
|
+
* age: optional(number()),
|
52
|
+
* info: object<Values['info']>({ surname: string(min(2)) }),
|
53
|
+
* customField: (value, ctx) => {
|
54
|
+
* return ctx.createError({ message: 'error', code: 'custom error' });
|
55
|
+
* },
|
56
|
+
* });
|
57
|
+
* ```
|
58
|
+
*/
|
59
|
+
export declare const objectAsync: <TValue extends Record<string, unknown>, TLastSchemaValues extends Record<string, unknown> = {}>(schema: AsyncSchema<TValue>) => AsyncGuard<TLastSchemaValues, AdditionalDefOptions>;
|
60
|
+
export type ObjectAsyncGuard<TValue extends Record<string, unknown>> = ReturnType<typeof objectAsync<TValue>>;
|
61
|
+
export {};
|
@@ -0,0 +1,71 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import isPlainObject from 'is-plain-obj';
|
11
|
+
import { callAsyncRule as callAsyncRecursiveRule, createContext, createErrorMap, createGuard, } from '../../core';
|
12
|
+
import { optional } from '../../optional';
|
13
|
+
import { isEmptyErrors } from '../isEmptyErrors';
|
14
|
+
import { OBJECT_TYPE_ERROR_INFO } from '../constants';
|
15
|
+
// TODO: необходимо реализовать переиспользование логики между object и objectAsync
|
16
|
+
/**
|
17
|
+
* @description Guard для объекта, который поддерживает асинхронную валидацию
|
18
|
+
* @example
|
19
|
+
* ```ts
|
20
|
+
* type Values = {
|
21
|
+
* name: string;
|
22
|
+
* age?: number;
|
23
|
+
* info: { surname: string };
|
24
|
+
* };
|
25
|
+
*
|
26
|
+
* const values: Values = { name: 'Vasya', info: { surname: 'Vasin' } };
|
27
|
+
*
|
28
|
+
* const validateObject = objectAsync<Values>({
|
29
|
+
* name: string(min(2), async (value, ctx) => {
|
30
|
+
* const result = await validateName(value);
|
31
|
+
*
|
32
|
+
* return result.isInvalid
|
33
|
+
* ? ctx.createError({
|
34
|
+
* message: 'Имя занято',
|
35
|
+
* code: 'name-is-not-available',
|
36
|
+
* })
|
37
|
+
* : undefined;
|
38
|
+
* }),
|
39
|
+
* age: optional(number()),
|
40
|
+
* info: object<Values['info']>({ surname: string(min(2)) }),
|
41
|
+
* customField: (value, ctx) => {
|
42
|
+
* return ctx.createError({ message: 'error', code: 'custom error' });
|
43
|
+
* },
|
44
|
+
* });
|
45
|
+
* ```
|
46
|
+
*/
|
47
|
+
export const objectAsync = (schema) => createGuard((value, ctx, { typeErrorMessage, isPartial }) => __awaiter(void 0, void 0, void 0, function* () {
|
48
|
+
const context = createContext(ctx, value, value);
|
49
|
+
if (!isPlainObject(value)) {
|
50
|
+
return context.createError(Object.assign(Object.assign({}, OBJECT_TYPE_ERROR_INFO), { message: typeErrorMessage || OBJECT_TYPE_ERROR_INFO.message }));
|
51
|
+
}
|
52
|
+
const generateErrorMap = () => __awaiter(void 0, void 0, void 0, function* () {
|
53
|
+
const schemaEntries = Object.entries(schema);
|
54
|
+
const isOptional = context.global.overrides.objectIsPartial || isPartial;
|
55
|
+
const results = yield Promise.all(schemaEntries.map(([key, rule]) => {
|
56
|
+
const isGuard = 'define' in rule;
|
57
|
+
const callRule = isGuard && isOptional ? optional(rule) : rule;
|
58
|
+
return callAsyncRecursiveRule(callRule, value[key], context);
|
59
|
+
}));
|
60
|
+
return results.reduce((errorMap, validationResult, index) => {
|
61
|
+
const [key] = schemaEntries[index];
|
62
|
+
errorMap[key] = validationResult;
|
63
|
+
return errorMap;
|
64
|
+
}, {});
|
65
|
+
});
|
66
|
+
const errorMap = yield generateErrorMap();
|
67
|
+
if (!isEmptyErrors(errorMap)) {
|
68
|
+
return createErrorMap(errorMap);
|
69
|
+
}
|
70
|
+
return undefined;
|
71
|
+
}));
|
package/package.json
CHANGED
package/partial/partial.d.ts
CHANGED
@@ -4,13 +4,6 @@ import { object } from '../object';
|
|
4
4
|
* @param objectGuard
|
5
5
|
* @example partial(object({ name: string() }))
|
6
6
|
*/
|
7
|
-
export declare const partial: (objectGuard: ReturnType<typeof object>) => {
|
8
|
-
|
9
|
-
|
10
|
-
isPartial?: boolean | undefined;
|
11
|
-
}> & {
|
12
|
-
requiredErrorMessage?: string | undefined;
|
13
|
-
typeErrorMessage?: string | undefined;
|
14
|
-
isOptional?: boolean | undefined;
|
15
|
-
}): any;
|
16
|
-
};
|
7
|
+
export declare const partial: (objectGuard: ReturnType<typeof object>) => import("../core").Guard<Record<string, unknown>, {
|
8
|
+
isPartial?: boolean | undefined;
|
9
|
+
}>;
|
package/string/index.d.ts
CHANGED
package/string/index.js
CHANGED
package/string/string.d.ts
CHANGED
@@ -1,9 +1,2 @@
|
|
1
1
|
import { ValidationRule } from '../core';
|
2
|
-
export declare const string: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<string, TLastSchemaValues>[]) => {
|
3
|
-
(value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined): import("../core").ValidationResult;
|
4
|
-
define(overridesDefOptions: Partial<{}> & {
|
5
|
-
requiredErrorMessage?: string | undefined;
|
6
|
-
typeErrorMessage?: string | undefined;
|
7
|
-
isOptional?: boolean | undefined;
|
8
|
-
}): any;
|
9
|
-
};
|
2
|
+
export declare const string: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<string, TLastSchemaValues>[]) => import("../core").Guard<TLastSchemaValues, {}>;
|
package/string/string.js
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
import { compose, createGuard } from '../core';
|
2
2
|
import { STRING_TYPE_ERROR_INFO } from './constants';
|
3
|
+
import { isString } from './utils';
|
3
4
|
export const string = (...rules) => createGuard((value, ctx, { typeErrorMessage }) => {
|
4
|
-
if (
|
5
|
+
if (!isString(value)) {
|
5
6
|
return ctx.createError(Object.assign(Object.assign({}, STRING_TYPE_ERROR_INFO), { message: typeErrorMessage || STRING_TYPE_ERROR_INFO.message }));
|
6
7
|
}
|
7
8
|
return compose(...rules)(value, ctx);
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './stringAsync';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './stringAsync';
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { AsyncValidationRule, ValidationRule } from '../../core';
|
2
|
+
/**
|
3
|
+
* Позволяет использовать для валидации асинхронные правила
|
4
|
+
* @example stringAsync(async () => undefined)
|
5
|
+
*/
|
6
|
+
export declare const stringAsync: <TLastSchemaValues extends Record<string, unknown>>(...rules: (ValidationRule<string, TLastSchemaValues> | AsyncValidationRule<string, TLastSchemaValues>)[]) => import("../../core").AsyncGuard<TLastSchemaValues, {}>;
|
@@ -0,0 +1,23 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import { composeAsync, createGuard, } from '../../core';
|
11
|
+
import { isString } from '../utils';
|
12
|
+
import { STRING_TYPE_ERROR_INFO } from '../constants';
|
13
|
+
// TODO: необходимо реализовать переиспользование логики между string и stringAsync
|
14
|
+
/**
|
15
|
+
* Позволяет использовать для валидации асинхронные правила
|
16
|
+
* @example stringAsync(async () => undefined)
|
17
|
+
*/
|
18
|
+
export const stringAsync = (...rules) => createGuard((value, ctx, { typeErrorMessage }) => __awaiter(void 0, void 0, void 0, function* () {
|
19
|
+
if (!isString(value)) {
|
20
|
+
return ctx.createError(Object.assign(Object.assign({}, STRING_TYPE_ERROR_INFO), { message: typeErrorMessage || STRING_TYPE_ERROR_INFO.message }));
|
21
|
+
}
|
22
|
+
return composeAsync(...rules)(value, ctx);
|
23
|
+
}));
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isString';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isString';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isString';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './isString';
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const isString: (value: unknown) => value is string;
|
@@ -0,0 +1 @@
|
|
1
|
+
export const isString = (value) => typeof value === 'string';
|