@astral/validations 4.4.0 → 4.5.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-условная-валидация)
@@ -1294,6 +1295,34 @@ validate('Hello');
1294
1295
  includesWorld()('Hello')
1295
1296
  ```
1296
1297
 
1298
+ ## Кастомная условная валидация
1299
+
1300
+ Для условной валидации рекомендуется использовать [when](#when-условная-валидация), но также доступна возможность реализации кастомной условной валидации.
1301
+
1302
+ ```ts
1303
+ import { object, string, boolean, optional } from '@astral/validations';
1304
+
1305
+ type Values = {
1306
+ isAgree: boolean;
1307
+ info: {
1308
+ name: string
1309
+ }
1310
+ };
1311
+
1312
+ const validate = object<Values>({
1313
+ isAgree: optional(boolean()),
1314
+ info: object<Values['info']>({
1315
+ name: (value, ctx) => {
1316
+ if(ctx.global.values?.isAgree) {
1317
+ return string();
1318
+ }
1319
+
1320
+ return any();
1321
+ }
1322
+ })
1323
+ });
1324
+ ```
1325
+
1297
1326
  ---
1298
1327
 
1299
1328
  # Common
@@ -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.5.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
  });