@astral/validations 4.6.1 → 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 +60 -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/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/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 +22 -8
- package/core/guard/createGuard/createGuard.js +13 -28
- 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/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/object.js +3 -1
- 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 +73 -0
- package/optional/optional.d.ts +2 -3
- package/optional/optional.js +2 -2
- 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)
|
@@ -1363,6 +1364,26 @@ validate({
|
|
1363
1364
|
});
|
1364
1365
|
```
|
1365
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
|
+
|
1366
1387
|
---
|
1367
1388
|
|
1368
1389
|
## when. Условная валидация
|
@@ -1464,6 +1485,45 @@ validate(new Date())
|
|
1464
1485
|
|
1465
1486
|
---
|
1466
1487
|
|
1488
|
+
# Async
|
1489
|
+
Пакет поддерживает асинхронную валидацию.
|
1490
|
+
|
1491
|
+
Guard, поддерживающие асинхронную валидацию имеют постфиксы ```async```:
|
1492
|
+
- ```objectAsync```
|
1493
|
+
- ```stringAsync```
|
1494
|
+
|
1495
|
+
Пример:
|
1496
|
+
|
1497
|
+
```ts
|
1498
|
+
type Values = {
|
1499
|
+
nickname: string;
|
1500
|
+
phone: string;
|
1501
|
+
};
|
1502
|
+
|
1503
|
+
const validate = objectAsync<Values>({
|
1504
|
+
phone: string(),
|
1505
|
+
nickname: stringAsync(min(3), async (value, ctx) => {
|
1506
|
+
const nicknameIsAvailable = await checkNickname(value);
|
1507
|
+
|
1508
|
+
if (nicknameIsAvailable) {
|
1509
|
+
return undefined;
|
1510
|
+
}
|
1511
|
+
|
1512
|
+
return ctx.createError({
|
1513
|
+
code: 'nickname-available',
|
1514
|
+
message: 'Nickname занят',
|
1515
|
+
});
|
1516
|
+
}),
|
1517
|
+
});
|
1518
|
+
|
1519
|
+
const result = await validate({ phone: '79308999999', nickname: 'Vasya' });
|
1520
|
+
|
1521
|
+
// { nickname: 'Nickname занят' }
|
1522
|
+
toPrettyError(result);
|
1523
|
+
```
|
1524
|
+
|
1525
|
+
---
|
1526
|
+
|
1467
1527
|
# Integrations
|
1468
1528
|
|
1469
1529
|
## 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';
|
@@ -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
|
}>;
|
package/core/errors/index.d.ts
CHANGED
package/core/errors/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ValidationResult } from '../../types';
|
2
2
|
import { ValidationContext } from '../../context';
|
3
|
-
type
|
3
|
+
export type GuardDefOptions<AddDefOptions extends Record<string, unknown>> = Partial<AddDefOptions> & {
|
4
4
|
/**
|
5
5
|
* @description Переопределяет дефолтное сообщения ошибки для required
|
6
6
|
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
@@ -17,7 +17,7 @@ type DefOptions<AddDefOptions extends Record<string, unknown>> = Partial<AddDefO
|
|
17
17
|
*/
|
18
18
|
isOptional?: boolean;
|
19
19
|
};
|
20
|
-
type GuardValue = unknown;
|
20
|
+
export type GuardValue = unknown;
|
21
21
|
/**
|
22
22
|
* @description Интерфейс функции guard, которая в прототипе содержит метод define
|
23
23
|
*/
|
@@ -28,12 +28,28 @@ export interface Guard<TLastSchemaValues extends Record<string, unknown> = {}, A
|
|
28
28
|
* @param options - параметры, позволяющие переопределить дефолтные настройки guard
|
29
29
|
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
30
30
|
*/
|
31
|
-
define(options:
|
31
|
+
define(options: GuardDefOptions<AddDefOptions>): Guard<TLastSchemaValues, AddDefOptions>;
|
32
32
|
}
|
33
|
+
/**
|
34
|
+
* @description Интерфейс асинхронной функции guard, которая в прототипе содержит метод define
|
35
|
+
*/
|
36
|
+
export interface AsyncGuard<TLastSchemaValues extends Record<string, unknown> = {}, AddDefOptions extends Record<string, unknown> = {}> {
|
37
|
+
(value: GuardValue, ctx?: ValidationContext<TLastSchemaValues>): Promise<ValidationResult>;
|
38
|
+
/**
|
39
|
+
* @description Функция для создания нового guard с переопределенными дефолтными параметрами. Возвращает новый guard
|
40
|
+
* @param options - параметры, позволяющие переопределить дефолтные настройки guard
|
41
|
+
* @example string.define({ requiredMessage: 'ИНН не может быть пустым' })(inn())
|
42
|
+
*/
|
43
|
+
define(options: GuardDefOptions<AddDefOptions>): AsyncGuard<TLastSchemaValues, AddDefOptions>;
|
44
|
+
}
|
45
|
+
/**
|
46
|
+
* @description Функция, которая позволяет определять частную логику для guard
|
47
|
+
*/
|
48
|
+
type GuardExecutor<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<TLastSchemaValues>, defOptions: GuardDefOptions<AddDefOptions>) => ValidationResult;
|
33
49
|
/**
|
34
50
|
* @description Функция, которая позволяет определять частную логику для guard
|
35
51
|
*/
|
36
|
-
type
|
52
|
+
type AsyncGuardExecutor<TLastSchemaValues extends Record<string, unknown>, AddDefOptions extends Record<string, unknown>> = (value: unknown, ctx: ValidationContext<TLastSchemaValues>, defOptions: GuardDefOptions<AddDefOptions>) => Promise<ValidationResult>;
|
37
53
|
/**
|
38
54
|
* @description Создает guard. Guard - функция, проверяющая тип значения
|
39
55
|
* По-дефолту проверяет value на required. Для выключения required необходимо использовать optional().
|
@@ -50,8 +66,6 @@ type GuardExecutor<AddDefOptions extends Record<string, unknown>> = (value: unkn
|
|
50
66
|
* });
|
51
67
|
* ```
|
52
68
|
*/
|
53
|
-
export declare
|
54
|
-
|
55
|
-
define(overridesDefOptions: DefOptions<AddDefOptions>): any;
|
56
|
-
};
|
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>;
|
57
71
|
export {};
|
@@ -1,41 +1,26 @@
|
|
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) => {
|
7
|
+
const actualDefOptions = Object.assign(Object.assign({}, defOptions), { isOptional: (prevCtx === null || prevCtx === void 0 ? void 0 : prevCtx.isOptional) || defOptions.isOptional });
|
24
8
|
const ctx = createContext(prevCtx,
|
25
9
|
// при создании контекста сейчас не имеет значение какого типа будет ctx.values
|
26
|
-
value
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
10
|
+
value, {
|
11
|
+
lastSchemaValue: value,
|
12
|
+
isOptional: false,
|
13
|
+
});
|
14
|
+
const requiredResult = required({
|
15
|
+
message: actualDefOptions === null || actualDefOptions === void 0 ? void 0 : actualDefOptions.requiredErrorMessage,
|
16
|
+
})(value, ctx);
|
17
|
+
if ((actualDefOptions === null || actualDefOptions === void 0 ? void 0 : actualDefOptions.isOptional) && requiredResult) {
|
33
18
|
return undefined;
|
34
19
|
}
|
35
|
-
return
|
20
|
+
return requiredResult || executor(value, ctx, actualDefOptions);
|
36
21
|
};
|
37
22
|
guard.define = (overridesDefOptions) => createInnerGuard(overridesDefOptions);
|
38
23
|
return guard;
|
39
24
|
};
|
40
25
|
return createInnerGuard();
|
41
|
-
}
|
26
|
+
}
|
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/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 {};
|
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
|
}
|
@@ -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,73 @@
|
|
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, {
|
49
|
+
lastSchemaValue: value,
|
50
|
+
});
|
51
|
+
if (!isPlainObject(value)) {
|
52
|
+
return context.createError(Object.assign(Object.assign({}, OBJECT_TYPE_ERROR_INFO), { message: typeErrorMessage || OBJECT_TYPE_ERROR_INFO.message }));
|
53
|
+
}
|
54
|
+
const generateErrorMap = () => __awaiter(void 0, void 0, void 0, function* () {
|
55
|
+
const schemaEntries = Object.entries(schema);
|
56
|
+
const isOptional = context.global.overrides.objectIsPartial || isPartial;
|
57
|
+
const results = yield Promise.all(schemaEntries.map(([key, rule]) => {
|
58
|
+
const isGuard = 'define' in rule;
|
59
|
+
const callRule = isGuard && isOptional ? optional(rule) : rule;
|
60
|
+
return callAsyncRecursiveRule(callRule, value[key], context);
|
61
|
+
}));
|
62
|
+
return results.reduce((errorMap, validationResult, index) => {
|
63
|
+
const [key] = schemaEntries[index];
|
64
|
+
errorMap[key] = validationResult;
|
65
|
+
return errorMap;
|
66
|
+
}, {});
|
67
|
+
});
|
68
|
+
const errorMap = yield generateErrorMap();
|
69
|
+
if (!isEmptyErrors(errorMap)) {
|
70
|
+
return createErrorMap(errorMap);
|
71
|
+
}
|
72
|
+
return undefined;
|
73
|
+
}));
|
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/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';
|