@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,217 @@
1
+ /**
2
+ * Применение валидаторов к форме
3
+ *
4
+ * Извлечено из GroupNode для соблюдения SRP (Single Responsibility Principle).
5
+ * Отвечает только за логику применения валидаторов к полям формы.
6
+ *
7
+ * @template T Тип формы
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * class GroupNode {
12
+ * private readonly validationApplicator = new ValidationApplicator(this);
13
+ *
14
+ * async applyContextualValidators(validators: ValidatorRegistration[]) {
15
+ * await this.validationApplicator.apply(validators);
16
+ * }
17
+ * }
18
+ * ```
19
+ */
20
+ import { ValidationContextImpl, TreeValidationContextImpl } from './validation-context';
21
+ import { isFieldNode } from '../utils/type-guards';
22
+ import { FormErrorHandler, ErrorStrategy } from '../utils/error-handler';
23
+ /**
24
+ * Класс для применения валидаторов к форме
25
+ *
26
+ * Выполняет:
27
+ * - Группировку валидаторов по полям
28
+ * - Фильтрацию по условиям (condition)
29
+ * - Применение sync/async валидаторов к FieldNode
30
+ * - Применение tree валидаторов (кросс-полевая валидация)
31
+ *
32
+ * @template T Тип формы (объект)
33
+ */
34
+ export class ValidationApplicator {
35
+ form;
36
+ constructor(form) {
37
+ this.form = form;
38
+ }
39
+ /**
40
+ * Применить валидаторы к полям формы
41
+ *
42
+ * Этапы применения:
43
+ * 1. Разделение валидаторов на field и tree
44
+ * 2. Применение field валидаторов (sync/async)
45
+ * 3. Применение tree валидаторов (кросс-полевая валидация)
46
+ *
47
+ * @param validators Зарегистрированные валидаторы
48
+ */
49
+ async apply(validators) {
50
+ // 1. Группировка валидаторов
51
+ const { validatorsByField, treeValidators } = this.groupValidators(validators);
52
+ // 2. Применение field валидаторов
53
+ await this.applyFieldValidators(validatorsByField);
54
+ // 3. Применение tree валидаторов
55
+ this.applyTreeValidators(treeValidators);
56
+ }
57
+ /**
58
+ * Группировка валидаторов по типам
59
+ *
60
+ * Разделяет валидаторы на:
61
+ * - Field validators (sync/async) - группируются по fieldPath
62
+ * - Tree validators - применяются ко всей форме
63
+ *
64
+ * @param validators Все зарегистрированные валидаторы
65
+ * @returns Сгруппированные валидаторы
66
+ */
67
+ groupValidators(validators) {
68
+ const validatorsByField = new Map();
69
+ const treeValidators = [];
70
+ for (const registration of validators) {
71
+ if (registration.type === 'tree') {
72
+ treeValidators.push(registration);
73
+ }
74
+ else {
75
+ const existing = validatorsByField.get(registration.fieldPath) || [];
76
+ existing.push(registration);
77
+ validatorsByField.set(registration.fieldPath, existing);
78
+ }
79
+ }
80
+ return { validatorsByField, treeValidators };
81
+ }
82
+ /**
83
+ * Применение field валидаторов к полям
84
+ *
85
+ * Для каждого поля:
86
+ * 1. Найти FieldNode по пути
87
+ * 2. Проверить условия (condition)
88
+ * 3. Выполнить sync/async валидаторы
89
+ * 4. Установить ошибки на поле
90
+ *
91
+ * @param validatorsByField Валидаторы, сгруппированные по полям
92
+ */
93
+ async applyFieldValidators(validatorsByField) {
94
+ for (const [fieldPath, fieldValidators] of validatorsByField) {
95
+ // Поддержка вложенных путей (например, "personalData.lastName")
96
+ const control = this.form.getFieldByPath(fieldPath);
97
+ if (!control) {
98
+ if (import.meta.env.DEV) {
99
+ throw new Error(`Field "${fieldPath}" not found in GroupNode`);
100
+ }
101
+ console.warn(`Field ${fieldPath} not found in GroupNode`);
102
+ continue;
103
+ }
104
+ // Валидация работает только с FieldNode
105
+ if (!isFieldNode(control)) {
106
+ if (process.env.NODE_ENV !== 'production') {
107
+ console.warn(`Validation can only run on FieldNode, skipping ${fieldPath}`);
108
+ }
109
+ continue;
110
+ }
111
+ const errors = [];
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ const context = new ValidationContextImpl(this.form, fieldPath, control);
114
+ // Выполнение валидаторов с учетом условий
115
+ for (const registration of fieldValidators) {
116
+ // Проверка условия (condition)
117
+ if (registration.condition) {
118
+ const shouldApply = this.checkCondition(registration.condition);
119
+ if (!shouldApply) {
120
+ continue;
121
+ }
122
+ }
123
+ // Выполнение валидатора
124
+ // Новый паттерн: (value, ctx) => ValidationError | null
125
+ try {
126
+ let error = null;
127
+ const value = context.value();
128
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
+ const validator = registration.validator;
130
+ if (registration.type === 'sync') {
131
+ error = validator(value, context);
132
+ }
133
+ else if (registration.type === 'async') {
134
+ error = await validator(value, context);
135
+ }
136
+ if (error) {
137
+ errors.push(error);
138
+ }
139
+ }
140
+ catch (e) {
141
+ FormErrorHandler.handle(e, `ValidationApplicator: validator for ${fieldPath}`, ErrorStrategy.LOG);
142
+ }
143
+ }
144
+ // Установка ошибок на поле
145
+ if (errors.length > 0) {
146
+ control.setErrors(errors);
147
+ }
148
+ else {
149
+ // Очистить ошибки, если они были contextual
150
+ if (control.errors.value.length > 0 &&
151
+ !control.errors.value.some((e) => e.code !== 'contextual')) {
152
+ control.clearErrors();
153
+ }
154
+ }
155
+ }
156
+ }
157
+ /**
158
+ * Применение tree валидаторов (кросс-полевая валидация)
159
+ *
160
+ * Tree валидаторы имеют доступ ко всей форме через TreeValidationContext.
161
+ * Ошибки устанавливаются на targetField (если указано).
162
+ *
163
+ * @param treeValidators Список tree валидаторов
164
+ */
165
+ applyTreeValidators(treeValidators) {
166
+ for (const registration of treeValidators) {
167
+ const context = new TreeValidationContextImpl(this.form);
168
+ // Проверка условия (condition)
169
+ if (registration.condition) {
170
+ const shouldApply = this.checkCondition(registration.condition);
171
+ if (!shouldApply) {
172
+ continue;
173
+ }
174
+ }
175
+ // Выполнение tree валидатора
176
+ try {
177
+ // Tree валидаторы должны использовать TreeValidatorFn
178
+ if (registration.type !== 'tree') {
179
+ continue;
180
+ }
181
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
+ const error = registration.validator(context);
183
+ if (error && registration.options && 'targetField' in registration.options) {
184
+ const targetField = registration.options.targetField;
185
+ if (targetField) {
186
+ const targetControl = this.form.getFieldByPath(String(targetField));
187
+ if (targetControl && isFieldNode(targetControl)) {
188
+ const existingErrors = targetControl.errors.value;
189
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
+ targetControl.setErrors([...existingErrors, error]);
191
+ }
192
+ }
193
+ }
194
+ }
195
+ catch (e) {
196
+ FormErrorHandler.handle(e, 'ValidationApplicator: tree validator', ErrorStrategy.LOG);
197
+ }
198
+ }
199
+ }
200
+ /**
201
+ * Проверка условия (condition) для валидатора
202
+ *
203
+ * Условие определяет, должен ли валидатор выполняться.
204
+ * Использует getFieldByPath для поддержки вложенных путей.
205
+ *
206
+ * @param condition Условие валидатора
207
+ * @returns true, если условие выполнено
208
+ */
209
+ checkCondition(condition) {
210
+ const conditionField = this.form.getFieldByPath(condition.fieldPath);
211
+ if (!conditionField) {
212
+ return false;
213
+ }
214
+ const conditionValue = conditionField.value.value;
215
+ return condition.conditionFn(conditionValue);
216
+ }
217
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Реализация контекста валидации
3
+ */
4
+ import type { GroupNode } from '../nodes/group-node';
5
+ import type { FieldNode } from '../nodes/field-node';
6
+ import type { GroupNodeWithControls } from '../types/group-node-proxy';
7
+ import type { FormContext } from '../types/form-context';
8
+ /**
9
+ * Реализация контекста валидации для отдельного поля
10
+ * Реализует FormContext
11
+ */
12
+ export declare class ValidationContextImpl<TForm, TField> implements FormContext<TForm> {
13
+ private _form;
14
+ private control;
15
+ /**
16
+ * Форма с типизированным Proxy-доступом к полям
17
+ */
18
+ readonly form: GroupNodeWithControls<TForm>;
19
+ constructor(form: GroupNode<TForm>, _fieldKey: keyof TForm, control: FieldNode<TField>);
20
+ /**
21
+ * Получить текущее значение поля (внутренний метод для validation-applicator)
22
+ * @internal
23
+ */
24
+ value(): TField;
25
+ /**
26
+ * Безопасно установить значение поля по строковому пути
27
+ * Автоматически использует emitEvent: false для предотвращения циклов
28
+ */
29
+ setFieldValue(path: string, value: unknown): void;
30
+ }
31
+ /**
32
+ * Реализация контекста для cross-field валидации
33
+ * Реализует FormContext
34
+ */
35
+ export declare class TreeValidationContextImpl<TForm> implements FormContext<TForm> {
36
+ private _form;
37
+ /**
38
+ * Форма с типизированным Proxy-доступом к полям
39
+ */
40
+ readonly form: GroupNodeWithControls<TForm>;
41
+ constructor(form: GroupNode<TForm>);
42
+ /**
43
+ * Безопасно установить значение поля по строковому пути
44
+ * Автоматически использует emitEvent: false для предотвращения циклов
45
+ */
46
+ setFieldValue(path: string, value: unknown): void;
47
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Реализация контекста валидации
3
+ */
4
+ import { isFormNode } from '../utils/type-guards';
5
+ // ============================================================================
6
+ // Field Validation Context (для обычных валидаторов)
7
+ // ============================================================================
8
+ /**
9
+ * Реализация контекста валидации для отдельного поля
10
+ * Реализует FormContext
11
+ */
12
+ export class ValidationContextImpl {
13
+ _form;
14
+ control;
15
+ /**
16
+ * Форма с типизированным Proxy-доступом к полям
17
+ */
18
+ form;
19
+ constructor(form, _fieldKey, control) {
20
+ this._form = form;
21
+ this.control = control;
22
+ // Получаем Proxy для типизированного доступа
23
+ this.form = (form
24
+ ._proxyInstance || form.getProxy());
25
+ }
26
+ /**
27
+ * Получить текущее значение поля (внутренний метод для validation-applicator)
28
+ * @internal
29
+ */
30
+ value() {
31
+ return this.control.value.value;
32
+ }
33
+ /**
34
+ * Безопасно установить значение поля по строковому пути
35
+ * Автоматически использует emitEvent: false для предотвращения циклов
36
+ */
37
+ setFieldValue(path, value) {
38
+ const node = this._form.getFieldByPath(path);
39
+ if (node && isFormNode(node)) {
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ node.setValue(value, { emitEvent: false });
42
+ }
43
+ }
44
+ }
45
+ // ============================================================================
46
+ // Tree Validation Context (для cross-field валидаторов)
47
+ // ============================================================================
48
+ /**
49
+ * Реализация контекста для cross-field валидации
50
+ * Реализует FormContext
51
+ */
52
+ export class TreeValidationContextImpl {
53
+ _form;
54
+ /**
55
+ * Форма с типизированным Proxy-доступом к полям
56
+ */
57
+ form;
58
+ constructor(form) {
59
+ this._form = form;
60
+ // Получаем Proxy для типизированного доступа
61
+ this.form = (form
62
+ ._proxyInstance || form.getProxy());
63
+ }
64
+ /**
65
+ * Безопасно установить значение поля по строковому пути
66
+ * Автоматически использует emitEvent: false для предотвращения циклов
67
+ */
68
+ setFieldValue(path, value) {
69
+ const node = this._form.getFieldByPath(path);
70
+ if (node && isFormNode(node)) {
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ node.setValue(value, { emitEvent: false });
73
+ }
74
+ }
75
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * ValidationRegistry - система регистрации и применения валидаторов
3
+ *
4
+ * Работает как стек контекстов:
5
+ * 1. При вызове validation schema функции создается новый контекст
6
+ * 2. Все вызовы validate(), applyWhen() и т.д. регистрируют валидаторы в текущем контексте
7
+ * 3. После завершения схемы валидаторы применяются к GroupNode
8
+ */
9
+ import type { GroupNode } from '../nodes/group-node';
10
+ import { FormFields } from '../types';
11
+ import type { ValidatorRegistration, ContextualValidatorFn, ContextualAsyncValidatorFn, TreeValidatorFn, ConditionFn, ValidateOptions, ValidateAsyncOptions, ValidateTreeOptions } from '../types/validation-schema';
12
+ /**
13
+ * Контекст регистрации валидаторов
14
+ */
15
+ declare class RegistrationContext {
16
+ private validators;
17
+ private conditionStack;
18
+ /**
19
+ * Добавить валидатор в контекст
20
+ */
21
+ addValidator(registration: ValidatorRegistration): void;
22
+ /**
23
+ * Войти в условный блок
24
+ */
25
+ enterCondition(fieldPath: string, conditionFn: ConditionFn<unknown>): void;
26
+ /**
27
+ * Выйти из условного блока
28
+ */
29
+ exitCondition(): void;
30
+ /**
31
+ * Получить все зарегистрированные валидаторы
32
+ */
33
+ getValidators(): ValidatorRegistration[];
34
+ }
35
+ /**
36
+ * Реестр валидаторов для формы
37
+ *
38
+ * Каждый экземпляр GroupNode создает собственный реестр (композиция).
39
+ * Устраняет race conditions и изолирует формы друг от друга.
40
+ *
41
+ * Context stack используется для tracking текущего активного реестра:
42
+ * - beginRegistration() помещает this в global stack
43
+ * - endRegistration() извлекает из global stack
44
+ * - getCurrent() возвращает текущий активный реестр
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * class GroupNode {
49
+ * private readonly validationRegistry = new ValidationRegistry();
50
+ *
51
+ * applyValidationSchema(schemaFn) {
52
+ * this.validationRegistry.beginRegistration(); // Pushes this to global stack
53
+ * schemaFn(createFieldPath(this)); // Uses getCurrent()
54
+ * this.validationRegistry.endRegistration(this); // Pops from global stack
55
+ * }
56
+ * }
57
+ * ```
58
+ */
59
+ export declare class ValidationRegistry {
60
+ /**
61
+ * Global stack активных реестров
62
+ * Используется для изоляции форм друг от друга
63
+ */
64
+ private static registryStack;
65
+ private contextStack;
66
+ private validators;
67
+ /**
68
+ * Получить текущий активный реестр из global stack
69
+ *
70
+ * @returns Текущий активный реестр или null
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // В schema-validators.ts
75
+ * export function required(...) {
76
+ * const registry = ValidationRegistry.getCurrent();
77
+ * if (registry) {
78
+ * registry.registerSync(...);
79
+ * }
80
+ * }
81
+ * ```
82
+ */
83
+ static getCurrent(): ValidationRegistry | null;
84
+ /**
85
+ * Начать регистрацию валидаторов для формы
86
+ *
87
+ * Помещает this в global stack для изоляции форм
88
+ */
89
+ beginRegistration(): RegistrationContext;
90
+ /**
91
+ * Завершить регистрацию и применить валидаторы к GroupNode
92
+ *
93
+ * Извлекает this из global stack
94
+ *
95
+ * Сохраняет валидаторы в локальном состоянии (this.validators) вместо глобального WeakMap.
96
+ */
97
+ endRegistration<T extends FormFields>(form: GroupNode<T>): void;
98
+ /**
99
+ * Отменить регистрацию без применения валидаторов
100
+ * Используется для временной валидации (например, в validateForm)
101
+ *
102
+ * Извлекает this из global stack
103
+ */
104
+ cancelRegistration(): void;
105
+ /**
106
+ * Получить текущий контекст регистрации
107
+ */
108
+ getCurrentContext(): RegistrationContext | undefined;
109
+ /**
110
+ * Зарегистрировать синхронный валидатор
111
+ */
112
+ registerSync<TForm = unknown, TField = unknown>(fieldPath: string, validator: ContextualValidatorFn<TForm, TField>, options?: ValidateOptions): void;
113
+ /**
114
+ * Зарегистрировать асинхронный валидатор
115
+ */
116
+ registerAsync<TForm = unknown, TField = unknown>(fieldPath: string, validator: ContextualAsyncValidatorFn<TForm, TField>, options?: ValidateAsyncOptions): void;
117
+ /**
118
+ * Зарегистрировать tree валидатор
119
+ */
120
+ registerTree<TForm = unknown>(validator: TreeValidatorFn<TForm>, options?: ValidateTreeOptions): void;
121
+ /**
122
+ * Войти в условный блок
123
+ */
124
+ enterCondition(fieldPath: string, conditionFn: ConditionFn<unknown>): void;
125
+ /**
126
+ * Выйти из условного блока
127
+ */
128
+ exitCondition(): void;
129
+ /**
130
+ * Зарегистрировать validation schema для элементов массива
131
+ *
132
+ * Используется функцией validateItems() для регистрации схемы валидации,
133
+ * которая будет применяться к каждому элементу ArrayNode.
134
+ *
135
+ * @param fieldPath - Путь к ArrayNode полю
136
+ * @param itemSchemaFn - Validation schema для элемента массива
137
+ */
138
+ registerArrayItemValidation(fieldPath: string, itemSchemaFn: unknown): void;
139
+ /**
140
+ * Получить зарегистрированные валидаторы для этого реестра
141
+ *
142
+ * Возвращает локальный массив валидаторов (без аргумента form).
143
+ */
144
+ getValidators(): ValidatorRegistration[];
145
+ /**
146
+ * Применить зарегистрированные валидаторы к GroupNode
147
+ * @private
148
+ */
149
+ private applyValidators;
150
+ /**
151
+ * Применить array-items validators к ArrayNode элементам
152
+ * @private
153
+ */
154
+ private applyArrayItemValidators;
155
+ }
156
+ export {};