@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,226 @@
1
+ /**
2
+ * FormErrorHandler - централизованная обработка ошибок в формах
3
+ *
4
+ * Устраняет несогласованность обработки ошибок между:
5
+ * - field-node.ts (логирует и конвертирует в ValidationError)
6
+ * - behavior-applicator.ts (логирует и пробрасывает)
7
+ * - validation-applicator.ts (логирует и проглатывает)
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * try {
12
+ * await validator(value);
13
+ * } catch (error) {
14
+ * return FormErrorHandler.handle(error, 'AsyncValidator', ErrorStrategy.CONVERT);
15
+ * }
16
+ * ```
17
+ */
18
+ /**
19
+ * Стратегия обработки ошибок
20
+ *
21
+ * Определяет, что делать с ошибкой после логирования
22
+ */
23
+ export var ErrorStrategy;
24
+ (function (ErrorStrategy) {
25
+ /**
26
+ * Пробросить ошибку дальше (throw)
27
+ * Используется когда ошибка критична и должна остановить выполнение
28
+ */
29
+ ErrorStrategy["THROW"] = "throw";
30
+ /**
31
+ * Залогировать и проглотить ошибку (продолжить выполнение)
32
+ * Используется когда ошибка не критична
33
+ */
34
+ ErrorStrategy["LOG"] = "log";
35
+ /**
36
+ * Конвертировать ошибку в ValidationError
37
+ * Используется в async validators для отображения ошибки валидации пользователю
38
+ */
39
+ ErrorStrategy["CONVERT"] = "convert";
40
+ })(ErrorStrategy || (ErrorStrategy = {}));
41
+ /**
42
+ * Централизованный обработчик ошибок для форм
43
+ *
44
+ * Обеспечивает:
45
+ * - Единообразное логирование ошибок в DEV режиме
46
+ * - Гибкие стратегии обработки (throw/log/convert)
47
+ * - Типобезопасное извлечение сообщений из Error/string/unknown
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * // В async validator (конвертировать в ValidationError)
52
+ * try {
53
+ * await validateEmail(value);
54
+ * } catch (error) {
55
+ * return FormErrorHandler.handle(error, 'EmailValidator', ErrorStrategy.CONVERT);
56
+ * }
57
+ *
58
+ * // В behavior applicator (пробросить критичную ошибку)
59
+ * try {
60
+ * applyBehavior(schema);
61
+ * } catch (error) {
62
+ * FormErrorHandler.handle(error, 'BehaviorApplicator', ErrorStrategy.THROW);
63
+ * }
64
+ *
65
+ * // В validator (залогировать и продолжить)
66
+ * try {
67
+ * validator(value);
68
+ * } catch (error) {
69
+ * FormErrorHandler.handle(error, 'Validator', ErrorStrategy.LOG);
70
+ * }
71
+ * ```
72
+ */
73
+ export class FormErrorHandler {
74
+ /**
75
+ * Обработать ошибку согласно заданной стратегии
76
+ *
77
+ * @param error Ошибка для обработки (Error | string | unknown)
78
+ * @param context Контекст ошибки для логирования (например, 'AsyncValidator', 'BehaviorRegistry')
79
+ * @param strategy Стратегия обработки (THROW | LOG | CONVERT)
80
+ * @returns ValidationError если strategy = CONVERT, undefined если strategy = LOG, никогда не возвращается если strategy = THROW
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * // THROW - пробросить ошибку
85
+ * try {
86
+ * riskyOperation();
87
+ * } catch (error) {
88
+ * FormErrorHandler.handle(error, 'RiskyOperation', ErrorStrategy.THROW);
89
+ * // Этот код никогда не выполнится
90
+ * }
91
+ *
92
+ * // LOG - залогировать и продолжить
93
+ * try {
94
+ * nonCriticalOperation();
95
+ * } catch (error) {
96
+ * FormErrorHandler.handle(error, 'NonCritical', ErrorStrategy.LOG);
97
+ * // Продолжаем выполнение
98
+ * }
99
+ *
100
+ * // CONVERT - конвертировать в ValidationError
101
+ * try {
102
+ * await validator(value);
103
+ * } catch (error) {
104
+ * const validationError = FormErrorHandler.handle(
105
+ * error,
106
+ * 'AsyncValidator',
107
+ * ErrorStrategy.CONVERT
108
+ * );
109
+ * return validationError;
110
+ * }
111
+ * ```
112
+ */
113
+ static handle(error, context, strategy = ErrorStrategy.THROW) {
114
+ // Извлекаем сообщение из ошибки
115
+ const message = this.extractMessage(error);
116
+ // Логируем в DEV режиме
117
+ if (import.meta.env.DEV) {
118
+ console.error(`[${context}]`, error);
119
+ }
120
+ // Применяем стратегию
121
+ switch (strategy) {
122
+ case ErrorStrategy.THROW:
123
+ throw error;
124
+ case ErrorStrategy.LOG:
125
+ // Просто логируем, не возвращаем ничего
126
+ return;
127
+ case ErrorStrategy.CONVERT:
128
+ // Конвертируем в ValidationError
129
+ return {
130
+ code: 'validator_error',
131
+ message,
132
+ params: { field: context },
133
+ };
134
+ }
135
+ }
136
+ /**
137
+ * Извлечь сообщение из ошибки
138
+ *
139
+ * Обрабатывает различные типы ошибок:
140
+ * - Error объекты → error.message
141
+ * - Строки → возвращает как есть
142
+ * - Объекты с message → извлекает message
143
+ * - Другое → String(error)
144
+ *
145
+ * @param error Ошибка для извлечения сообщения
146
+ * @returns Сообщение ошибки
147
+ * @private
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * FormErrorHandler.extractMessage(new Error('Test'));
152
+ * // 'Test'
153
+ *
154
+ * FormErrorHandler.extractMessage('String error');
155
+ * // 'String error'
156
+ *
157
+ * FormErrorHandler.extractMessage({ message: 'Object error' });
158
+ * // 'Object error'
159
+ *
160
+ * FormErrorHandler.extractMessage(null);
161
+ * // 'null'
162
+ * ```
163
+ */
164
+ static extractMessage(error) {
165
+ if (error instanceof Error) {
166
+ return error.message;
167
+ }
168
+ if (typeof error === 'string') {
169
+ return error;
170
+ }
171
+ if (typeof error === 'object' && error !== null && 'message' in error) {
172
+ return String(error.message);
173
+ }
174
+ return String(error);
175
+ }
176
+ /**
177
+ * Создать ValidationError с заданными параметрами
178
+ *
179
+ * Утилитная функция для создания ValidationError объектов
180
+ *
181
+ * @param code Код ошибки
182
+ * @param message Сообщение ошибки
183
+ * @param field Поле (опционально)
184
+ * @returns ValidationError объект
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const error = FormErrorHandler.createValidationError(
189
+ * 'required',
190
+ * 'This field is required',
191
+ * 'email'
192
+ * );
193
+ * // { code: 'required', message: 'This field is required', field: 'email' }
194
+ * ```
195
+ */
196
+ static createValidationError(code, message, field) {
197
+ return {
198
+ code,
199
+ message,
200
+ params: field ? { field } : undefined,
201
+ };
202
+ }
203
+ /**
204
+ * Проверить, является ли объект ValidationError
205
+ *
206
+ * Type guard для ValidationError
207
+ *
208
+ * @param value Значение для проверки
209
+ * @returns true если value является ValidationError
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * if (FormErrorHandler.isValidationError(result)) {
214
+ * console.log(result.code); // OK, типобезопасно
215
+ * }
216
+ * ```
217
+ */
218
+ static isValidationError(value) {
219
+ return (typeof value === 'object' &&
220
+ value !== null &&
221
+ 'code' in value &&
222
+ 'message' in value &&
223
+ typeof value.code === 'string' &&
224
+ typeof value.message === 'string');
225
+ }
226
+ }
@@ -0,0 +1,240 @@
1
+ import type { UnknownRecord } from '../types';
2
+ /**
3
+ * Сегмент пути к полю формы
4
+ *
5
+ * Представляет один сегмент в пути к полю, например:
6
+ * - `"email" → { key: 'email' }`
7
+ * - `"items[0]" → { key: 'items', index: 0 }`
8
+ *
9
+ * @internal
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Путь "items[0].name" разбивается на:
14
+ * [
15
+ * { key: 'items', index: 0 },
16
+ * { key: 'name' }
17
+ * ]
18
+ * ```
19
+ */
20
+ export interface PathSegment {
21
+ /**
22
+ * Ключ поля
23
+ */
24
+ key: string;
25
+ /**
26
+ * Индекс в массиве (опционально)
27
+ * Присутствует только для сегментов вида "items[0]"
28
+ */
29
+ index?: number;
30
+ }
31
+ /**
32
+ * Навигация по путям к полям формы
33
+ *
34
+ * Централизует логику парсинга и навигации по путям к полям формы.
35
+ * Используется в ValidationContext, BehaviorContext, GroupNode для единообразной
36
+ * обработки путей вида "address.city" или "items[0].name".
37
+ *
38
+ * Устраняет дублирование логики парсинга путей в 4 местах кодовой базы.
39
+ *
40
+ * @internal
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const navigator = new FieldPathNavigator();
45
+ *
46
+ * // Парсинг пути
47
+ * const segments = navigator.parsePath('items[0].title');
48
+ * // [{ key: 'items', index: 0 }, { key: 'title' }]
49
+ *
50
+ * // Получение значения из объекта
51
+ * const obj = { items: [{ title: 'Item 1' }] };
52
+ * const value = navigator.getValueByPath(obj, 'items[0].title');
53
+ * // 'Item 1'
54
+ *
55
+ * // Получение узла формы
56
+ * const titleNode = navigator.getNodeByPath(form, 'items[0].title');
57
+ * titleNode?.setValue('New Title');
58
+ * ```
59
+ */
60
+ export declare class FieldPathNavigator {
61
+ /**
62
+ * Парсит путь в массив сегментов
63
+ *
64
+ * Поддерживаемые форматы:
65
+ * - Простые пути: "name", "email"
66
+ * - Вложенные пути: "address.city", "user.profile.avatar"
67
+ * - Массивы: "items[0]", "items[0].name", "tags[1][0]"
68
+ * - Комбинации: "orders[0].items[1].price"
69
+ *
70
+ * @param path Путь к полю (строка с точками и квадратными скобками)
71
+ * @returns Массив сегментов пути
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * navigator.parsePath('email');
76
+ * // [{ key: 'email' }]
77
+ *
78
+ * navigator.parsePath('address.city');
79
+ * // [{ key: 'address' }, { key: 'city' }]
80
+ *
81
+ * navigator.parsePath('items[0].name');
82
+ * // [{ key: 'items', index: 0 }, { key: 'name' }]
83
+ * ```
84
+ */
85
+ parsePath(path: string): PathSegment[];
86
+ /**
87
+ * Добавляет сегмент в массив, обрабатывая массивы
88
+ * @private
89
+ */
90
+ private addSegment;
91
+ /**
92
+ * Получает значение по пути из объекта
93
+ *
94
+ * Проходит по всем сегментам пути и возвращает конечное значение.
95
+ * Если путь не найден, возвращает undefined.
96
+ *
97
+ * @param obj Объект для навигации
98
+ * @param path Путь к значению
99
+ * @returns Значение или undefined, если путь не найден
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const obj = {
104
+ * email: 'test@mail.com',
105
+ * address: { city: 'Moscow' },
106
+ * items: [{ title: 'Item 1' }]
107
+ * };
108
+ *
109
+ * navigator.getValueByPath(obj, 'email');
110
+ * // 'test@mail.com'
111
+ *
112
+ * navigator.getValueByPath(obj, 'address.city');
113
+ * // 'Moscow'
114
+ *
115
+ * navigator.getValueByPath(obj, 'items[0].title');
116
+ * // 'Item 1'
117
+ *
118
+ * navigator.getValueByPath(obj, 'invalid.path');
119
+ * // undefined
120
+ * ```
121
+ */
122
+ getValueByPath(obj: UnknownRecord, path: string): unknown;
123
+ /**
124
+ * Устанавливает значение по пути в объекте (мутирует объект)
125
+ *
126
+ * Создает промежуточные объекты, если они не существуют.
127
+ * Выбрасывает ошибку, если ожидается массив, но его нет.
128
+ *
129
+ * @param obj Объект для модификации
130
+ * @param path Путь к значению
131
+ * @param value Новое значение
132
+ *
133
+ * @throws {Error} Если ожидается массив по пути, но его нет
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const obj = { address: { city: '' } };
138
+ * navigator.setValueByPath(obj, 'address.city', 'Moscow');
139
+ * // obj.address.city === 'Moscow'
140
+ *
141
+ * const obj2: UnknownRecord = {};
142
+ * navigator.setValueByPath(obj2, 'address.city', 'Moscow');
143
+ * // Создаст { address: { city: 'Moscow' } }
144
+ *
145
+ * const obj3 = { items: [{ title: 'Old' }] };
146
+ * navigator.setValueByPath(obj3, 'items[0].title', 'New');
147
+ * // obj3.items[0].title === 'New'
148
+ * ```
149
+ */
150
+ setValueByPath(obj: UnknownRecord, path: string, value: unknown): void;
151
+ /**
152
+ * Получить значение из FormNode по пути
153
+ *
154
+ * Автоматически извлекает значение из FormNode (через .value.value).
155
+ * Используется в ValidationContext и BehaviorContext для единообразного
156
+ * доступа к значениям полей формы.
157
+ *
158
+ * @param form Корневой узел формы (обычно GroupNode)
159
+ * @param path Путь к полю
160
+ * @returns Значение поля или undefined, если путь не найден
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * const form = new GroupNode({
165
+ * email: { value: 'test@mail.com', component: Input },
166
+ * address: {
167
+ * city: { value: 'Moscow', component: Input }
168
+ * },
169
+ * items: [{ title: { value: 'Item 1', component: Input } }]
170
+ * });
171
+ *
172
+ * navigator.getFormNodeValue(form, 'email');
173
+ * // 'test@mail.com'
174
+ *
175
+ * navigator.getFormNodeValue(form, 'address.city');
176
+ * // 'Moscow'
177
+ *
178
+ * navigator.getFormNodeValue(form, 'items[0].title');
179
+ * // 'Item 1'
180
+ *
181
+ * navigator.getFormNodeValue(form, 'invalid.path');
182
+ * // undefined
183
+ * ```
184
+ */
185
+ getFormNodeValue(form: unknown, path: string): unknown;
186
+ /**
187
+ * Type guard для проверки, является ли объект FormNode
188
+ *
189
+ * Проверяет наличие характерных свойств FormNode:
190
+ * - value (Signal)
191
+ * - value.value (значение Signal)
192
+ *
193
+ * @param obj Объект для проверки
194
+ * @returns true, если объект является FormNode
195
+ * @private
196
+ */
197
+ private isFormNode;
198
+ /**
199
+ * Получает узел формы по пути
200
+ *
201
+ * Навигирует по структуре FormNode (GroupNode/FieldNode/ArrayNode)
202
+ * и возвращает узел по указанному пути.
203
+ *
204
+ * Поддерживает:
205
+ * - Доступ к полям GroupNode через fields Map
206
+ * - Доступ к элементам ArrayNode через индекс
207
+ * - Proxy-доступ к полям (для обратной совместимости)
208
+ *
209
+ * @param form Корневой узел формы (обычно GroupNode)
210
+ * @param path Путь к узлу
211
+ * @returns Узел формы или null, если путь не найден
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * const form = new GroupNode({
216
+ * email: { value: '', component: Input },
217
+ * address: {
218
+ * city: { value: '', component: Input }
219
+ * },
220
+ * items: [{ title: { value: '', component: Input } }]
221
+ * });
222
+ *
223
+ * const emailNode = navigator.getNodeByPath(form, 'email');
224
+ * // FieldNode
225
+ *
226
+ * const cityNode = navigator.getNodeByPath(form, 'address.city');
227
+ * // FieldNode
228
+ *
229
+ * const itemNode = navigator.getNodeByPath(form, 'items[0]');
230
+ * // GroupNode
231
+ *
232
+ * const titleNode = navigator.getNodeByPath(form, 'items[0].title');
233
+ * // FieldNode
234
+ *
235
+ * const invalidNode = navigator.getNodeByPath(form, 'invalid.path');
236
+ * // null
237
+ * ```
238
+ */
239
+ getNodeByPath(form: unknown, path: string): unknown | null;
240
+ }