@reformer/core 1.0.0-beta.3

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.
Files changed (150) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/behaviors.d.ts +2 -0
  4. package/dist/behaviors.js +230 -0
  5. package/dist/core/behavior/behavior-applicator.d.ts +71 -0
  6. package/dist/core/behavior/behavior-applicator.js +92 -0
  7. package/dist/core/behavior/behavior-context.d.ts +29 -0
  8. package/dist/core/behavior/behavior-context.js +38 -0
  9. package/dist/core/behavior/behavior-registry.d.ts +97 -0
  10. package/dist/core/behavior/behavior-registry.js +198 -0
  11. package/dist/core/behavior/behaviors/compute-from.d.ts +41 -0
  12. package/dist/core/behavior/behaviors/compute-from.js +84 -0
  13. package/dist/core/behavior/behaviors/copy-from.d.ts +31 -0
  14. package/dist/core/behavior/behaviors/copy-from.js +64 -0
  15. package/dist/core/behavior/behaviors/enable-when.d.ts +49 -0
  16. package/dist/core/behavior/behaviors/enable-when.js +81 -0
  17. package/dist/core/behavior/behaviors/index.d.ts +11 -0
  18. package/dist/core/behavior/behaviors/index.js +11 -0
  19. package/dist/core/behavior/behaviors/reset-when.d.ts +51 -0
  20. package/dist/core/behavior/behaviors/reset-when.js +63 -0
  21. package/dist/core/behavior/behaviors/revalidate-when.d.ts +30 -0
  22. package/dist/core/behavior/behaviors/revalidate-when.js +51 -0
  23. package/dist/core/behavior/behaviors/sync-fields.d.ts +28 -0
  24. package/dist/core/behavior/behaviors/sync-fields.js +66 -0
  25. package/dist/core/behavior/behaviors/transform-value.d.ts +120 -0
  26. package/dist/core/behavior/behaviors/transform-value.js +110 -0
  27. package/dist/core/behavior/behaviors/watch-field.d.ts +35 -0
  28. package/dist/core/behavior/behaviors/watch-field.js +56 -0
  29. package/dist/core/behavior/compose-behavior.d.ts +106 -0
  30. package/dist/core/behavior/compose-behavior.js +166 -0
  31. package/dist/core/behavior/create-field-path.d.ts +20 -0
  32. package/dist/core/behavior/create-field-path.js +69 -0
  33. package/dist/core/behavior/index.d.ts +12 -0
  34. package/dist/core/behavior/index.js +17 -0
  35. package/dist/core/behavior/types.d.ts +152 -0
  36. package/dist/core/behavior/types.js +7 -0
  37. package/dist/core/context/form-context-impl.d.ts +29 -0
  38. package/dist/core/context/form-context-impl.js +37 -0
  39. package/dist/core/factories/index.d.ts +6 -0
  40. package/dist/core/factories/index.js +6 -0
  41. package/dist/core/factories/node-factory.d.ts +209 -0
  42. package/dist/core/factories/node-factory.js +281 -0
  43. package/dist/core/nodes/array-node.d.ts +308 -0
  44. package/dist/core/nodes/array-node.js +534 -0
  45. package/dist/core/nodes/field-node.d.ts +269 -0
  46. package/dist/core/nodes/field-node.js +510 -0
  47. package/dist/core/nodes/form-node.d.ts +342 -0
  48. package/dist/core/nodes/form-node.js +343 -0
  49. package/dist/core/nodes/group-node/field-registry.d.ts +191 -0
  50. package/dist/core/nodes/group-node/field-registry.js +215 -0
  51. package/dist/core/nodes/group-node/index.d.ts +11 -0
  52. package/dist/core/nodes/group-node/index.js +11 -0
  53. package/dist/core/nodes/group-node/proxy-builder.d.ts +71 -0
  54. package/dist/core/nodes/group-node/proxy-builder.js +161 -0
  55. package/dist/core/nodes/group-node/state-manager.d.ts +184 -0
  56. package/dist/core/nodes/group-node/state-manager.js +265 -0
  57. package/dist/core/nodes/group-node.d.ts +494 -0
  58. package/dist/core/nodes/group-node.js +770 -0
  59. package/dist/core/types/deep-schema.d.ts +78 -0
  60. package/dist/core/types/deep-schema.js +11 -0
  61. package/dist/core/types/field-path.d.ts +42 -0
  62. package/dist/core/types/field-path.js +4 -0
  63. package/dist/core/types/form-context.d.ts +83 -0
  64. package/dist/core/types/form-context.js +25 -0
  65. package/dist/core/types/group-node-proxy.d.ts +135 -0
  66. package/dist/core/types/group-node-proxy.js +31 -0
  67. package/dist/core/types/index.d.ts +163 -0
  68. package/dist/core/types/index.js +4 -0
  69. package/dist/core/types/validation-schema.d.ts +104 -0
  70. package/dist/core/types/validation-schema.js +10 -0
  71. package/dist/core/utils/create-form.d.ts +61 -0
  72. package/dist/core/utils/create-form.js +24 -0
  73. package/dist/core/utils/debounce.d.ts +160 -0
  74. package/dist/core/utils/debounce.js +197 -0
  75. package/dist/core/utils/error-handler.d.ts +180 -0
  76. package/dist/core/utils/error-handler.js +226 -0
  77. package/dist/core/utils/field-path-navigator.d.ts +240 -0
  78. package/dist/core/utils/field-path-navigator.js +374 -0
  79. package/dist/core/utils/index.d.ts +14 -0
  80. package/dist/core/utils/index.js +14 -0
  81. package/dist/core/utils/registry-helpers.d.ts +50 -0
  82. package/dist/core/utils/registry-helpers.js +79 -0
  83. package/dist/core/utils/registry-stack.d.ts +69 -0
  84. package/dist/core/utils/registry-stack.js +86 -0
  85. package/dist/core/utils/resources.d.ts +41 -0
  86. package/dist/core/utils/resources.js +69 -0
  87. package/dist/core/utils/subscription-manager.d.ts +180 -0
  88. package/dist/core/utils/subscription-manager.js +214 -0
  89. package/dist/core/utils/type-guards.d.ts +116 -0
  90. package/dist/core/utils/type-guards.js +169 -0
  91. package/dist/core/validation/core/apply-when.d.ts +28 -0
  92. package/dist/core/validation/core/apply-when.js +41 -0
  93. package/dist/core/validation/core/apply.d.ts +63 -0
  94. package/dist/core/validation/core/apply.js +38 -0
  95. package/dist/core/validation/core/index.d.ts +8 -0
  96. package/dist/core/validation/core/index.js +8 -0
  97. package/dist/core/validation/core/validate-async.d.ts +42 -0
  98. package/dist/core/validation/core/validate-async.js +45 -0
  99. package/dist/core/validation/core/validate-tree.d.ts +35 -0
  100. package/dist/core/validation/core/validate-tree.js +37 -0
  101. package/dist/core/validation/core/validate.d.ts +32 -0
  102. package/dist/core/validation/core/validate.js +38 -0
  103. package/dist/core/validation/field-path.d.ts +43 -0
  104. package/dist/core/validation/field-path.js +147 -0
  105. package/dist/core/validation/index.d.ts +21 -0
  106. package/dist/core/validation/index.js +33 -0
  107. package/dist/core/validation/validate-form.d.ts +85 -0
  108. package/dist/core/validation/validate-form.js +152 -0
  109. package/dist/core/validation/validation-applicator.d.ts +89 -0
  110. package/dist/core/validation/validation-applicator.js +217 -0
  111. package/dist/core/validation/validation-context.d.ts +47 -0
  112. package/dist/core/validation/validation-context.js +75 -0
  113. package/dist/core/validation/validation-registry.d.ts +156 -0
  114. package/dist/core/validation/validation-registry.js +298 -0
  115. package/dist/core/validation/validators/array-validators.d.ts +63 -0
  116. package/dist/core/validation/validators/array-validators.js +86 -0
  117. package/dist/core/validation/validators/date.d.ts +38 -0
  118. package/dist/core/validation/validators/date.js +117 -0
  119. package/dist/core/validation/validators/email.d.ts +44 -0
  120. package/dist/core/validation/validators/email.js +60 -0
  121. package/dist/core/validation/validators/index.d.ts +14 -0
  122. package/dist/core/validation/validators/index.js +14 -0
  123. package/dist/core/validation/validators/max-length.d.ts +45 -0
  124. package/dist/core/validation/validators/max-length.js +60 -0
  125. package/dist/core/validation/validators/max.d.ts +45 -0
  126. package/dist/core/validation/validators/max.js +60 -0
  127. package/dist/core/validation/validators/min-length.d.ts +45 -0
  128. package/dist/core/validation/validators/min-length.js +60 -0
  129. package/dist/core/validation/validators/min.d.ts +45 -0
  130. package/dist/core/validation/validators/min.js +60 -0
  131. package/dist/core/validation/validators/number.d.ts +38 -0
  132. package/dist/core/validation/validators/number.js +90 -0
  133. package/dist/core/validation/validators/pattern.d.ts +47 -0
  134. package/dist/core/validation/validators/pattern.js +62 -0
  135. package/dist/core/validation/validators/phone.d.ts +34 -0
  136. package/dist/core/validation/validators/phone.js +58 -0
  137. package/dist/core/validation/validators/required.d.ts +48 -0
  138. package/dist/core/validation/validators/required.js +69 -0
  139. package/dist/core/validation/validators/url.d.ts +29 -0
  140. package/dist/core/validation/validators/url.js +55 -0
  141. package/dist/create-field-path-CdPF3lIK.js +704 -0
  142. package/dist/hooks/useFormControl.d.ts +48 -0
  143. package/dist/hooks/useFormControl.js +298 -0
  144. package/dist/index.d.ts +10 -0
  145. package/dist/index.js +8 -0
  146. package/dist/node-factory-D7DOnSSN.js +3200 -0
  147. package/dist/validators.d.ts +2 -0
  148. package/dist/validators.js +298 -0
  149. package/llms.txt +847 -0
  150. package/package.json +86 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Валидатор паттерна (регулярного выражения)
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/pattern
7
+ */
8
+ import type { ValidateOptions } from '../../types/validation-schema';
9
+ import type { FieldPathNode } from '../../types';
10
+ /**
11
+ * Валидатор паттерна (регулярного выражения)
12
+ *
13
+ * Проверяет, что значение соответствует указанному регулярному выражению.
14
+ * Пустые значения пропускаются (используйте `required` для обязательности).
15
+ *
16
+ * @group Validation
17
+ * @category Validators
18
+ *
19
+ * @param fieldPath - Путь к полю для валидации
20
+ * @param regex - Регулярное выражение для проверки
21
+ * @param options - Опции валидации (message, params)
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Только буквы
26
+ * pattern(path.name, /^[а-яА-Яa-zA-Z]+$/)
27
+ *
28
+ * // Только цифры
29
+ * pattern(path.code, /^\d+$/)
30
+ *
31
+ * // С кастомным сообщением
32
+ * pattern(path.username, /^[a-z0-9_]+$/i, {
33
+ * message: 'Только латинские буквы, цифры и подчёркивание'
34
+ * })
35
+ * ```
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Ошибка валидации
40
+ * {
41
+ * code: 'pattern',
42
+ * message: 'Значение не соответствует требуемому формату',
43
+ * params: { pattern: '^[a-z]+$' }
44
+ * }
45
+ * ```
46
+ */
47
+ export declare function pattern<TForm, TField extends string | undefined = string>(fieldPath: FieldPathNode<TForm, TField> | undefined, regex: RegExp, options?: ValidateOptions): void;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Валидатор паттерна (регулярного выражения)
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/pattern
7
+ */
8
+ import { validate } from '../core/validate';
9
+ /**
10
+ * Валидатор паттерна (регулярного выражения)
11
+ *
12
+ * Проверяет, что значение соответствует указанному регулярному выражению.
13
+ * Пустые значения пропускаются (используйте `required` для обязательности).
14
+ *
15
+ * @group Validation
16
+ * @category Validators
17
+ *
18
+ * @param fieldPath - Путь к полю для валидации
19
+ * @param regex - Регулярное выражение для проверки
20
+ * @param options - Опции валидации (message, params)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Только буквы
25
+ * pattern(path.name, /^[а-яА-Яa-zA-Z]+$/)
26
+ *
27
+ * // Только цифры
28
+ * pattern(path.code, /^\d+$/)
29
+ *
30
+ * // С кастомным сообщением
31
+ * pattern(path.username, /^[a-z0-9_]+$/i, {
32
+ * message: 'Только латинские буквы, цифры и подчёркивание'
33
+ * })
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * // Ошибка валидации
39
+ * {
40
+ * code: 'pattern',
41
+ * message: 'Значение не соответствует требуемому формату',
42
+ * params: { pattern: '^[a-z]+$' }
43
+ * }
44
+ * ```
45
+ */
46
+ export function pattern(fieldPath, regex, options) {
47
+ if (!fieldPath)
48
+ return; // Защита от undefined fieldPath
49
+ validate(fieldPath, (value) => {
50
+ if (!value) {
51
+ return null;
52
+ }
53
+ if (!regex.test(value)) {
54
+ return {
55
+ code: 'pattern',
56
+ message: options?.message || 'Значение не соответствует требуемому формату',
57
+ params: { pattern: regex.source, ...options?.params },
58
+ };
59
+ }
60
+ return null;
61
+ });
62
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Валидатор номера телефона
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/phone
7
+ */
8
+ import type { ValidateOptions } from '../../types/validation-schema';
9
+ import type { FieldPathNode } from '../../types';
10
+ /**
11
+ * Формат телефона для валидации
12
+ *
13
+ * @group Validation
14
+ * @category Validators
15
+ */
16
+ export type PhoneFormat = 'international' | 'ru' | 'us' | 'any';
17
+ /**
18
+ * Адаптер для phone валидатора
19
+ * Поддерживает опциональные поля (string | undefined)
20
+ *
21
+ * @group Validation
22
+ * @category Validators
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * phone(path.phoneNumber);
27
+ * phone(path.phoneNumber, { format: 'ru' });
28
+ * phone(path.phoneNumber, { format: 'international', message: 'Неверный формат телефона' });
29
+ * ```
30
+ */
31
+ export declare function phone<TForm, TField extends string | undefined = string>(fieldPath: FieldPathNode<TForm, TField> | undefined, options?: ValidateOptions & {
32
+ /** Формат телефона */
33
+ format?: PhoneFormat;
34
+ }): void;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Валидатор номера телефона
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/phone
7
+ */
8
+ import { validate } from '../core/validate';
9
+ /**
10
+ * Адаптер для phone валидатора
11
+ * Поддерживает опциональные поля (string | undefined)
12
+ *
13
+ * @group Validation
14
+ * @category Validators
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * phone(path.phoneNumber);
19
+ * phone(path.phoneNumber, { format: 'ru' });
20
+ * phone(path.phoneNumber, { format: 'international', message: 'Неверный формат телефона' });
21
+ * ```
22
+ */
23
+ export function phone(fieldPath, options) {
24
+ if (!fieldPath)
25
+ return; // Защита от undefined fieldPath
26
+ const format = options?.format || 'any';
27
+ // Регулярные выражения для разных форматов
28
+ const patterns = {
29
+ // Международный формат: +1234567890 или +1 234 567 8900
30
+ international: /^\+?[1-9]\d{1,14}$/,
31
+ // Российский формат: +7 (XXX) XXX-XX-XX, 8 (XXX) XXX-XX-XX, и вариации
32
+ ru: /^(\+7|7|8)?[\s\-]?\(?[489][0-9]{2}\)?[\s\-]?[0-9]{3}[\s\-]?[0-9]{2}[\s\-]?[0-9]{2}$/,
33
+ // US формат: (123) 456-7890, 123-456-7890, 1234567890
34
+ us: /^(\+?1)?[\s\-]?\(?[2-9]\d{2}\)?[\s\-]?\d{3}[\s\-]?\d{4}$/,
35
+ // Любой формат: минимум 10 цифр с возможными разделителями
36
+ any: /^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,9}$/,
37
+ };
38
+ validate(fieldPath, (value) => {
39
+ if (!value) {
40
+ return null;
41
+ }
42
+ const regex = patterns[format];
43
+ if (!regex.test(value)) {
44
+ const formatMessages = {
45
+ international: 'Введите телефон в международном формате (например, +1234567890)',
46
+ ru: 'Введите российский номер телефона (например, +7 900 123-45-67)',
47
+ us: 'Введите американский номер телефона (например, (123) 456-7890)',
48
+ any: 'Неверный формат телефона',
49
+ };
50
+ return {
51
+ code: 'phone',
52
+ message: options?.message || formatMessages[format],
53
+ params: { format, ...options?.params },
54
+ };
55
+ }
56
+ return null;
57
+ });
58
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Валидатор обязательного поля
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/required
7
+ */
8
+ import type { ValidateOptions } from '../../types/validation-schema';
9
+ import type { FieldPathNode } from '../../types';
10
+ /**
11
+ * Валидатор обязательного поля
12
+ *
13
+ * Проверяет, что поле имеет непустое значение.
14
+ * Пустыми считаются: `null`, `undefined`, `''` (пустая строка).
15
+ * Для boolean полей требуется значение `true`.
16
+ *
17
+ * @group Validation
18
+ * @category Validators
19
+ *
20
+ * @param fieldPath - Путь к полю для валидации
21
+ * @param options - Опции валидации (message, params)
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Базовое использование
26
+ * validationSchema: (path, { validate }) => [
27
+ * required(path.name),
28
+ * required(path.email),
29
+ * ]
30
+ *
31
+ * // С кастомным сообщением
32
+ * required(path.phone, { message: 'Укажите номер телефона' })
33
+ *
34
+ * // Для checkbox (требует true)
35
+ * required(path.agreeToTerms, { message: 'Необходимо принять условия' })
36
+ * ```
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Ошибка валидации
41
+ * {
42
+ * code: 'required',
43
+ * message: 'Поле обязательно для заполнения',
44
+ * params: {}
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function required<TForm, TField>(fieldPath: FieldPathNode<TForm, TField> | undefined, options?: ValidateOptions): void;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Валидатор обязательного поля
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/required
7
+ */
8
+ import { validate } from '../core/validate';
9
+ /**
10
+ * Валидатор обязательного поля
11
+ *
12
+ * Проверяет, что поле имеет непустое значение.
13
+ * Пустыми считаются: `null`, `undefined`, `''` (пустая строка).
14
+ * Для boolean полей требуется значение `true`.
15
+ *
16
+ * @group Validation
17
+ * @category Validators
18
+ *
19
+ * @param fieldPath - Путь к полю для валидации
20
+ * @param options - Опции валидации (message, params)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Базовое использование
25
+ * validationSchema: (path, { validate }) => [
26
+ * required(path.name),
27
+ * required(path.email),
28
+ * ]
29
+ *
30
+ * // С кастомным сообщением
31
+ * required(path.phone, { message: 'Укажите номер телефона' })
32
+ *
33
+ * // Для checkbox (требует true)
34
+ * required(path.agreeToTerms, { message: 'Необходимо принять условия' })
35
+ * ```
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Ошибка валидации
40
+ * {
41
+ * code: 'required',
42
+ * message: 'Поле обязательно для заполнения',
43
+ * params: {}
44
+ * }
45
+ * ```
46
+ */
47
+ export function required(fieldPath, options) {
48
+ if (!fieldPath)
49
+ return; // Защита от undefined fieldPath
50
+ validate(fieldPath, (value) => {
51
+ // Проверка на пустое значение
52
+ if (value === null || value === undefined || value === '') {
53
+ return {
54
+ code: 'required',
55
+ message: options?.message || 'Поле обязательно для заполнения',
56
+ params: options?.params,
57
+ };
58
+ }
59
+ // Для булевых значений требуем true
60
+ if (typeof value === 'boolean' && value !== true) {
61
+ return {
62
+ code: 'required',
63
+ message: options?.message || 'Поле обязательно для заполнения',
64
+ params: options?.params,
65
+ };
66
+ }
67
+ return null;
68
+ });
69
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Валидатор URL
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/url
7
+ */
8
+ import type { ValidateOptions } from '../../types/validation-schema';
9
+ import type { FieldPathNode } from '../../types';
10
+ /**
11
+ * Адаптер для URL валидатора
12
+ * Поддерживает опциональные поля (string | undefined)
13
+ *
14
+ * @group Validation
15
+ * @category Validators
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * url(path.website);
20
+ * url(path.website, { message: 'Введите корректный URL' });
21
+ * url(path.website, { requireProtocol: true });
22
+ * ```
23
+ */
24
+ export declare function url<TForm, TField extends string | undefined = string>(fieldPath: FieldPathNode<TForm, TField> | undefined, options?: ValidateOptions & {
25
+ /** Требовать наличие протокола (http:// или https://) */
26
+ requireProtocol?: boolean;
27
+ /** Разрешенные протоколы */
28
+ allowedProtocols?: string[];
29
+ }): void;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Валидатор URL
3
+ *
4
+ * @group Validation
5
+ * @category Validators
6
+ * @module validators/url
7
+ */
8
+ import { validate } from '../core/validate';
9
+ /**
10
+ * Адаптер для URL валидатора
11
+ * Поддерживает опциональные поля (string | undefined)
12
+ *
13
+ * @group Validation
14
+ * @category Validators
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * url(path.website);
19
+ * url(path.website, { message: 'Введите корректный URL' });
20
+ * url(path.website, { requireProtocol: true });
21
+ * ```
22
+ */
23
+ export function url(fieldPath, options) {
24
+ if (!fieldPath)
25
+ return; // Защита от undefined fieldPath
26
+ // URL regex с опциональным протоколом
27
+ const urlRegexWithProtocol = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/i;
28
+ const urlRegexRequireProtocol = /^https?:\/\/([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/i;
29
+ validate(fieldPath, (value) => {
30
+ if (!value) {
31
+ return null;
32
+ }
33
+ const regex = options?.requireProtocol ? urlRegexRequireProtocol : urlRegexWithProtocol;
34
+ if (!regex.test(value)) {
35
+ return {
36
+ code: 'url',
37
+ message: options?.message || 'Неверный формат URL',
38
+ params: options?.params,
39
+ };
40
+ }
41
+ // Проверка разрешенных протоколов
42
+ if (options?.allowedProtocols && options.allowedProtocols.length > 0) {
43
+ const hasAllowedProtocol = options.allowedProtocols.some((protocol) => value.toLowerCase().startsWith(`${protocol}://`));
44
+ if (!hasAllowedProtocol) {
45
+ return {
46
+ code: 'url_protocol',
47
+ message: options?.message ||
48
+ `URL должен использовать один из протоколов: ${options.allowedProtocols.join(', ')}`,
49
+ params: { allowedProtocols: options.allowedProtocols, ...options?.params },
50
+ };
51
+ }
52
+ }
53
+ return null;
54
+ });
55
+ }