@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.
- package/dist/behaviors-DzYL8kY_.js +499 -0
- package/dist/behaviors.d.ts +6 -2
- package/dist/behaviors.js +19 -227
- package/dist/core/behavior/behavior-context.d.ts +6 -2
- package/dist/core/behavior/create-field-path.d.ts +3 -16
- package/dist/core/nodes/group-node.d.ts +14 -193
- package/dist/core/types/form-context.d.ts +10 -4
- package/dist/core/utils/field-path.d.ts +48 -0
- package/dist/core/utils/index.d.ts +1 -0
- package/dist/core/validation/core/validate-tree.d.ts +10 -4
- package/dist/core/validation/field-path.d.ts +3 -39
- package/dist/core/validation/validation-context.d.ts +23 -0
- package/dist/hooks/types.d.ts +328 -0
- package/dist/hooks/useFormControl.d.ts +13 -37
- package/dist/hooks/useFormControlValue.d.ts +167 -0
- package/dist/hooks/useSignalSubscription.d.ts +17 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +2886 -8
- package/dist/{create-field-path-CdPF3lIK.js → registry-helpers-BRxAr6nG.js} +133 -347
- package/dist/validators-gXoHPdqM.js +418 -0
- package/dist/validators.d.ts +6 -2
- package/dist/validators.js +29 -296
- package/llms.txt +1283 -22
- package/package.json +8 -4
- package/dist/core/behavior/behavior-applicator.d.ts +0 -71
- package/dist/core/behavior/behavior-applicator.js +0 -92
- package/dist/core/behavior/behavior-context.js +0 -38
- package/dist/core/behavior/behavior-registry.js +0 -198
- package/dist/core/behavior/behaviors/compute-from.js +0 -84
- package/dist/core/behavior/behaviors/copy-from.js +0 -64
- package/dist/core/behavior/behaviors/enable-when.js +0 -81
- package/dist/core/behavior/behaviors/index.js +0 -11
- package/dist/core/behavior/behaviors/reset-when.js +0 -63
- package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
- package/dist/core/behavior/behaviors/sync-fields.js +0 -66
- package/dist/core/behavior/behaviors/transform-value.js +0 -110
- package/dist/core/behavior/behaviors/watch-field.js +0 -56
- package/dist/core/behavior/compose-behavior.js +0 -166
- package/dist/core/behavior/create-field-path.js +0 -69
- package/dist/core/behavior/index.js +0 -17
- package/dist/core/behavior/types.js +0 -7
- package/dist/core/context/form-context-impl.js +0 -37
- package/dist/core/factories/index.js +0 -6
- package/dist/core/factories/node-factory.js +0 -281
- package/dist/core/nodes/array-node.js +0 -534
- package/dist/core/nodes/field-node.js +0 -510
- package/dist/core/nodes/form-node.js +0 -343
- package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
- package/dist/core/nodes/group-node/field-registry.js +0 -215
- package/dist/core/nodes/group-node/index.d.ts +0 -11
- package/dist/core/nodes/group-node/index.js +0 -11
- package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
- package/dist/core/nodes/group-node/proxy-builder.js +0 -161
- package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
- package/dist/core/nodes/group-node/state-manager.js +0 -265
- package/dist/core/nodes/group-node.js +0 -770
- package/dist/core/types/deep-schema.js +0 -11
- package/dist/core/types/field-path.js +0 -4
- package/dist/core/types/form-context.js +0 -25
- package/dist/core/types/group-node-proxy.js +0 -31
- package/dist/core/types/index.js +0 -4
- package/dist/core/types/validation-schema.js +0 -10
- package/dist/core/utils/create-form.js +0 -24
- package/dist/core/utils/debounce.js +0 -197
- package/dist/core/utils/error-handler.js +0 -226
- package/dist/core/utils/field-path-navigator.js +0 -374
- package/dist/core/utils/index.js +0 -14
- package/dist/core/utils/registry-helpers.js +0 -79
- package/dist/core/utils/registry-stack.js +0 -86
- package/dist/core/utils/resources.js +0 -69
- package/dist/core/utils/subscription-manager.js +0 -214
- package/dist/core/utils/type-guards.js +0 -169
- package/dist/core/validation/core/apply-when.js +0 -41
- package/dist/core/validation/core/apply.js +0 -38
- package/dist/core/validation/core/index.js +0 -8
- package/dist/core/validation/core/validate-async.js +0 -45
- package/dist/core/validation/core/validate-tree.js +0 -37
- package/dist/core/validation/core/validate.js +0 -38
- package/dist/core/validation/field-path.js +0 -147
- package/dist/core/validation/index.js +0 -33
- package/dist/core/validation/validate-form.js +0 -152
- package/dist/core/validation/validation-applicator.js +0 -217
- package/dist/core/validation/validation-context.js +0 -75
- package/dist/core/validation/validation-registry.js +0 -298
- package/dist/core/validation/validators/array-validators.js +0 -86
- package/dist/core/validation/validators/date.js +0 -117
- package/dist/core/validation/validators/email.js +0 -60
- package/dist/core/validation/validators/index.js +0 -14
- package/dist/core/validation/validators/max-length.js +0 -60
- package/dist/core/validation/validators/max.js +0 -60
- package/dist/core/validation/validators/min-length.js +0 -60
- package/dist/core/validation/validators/min.js +0 -60
- package/dist/core/validation/validators/number.js +0 -90
- package/dist/core/validation/validators/pattern.js +0 -62
- package/dist/core/validation/validators/phone.js +0 -58
- package/dist/core/validation/validators/required.js +0 -69
- package/dist/core/validation/validators/url.js +0 -55
- package/dist/hooks/useFormControl.js +0 -298
- package/dist/node-factory-D7DOnSSN.js +0 -3200
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FormNode - абстрактный базовый класс для всех узлов формы
|
|
3
|
-
*
|
|
4
|
-
* Аналог AbstractControl из Angular Forms
|
|
5
|
-
* Унифицирует работу с полями (FieldNode), группами (GroupNode) и массивами (ArrayNode)
|
|
6
|
-
*
|
|
7
|
-
* Использует Template Method паттерн для управления состоянием:
|
|
8
|
-
* - Публичные методы (markAsTouched, disable и т.д.) реализованы в базовом классе
|
|
9
|
-
* - Protected hooks (onMarkAsTouched, onDisable и т.д.) переопределяются в наследниках
|
|
10
|
-
*
|
|
11
|
-
* @group Nodes
|
|
12
|
-
*/
|
|
13
|
-
import { signal, computed } from '@preact/signals-core';
|
|
14
|
-
/**
|
|
15
|
-
* Абстрактный базовый класс для всех узлов формы
|
|
16
|
-
*
|
|
17
|
-
* Все узлы (поля, группы, массивы) наследуют от этого класса
|
|
18
|
-
* и реализуют единый интерфейс для работы с состоянием и валидацией
|
|
19
|
-
*
|
|
20
|
-
* Template Method паттерн используется для управления состоянием:
|
|
21
|
-
* - Общие signals (_touched, _dirty, _status) определены в базовом классе
|
|
22
|
-
* - Публичные методы (markAsTouched, disable и т.д.) реализованы здесь
|
|
23
|
-
* - Protected hooks (onMarkAsTouched, onDisable и т.д.) переопределяются в наследниках
|
|
24
|
-
*
|
|
25
|
-
* @group Nodes
|
|
26
|
-
*/
|
|
27
|
-
export class FormNode {
|
|
28
|
-
// ============================================================================
|
|
29
|
-
// Protected состояние (для Template Method паттерна)
|
|
30
|
-
// ============================================================================
|
|
31
|
-
/**
|
|
32
|
-
* Пользователь взаимодействовал с узлом (touched)
|
|
33
|
-
* Protected: наследники могут читать/изменять через методы
|
|
34
|
-
*/
|
|
35
|
-
_touched = signal(false);
|
|
36
|
-
/**
|
|
37
|
-
* Значение узла было изменено (dirty)
|
|
38
|
-
* Protected: наследники могут читать/изменять через методы
|
|
39
|
-
*/
|
|
40
|
-
_dirty = signal(false);
|
|
41
|
-
/**
|
|
42
|
-
* Текущий статус узла
|
|
43
|
-
* Protected: наследники могут читать/изменять через методы
|
|
44
|
-
*/
|
|
45
|
-
_status = signal('valid');
|
|
46
|
-
// ============================================================================
|
|
47
|
-
// Публичные computed signals (readonly для внешнего мира)
|
|
48
|
-
// ============================================================================
|
|
49
|
-
/**
|
|
50
|
-
* Пользователь взаимодействовал с узлом (touched)
|
|
51
|
-
* Computed из _touched для предоставления readonly интерфейса
|
|
52
|
-
*/
|
|
53
|
-
touched = computed(() => this._touched.value);
|
|
54
|
-
/**
|
|
55
|
-
* Пользователь не взаимодействовал с узлом (untouched)
|
|
56
|
-
*/
|
|
57
|
-
untouched = computed(() => !this._touched.value);
|
|
58
|
-
/**
|
|
59
|
-
* Значение узла было изменено (dirty)
|
|
60
|
-
* Computed из _dirty для предоставления readonly интерфейса
|
|
61
|
-
*/
|
|
62
|
-
dirty = computed(() => this._dirty.value);
|
|
63
|
-
/**
|
|
64
|
-
* Значение узла не было изменено (pristine)
|
|
65
|
-
*/
|
|
66
|
-
pristine = computed(() => !this._dirty.value);
|
|
67
|
-
/**
|
|
68
|
-
* Текущий статус узла
|
|
69
|
-
* Computed из _status для предоставления readonly интерфейса
|
|
70
|
-
*/
|
|
71
|
-
status = computed(() => this._status.value);
|
|
72
|
-
/**
|
|
73
|
-
* Узел отключен (disabled)
|
|
74
|
-
*/
|
|
75
|
-
disabled = computed(() => this._status.value === 'disabled');
|
|
76
|
-
/**
|
|
77
|
-
* Узел включен (enabled)
|
|
78
|
-
*/
|
|
79
|
-
enabled = computed(() => this._status.value !== 'disabled');
|
|
80
|
-
/**
|
|
81
|
-
* Получить ошибки валидации с фильтрацией
|
|
82
|
-
*
|
|
83
|
-
* Позволяет фильтровать ошибки по различным критериям:
|
|
84
|
-
* - По коду ошибки
|
|
85
|
-
* - По сообщению (частичное совпадение)
|
|
86
|
-
* - По параметрам
|
|
87
|
-
* - Через кастомный предикат
|
|
88
|
-
*
|
|
89
|
-
* Без параметров возвращает все ошибки (эквивалент errors.value)
|
|
90
|
-
*
|
|
91
|
-
* @param options - Опции фильтрации ошибок
|
|
92
|
-
* @returns Отфильтрованный массив ошибок валидации
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```typescript
|
|
96
|
-
* // Все ошибки
|
|
97
|
-
* const allErrors = form.getErrors();
|
|
98
|
-
*
|
|
99
|
-
* // Ошибки с конкретным кодом
|
|
100
|
-
* const requiredErrors = form.getErrors({ code: 'required' });
|
|
101
|
-
*
|
|
102
|
-
* // Ошибки с несколькими кодами
|
|
103
|
-
* const errors = form.getErrors({ code: ['required', 'email'] });
|
|
104
|
-
*
|
|
105
|
-
* // Ошибки по сообщению
|
|
106
|
-
* const passwordErrors = form.getErrors({ message: 'Password' });
|
|
107
|
-
*
|
|
108
|
-
* // Ошибки по параметрам
|
|
109
|
-
* const minLengthErrors = form.getErrors({
|
|
110
|
-
* params: { minLength: 8 }
|
|
111
|
-
* });
|
|
112
|
-
*
|
|
113
|
-
* // Кастомная фильтрация
|
|
114
|
-
* const customErrors = form.getErrors({
|
|
115
|
-
* predicate: (err) => err.code.startsWith('custom_')
|
|
116
|
-
* });
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
getErrors(options) {
|
|
120
|
-
const allErrors = this.errors.value;
|
|
121
|
-
// Без фильтрации - вернуть все ошибки
|
|
122
|
-
if (!options) {
|
|
123
|
-
return allErrors;
|
|
124
|
-
}
|
|
125
|
-
return allErrors.filter((error) => {
|
|
126
|
-
// Фильтр по коду
|
|
127
|
-
if (options.code !== undefined) {
|
|
128
|
-
const codes = Array.isArray(options.code) ? options.code : [options.code];
|
|
129
|
-
if (!codes.includes(error.code)) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
// Фильтр по сообщению (частичное совпадение, регистронезависимый)
|
|
134
|
-
if (options.message !== undefined) {
|
|
135
|
-
if (!error.message.toLowerCase().includes(options.message.toLowerCase())) {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Фильтр по параметрам
|
|
140
|
-
if (options.params !== undefined) {
|
|
141
|
-
if (!error.params) {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
// Проверяем, что все ключи из options.params присутствуют в error.params
|
|
145
|
-
// и имеют те же значения
|
|
146
|
-
for (const [key, value] of Object.entries(options.params)) {
|
|
147
|
-
if (error.params[key] !== value) {
|
|
148
|
-
return false;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
// Кастомный предикат
|
|
153
|
-
if (options.predicate !== undefined) {
|
|
154
|
-
if (!options.predicate(error)) {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return true;
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
// ============================================================================
|
|
162
|
-
// Методы управления состоянием (Template Method)
|
|
163
|
-
// ============================================================================
|
|
164
|
-
/**
|
|
165
|
-
* Отметить узел как touched (пользователь взаимодействовал)
|
|
166
|
-
*
|
|
167
|
-
* Template Method: обновляет signal в базовом классе,
|
|
168
|
-
* вызывает hook для кастомной логики в наследниках
|
|
169
|
-
*/
|
|
170
|
-
markAsTouched() {
|
|
171
|
-
this._touched.value = true;
|
|
172
|
-
this.onMarkAsTouched();
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Отметить узел как untouched
|
|
176
|
-
*
|
|
177
|
-
* Template Method: обновляет signal в базовом классе,
|
|
178
|
-
* вызывает hook для кастомной логики в наследниках
|
|
179
|
-
*/
|
|
180
|
-
markAsUntouched() {
|
|
181
|
-
this._touched.value = false;
|
|
182
|
-
this.onMarkAsUntouched();
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Отметить узел как dirty (значение изменено)
|
|
186
|
-
*
|
|
187
|
-
* Template Method: обновляет signal в базовом классе,
|
|
188
|
-
* вызывает hook для кастомной логики в наследниках
|
|
189
|
-
*/
|
|
190
|
-
markAsDirty() {
|
|
191
|
-
this._dirty.value = true;
|
|
192
|
-
this.onMarkAsDirty();
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Отметить узел как pristine (значение не изменено)
|
|
196
|
-
*
|
|
197
|
-
* Template Method: обновляет signal в базовом классе,
|
|
198
|
-
* вызывает hook для кастомной логики в наследниках
|
|
199
|
-
*/
|
|
200
|
-
markAsPristine() {
|
|
201
|
-
this._dirty.value = false;
|
|
202
|
-
this.onMarkAsPristine();
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Пометить все поля (включая вложенные) как touched
|
|
206
|
-
* Алиас для markAsTouched(), но более явно показывает намерение
|
|
207
|
-
* пометить ВСЕ поля рекурсивно
|
|
208
|
-
*
|
|
209
|
-
* Полезно для:
|
|
210
|
-
* - Показа всех ошибок валидации перед submit
|
|
211
|
-
* - Принудительного отображения ошибок при нажатии "Validate All"
|
|
212
|
-
* - Отображения невалидных полей в wizard/step form
|
|
213
|
-
*
|
|
214
|
-
* @example
|
|
215
|
-
* ```typescript
|
|
216
|
-
* // Показать все ошибки перед submit
|
|
217
|
-
* form.touchAll();
|
|
218
|
-
* const isValid = await form.validate();
|
|
219
|
-
* if (!isValid) {
|
|
220
|
-
* // Все ошибки теперь видны пользователю
|
|
221
|
-
* }
|
|
222
|
-
*
|
|
223
|
-
* // Или использовать submit() который уже вызывает touchAll
|
|
224
|
-
* await form.submit(async (values) => {
|
|
225
|
-
* await api.save(values);
|
|
226
|
-
* });
|
|
227
|
-
* ```
|
|
228
|
-
*/
|
|
229
|
-
touchAll() {
|
|
230
|
-
this.markAsTouched();
|
|
231
|
-
}
|
|
232
|
-
// ============================================================================
|
|
233
|
-
// Методы управления доступностью (Template Method)
|
|
234
|
-
// ============================================================================
|
|
235
|
-
/**
|
|
236
|
-
* Отключить узел
|
|
237
|
-
*
|
|
238
|
-
* Template Method: обновляет статус в базовом классе,
|
|
239
|
-
* вызывает hook для кастомной логики в наследниках
|
|
240
|
-
*
|
|
241
|
-
* Отключенные узлы не проходят валидацию и не включаются в getValue()
|
|
242
|
-
*/
|
|
243
|
-
disable() {
|
|
244
|
-
this._status.value = 'disabled';
|
|
245
|
-
this.onDisable();
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Включить узел
|
|
249
|
-
*
|
|
250
|
-
* Template Method: обновляет статус в базовом классе,
|
|
251
|
-
* вызывает hook для кастомной логики в наследниках
|
|
252
|
-
*/
|
|
253
|
-
enable() {
|
|
254
|
-
this._status.value = 'valid';
|
|
255
|
-
this.onEnable();
|
|
256
|
-
}
|
|
257
|
-
// ============================================================================
|
|
258
|
-
// Protected hooks (для переопределения в наследниках)
|
|
259
|
-
// ============================================================================
|
|
260
|
-
/**
|
|
261
|
-
* Hook: вызывается после markAsTouched()
|
|
262
|
-
*
|
|
263
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
264
|
-
* - GroupNode: пометить все дочерние узлы как touched
|
|
265
|
-
* - ArrayNode: пометить все элементы массива как touched
|
|
266
|
-
* - FieldNode: пустая реализация (нет дочерних узлов)
|
|
267
|
-
*
|
|
268
|
-
* @example
|
|
269
|
-
* ```typescript
|
|
270
|
-
* // GroupNode
|
|
271
|
-
* protected onMarkAsTouched(): void {
|
|
272
|
-
* this.fields.forEach(field => field.markAsTouched());
|
|
273
|
-
* }
|
|
274
|
-
* ```
|
|
275
|
-
*/
|
|
276
|
-
onMarkAsTouched() {
|
|
277
|
-
// Пустая реализация по умолчанию
|
|
278
|
-
// Наследники переопределяют при необходимости
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Hook: вызывается после markAsUntouched()
|
|
282
|
-
*
|
|
283
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
284
|
-
* - GroupNode: пометить все дочерние узлы как untouched
|
|
285
|
-
* - ArrayNode: пометить все элементы массива как untouched
|
|
286
|
-
* - FieldNode: пустая реализация (нет дочерних узлов)
|
|
287
|
-
*/
|
|
288
|
-
onMarkAsUntouched() {
|
|
289
|
-
// Пустая реализация по умолчанию
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Hook: вызывается после markAsDirty()
|
|
293
|
-
*
|
|
294
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
295
|
-
* - GroupNode: может обновить родительскую форму
|
|
296
|
-
* - ArrayNode: может обновить родительскую форму
|
|
297
|
-
* - FieldNode: пустая реализация
|
|
298
|
-
*/
|
|
299
|
-
onMarkAsDirty() {
|
|
300
|
-
// Пустая реализация по умолчанию
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Hook: вызывается после markAsPristine()
|
|
304
|
-
*
|
|
305
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
306
|
-
* - GroupNode: пометить все дочерние узлы как pristine
|
|
307
|
-
* - ArrayNode: пометить все элементы массива как pristine
|
|
308
|
-
* - FieldNode: пустая реализация
|
|
309
|
-
*/
|
|
310
|
-
onMarkAsPristine() {
|
|
311
|
-
// Пустая реализация по умолчанию
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Hook: вызывается после disable()
|
|
315
|
-
*
|
|
316
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
317
|
-
* - GroupNode: отключить все дочерние узлы
|
|
318
|
-
* - ArrayNode: отключить все элементы массива
|
|
319
|
-
* - FieldNode: очистить ошибки валидации
|
|
320
|
-
*
|
|
321
|
-
* @example
|
|
322
|
-
* ```typescript
|
|
323
|
-
* // GroupNode
|
|
324
|
-
* protected onDisable(): void {
|
|
325
|
-
* this.fields.forEach(field => field.disable());
|
|
326
|
-
* }
|
|
327
|
-
* ```
|
|
328
|
-
*/
|
|
329
|
-
onDisable() {
|
|
330
|
-
// Пустая реализация по умолчанию
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Hook: вызывается после enable()
|
|
334
|
-
*
|
|
335
|
-
* Переопределите в наследниках для дополнительной логики:
|
|
336
|
-
* - GroupNode: включить все дочерние узлы
|
|
337
|
-
* - ArrayNode: включить все элементы массива
|
|
338
|
-
* - FieldNode: пустая реализация
|
|
339
|
-
*/
|
|
340
|
-
onEnable() {
|
|
341
|
-
// Пустая реализация по умолчанию
|
|
342
|
-
}
|
|
343
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FieldRegistry - управление полями в GroupNode
|
|
3
|
-
*
|
|
4
|
-
* Извлечено из GroupNode для соблюдения SRP (Single Responsibility Principle).
|
|
5
|
-
* Отвечает только за хранение и управление коллекцией полей формы.
|
|
6
|
-
*
|
|
7
|
-
* @template T Тип формы (объект)
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* const registry = new FieldRegistry<{ email: string; name: string }>();
|
|
12
|
-
* registry.set('email', emailField);
|
|
13
|
-
* registry.set('name', nameField);
|
|
14
|
-
*
|
|
15
|
-
* const emailField = registry.get('email');
|
|
16
|
-
* registry.forEach((field, key) => {
|
|
17
|
-
* console.log(key, field.value.value);
|
|
18
|
-
* });
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
import type { FormNode } from '../form-node';
|
|
22
|
-
import type { FormValue } from '../../types';
|
|
23
|
-
/**
|
|
24
|
-
* Реестр полей формы
|
|
25
|
-
*
|
|
26
|
-
* Предоставляет типобезопасный доступ к полям формы
|
|
27
|
-
* через Map-подобный интерфейс
|
|
28
|
-
*
|
|
29
|
-
* @template T Тип формы (объект)
|
|
30
|
-
*/
|
|
31
|
-
export declare class FieldRegistry<T> {
|
|
32
|
-
/**
|
|
33
|
-
* Внутреннее хранилище полей
|
|
34
|
-
* Map обеспечивает быструю lookup производительность O(1)
|
|
35
|
-
*/
|
|
36
|
-
private fields;
|
|
37
|
-
/**
|
|
38
|
-
* Установить поле в реестр
|
|
39
|
-
*
|
|
40
|
-
* @param key - Ключ поля (имя свойства в типе T)
|
|
41
|
-
* @param node - FormNode для этого поля
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```typescript
|
|
45
|
-
* registry.set('email', new FieldNode({ value: '' }));
|
|
46
|
-
* ```
|
|
47
|
-
*/
|
|
48
|
-
set<K extends keyof T>(key: K, node: FormNode<T[K]>): void;
|
|
49
|
-
/**
|
|
50
|
-
* Получить поле из реестра
|
|
51
|
-
*
|
|
52
|
-
* @param key - Ключ поля
|
|
53
|
-
* @returns FormNode или undefined, если поле не найдено
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const emailField = registry.get('email');
|
|
58
|
-
* if (emailField) {
|
|
59
|
-
* console.log(emailField.value.value);
|
|
60
|
-
* }
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
get<K extends keyof T>(key: K): FormNode<T[K]> | undefined;
|
|
64
|
-
/**
|
|
65
|
-
* Проверить наличие поля в реестре
|
|
66
|
-
*
|
|
67
|
-
* @param key - Ключ поля
|
|
68
|
-
* @returns true если поле существует
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```typescript
|
|
72
|
-
* if (registry.has('email')) {
|
|
73
|
-
* console.log('Email field exists');
|
|
74
|
-
* }
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
has(key: keyof T): boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Удалить поле из реестра
|
|
80
|
-
*
|
|
81
|
-
* @param key - Ключ поля
|
|
82
|
-
* @returns true если поле было удалено, false если поля не было
|
|
83
|
-
*
|
|
84
|
-
* @example
|
|
85
|
-
* ```typescript
|
|
86
|
-
* registry.delete('email');
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
delete(key: keyof T): boolean;
|
|
90
|
-
/**
|
|
91
|
-
* Перебрать все поля
|
|
92
|
-
*
|
|
93
|
-
* @param callback - Функция обратного вызова для каждого поля
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```typescript
|
|
97
|
-
* registry.forEach((field, key) => {
|
|
98
|
-
* console.log(`${key}: ${field.value.value}`);
|
|
99
|
-
* });
|
|
100
|
-
* ```
|
|
101
|
-
*/
|
|
102
|
-
forEach(callback: (field: FormNode<FormValue>, key: keyof T) => void): void;
|
|
103
|
-
/**
|
|
104
|
-
* Получить итератор значений (полей)
|
|
105
|
-
*
|
|
106
|
-
* @returns Итератор по всем полям
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```typescript
|
|
110
|
-
* for (const field of registry.values()) {
|
|
111
|
-
* await field.validate();
|
|
112
|
-
* }
|
|
113
|
-
* ```
|
|
114
|
-
*/
|
|
115
|
-
values(): IterableIterator<FormNode<FormValue>>;
|
|
116
|
-
/**
|
|
117
|
-
* Получить итератор пар [ключ, значение]
|
|
118
|
-
*
|
|
119
|
-
* @returns Итератор по всем записям
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```typescript
|
|
123
|
-
* for (const [key, field] of registry.entries()) {
|
|
124
|
-
* console.log(key, field.value.value);
|
|
125
|
-
* }
|
|
126
|
-
* ```
|
|
127
|
-
*/
|
|
128
|
-
entries(): IterableIterator<[keyof T, FormNode<FormValue>]>;
|
|
129
|
-
/**
|
|
130
|
-
* Получить итератор ключей полей
|
|
131
|
-
*
|
|
132
|
-
* @returns Итератор по всем ключам
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```typescript
|
|
136
|
-
* const fieldNames = Array.from(registry.keys());
|
|
137
|
-
* // ['email', 'name', 'age']
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
keys(): IterableIterator<keyof T>;
|
|
141
|
-
/**
|
|
142
|
-
* Получить количество полей
|
|
143
|
-
*
|
|
144
|
-
* @returns Количество зарегистрированных полей
|
|
145
|
-
*
|
|
146
|
-
* @example
|
|
147
|
-
* ```typescript
|
|
148
|
-
* console.log(`Form has ${registry.size()} fields`);
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
size(): number;
|
|
152
|
-
/**
|
|
153
|
-
* Очистить все поля
|
|
154
|
-
*
|
|
155
|
-
* Удаляет все поля из реестра
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```typescript
|
|
159
|
-
* registry.clear();
|
|
160
|
-
* console.log(registry.size()); // 0
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
clear(): void;
|
|
164
|
-
/**
|
|
165
|
-
* Получить все поля как массив
|
|
166
|
-
*
|
|
167
|
-
* Полезно для операций, требующих работу с массивом
|
|
168
|
-
*
|
|
169
|
-
* @returns Массив всех полей
|
|
170
|
-
*
|
|
171
|
-
* @example
|
|
172
|
-
* ```typescript
|
|
173
|
-
* const allValid = registry.toArray().every(field => field.valid.value);
|
|
174
|
-
* ```
|
|
175
|
-
*/
|
|
176
|
-
toArray(): FormNode<FormValue>[];
|
|
177
|
-
/**
|
|
178
|
-
* Получить Map-представление реестра (readonly)
|
|
179
|
-
*
|
|
180
|
-
* Используйте для совместимости с существующим кодом
|
|
181
|
-
*
|
|
182
|
-
* @returns ReadonlyMap с полями
|
|
183
|
-
* @internal
|
|
184
|
-
*
|
|
185
|
-
* @example
|
|
186
|
-
* ```typescript
|
|
187
|
-
* const mapView = registry.asMap();
|
|
188
|
-
* ```
|
|
189
|
-
*/
|
|
190
|
-
asMap(): ReadonlyMap<keyof T, FormNode<FormValue>>;
|
|
191
|
-
}
|