@astral/validations 4.7.0 → 4.8.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 +20 -0
- package/core/context/createContext/createContext.d.ts +13 -2
- package/core/context/createContext/createContext.js +8 -7
- package/core/context/types.d.ts +6 -2
- package/core/guard/createGuard/createGuard.d.ts +22 -5
- package/core/guard/createGuard/createGuard.js +8 -4
- package/object/object.js +3 -1
- package/object/objectAsync/objectAsync.js +3 -1
- package/optional/optional.d.ts +2 -3
- package/optional/optional.js +2 -2
- package/package.json +1 -1
- package/core/guard/types.d.ts +0 -18
- package/core/guard/types.js +0 -1
package/README.md
CHANGED
@@ -1364,6 +1364,26 @@ validate({
|
|
1364
1364
|
});
|
1365
1365
|
```
|
1366
1366
|
|
1367
|
+
Позволяет делать optional вложенные правила:
|
1368
|
+
|
1369
|
+
```ts
|
1370
|
+
type Values = { name: string | number; isAgree: boolean };
|
1371
|
+
|
1372
|
+
const validate = object<Values>({
|
1373
|
+
name: optional(
|
1374
|
+
when({
|
1375
|
+
is: (_, ctx) => Boolean(ctx.values?.isAgree),
|
1376
|
+
then: string(),
|
1377
|
+
otherwise: number(),
|
1378
|
+
})
|
1379
|
+
),
|
1380
|
+
isAgree: optional(boolean()),
|
1381
|
+
});
|
1382
|
+
|
1383
|
+
// undefined
|
1384
|
+
validate({ isAgree: false, name: undefined });
|
1385
|
+
```
|
1386
|
+
|
1367
1387
|
---
|
1368
1388
|
|
1369
1389
|
## when. Условная валидация
|
@@ -1,8 +1,19 @@
|
|
1
|
+
import { DeepPartial } from 'utility-types';
|
1
2
|
import { ValidationContext } from '../types';
|
2
3
|
import { ValidationTypes } from '../../types';
|
4
|
+
type Params<TLastSchemaValues extends Record<string, unknown>> = {
|
5
|
+
/**
|
6
|
+
* Value последнего валидируемого объекта
|
7
|
+
*/
|
8
|
+
lastSchemaValue?: DeepPartial<TLastSchemaValues>;
|
9
|
+
/**
|
10
|
+
* Позволяет создать ctx, в котором будет соответсвующий isOptional
|
11
|
+
*/
|
12
|
+
isOptional?: boolean;
|
13
|
+
};
|
3
14
|
/**
|
4
15
|
* @description Создает context валидации. Используется внутри фабрик guard и rule
|
5
16
|
* @default по-дефолту сбрасывает все флаги в false
|
6
17
|
*/
|
7
|
-
export declare function createContext<TValue extends ValidationTypes>(prevCtx: ValidationContext<
|
8
|
-
export
|
18
|
+
export declare function createContext<TValue extends ValidationTypes, TLastSchemaValues extends Record<string, unknown> = {}>(prevCtx: ValidationContext<Record<string, unknown>> | undefined, value: TValue, { lastSchemaValue, isOptional }?: Params<TLastSchemaValues>): ValidationContext<TLastSchemaValues>;
|
19
|
+
export {};
|
@@ -1,20 +1,21 @@
|
|
1
1
|
import { createSimpleError } from '../../errors';
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
/**
|
3
|
+
* @description Создает context валидации. Используется внутри фабрик guard и rule
|
4
|
+
* @default по-дефолту сбрасывает все флаги в false
|
5
|
+
*/
|
6
|
+
export function createContext(prevCtx, value, { lastSchemaValue, isOptional } = {}) {
|
7
7
|
if (prevCtx) {
|
8
|
-
return Object.assign(Object.assign({}, prevCtx), { values:
|
8
|
+
return Object.assign(Object.assign({}, prevCtx), { isOptional: isOptional !== null && isOptional !== void 0 ? isOptional : prevCtx.isOptional, values: lastSchemaValue || prevCtx.values });
|
9
9
|
}
|
10
10
|
return {
|
11
|
-
values:
|
11
|
+
values: lastSchemaValue,
|
12
12
|
global: {
|
13
13
|
values: value,
|
14
14
|
overrides: {
|
15
15
|
objectIsPartial: false,
|
16
16
|
},
|
17
17
|
},
|
18
|
+
isOptional: isOptional !== null && isOptional !== void 0 ? isOptional : false,
|
18
19
|
createError: createSimpleError,
|
19
20
|
};
|
20
21
|
}
|
package/core/context/types.d.ts
CHANGED
@@ -11,7 +11,7 @@ export type ValidationContext<TLastSchemaValues extends Record<string, unknown>
|
|
11
11
|
/**
|
12
12
|
* @description Глобальные значения, идущие от самого верхнего правила к самому нижнему
|
13
13
|
*/
|
14
|
-
global: {
|
14
|
+
global: DeepReadonly<{
|
15
15
|
/**
|
16
16
|
* @description Значения, которые валидируется guard самого высоко порядка
|
17
17
|
*/
|
@@ -25,9 +25,13 @@ export type ValidationContext<TLastSchemaValues extends Record<string, unknown>
|
|
25
25
|
*/
|
26
26
|
objectIsPartial: boolean;
|
27
27
|
};
|
28
|
-
}
|
28
|
+
}>;
|
29
29
|
/**
|
30
30
|
* @description Фабрика ошибок. Возвращает новую ошибку валидации
|
31
31
|
*/
|
32
32
|
createError: typeof createSimpleError;
|
33
|
+
/**
|
34
|
+
* @description Флаг, позволяющий отключать в guard'ах required правило. Первый guard, который примет isOptional===true сбросит его
|
35
|
+
*/
|
36
|
+
isOptional: boolean;
|
33
37
|
}>;
|
@@ -1,6 +1,23 @@
|
|
1
1
|
import { ValidationResult } from '../../types';
|
2
2
|
import { ValidationContext } from '../../context';
|
3
|
-
|
3
|
+
export type GuardDefOptions<AddDefOptions extends Record<string, unknown>> = Partial<AddDefOptions> & {
|
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
|
+
export type GuardValue = unknown;
|
4
21
|
/**
|
5
22
|
* @description Интерфейс функции guard, которая в прототипе содержит метод define
|
6
23
|
*/
|
@@ -28,11 +45,11 @@ export interface AsyncGuard<TLastSchemaValues extends Record<string, unknown> =
|
|
28
45
|
/**
|
29
46
|
* @description Функция, которая позволяет определять частную логику для guard
|
30
47
|
*/
|
31
|
-
type GuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<
|
48
|
+
type GuardExecutor<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<TLastSchemaValues>, defOptions: GuardDefOptions<AddDefOptions>) => ValidationResult;
|
32
49
|
/**
|
33
50
|
* @description Функция, которая позволяет определять частную логику для guard
|
34
51
|
*/
|
35
|
-
type AsyncGuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<
|
52
|
+
type AsyncGuardExecutor<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<TLastSchemaValues>, defOptions: GuardDefOptions<AddDefOptions>) => Promise<ValidationResult>;
|
36
53
|
/**
|
37
54
|
* @description Создает guard. Guard - функция, проверяющая тип значения
|
38
55
|
* По-дефолту проверяет value на required. Для выключения required необходимо использовать optional().
|
@@ -49,6 +66,6 @@ type AsyncGuardExecutor<AddDefOptions extends Record<string, unknown>> = (value:
|
|
49
66
|
* });
|
50
67
|
* ```
|
51
68
|
*/
|
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>;
|
69
|
+
export declare function createGuard<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown> = {}>(executor: GuardExecutor<TLastSchemaValues, AddDefOptions>): Guard<TLastSchemaValues, AddDefOptions>;
|
70
|
+
export declare function createGuard<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown> = {}>(executor: AsyncGuardExecutor<TLastSchemaValues, AddDefOptions>): AsyncGuard<TLastSchemaValues, AddDefOptions>;
|
54
71
|
export {};
|
@@ -4,16 +4,20 @@ export function createGuard(executor) {
|
|
4
4
|
// выделено в отдельную именованную функцию для того, чтобы ее можно было рекурсивно вызывать в define
|
5
5
|
const createInnerGuard = (defOptions = {}) => {
|
6
6
|
const guard = (value, prevCtx) => {
|
7
|
+
const actualDefOptions = Object.assign(Object.assign({}, defOptions), { isOptional: (prevCtx === null || prevCtx === void 0 ? void 0 : prevCtx.isOptional) || defOptions.isOptional });
|
7
8
|
const ctx = createContext(prevCtx,
|
8
9
|
// при создании контекста сейчас не имеет значение какого типа будет ctx.values
|
9
|
-
value
|
10
|
+
value, {
|
11
|
+
lastSchemaValue: value,
|
12
|
+
isOptional: false,
|
13
|
+
});
|
10
14
|
const requiredResult = required({
|
11
|
-
message:
|
15
|
+
message: actualDefOptions === null || actualDefOptions === void 0 ? void 0 : actualDefOptions.requiredErrorMessage,
|
12
16
|
})(value, ctx);
|
13
|
-
if ((
|
17
|
+
if ((actualDefOptions === null || actualDefOptions === void 0 ? void 0 : actualDefOptions.isOptional) && requiredResult) {
|
14
18
|
return undefined;
|
15
19
|
}
|
16
|
-
return requiredResult || executor(value, ctx,
|
20
|
+
return requiredResult || executor(value, ctx, actualDefOptions);
|
17
21
|
};
|
18
22
|
guard.define = (overridesDefOptions) => createInnerGuard(overridesDefOptions);
|
19
23
|
return guard;
|
package/object/object.js
CHANGED
@@ -27,7 +27,9 @@ import { OBJECT_TYPE_ERROR_INFO } from './constants';
|
|
27
27
|
* ```
|
28
28
|
*/
|
29
29
|
export const object = (schema) => createGuard((value, ctx, { typeErrorMessage, isPartial }) => {
|
30
|
-
const context = createContext(ctx, value,
|
30
|
+
const context = createContext(ctx, value, {
|
31
|
+
lastSchemaValue: value,
|
32
|
+
});
|
31
33
|
if (!isPlainObject(value)) {
|
32
34
|
return context.createError(Object.assign(Object.assign({}, OBJECT_TYPE_ERROR_INFO), { message: typeErrorMessage || OBJECT_TYPE_ERROR_INFO.message }));
|
33
35
|
}
|
@@ -45,7 +45,9 @@ import { OBJECT_TYPE_ERROR_INFO } from '../constants';
|
|
45
45
|
* ```
|
46
46
|
*/
|
47
47
|
export const objectAsync = (schema) => createGuard((value, ctx, { typeErrorMessage, isPartial }) => __awaiter(void 0, void 0, void 0, function* () {
|
48
|
-
const context = createContext(ctx, value,
|
48
|
+
const context = createContext(ctx, value, {
|
49
|
+
lastSchemaValue: value,
|
50
|
+
});
|
49
51
|
if (!isPlainObject(value)) {
|
50
52
|
return context.createError(Object.assign(Object.assign({}, OBJECT_TYPE_ERROR_INFO), { message: typeErrorMessage || OBJECT_TYPE_ERROR_INFO.message }));
|
51
53
|
}
|
package/optional/optional.d.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
import {
|
1
|
+
import { IndependentValidationRule, ValidationRule } from '../core';
|
2
2
|
/**
|
3
3
|
* @description Выключает проверку на required в guard
|
4
|
-
* @param guard - правило, проверяющее тип значения
|
5
4
|
* @example object({ name: optional(string(min(22))) })
|
6
5
|
*/
|
7
|
-
export declare const optional: <TLastSchemaValues extends Record<string, unknown>>(
|
6
|
+
export declare const optional: <TLastSchemaValues extends Record<string, unknown>>(rule: ValidationRule<unknown, TLastSchemaValues>) => IndependentValidationRule<unknown, TLastSchemaValues>;
|
package/optional/optional.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
import { callRule, createContext, } from '../core';
|
1
2
|
/**
|
2
3
|
* @description Выключает проверку на required в guard
|
3
|
-
* @param guard - правило, проверяющее тип значения
|
4
4
|
* @example object({ name: optional(string(min(22))) })
|
5
5
|
*/
|
6
|
-
export const optional = (
|
6
|
+
export const optional = (rule) => (value, ctx) => callRule(rule, value, createContext(ctx, value, { isOptional: true }));
|
package/package.json
CHANGED
package/core/guard/types.d.ts
DELETED
@@ -1,18 +0,0 @@
|
|
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;
|
package/core/guard/types.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {};
|