@reformer/core 1.1.0 → 2.0.0-beta.2

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 (99) hide show
  1. package/dist/behaviors-DzYL8kY_.js +499 -0
  2. package/dist/behaviors.d.ts +6 -2
  3. package/dist/behaviors.js +19 -227
  4. package/dist/core/behavior/behavior-context.d.ts +6 -2
  5. package/dist/core/behavior/create-field-path.d.ts +3 -16
  6. package/dist/core/nodes/group-node.d.ts +14 -193
  7. package/dist/core/types/form-context.d.ts +10 -4
  8. package/dist/core/utils/field-path.d.ts +48 -0
  9. package/dist/core/utils/index.d.ts +1 -0
  10. package/dist/core/validation/core/validate-tree.d.ts +10 -4
  11. package/dist/core/validation/field-path.d.ts +3 -39
  12. package/dist/core/validation/validation-context.d.ts +23 -0
  13. package/dist/hooks/types.d.ts +328 -0
  14. package/dist/hooks/useFormControl.d.ts +13 -37
  15. package/dist/hooks/useFormControlValue.d.ts +167 -0
  16. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  17. package/dist/index.d.ts +6 -1
  18. package/dist/index.js +2886 -8
  19. package/dist/{create-field-path-CdPF3lIK.js → registry-helpers-BRxAr6nG.js} +133 -347
  20. package/dist/validators-gXoHPdqM.js +418 -0
  21. package/dist/validators.d.ts +6 -2
  22. package/dist/validators.js +29 -296
  23. package/llms.txt +1283 -22
  24. package/package.json +8 -4
  25. package/dist/core/behavior/behavior-applicator.d.ts +0 -71
  26. package/dist/core/behavior/behavior-applicator.js +0 -92
  27. package/dist/core/behavior/behavior-context.js +0 -38
  28. package/dist/core/behavior/behavior-registry.js +0 -198
  29. package/dist/core/behavior/behaviors/compute-from.js +0 -84
  30. package/dist/core/behavior/behaviors/copy-from.js +0 -64
  31. package/dist/core/behavior/behaviors/enable-when.js +0 -81
  32. package/dist/core/behavior/behaviors/index.js +0 -11
  33. package/dist/core/behavior/behaviors/reset-when.js +0 -63
  34. package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
  35. package/dist/core/behavior/behaviors/sync-fields.js +0 -66
  36. package/dist/core/behavior/behaviors/transform-value.js +0 -110
  37. package/dist/core/behavior/behaviors/watch-field.js +0 -56
  38. package/dist/core/behavior/compose-behavior.js +0 -166
  39. package/dist/core/behavior/create-field-path.js +0 -69
  40. package/dist/core/behavior/index.js +0 -17
  41. package/dist/core/behavior/types.js +0 -7
  42. package/dist/core/context/form-context-impl.js +0 -37
  43. package/dist/core/factories/index.js +0 -6
  44. package/dist/core/factories/node-factory.js +0 -281
  45. package/dist/core/nodes/array-node.js +0 -534
  46. package/dist/core/nodes/field-node.js +0 -510
  47. package/dist/core/nodes/form-node.js +0 -343
  48. package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
  49. package/dist/core/nodes/group-node/field-registry.js +0 -215
  50. package/dist/core/nodes/group-node/index.d.ts +0 -11
  51. package/dist/core/nodes/group-node/index.js +0 -11
  52. package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
  53. package/dist/core/nodes/group-node/proxy-builder.js +0 -161
  54. package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
  55. package/dist/core/nodes/group-node/state-manager.js +0 -265
  56. package/dist/core/nodes/group-node.js +0 -770
  57. package/dist/core/types/deep-schema.js +0 -11
  58. package/dist/core/types/field-path.js +0 -4
  59. package/dist/core/types/form-context.js +0 -25
  60. package/dist/core/types/group-node-proxy.js +0 -31
  61. package/dist/core/types/index.js +0 -4
  62. package/dist/core/types/validation-schema.js +0 -10
  63. package/dist/core/utils/create-form.js +0 -24
  64. package/dist/core/utils/debounce.js +0 -197
  65. package/dist/core/utils/error-handler.js +0 -226
  66. package/dist/core/utils/field-path-navigator.js +0 -374
  67. package/dist/core/utils/index.js +0 -14
  68. package/dist/core/utils/registry-helpers.js +0 -79
  69. package/dist/core/utils/registry-stack.js +0 -86
  70. package/dist/core/utils/resources.js +0 -69
  71. package/dist/core/utils/subscription-manager.js +0 -214
  72. package/dist/core/utils/type-guards.js +0 -169
  73. package/dist/core/validation/core/apply-when.js +0 -41
  74. package/dist/core/validation/core/apply.js +0 -38
  75. package/dist/core/validation/core/index.js +0 -8
  76. package/dist/core/validation/core/validate-async.js +0 -45
  77. package/dist/core/validation/core/validate-tree.js +0 -37
  78. package/dist/core/validation/core/validate.js +0 -38
  79. package/dist/core/validation/field-path.js +0 -147
  80. package/dist/core/validation/index.js +0 -33
  81. package/dist/core/validation/validate-form.js +0 -152
  82. package/dist/core/validation/validation-applicator.js +0 -217
  83. package/dist/core/validation/validation-context.js +0 -75
  84. package/dist/core/validation/validation-registry.js +0 -298
  85. package/dist/core/validation/validators/array-validators.js +0 -86
  86. package/dist/core/validation/validators/date.js +0 -117
  87. package/dist/core/validation/validators/email.js +0 -60
  88. package/dist/core/validation/validators/index.js +0 -14
  89. package/dist/core/validation/validators/max-length.js +0 -60
  90. package/dist/core/validation/validators/max.js +0 -60
  91. package/dist/core/validation/validators/min-length.js +0 -60
  92. package/dist/core/validation/validators/min.js +0 -60
  93. package/dist/core/validation/validators/number.js +0 -90
  94. package/dist/core/validation/validators/pattern.js +0 -62
  95. package/dist/core/validation/validators/phone.js +0 -58
  96. package/dist/core/validation/validators/required.js +0 -69
  97. package/dist/core/validation/validators/url.js +0 -55
  98. package/dist/hooks/useFormControl.js +0 -298
  99. package/dist/node-factory-D7DOnSSN.js +0 -3200
