@reformer/core 1.0.0-beta.1

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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +143 -0
  3. package/dist/behaviors/compute-from.d.ts +2 -0
  4. package/dist/behaviors/compute-from.js +31 -0
  5. package/dist/behaviors/copy-from.d.ts +2 -0
  6. package/dist/behaviors/copy-from.js +29 -0
  7. package/dist/behaviors/enable-when.d.ts +2 -0
  8. package/dist/behaviors/enable-when.js +25 -0
  9. package/dist/behaviors/reset-when.d.ts +2 -0
  10. package/dist/behaviors/reset-when.js +24 -0
  11. package/dist/behaviors/revalidate-when.d.ts +2 -0
  12. package/dist/behaviors/revalidate-when.js +18 -0
  13. package/dist/behaviors/sync-fields.d.ts +2 -0
  14. package/dist/behaviors/sync-fields.js +41 -0
  15. package/dist/behaviors/transform-value.d.ts +2 -0
  16. package/dist/behaviors/transform-value.js +45 -0
  17. package/dist/behaviors/watch-field.d.ts +2 -0
  18. package/dist/behaviors/watch-field.js +21 -0
  19. package/dist/behaviors.d.ts +6 -0
  20. package/dist/behaviors.js +29 -0
  21. package/dist/core/behavior/behavior-context.d.ts +47 -0
  22. package/dist/core/behavior/behavior-registry.d.ts +85 -0
  23. package/dist/core/behavior/behaviors/compute-from.d.ts +70 -0
  24. package/dist/core/behavior/behaviors/copy-from.d.ts +56 -0
  25. package/dist/core/behavior/behaviors/enable-when.d.ts +118 -0
  26. package/dist/core/behavior/behaviors/index.d.ts +11 -0
  27. package/dist/core/behavior/behaviors/reset-when.d.ts +64 -0
  28. package/dist/core/behavior/behaviors/revalidate-when.d.ts +53 -0
  29. package/dist/core/behavior/behaviors/sync-fields.d.ts +48 -0
  30. package/dist/core/behavior/behaviors/transform-value.d.ts +192 -0
  31. package/dist/core/behavior/behaviors/watch-field.d.ts +80 -0
  32. package/dist/core/behavior/compose-behavior.d.ts +96 -0
  33. package/dist/core/behavior/index.d.ts +11 -0
  34. package/dist/core/behavior/types.d.ts +146 -0
  35. package/dist/core/factories/index.d.ts +6 -0
  36. package/dist/core/factories/node-factory.d.ts +186 -0
  37. package/dist/core/nodes/array-node.d.ts +328 -0
  38. package/dist/core/nodes/field-node.d.ts +294 -0
  39. package/dist/core/nodes/form-node.d.ts +340 -0
  40. package/dist/core/nodes/group-node.d.ts +319 -0
  41. package/dist/core/types/deep-schema.d.ts +68 -0
  42. package/dist/core/types/field-path.d.ts +42 -0
  43. package/dist/core/types/form-context.d.ts +89 -0
  44. package/dist/core/types/form-proxy.d.ts +105 -0
  45. package/dist/core/types/index.d.ts +209 -0
  46. package/dist/core/types/validation-schema.d.ts +95 -0
  47. package/dist/core/utils/abstract-registry.d.ts +74 -0
  48. package/dist/core/utils/aggregate-signals.d.ts +71 -0
  49. package/dist/core/utils/create-form.d.ts +44 -0
  50. package/dist/core/utils/error-handler.d.ts +163 -0
  51. package/dist/core/utils/field-path-navigator.d.ts +240 -0
  52. package/dist/core/utils/field-path.d.ts +60 -0
  53. package/dist/core/utils/form-observer.d.ts +176 -0
  54. package/dist/core/utils/form-proxy-builder.d.ts +25 -0
  55. package/dist/core/utils/form-submitter.d.ts +121 -0
  56. package/dist/core/utils/index.d.ts +22 -0
  57. package/dist/core/utils/registry-helpers.d.ts +43 -0
  58. package/dist/core/utils/registry-stack.d.ts +69 -0
  59. package/dist/core/utils/safe-effect.d.ts +73 -0
  60. package/dist/core/utils/status-machine.d.ts +153 -0
  61. package/dist/core/utils/subscription-manager.d.ts +180 -0
  62. package/dist/core/utils/type-guards.d.ts +98 -0
  63. package/dist/core/utils/unique-id.d.ts +53 -0
  64. package/dist/core/validation/core/apply-when.d.ts +22 -0
  65. package/dist/core/validation/core/apply.d.ts +52 -0
  66. package/dist/core/validation/core/index.d.ts +8 -0
  67. package/dist/core/validation/core/validate-async.d.ts +36 -0
  68. package/dist/core/validation/core/validate-tree.d.ts +35 -0
  69. package/dist/core/validation/core/validate.d.ts +26 -0
  70. package/dist/core/validation/index.d.ts +27 -0
  71. package/dist/core/validation/validate-form.d.ts +48 -0
  72. package/dist/core/validation/validation-applicator.d.ts +70 -0
  73. package/dist/core/validation/validation-context.d.ts +86 -0
  74. package/dist/core/validation/validation-registry.d.ts +142 -0
  75. package/dist/core/validation/validators/array-validators.d.ts +53 -0
  76. package/dist/core/validation/validators/date-utils.d.ts +26 -0
  77. package/dist/core/validation/validators/email.d.ts +37 -0
  78. package/dist/core/validation/validators/future-date.d.ts +35 -0
  79. package/dist/core/validation/validators/index.d.ts +20 -0
  80. package/dist/core/validation/validators/is-date.d.ts +36 -0
  81. package/dist/core/validation/validators/max-age.d.ts +36 -0
  82. package/dist/core/validation/validators/max-date.d.ts +36 -0
  83. package/dist/core/validation/validators/max-length.d.ts +38 -0
  84. package/dist/core/validation/validators/max.d.ts +38 -0
  85. package/dist/core/validation/validators/min-age.d.ts +36 -0
  86. package/dist/core/validation/validators/min-date.d.ts +36 -0
  87. package/dist/core/validation/validators/min-length.d.ts +38 -0
  88. package/dist/core/validation/validators/min.d.ts +38 -0
  89. package/dist/core/validation/validators/number.d.ts +31 -0
  90. package/dist/core/validation/validators/past-date.d.ts +35 -0
  91. package/dist/core/validation/validators/pattern.d.ts +40 -0
  92. package/dist/core/validation/validators/phone.d.ts +27 -0
  93. package/dist/core/validation/validators/required.d.ts +41 -0
  94. package/dist/core/validation/validators/url.d.ts +22 -0
  95. package/dist/date-utils-xUWFslTj.js +29 -0
  96. package/dist/field-path-DuKdGcIE.js +66 -0
  97. package/dist/hooks/types.d.ts +328 -0
  98. package/dist/hooks/useArrayLength.d.ts +31 -0
  99. package/dist/hooks/useFormControl.d.ts +24 -0
  100. package/dist/hooks/useFormControlValue.d.ts +167 -0
  101. package/dist/hooks/useHiddenCondition.d.ts +25 -0
  102. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  103. package/dist/index-D25LsbRm.js +73 -0
  104. package/dist/index.d.ts +17 -0
  105. package/dist/index.js +3271 -0
  106. package/dist/registry-helpers-Bv_BJ1s-.js +615 -0
  107. package/dist/safe-effect-Dh8uw81c.js +20 -0
  108. package/dist/validate-C3XiA_zf.js +10 -0
  109. package/dist/validators/email.d.ts +2 -0
  110. package/dist/validators/email.js +13 -0
  111. package/dist/validators/future-date.d.ts +2 -0
  112. package/dist/validators/future-date.js +20 -0
  113. package/dist/validators/is-date.d.ts +2 -0
  114. package/dist/validators/is-date.js +12 -0
  115. package/dist/validators/max-age.d.ts +2 -0
  116. package/dist/validators/max-age.js +20 -0
  117. package/dist/validators/max-date.d.ts +2 -0
  118. package/dist/validators/max-date.js +20 -0
  119. package/dist/validators/max-length.d.ts +2 -0
  120. package/dist/validators/max-length.js +11 -0
  121. package/dist/validators/max.d.ts +2 -0
  122. package/dist/validators/max.js +11 -0
  123. package/dist/validators/min-age.d.ts +2 -0
  124. package/dist/validators/min-age.js +20 -0
  125. package/dist/validators/min-date.d.ts +2 -0
  126. package/dist/validators/min-date.js +20 -0
  127. package/dist/validators/min-length.d.ts +2 -0
  128. package/dist/validators/min-length.js +11 -0
  129. package/dist/validators/min.d.ts +2 -0
  130. package/dist/validators/min.js +11 -0
  131. package/dist/validators/number.d.ts +2 -0
  132. package/dist/validators/number.js +35 -0
  133. package/dist/validators/past-date.d.ts +2 -0
  134. package/dist/validators/past-date.js +20 -0
  135. package/dist/validators/pattern.d.ts +2 -0
  136. package/dist/validators/pattern.js +11 -0
  137. package/dist/validators/phone.d.ts +2 -0
  138. package/dist/validators/phone.js +35 -0
  139. package/dist/validators/required.d.ts +2 -0
  140. package/dist/validators/required.js +15 -0
  141. package/dist/validators/url.d.ts +2 -0
  142. package/dist/validators/url.js +19 -0
  143. package/dist/validators-BGsNOgT1.js +207 -0
  144. package/dist/validators.d.ts +6 -0
  145. package/dist/validators.js +56 -0
  146. package/llms.txt +9351 -0
  147. package/package.json +166 -0
