@astral/validations 4.4.0 → 4.6.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 CHANGED
@@ -59,6 +59,7 @@
59
59
  - [Связанные поля](#связанные-поля)
60
60
  - [Доступ к ctx.global.values](#доступ-к-высокоуровневым-values-ctxglobalvalues)
61
61
  - [Переиспользуемое правило](#переиспользуемое-правило)
62
+ - [Кастомная условная валидация](#кастомная-условная-валидация)
62
63
  - [Common](#common)
63
64
  - [optional](#optional)
64
65
  - [when. Условная валидация](#when-условная-валидация)
@@ -1119,7 +1120,7 @@ validate([1, 2]);
1119
1120
 
1120
1121
  ## any
1121
1122
 
1122
- Позволяет выключить любые проверки.
1123
+ Позволяет выключить любые проверки и делать композицию для правил, валидирующих любые значения.
1123
1124
 
1124
1125
  ```ts
1125
1126
  type Values = { name: string; isAgree: boolean };
@@ -1141,8 +1142,15 @@ toPrettyError(
1141
1142
  validate({ isAgree: true, name: '' })
1142
1143
  );
1143
1144
  ```
1145
+ ```ts
1146
+ const validate = any(transform((value) => new Date(value), date()));
1144
1147
 
1145
- ---
1148
+ // undefined
1149
+ validate('12.22.2022');
1150
+
1151
+ // invalid date error
1152
+ validate('13.22.2022');
1153
+ ```
1146
1154
 
1147
1155
  ## Define. Переопределение дефолтных параметров guard
1148
1156
 
@@ -1294,6 +1302,34 @@ validate('Hello');
1294
1302
  includesWorld()('Hello')
1295
1303
  ```
1296
1304
 
1305
+ ## Кастомная условная валидация
1306
+
1307
+ Для условной валидации рекомендуется использовать [when](#when-условная-валидация), но также доступна возможность реализации кастомной условной валидации.
1308
+
1309
+ ```ts
1310
+ import { object, string, boolean, optional } from '@astral/validations';
1311
+
1312
+ type Values = {
1313
+ isAgree: boolean;
1314
+ info: {
1315
+ name: string
1316
+ }
1317
+ };
1318
+
1319
+ const validate = object<Values>({
1320
+ isAgree: optional(boolean()),
1321
+ info: object<Values['info']>({
1322
+ name: (value, ctx) => {
1323
+ if(ctx.global.values?.isAgree) {
1324
+ return string();
1325
+ }
1326
+
1327
+ return any();
1328
+ }
1329
+ })
1330
+ });
1331
+ ```
1332
+
1297
1333
  ---
1298
1334
 
1299
1335
  # Common
package/any/any.d.ts CHANGED
@@ -1,5 +1,7 @@
1
+ import { ValidationRule } from '../core';
1
2
  /**
2
- * @description Выключает любые проверки
3
+ * @description Выключает любые проверки и валидирует value
4
+ * @param rules - правила, валидирующие любые значения
3
5
  * @example
4
6
  * ```ts
5
7
  * type Values = { name: string; surname?: string };
@@ -9,5 +11,13 @@
9
11
  * // undefined
10
12
  * validate({});
11
13
  * ```
14
+ * const validate = any(transform((value) => new Date(value), date()));
15
+ *
16
+ * // undefined
17
+ * validate('12.22.2022');
18
+ *
19
+ * // invalid date error
20
+ * validate('13.22.2022');
21
+ * ```
12
22
  */
13
- export declare const any: <TLastSchemaValues extends Record<string, unknown>>() => (value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
23
+ export declare const any: <TLastSchemaValues extends Record<string, unknown>>(...rules: ValidationRule<unknown, TLastSchemaValues>[]) => (value: unknown, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
package/any/any.js CHANGED
@@ -1,6 +1,7 @@
1
- import { createRule } from '../core';
1
+ import { compose, createRule } from '../core';
2
2
  /**
3
- * @description Выключает любые проверки
3
+ * @description Выключает любые проверки и валидирует value
4
+ * @param rules - правила, валидирующие любые значения
4
5
  * @example
5
6
  * ```ts
6
7
  * type Values = { name: string; surname?: string };
@@ -10,5 +11,15 @@ import { createRule } from '../core';
10
11
  * // undefined
11
12
  * validate({});
12
13
  * ```
14
+ * const validate = any(transform((value) => new Date(value), date()));
15
+ *
16
+ * // undefined
17
+ * validate('12.22.2022');
18
+ *
19
+ * // invalid date error
20
+ * validate('13.22.2022');
21
+ * ```
13
22
  */
14
- export const any = () => createRule(() => undefined);
23
+ export const any = (...rules) => createRule((value, ctx) => {
24
+ return compose(...rules)(value, ctx);
25
+ });
@@ -1,5 +1,7 @@
1
+ import { callRule } from '../rule';
1
2
  /**
2
3
  * @description Объединяет переданные правила в цепочку правил, останавливает выполнение цепочки, если появилась ошибка. Выполняет правила слева направо
3
4
  * @example compose(min(), max());
4
5
  */
5
- export const compose = (...rules) => (value, ctx) => rules.reduce((result, rule) => result || rule(value, ctx), undefined);
6
+ export const compose = (...rules) => (value, ctx) => rules.reduce((result, rule) => result ||
7
+ callRule(rule, value, ctx), undefined);
@@ -0,0 +1,7 @@
1
+ import { ValidationRule } from '../types';
2
+ import { ValidationResult } from '../../types';
3
+ import { ValidationContext } from '../../context';
4
+ /**
5
+ * Позволяет рекурсивно вызывать правила. Rule может возвращать другой rule
6
+ */
7
+ export declare const callRule: <TValue, TLastSchemaValues extends Record<string, unknown>>(rule: ValidationRule<TValue, TLastSchemaValues>, value: TValue, ctx: ValidationContext<TLastSchemaValues>) => ValidationResult;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Позволяет рекурсивно вызывать правила. Rule может возвращать другой rule
3
+ */
4
+ export const callRule = (rule, value, ctx) => {
5
+ const ruleResult = rule(value, ctx);
6
+ return typeof ruleResult === 'function'
7
+ ? callRule(ruleResult, value, ctx)
8
+ : ruleResult;
9
+ };
@@ -0,0 +1 @@
1
+ export * from './callRule';
@@ -0,0 +1 @@
1
+ export * from './callRule';
@@ -1,3 +1,4 @@
1
1
  export * from './createRule';
2
2
  export * from './types';
3
3
  export * from './required';
4
+ export * from './callRule';
@@ -1,3 +1,4 @@
1
1
  export * from './createRule';
2
2
  export * from './types';
3
3
  export * from './required';
4
+ export * from './callRule';
@@ -7,7 +7,7 @@ export type IndependentValidationRule<TValue, TLastSchemaValues extends Record<s
7
7
  /**
8
8
  * @description Правило для валидации, работающее исключительно с guard'ами
9
9
  */
10
- export type ValidationRule<TValue, TLastSchemaValues extends Record<string, unknown> = {}> = (value: TValue, ctx: ValidationContext<TLastSchemaValues>) => ValidationResult;
10
+ export type ValidationRule<TValue, TLastSchemaValues extends Record<string, unknown> = {}> = (value: TValue, ctx: ValidationContext<TLastSchemaValues>) => ValidationResult | ValidationRule<TValue, TLastSchemaValues>;
11
11
  /**
12
12
  * @description Композиционное правило валидации, умеющее работать с любыми значениями.
13
13
  * В основном используется для композиционных правил, которые принимают rule, умеющие валидировать разные значения (optional, transform...)
package/object/object.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import isPlainObject from 'is-plain-obj';
2
- import { createContext, createErrorMap, createGuard, } from '../core';
2
+ import { callRule as callRecursiveRule, createContext, createErrorMap, createGuard, } from '../core';
3
3
  import { optional } from '../optional';
4
4
  import { isEmptyErrors } from './isEmptyErrors';
5
5
  import { OBJECT_TYPE_ERROR_INFO } from './constants';
@@ -37,7 +37,7 @@ export const object = (schema) => createGuard((value, ctx, { typeErrorMessage, i
37
37
  return schemaEntries.reduce((errorMap, [key, rule]) => {
38
38
  const isGuard = 'define' in rule;
39
39
  const callRule = isGuard && isOptional ? optional(rule) : rule;
40
- errorMap[key] = callRule(value[key], context);
40
+ errorMap[key] = callRecursiveRule(callRule, value[key], context);
41
41
  return errorMap;
42
42
  }, {});
43
43
  };
package/or/or.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createRule } from '../core';
1
+ import { callRule, createRule, } from '../core';
2
2
  /**
3
3
  * @description Выполняет переданные правила аналогично оператору ||. Если одно из правил не завершилось ошибкой, то or вернет undefined
4
4
  * Если все переданные правила завершились с ошибкой, то вернется ошибка из последнего правила
@@ -14,7 +14,7 @@ import { createRule } from '../core';
14
14
  export const or = (...rules) => createRule((value, ctx) => {
15
15
  let result;
16
16
  rules.some((rule) => {
17
- result = rule(value, ctx);
17
+ result = callRule(rule, value, ctx);
18
18
  return result ? false : true;
19
19
  });
20
20
  return result;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astral/validations",
3
- "version": "4.4.0",
3
+ "version": "4.6.0",
4
4
  "browser": "./index.js",
5
5
  "main": "./index.js",
6
6
  "dependencies": {
package/when/when.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createRule } from '../core';
1
+ import { callRule, createRule, } from '../core';
2
2
  /**
3
3
  * @description Позволяет указывать условные валидации
4
4
  * @example
@@ -23,7 +23,7 @@ import { createRule } from '../core';
23
23
  */
24
24
  export const when = ({ is, then, otherwise, }) => createRule((value, ctx) => {
25
25
  if (is(value, ctx)) {
26
- return then(value, ctx);
26
+ return callRule(then, value, ctx);
27
27
  }
28
- return otherwise(value, ctx);
28
+ return callRule(otherwise, value, ctx);
29
29
  });