@@ -1,214 +0,0 @@
1
- /**
2
- * Менеджер подписок для FormNode
3
- *
4
- * Централизует управление effect-подписками в узлах формы,
5
- * предотвращает утечки памяти и упрощает отладку.
6
- *
7
- * Каждая подписка имеет уникальный ключ, что позволяет:
8
- * - Отписываться от конкретной подписки по ключу
9
- * - Автоматически заменять существующие подписки
10
- * - Отслеживать количество активных подписок (для отладки)
11
- *
12
- * @internal
13
- *
14
- * @example
15
- * ```typescript
16
- * class FieldNode {
17
- * private subscriptions = new SubscriptionManager();
18
- *
19
- * watch(callback: Function) {
20
- * const dispose = effect(() => callback(this.value.value));
21
- * return this.subscriptions.add('watch', dispose);
22
- * }
23
- *
24
- * dispose() {
25
- * this.subscriptions.clear();
26
- * }
27
- * }
28
- * ```
29
- */
30
- export class SubscriptionManager {
31
- /**
32
- * Хранилище подписок
33
- * Ключ: уникальный идентификатор подписки
34
- * Значение: функция отписки (dispose)
35
- */
36
- subscriptions = new Map();
37
- /**
38
- * Добавляет подписку
39
- *
40
- * Если подписка с таким ключом уже существует, отписывается от неё
41
- * и заменяет новой. Это предотвращает утечки памяти при повторной
42
- * регистрации подписки с тем же ключом.
43
- *
44
- * @param key Уникальный ключ подписки
45
- * @param dispose Функция отписки (обычно возвращаемая из effect())
46
- * @returns Функция для отписки от этой конкретной подписки
47
- *
48
- * @example
49
- * ```typescript
50
- * const manager = new SubscriptionManager();
51
- *
52
- * // Добавление подписки
53
- * const unsubscribe = manager.add('mySubscription', () => {
54
- * console.log('Disposing subscription');
55
- * });
56
- *
57
- * // Отписка через возвращаемую функцию
58
- * unsubscribe();
59
- *
60
- * // Или через manager.remove()
61
- * manager.add('anotherSub', disposeFn);
62
- * manager.remove('anotherSub');
63
- * ```
64
- */
65
- add(key, dispose) {
66
- // Если подписка с таким ключом уже есть, отписываемся от неё
67
- if (this.subscriptions.has(key)) {
68
- if (process.env.NODE_ENV !== 'production') {
69
- console.warn(`[SubscriptionManager] Subscription "${key}" already exists, replacing`);
70
- }
71
- this.subscriptions.get(key)?.();
72
- }
73
- // Сохраняем новую подписку
74
- this.subscriptions.set(key, dispose);
75
- // Возвращаем функцию отписки
76
- return () => this.remove(key);
77
- }
78
- /**
79
- * Удаляет подписку по ключу
80
- *
81
- * Вызывает функцию отписки и удаляет подписку из хранилища.
82
- * Если подписка с таким ключом не найдена, ничего не делает.
83
- *
84
- * @param key Ключ подписки
85
- * @returns true, если подписка была удалена, false если не найдена
86
- *
87
- * @example
88
- * ```typescript
89
- * const manager = new SubscriptionManager();
90
- * manager.add('mySub', disposeFn);
91
- *
92
- * // Удаление подписки
93
- * const removed = manager.remove('mySub'); // true
94
- *
95
- * // Попытка удалить несуществующую подписку
96
- * const removed2 = manager.remove('nonExistent'); // false
97
- * ```
98
- */
99
- remove(key) {
100
- const dispose = this.subscriptions.get(key);
101
- if (dispose) {
102
- dispose();
103
- this.subscriptions.delete(key);
104
- return true;
105
- }
106
- return false;
107
- }
108
- /**
109
- * Очищает все подписки
110
- *
111
- * Вызывает функции отписки для всех активных подписок
112
- * и очищает хранилище. Обычно используется при dispose узла формы.
113
- *
114
- * @example
115
- * ```typescript
116
- * class FieldNode {
117
- * private subscriptions = new SubscriptionManager();
118
- *
119
- * dispose() {
120
- * // Отписываемся от всех effect
121
- * this.subscriptions.clear();
122
- * }
123
- * }
124
- * ```
125
- */
126
- clear() {
127
- // Используем forEach для совместимости
128
- this.subscriptions.forEach((dispose) => {
129
- dispose();
130
- });
131
- this.subscriptions.clear();
132
- }
133
- /**
134
- * Возвращает количество активных подписок
135
- *
136
- * Полезно для отладки утечек памяти. Если количество подписок
137
- * растет без ограничений, это может указывать на то, что
138
- * компоненты не отписываются должным образом.
139
- *
140
- * @returns Количество активных подписок
141
- *
142
- * @example
143
- * ```typescript
144
- * const manager = new SubscriptionManager();
145
- * console.log(manager.size()); // 0
146
- *
147
- * manager.add('sub1', disposeFn1);
148
- * manager.add('sub2', disposeFn2);
149
- * console.log(manager.size()); // 2
150
- *
151
- * manager.clear();
152
- * console.log(manager.size()); // 0
153
- * ```
154
- */
155
- size() {
156
- return this.subscriptions.size;
157
- }
158
- /**
159
- * Проверяет, есть ли подписка с данным ключом
160
- *
161
- * @param key Ключ подписки
162
- * @returns true, если подписка существует
163
- *
164
- * @example
165
- * ```typescript
166
- * const manager = new SubscriptionManager();
167
- * manager.add('mySub', disposeFn);
168
- *
169
- * console.log(manager.has('mySub')); // true
170
- * console.log(manager.has('nonExistent')); // false
171
- * ```
172
- */
173
- has(key) {
174
- return this.subscriptions.has(key);
175
- }
176
- /**
177
- * Возвращает список всех ключей активных подписок
178
- *
179
- * Полезно для отладки: можно увидеть, какие подписки активны.
180
- *
181
- * @returns Массив ключей всех активных подписок
182
- *
183
- * @example
184
- * ```typescript
185
- * const manager = new SubscriptionManager();
186
- * manager.add('watch-value', disposeFn1);
187
- * manager.add('watch-errors', disposeFn2);
188
- *
189
- * console.log(manager.getKeys()); // ['watch-value', 'watch-errors']
190
- * ```
191
- */
192
- getKeys() {
193
- return Array.from(this.subscriptions.keys());
194
- }
195
- /**
196
- * Отписывается от всех подписок (алиас для clear())
197
- *
198
- * Используется при dispose() узла формы для совместимости с ожидаемым API.
199
- *
200
- * @example
201
- * ```typescript
202
- * class FieldNode {
203
- * private subscriptions = new SubscriptionManager();
204
- *
205
- * dispose() {
206
- * this.subscriptions.dispose();
207
- * }
208
- * }
209
- * ```
210
- */
211
- dispose() {
212
- this.clear();
213
- }
214
- }
@@ -1,169 +0,0 @@
1
- /**
2
- * Type Guards - централизованные функции проверки типов узлов
3
- *
4
- * Устраняет дублирование между form-node.ts, validation-applicator.ts и validation-context.ts
5
- *
6
- * @group Utilities
7
- * @category Type Guards
8
- *
9
- * @example
10
- * ```typescript
11
- * import { isFieldNode, isGroupNode } from '@/core/utils/type-guards';
12
- *
13
- * if (isFieldNode(node)) {
14
- * // TypeScript знает, что node это FieldNode
15
- * node.validators;
16
- * }
17
- * ```
18
- */
19
- /**
20
- * Проверить, является ли значение любым FormNode
21
- *
22
- * Проверяет базовые свойства, общие для всех типов узлов
23
- *
24
- * @group Utilities
25
- * @category Type Guards
26
- *
27
- * @param value - Значение для проверки
28
- * @returns true если value является FormNode
29
- *
30
- * @example
31
- * ```typescript
32
- * if (isFormNode(value)) {
33
- * value.setValue(newValue);
34
- * value.validate();
35
- * }
36
- * ```
37
- */
38
- export function isFormNode(value) {
39
- if (value === null || value === undefined) {
40
- return false;
41
- }
42
- return (typeof value === 'object' &&
43
- 'value' in value &&
44
- 'setValue' in value &&
45
- 'getValue' in value &&
46
- 'validate' in value);
47
- }
48
- /**
49
- * Проверить, является ли значение FieldNode (примитивное поле)
50
- *
51
- * FieldNode представляет примитивное поле формы (string, number, boolean и т.д.)
52
- * и имеет валидаторы, но не имеет вложенных полей или элементов массива
53
- *
54
- * @group Utilities
55
- * @category Type Guards
56
- *
57
- * @param value - Значение для проверки
58
- * @returns true если value является FieldNode
59
- *
60
- * @example
61
- * ```typescript
62
- * if (isFieldNode(node)) {
63
- * node.validators; // OK
64
- * node.asyncValidators; // OK
65
- * node.markAsTouched(); // OK
66
- * }
67
- * ```
68
- */
69
- export function isFieldNode(value) {
70
- if (value === null || value === undefined) {
71
- return false;
72
- }
73
- return (isFormNode(value) &&
74
- 'validators' in value &&
75
- 'asyncValidators' in value &&
76
- // FieldNode имеет markAsTouched метод
77
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
- typeof value.markAsTouched === 'function' &&
79
- // У FieldNode нет fields или items
80
- !('fields' in value) &&
81
- !('items' in value));
82
- }
83
- /**
84
- * Проверить, является ли значение GroupNode (объект с вложенными полями)
85
- *
86
- * GroupNode представляет объект с вложенными полями формы
87
- * и имеет методы для применения validation/behavior схем
88
- *
89
- * @param value - Значение для проверки
90
- * @returns true если value является GroupNode
91
- *
92
- * @example
93
- * ```typescript
94
- * if (isGroupNode(node)) {
95
- * node.applyValidationSchema(schema); // OK
96
- * node.getFieldByPath('user.email'); // OK
97
- * }
98
- * ```
99
- */
100
- export function isGroupNode(value) {
101
- if (value === null || value === undefined) {
102
- return false;
103
- }
104
- return (isFormNode(value) &&
105
- 'applyValidationSchema' in value &&
106
- 'applyBehaviorSchema' in value &&
107
- 'getFieldByPath' in value &&
108
- // GroupNode НЕ имеет items/push/removeAt (это ArrayNode)
109
- !('items' in value) &&
110
- !('push' in value) &&
111
- !('removeAt' in value));
112
- }
113
- /**
114
- * Проверить, является ли значение ArrayNode (массив форм)
115
- *
116
- * ArrayNode представляет массив вложенных форм (обычно GroupNode)
117
- * и имеет array-like методы (push, removeAt, at)
118
- *
119
- * @param value - Значение для проверки
120
- * @returns true если value является ArrayNode
121
- *
122
- * @example
123
- * ```typescript
124
- * if (isArrayNode(node)) {
125
- * node.push(); // OK - добавить элемент
126
- * node.removeAt(0); // OK - удалить элемент
127
- * const item = node.at(0); // OK - получить элемент
128
- * }
129
- * ```
130
- */
131
- export function isArrayNode(value) {
132
- if (value === null || value === undefined) {
133
- return false;
134
- }
135
- return (isFormNode(value) &&
136
- 'items' in value &&
137
- 'length' in value &&
138
- 'push' in value &&
139
- 'removeAt' in value &&
140
- 'at' in value &&
141
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
- typeof value.push === 'function' &&
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
- typeof value.removeAt === 'function');
145
- }
146
- /**
147
- * Получить тип узла как строку (для отладки)
148
- *
149
- * Полезно для логирования и отладки
150
- *
151
- * @param node - Узел для проверки
152
- * @returns Строковое название типа узла
153
- *
154
- * @example
155
- * ```typescript
156
- * console.log('Node type:', getNodeType(node)); // "FieldNode" | "GroupNode" | "ArrayNode" | "FormNode" | "Unknown"
157
- * ```
158
- */
159
- export function getNodeType(node) {
160
- if (isFieldNode(node))
161
- return 'FieldNode';
162
- if (isGroupNode(node))
163
- return 'GroupNode';
164
- if (isArrayNode(node))
165
- return 'ArrayNode';
166
- if (isFormNode(node))
167
- return 'FormNode';
168
- return 'Unknown';
169
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * Условная валидация
3
- *
4
- * @group Validation
5
- * @category Core Functions
6
- */
7
- import { extractPath, createFieldPath } from '../field-path';
8
- import { getCurrentValidationRegistry } from '../../utils/registry-helpers';
9
- /**
10
- * Применить валидацию только при выполнении условия
11
- *
12
- * @group Validation
13
- * @category Core Functions
14
- *
15
- * @example
16
- * ```typescript
17
- * applyWhen(
18
- * path.loanType,
19
- * (type) => type === 'mortgage',
20
- * (path) => {
21
- * required(path.propertyValue, { message: 'Укажите стоимость' });
22
- * min(path.propertyValue, 1000000);
23
- * }
24
- * );
25
- * ```
26
- */
27
- export function applyWhen(fieldPath, condition, validationFn) {
28
- const path = extractPath(fieldPath);
29
- // Входим в условный блок
30
- getCurrentValidationRegistry().enterCondition(path, condition);
31
- try {
32
- // Выполняем вложенную валидацию
33
- // Создаем новый FieldPath proxy для вложенной функции
34
- const nestedPath = createFieldPath();
35
- validationFn(nestedPath);
36
- }
37
- finally {
38
- // Выходим из условного блока
39
- getCurrentValidationRegistry().exitCondition();
40
- }
41
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Композиция validation схем
3
- *
4
- * Предоставляет функции для переиспользования validation схем:
5
- * - apply: применение схемы к полям (новый API)
6
- *
7
- * Дополняет существующий toFieldPath и applyWhen.
8
- *
9
- * @group Validation
10
- * @category Core Functions
11
- */
12
- import { toFieldPath } from '../field-path';
13
- // Реализация
14
- export function apply(pathOrFields, validationSchemas) {
15
- // Случай 1: FieldPath<TForm> + одна схема (композиция на уровне формы)
16
- // Проверяем, является ли это FieldPath (не имеет __key и __path)
17
- if (!Array.isArray(pathOrFields) &&
18
- !Array.isArray(validationSchemas) &&
19
- pathOrFields &&
20
- !('__key' in pathOrFields) &&
21
- !('__path' in pathOrFields)) {
22
- const path = pathOrFields;
23
- const schema = validationSchemas;
24
- schema(path);
25
- return;
26
- }
27
- // Случай 2: FieldPathNode или массив полей
28
- const fieldArray = (Array.isArray(pathOrFields) ? pathOrFields : [pathOrFields]).filter(Boolean);
29
- const schemaArray = Array.isArray(validationSchemas) ? validationSchemas : [validationSchemas];
30
- // Применяем все схемы ко всем полям
31
- for (const field of fieldArray) {
32
- const nestedPath = toFieldPath(field);
33
- for (const schema of schemaArray) {
34
- // Type assertion: в случае 2 мы работаем только с ValidationSchemaFn<TField>
35
- schema(nestedPath);
36
- }
37
- }
38
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Core validation functions
3
- */
4
- export { validate } from './validate';
5
- export { validateAsync } from './validate-async';
6
- export { validateTree } from './validate-tree';
7
- export { applyWhen } from './apply-when';
8
- export { apply } from './apply';
@@ -1,45 +0,0 @@
1
- /**
2
- * Асинхронная валидация поля
3
- *
4
- * @group Validation
5
- * @category Core Functions
6
- */
7
- import { extractPath } from '../field-path';
8
- import { getCurrentValidationRegistry } from '../../utils/registry-helpers';
9
- /**
10
- * Зарегистрировать асинхронный валидатор для поля
11
- *
12
- * @group Validation
13
- * @category Core Functions
14
- *
15
- * @example
16
- * ```typescript
17
- * validateAsync(
18
- * path.inn,
19
- * async (ctx: ValidationContext<TForm, TField>) => {
20
- * const inn = ctx.value();
21
- * if (!inn) return null;
22
- *
23
- * const response = await fetch('/api/validate-inn', {
24
- * method: 'POST',
25
- * body: JSON.stringify({ inn }),
26
- * });
27
- *
28
- * const data = await response.json();
29
- * if (!data.valid) {
30
- * return {
31
- * code: 'invalidInn',
32
- * message: 'ИНН не найден в базе данных ФНС',
33
- * };
34
- * }
35
- *
36
- * return null;
37
- * },
38
- * { debounce: 1000 }
39
- * );
40
- * ```
41
- */
42
- export function validateAsync(fieldPath, validatorFn, options) {
43
- const path = extractPath(fieldPath);
44
- getCurrentValidationRegistry().registerAsync(path, validatorFn, options);
45
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * Cross-field валидация
3
- *
4
- * @group Validation
5
- * @category Core Functions
6
- */
7
- import { getCurrentValidationRegistry } from '../../utils/registry-helpers';
8
- /**
9
- * Зарегистрировать cross-field валидатор
10
- *
11
- * Используется для валидации, которая зависит от нескольких полей
12
- *
13
- * @group Validation
14
- * @category Core Functions
15
- *
16
- * @example
17
- * ```typescript
18
- * validateTree(
19
- * (ctx: ValidationContext<TForm, TField>) => {
20
- * const form = ctx.formValue();
21
- * if (form.initialPayment && form.propertyValue) {
22
- * if (form.initialPayment > form.propertyValue) {
23
- * return {
24
- * code: 'initialPaymentTooHigh',
25
- * message: 'Первоначальный взнос не может превышать стоимость',
26
- * };
27
- * }
28
- * }
29
- * return null;
30
- * },
31
- * { targetField: 'initialPayment' }
32
- * );
33
- * ```
34
- */
35
- export function validateTree(validatorFn, options) {
36
- getCurrentValidationRegistry().registerTree(validatorFn, options);
37
- }
@@ -1,38 +0,0 @@
1
- /**
2
- * Кастомная синхронная валидация поля
3
- *
4
- * @group Validation
5
- * @category Core Functions
6
- */
7
- import { extractPath } from '../field-path';
8
- import { getCurrentValidationRegistry } from '../../utils/registry-helpers';
9
- /**
10
- * Зарегистрировать кастомный синхронный валидатор для поля
11
- * Поддерживает опциональные поля
12
- *
13
- * @group Validation
14
- * @category Core Functions
15
- *
16
- * @example
17
- * ```typescript
18
- * validate(path.birthDate, (ctx: ValidationContext<TForm, TField>) => {
19
- * const birthDate = new Date(ctx.value());
20
- * const age = calculateAge(birthDate);
21
- *
22
- * if (age < 18) {
23
- * return {
24
- * code: 'tooYoung',
25
- * message: 'Заемщику должно быть не менее 18 лет',
26
- * };
27
- * }
28
- *
29
- * return null;
30
- * });
31
- * ```
32
- */
33
- export function validate(fieldPath, validatorFn, options) {
34
- if (!fieldPath)
35
- return; // Защита от undefined fieldPath
36
- const path = extractPath(fieldPath);
37
- getCurrentValidationRegistry().registerSync(path, validatorFn, options);
38
- }