@astral/validations 4.3.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
@@ -25,6 +25,7 @@
25
25
  - [min](#min-string)
26
26
  - [max](#max-string)
27
27
  - [email](#email)
28
+ - [guid](#guid)
28
29
  - [pattern](#pattern)
29
30
  - [onlyNumber](#onlyNumber)
30
31
  - [snils](#snils)
@@ -58,6 +59,7 @@
58
59
  - [Связанные поля](#связанные-поля)
59
60
  - [Доступ к ctx.global.values](#доступ-к-высокоуровневым-values-ctxglobalvalues)
60
61
  - [Переиспользуемое правило](#переиспользуемое-правило)
62
+ - [Кастомная условная валидация](#кастомная-условная-валидация)
61
63
  - [Common](#common)
62
64
  - [optional](#optional)
63
65
  - [when. Условная валидация](#when-условная-валидация)
@@ -386,6 +388,25 @@ validateEmail('longlonglong.......')
386
388
 
387
389
  ---
388
390
 
391
+ ### guid
392
+
393
+ Проверяет валиден ли GUID.
394
+
395
+ ```ts
396
+ import { string, guid } from '@astral/validations';
397
+
398
+ const validate = string(guid());
399
+
400
+ // undefined
401
+ validate('C56A4180-65AA-42EC-A945-5FD21DEC0538');
402
+
403
+
404
+ // { message: 'Некорректный GUID' }
405
+ validate('x56a4180-h5aa-42ec-a945-5fd21dec0538');
406
+ ```
407
+
408
+ ---
409
+
389
410
  ### pattern
390
411
 
391
412
  Проверяет строку на соответствие регулярному выражению.
@@ -1274,6 +1295,34 @@ validate('Hello');
1274
1295
  includesWorld()('Hello')
1275
1296
  ```
1276
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
+
1277
1326
  ---
1278
1327
 
1279
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...)
@@ -0,0 +1,3 @@
1
+ import { ErrorInfo } from '../core';
2
+ export declare const GUID_REGEXP: RegExp;
3
+ export declare const INVALID_GUID_ERROR_INFO: ErrorInfo;
@@ -0,0 +1,6 @@
1
+ import { createErrorCode } from '../core';
2
+ export const GUID_REGEXP = /^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/;
3
+ export const INVALID_GUID_ERROR_INFO = {
4
+ code: createErrorCode('guid-invalid'),
5
+ message: 'Некорректный GUID',
6
+ };
package/guid/guid.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ type GuidParams = {
2
+ /**
3
+ * @description Замена стандартного сообщения ошибки.
4
+ */
5
+ message?: string;
6
+ };
7
+ /**
8
+ * @description Проверяет валидность GUID.
9
+ * @example
10
+ * ```ts
11
+ * const validate = string(guid());
12
+ * validate('C56A4180-65AA-42EC-A945-5FD21DEC0538');
13
+ * ```
14
+ */
15
+ export declare const guid: <TLastSchemaValues extends Record<string, unknown>>(params?: GuidParams) => (value: string, prevCtx?: import("../core").ValidationContext<TLastSchemaValues> | undefined) => import("../core").ValidationResult;
16
+ export {};
package/guid/guid.js ADDED
@@ -0,0 +1,16 @@
1
+ import { createRule } from '../core';
2
+ import { GUID_REGEXP, INVALID_GUID_ERROR_INFO } from './constants';
3
+ /**
4
+ * @description Проверяет валидность GUID.
5
+ * @example
6
+ * ```ts
7
+ * const validate = string(guid());
8
+ * validate('C56A4180-65AA-42EC-A945-5FD21DEC0538');
9
+ * ```
10
+ */
11
+ export const guid = (params) => createRule((value, ctx) => {
12
+ if (!GUID_REGEXP.test(value)) {
13
+ return ctx.createError(Object.assign(Object.assign({}, INVALID_GUID_ERROR_INFO), { message: (params === null || params === void 0 ? void 0 : params.message) || INVALID_GUID_ERROR_INFO.message }));
14
+ }
15
+ return undefined;
16
+ });
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './guid';
package/guid/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './guid';
package/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export { pattern, PATTERN_ERROR_CODE } from './pattern';
16
16
  export { onlyNumber, ONLY_NUMBER_ERROR_CODE } from './onlyNumber';
17
17
  export { toPlainError } from './toPlainError';
18
18
  export { email, LENGTH_EMAIL_ERROR_INFO, INVALID_EMAIL_ERROR_INFO, } from './email';
19
+ export { guid, INVALID_GUID_ERROR_INFO } from './guid';
19
20
  export { mobilePhone, MOBILE_PHONE_ERROR_INFO } from './mobilePhone';
20
21
  export { innUL, INN_UL_ERROR_INFO } from './innUL';
21
22
  export { innIP, INN_IP_ERROR_INFO } from './innIP';
package/index.js CHANGED
@@ -16,6 +16,7 @@ export { pattern, PATTERN_ERROR_CODE } from './pattern';
16
16
  export { onlyNumber, ONLY_NUMBER_ERROR_CODE } from './onlyNumber';
17
17
  export { toPlainError } from './toPlainError';
18
18
  export { email, LENGTH_EMAIL_ERROR_INFO, INVALID_EMAIL_ERROR_INFO, } from './email';
19
+ export { guid, INVALID_GUID_ERROR_INFO } from './guid';
19
20
  export { mobilePhone, MOBILE_PHONE_ERROR_INFO } from './mobilePhone';
20
21
  export { innUL, INN_UL_ERROR_INFO } from './innUL';
21
22
  export { innIP, INN_IP_ERROR_INFO } from './innIP';
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.3.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
  });