@@ -0,0 +1,71 @@
1
+ import { ReadonlySignal, Signal } from '@preact/signals-core';
2
+ import { FieldStatus, ValidationError } from '../types';
3
+ import { FormNode } from '../nodes/form-node';
4
+ /**
5
+ * Функция получения дочерних узлов
6
+ * Возвращает массив FormNode для агрегации состояния
7
+ */
8
+ type GetChildrenFn<T> = () => FormNode<T>[];
9
+ /**
10
+ * Результат создания агрегированных сигналов
11
+ */
12
+ export interface AggregateSignals {
13
+ /** Все дочерние узлы валидны и нет собственных ошибок */
14
+ valid: ReadonlySignal<boolean>;
15
+ /** Есть ошибки (инверсия valid) */
16
+ invalid: ReadonlySignal<boolean>;
17
+ /** Хотя бы один дочерний узел в состоянии pending */
18
+ pending: ReadonlySignal<boolean>;
19
+ /** Хотя бы один дочерний узел touched */
20
+ touched: ReadonlySignal<boolean>;
21
+ /** Хотя бы один дочерний узел dirty */
22
+ dirty: ReadonlySignal<boolean>;
23
+ /** Собственные ошибки + ошибки всех дочерних узлов */
24
+ errors: ReadonlySignal<ValidationError[]>;
25
+ /** Статус: disabled > pending > invalid > valid */
26
+ status: ReadonlySignal<FieldStatus>;
27
+ }
28
+ /**
29
+ * Опции для создания агрегированных сигналов
30
+ */
31
+ export interface AggregateSignalsOptions<T> {
32
+ /** Функция получения дочерних узлов */
33
+ getChildren: GetChildrenFn<T>;
34
+ /** Signal с собственными ошибками контейнера (form-level или array-level) */
35
+ ownErrors: Signal<ValidationError[]>;
36
+ /** Опциональный signal disabled состояния (для GroupNode) */
37
+ disabled?: Signal<boolean>;
38
+ }
39
+ /**
40
+ * Создать агрегированные computed signals для контейнерного узла
41
+ *
42
+ * Используется в GroupNode и ArrayNode для унификации логики
43
+ * вычисления состояния на основе дочерних узлов.
44
+ *
45
+ * @param options - Опции конфигурации
46
+ * @returns Объект с computed signals
47
+ *
48
+ * @example GroupNode
49
+ * ```typescript
50
+ * const signals = createAggregateSignals({
51
+ * getChildren: () => Array.from(this._fields.values()),
52
+ * ownErrors: this._formErrors,
53
+ * disabled: this._disabled,
54
+ * });
55
+ * this.valid = signals.valid;
56
+ * this.invalid = signals.invalid;
57
+ * // ...
58
+ * ```
59
+ *
60
+ * @example ArrayNode
61
+ * ```typescript
62
+ * const signals = createAggregateSignals({
63
+ * getChildren: () => this.items.value,
64
+ * ownErrors: this._arrayErrors,
65
+ * });
66
+ * this.valid = signals.valid;
67
+ * // ...
68
+ * ```
69
+ */
70
+ export declare function createAggregateSignals<T>(options: AggregateSignalsOptions<T>): AggregateSignals;
71
+ export {};
@@ -0,0 +1,44 @@
1
+ import { FormProxy, GroupNodeConfig, FormSchema } from '../types';
2
+ /**
3
+ * Создать форму с полной конфигурацией (form, behavior, validation)
4
+ *
5
+ * @group Utilities
6
+ *
7
+ * @param config - Конфигурация формы с полями, поведением и валидацией
8
+ * @returns Типизированная форма с Proxy-доступом к полям
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const form = createForm<UserForm>({
13
+ * form: {
14
+ * email: { value: '', component: Input },
15
+ * password: { value: '', component: Input },
16
+ * },
17
+ * validation: (path) => {
18
+ * required(path.email);
19
+ * email(path.email);
20
+ * required(path.password);
21
+ * minLength(path.password, 8);
22
+ * },
23
+ * });
24
+ *
25
+ * // TypeScript знает о полях:
26
+ * form.email.setValue('test@mail.com');
27
+ * ```
28
+ */
29
+ export declare function createForm<T>(config: GroupNodeConfig<T>): FormProxy<T>;
30
+ /**
31
+ * Создать форму только со схемой полей (обратная совместимость)
32
+ *
33
+ * @param schema - Схема полей формы
34
+ * @returns Типизированная форма с Proxy-доступом к полям
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const form = createForm<UserForm>({
39
+ * email: { value: '', component: Input },
40
+ * password: { value: '', component: Input },
41
+ * });
42
+ * ```
43
+ */
44
+ export declare function createForm<T>(schema: FormSchema<T>): FormProxy<T>;
@@ -0,0 +1,163 @@
1
+ import { ValidationError } from '../types';
2
+ /**
3
+ * Стратегия обработки ошибок
4
+ *
5
+ * Определяет, что делать с ошибкой после логирования
6
+ */
7
+ export declare enum ErrorStrategy {
8
+ /**
9
+ * Пробросить ошибку дальше (throw)
10
+ * Используется когда ошибка критична и должна остановить выполнение
11
+ */
12
+ THROW = "throw",
13
+ /**
14
+ * Залогировать и проглотить ошибку (продолжить выполнение)
15
+ * Используется когда ошибка не критична
16
+ */
17
+ LOG = "log",
18
+ /**
19
+ * Конвертировать ошибку в ValidationError
20
+ * Используется в async validators для отображения ошибки валидации пользователю
21
+ */
22
+ CONVERT = "convert"
23
+ }
24
+ /**
25
+ * Централизованный обработчик ошибок для форм
26
+ *
27
+ * Обеспечивает:
28
+ * - Единообразное логирование ошибок в DEV режиме
29
+ * - Гибкие стратегии обработки (throw/log/convert)
30
+ * - Типобезопасное извлечение сообщений из Error/string/unknown
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // В async validator (конвертировать в ValidationError)
35
+ * try {
36
+ * await validateEmail(value);
37
+ * } catch (error) {
38
+ * return FormErrorHandler.handle(error, 'EmailValidator', ErrorStrategy.CONVERT);
39
+ * }
40
+ *
41
+ * // В behavior applicator (пробросить критичную ошибку)
42
+ * try {
43
+ * applyBehavior(schema);
44
+ * } catch (error) {
45
+ * FormErrorHandler.handle(error, 'BehaviorApplicator', ErrorStrategy.THROW);
46
+ * }
47
+ *
48
+ * // В validator (залогировать и продолжить)
49
+ * try {
50
+ * validator(value);
51
+ * } catch (error) {
52
+ * FormErrorHandler.handle(error, 'Validator', ErrorStrategy.LOG);
53
+ * }
54
+ * ```
55
+ */
56
+ export declare class FormErrorHandler {
57
+ /**
58
+ * Обработать ошибку согласно заданной стратегии
59
+ *
60
+ * @param error Ошибка для обработки (Error | string | unknown)
61
+ * @param context Контекст ошибки для логирования (например, 'AsyncValidator', 'BehaviorRegistry')
62
+ * @param strategy Стратегия обработки (THROW | LOG | CONVERT)
63
+ * @returns ValidationError если strategy = CONVERT, undefined если strategy = LOG, никогда не возвращается если strategy = THROW
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * // THROW - пробросить ошибку
68
+ * try {
69
+ * riskyOperation();
70
+ * } catch (error) {
71
+ * FormErrorHandler.handle(error, 'RiskyOperation', ErrorStrategy.THROW);
72
+ * // Этот код никогда не выполнится
73
+ * }
74
+ *
75
+ * // LOG - залогировать и продолжить
76
+ * try {
77
+ * nonCriticalOperation();
78
+ * } catch (error) {
79
+ * FormErrorHandler.handle(error, 'NonCritical', ErrorStrategy.LOG);
80
+ * // Продолжаем выполнение
81
+ * }
82
+ *
83
+ * // CONVERT - конвертировать в ValidationError
84
+ * try {
85
+ * await validator(value);
86
+ * } catch (error) {
87
+ * const validationError = FormErrorHandler.handle(
88
+ * error,
89
+ * 'AsyncValidator',
90
+ * ErrorStrategy.CONVERT
91
+ * );
92
+ * return validationError;
93
+ * }
94
+ * ```
95
+ */
96
+ static handle(error: unknown, context: string, strategy?: ErrorStrategy): ValidationError | never | void;
97
+ /**
98
+ * Извлечь сообщение из ошибки
99
+ *
100
+ * Обрабатывает различные типы ошибок:
101
+ * - Error объекты → error.message
102
+ * - Строки → возвращает как есть
103
+ * - Объекты с message → извлекает message
104
+ * - Другое → String(error)
105
+ *
106
+ * @param error Ошибка для извлечения сообщения
107
+ * @returns Сообщение ошибки
108
+ * @private
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * FormErrorHandler.extractMessage(new Error('Test'));
113
+ * // 'Test'
114
+ *
115
+ * FormErrorHandler.extractMessage('String error');
116
+ * // 'String error'
117
+ *
118
+ * FormErrorHandler.extractMessage({ message: 'Object error' });
119
+ * // 'Object error'
120
+ *
121
+ * FormErrorHandler.extractMessage(null);
122
+ * // 'null'
123
+ * ```
124
+ */
125
+ private static extractMessage;
126
+ /**
127
+ * Создать ValidationError с заданными параметрами
128
+ *
129
+ * Утилитная функция для создания ValidationError объектов
130
+ *
131
+ * @param code Код ошибки
132
+ * @param message Сообщение ошибки
133
+ * @param field Поле (опционально)
134
+ * @returns ValidationError объект
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const error = FormErrorHandler.createValidationError(
139
+ * 'required',
140
+ * 'This field is required',
141
+ * 'email'
142
+ * );
143
+ * // { code: 'required', message: 'This field is required', field: 'email' }
144
+ * ```
145
+ */
146
+ static createValidationError(code: string, message: string, field?: string): ValidationError;
147
+ /**
148
+ * Проверить, является ли объект ValidationError
149
+ *
150
+ * Type guard для ValidationError
151
+ *
152
+ * @param value Значение для проверки
153
+ * @returns true если value является ValidationError
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * if (FormErrorHandler.isValidationError(result)) {
158
+ * console.log(result.code); // OK, типобезопасно
159
+ * }
160
+ * ```
161
+ */
162
+ static isValidationError(value: unknown): value is ValidationError;
163
+ }
@@ -0,0 +1,240 @@
1
+ import { 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
+ }
@@ -0,0 +1,60 @@
1
+ import { FieldPath, FieldPathNode } from '../types';
2
+ /**
3
+ * Создать FieldPath proxy для формы
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * const path = createFieldPath<MyForm>();
8
+ * console.log(path.email.__path); // 'email'
9
+ * console.log(path.personalData.firstName.__path); // 'personalData.firstName'
10
+ * ```
11
+ */
12
+ export declare function createFieldPath<T>(): FieldPath<T>;
13
+ /**
14
+ * Извлечь строковый путь из {@link FieldPathNode}.
15
+ *
16
+ * @param node - Узел `FieldPathNode` либо строка-путь.
17
+ * @returns Путь вида `"a.b.c"`.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { extractPath } from '@reformer/core';
22
+ *
23
+ * const path = (renderPath) => extractPath(renderPath.user.email); // → 'user.email'
24
+ * ```
25
+ */
26
+ export declare function extractPath(node: FieldPathNode<unknown, unknown> | unknown): string;
27
+ /**
28
+ * Преобразовать FieldPathNode в FieldPath для переиспользования схем
29
+ *
30
+ * Позволяет композировать validation schemas:
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const personalDataValidation = (path: FieldPath<PersonalData>) => {
35
+ * required(path.firstName, { message: 'Имя обязательно' });
36
+ * required(path.lastName, { message: 'Фамилия обязательна' });
37
+ * };
38
+ *
39
+ * const mainValidation = (path: FieldPath<MyForm>) => {
40
+ * // Переиспользуем схему
41
+ * personalDataValidation(toFieldPath(path.personalData));
42
+ * required(path.email);
43
+ * };
44
+ * ```
45
+ */
46
+ export declare function toFieldPath<T>(node: FieldPathNode<unknown, T, never> | FieldPathNode<any, T, any>): FieldPath<T>;
47
+ /**
48
+ * Извлечь имя последнего сегмента ({@link FieldPathSegment}) пути.
49
+ *
50
+ * @param node - Узел `FieldPathNode` либо строка-путь.
51
+ * @returns Имя поля без префикса родителя (последний сегмент).
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { extractKey } from '@reformer/core';
56
+ *
57
+ * extractKey(path.user.email); // → 'email'
58
+ * ```
59
+ */
60
+ export declare function extractKey(node: FieldPathNode<unknown, unknown> | unknown): string;