@reformer/core 5.0.0 → 6.0.0
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/README.md +7 -5
- package/dist/behaviors-O9a1Djj9.js +147 -0
- package/dist/behaviors.d.ts +131 -4
- package/dist/behaviors.js +298 -27
- package/dist/core/model/behaviors.d.ts +123 -0
- package/dist/core/model/form-model.d.ts +18 -0
- package/dist/core/model/index.d.ts +12 -0
- package/dist/core/model/types.d.ts +112 -0
- package/dist/core/model/validate-model.d.ts +46 -0
- package/dist/core/nodes/array-node.d.ts +34 -2
- package/dist/core/nodes/group-node.d.ts +19 -71
- package/dist/core/nodes/model-array-node.d.ts +71 -0
- package/dist/core/types/deep-schema.d.ts +16 -2
- package/dist/core/types/form-proxy.d.ts +17 -6
- package/dist/core/types/index.d.ts +5 -23
- package/dist/core/types/validation-schema.d.ts +15 -66
- package/dist/core/utils/create-form.d.ts +24 -0
- package/dist/core/utils/derived-registry.d.ts +5 -0
- package/dist/core/utils/index.d.ts +4 -4
- package/dist/core/utils/signal-node-registry.d.ts +12 -0
- package/dist/core/utils/type-guards.d.ts +2 -3
- package/dist/core/validation/index.d.ts +5 -11
- package/dist/core/validation/validators/email.d.ts +5 -29
- package/dist/core/validation/validators/future-date.d.ts +6 -28
- package/dist/core/validation/validators/index.d.ts +11 -4
- package/dist/core/validation/validators/integer.d.ts +13 -0
- package/dist/core/validation/validators/is-date.d.ts +5 -28
- package/dist/core/validation/validators/is-number.d.ts +14 -0
- package/dist/core/validation/validators/max-age.d.ts +6 -29
- package/dist/core/validation/validators/max-date.d.ts +6 -29
- package/dist/core/validation/validators/max-length.d.ts +5 -30
- package/dist/core/validation/validators/max.d.ts +7 -29
- package/dist/core/validation/validators/min-age.d.ts +6 -29
- package/dist/core/validation/validators/min-date.d.ts +6 -29
- package/dist/core/validation/validators/min-length.d.ts +5 -30
- package/dist/core/validation/validators/min.d.ts +7 -29
- package/dist/core/validation/validators/multiple-of.d.ts +13 -0
- package/dist/core/validation/validators/non-negative.d.ts +13 -0
- package/dist/core/validation/validators/non-zero.d.ts +13 -0
- package/dist/core/validation/validators/past-date.d.ts +5 -28
- package/dist/core/validation/validators/pattern.d.ts +5 -32
- package/dist/core/validation/validators/phone.d.ts +9 -19
- package/dist/core/validation/validators/required.d.ts +10 -31
- package/dist/core/validation/validators/url.d.ts +13 -15
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1299 -875
- package/dist/validators/email.js +7 -9
- package/dist/validators/future-date.js +11 -12
- package/dist/validators/integer.d.ts +2 -0
- package/dist/validators/integer.js +10 -0
- package/dist/validators/is-date.js +6 -7
- package/dist/validators/is-number.d.ts +2 -0
- package/dist/validators/is-number.js +10 -0
- package/dist/validators/max-age.js +11 -12
- package/dist/validators/max-date.js +11 -12
- package/dist/validators/max-length.js +12 -8
- package/dist/validators/max.js +5 -6
- package/dist/validators/min-age.js +10 -11
- package/dist/validators/min-date.js +12 -13
- package/dist/validators/min-length.js +12 -8
- package/dist/validators/min.js +6 -7
- package/dist/validators/multiple-of.d.ts +2 -0
- package/dist/validators/multiple-of.js +10 -0
- package/dist/validators/non-negative.d.ts +2 -0
- package/dist/validators/non-negative.js +10 -0
- package/dist/validators/non-zero.d.ts +2 -0
- package/dist/validators/non-zero.js +10 -0
- package/dist/validators/past-date.js +11 -12
- package/dist/validators/pattern.js +6 -7
- package/dist/validators/phone.js +14 -32
- package/dist/validators/required.js +9 -10
- package/dist/validators/url.js +19 -16
- package/dist/validators.js +67 -54
- package/llms.txt +959 -2584
- package/package.json +19 -35
- package/dist/behaviors/compute-from.d.ts +0 -2
- package/dist/behaviors/compute-from.js +0 -31
- package/dist/behaviors/copy-from.d.ts +0 -2
- package/dist/behaviors/copy-from.js +0 -29
- package/dist/behaviors/enable-when.d.ts +0 -2
- package/dist/behaviors/enable-when.js +0 -25
- package/dist/behaviors/reset-when.d.ts +0 -2
- package/dist/behaviors/reset-when.js +0 -24
- package/dist/behaviors/revalidate-when.d.ts +0 -2
- package/dist/behaviors/revalidate-when.js +0 -18
- package/dist/behaviors/sync-fields.d.ts +0 -2
- package/dist/behaviors/sync-fields.js +0 -41
- package/dist/behaviors/transform-value.d.ts +0 -2
- package/dist/behaviors/transform-value.js +0 -45
- package/dist/behaviors/watch-field.d.ts +0 -2
- package/dist/behaviors/watch-field.js +0 -21
- package/dist/core/behavior/behavior-context.d.ts +0 -47
- package/dist/core/behavior/behavior-registry.d.ts +0 -85
- package/dist/core/behavior/behaviors/compute-from.d.ts +0 -70
- package/dist/core/behavior/behaviors/copy-from.d.ts +0 -56
- package/dist/core/behavior/behaviors/enable-when.d.ts +0 -118
- package/dist/core/behavior/behaviors/index.d.ts +0 -11
- package/dist/core/behavior/behaviors/reset-when.d.ts +0 -64
- package/dist/core/behavior/behaviors/revalidate-when.d.ts +0 -53
- package/dist/core/behavior/behaviors/sync-fields.d.ts +0 -48
- package/dist/core/behavior/behaviors/transform-value.d.ts +0 -192
- package/dist/core/behavior/behaviors/watch-field.d.ts +0 -80
- package/dist/core/behavior/compose-behavior.d.ts +0 -96
- package/dist/core/behavior/index.d.ts +0 -11
- package/dist/core/behavior/types.d.ts +0 -146
- package/dist/core/types/field-path.d.ts +0 -42
- package/dist/core/types/form-context.d.ts +0 -89
- package/dist/core/utils/field-path-navigator.d.ts +0 -240
- package/dist/core/utils/field-path.d.ts +0 -60
- package/dist/core/utils/registry-helpers.d.ts +0 -43
- package/dist/core/validation/core/apply-when.d.ts +0 -22
- package/dist/core/validation/core/apply.d.ts +0 -52
- package/dist/core/validation/core/index.d.ts +0 -8
- package/dist/core/validation/core/validate-async.d.ts +0 -36
- package/dist/core/validation/core/validate-tree.d.ts +0 -35
- package/dist/core/validation/core/validate.d.ts +0 -26
- package/dist/core/validation/validate-form.d.ts +0 -48
- package/dist/core/validation/validation-applicator.d.ts +0 -70
- package/dist/core/validation/validation-context.d.ts +0 -86
- package/dist/core/validation/validation-registry.d.ts +0 -142
- package/dist/core/validation/validators/array-validators.d.ts +0 -53
- package/dist/core/validation/validators/number.d.ts +0 -31
- package/dist/field-path-DuKdGcIE.js +0 -66
- package/dist/hooks/useHiddenCondition.d.ts +0 -25
- package/dist/index-D25LsbRm.js +0 -73
- package/dist/registry-helpers-Bv_BJ1s-.js +0 -615
- package/dist/safe-effect-Dh8uw81c.js +0 -20
- package/dist/validate-C3XiA_zf.js +0 -10
- package/dist/validators/number.d.ts +0 -2
- package/dist/validators/number.js +0 -35
- package/dist/validators-BGsNOgT1.js +0 -207
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { GroupNode } from '../nodes/group-node';
|
|
2
|
-
import { FieldPath } from '../types/field-path';
|
|
3
|
-
import { FormContext } from '../types/form-context';
|
|
4
|
-
/**
|
|
5
|
-
* Тип функции behavior схемы
|
|
6
|
-
* Принимает FieldPath и описывает поведение формы
|
|
7
|
-
*
|
|
8
|
-
* @group Behaviors
|
|
9
|
-
* @category Behavior Types
|
|
10
|
-
*/
|
|
11
|
-
export type BehaviorSchemaFn<T> = (path: FieldPath<T>) => void;
|
|
12
|
-
/**
|
|
13
|
-
* Контекст для behavior callback функций
|
|
14
|
-
* Алиас для FormContext
|
|
15
|
-
*
|
|
16
|
-
* @group Behaviors
|
|
17
|
-
* @category Behavior Types
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* watchField(path.country, async (country, ctx) => {
|
|
22
|
-
* // Прямой типизированный доступ к полям
|
|
23
|
-
* const cities = await fetchCities(country);
|
|
24
|
-
* ctx.form.city.updateComponentProps({ options: cities });
|
|
25
|
-
*
|
|
26
|
-
* // Безопасная установка значения (без циклов)
|
|
27
|
-
* ctx.setFieldValue('city', null);
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export type BehaviorContext<TForm> = FormContext<TForm>;
|
|
32
|
-
/**
|
|
33
|
-
* Функция-handler для behavior
|
|
34
|
-
*
|
|
35
|
-
* Создает effect подписку для реактивного поведения формы.
|
|
36
|
-
*
|
|
37
|
-
* @group Behaviors
|
|
38
|
-
* @category Behavior Types
|
|
39
|
-
*
|
|
40
|
-
* @template TForm - Тип формы
|
|
41
|
-
* @param form - Корневой узел формы (GroupNode)
|
|
42
|
-
* @param context - Контекст для работы с формой
|
|
43
|
-
* @param withDebounce - Функция-обертка для debounce
|
|
44
|
-
* @returns Функция cleanup для отписки от effect или null
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```typescript
|
|
48
|
-
* const handler: BehaviorHandlerFn<MyForm> = (form, context, withDebounce) => {
|
|
49
|
-
* const sourceNode = form.getFieldByPath('email');
|
|
50
|
-
*
|
|
51
|
-
* return effect(() => {
|
|
52
|
-
* const value = sourceNode.value.value;
|
|
53
|
-
* withDebounce(() => {
|
|
54
|
-
* // Логика behavior
|
|
55
|
-
* });
|
|
56
|
-
* });
|
|
57
|
-
* };
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
export type BehaviorHandlerFn<TForm> = (form: GroupNode<TForm>, context: BehaviorContext<TForm>, withDebounce: (callback: () => void) => void) => (() => void) | null;
|
|
61
|
-
/**
|
|
62
|
-
* Общие опции для behavior
|
|
63
|
-
*
|
|
64
|
-
* @group Behaviors
|
|
65
|
-
* @category Behavior Types
|
|
66
|
-
*/
|
|
67
|
-
export interface BehaviorOptions {
|
|
68
|
-
/** Debounce в миллисекундах */
|
|
69
|
-
debounce?: number;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Опции для copyFrom
|
|
73
|
-
*
|
|
74
|
-
* @group Behaviors
|
|
75
|
-
* @category Behavior Types
|
|
76
|
-
*/
|
|
77
|
-
export interface CopyFromOptions<TSource, TForm = unknown> {
|
|
78
|
-
/** Условие копирования */
|
|
79
|
-
when?: (form: TForm) => boolean;
|
|
80
|
-
/** Какие поля копировать (для групп) */
|
|
81
|
-
fields?: (keyof TSource)[] | 'all';
|
|
82
|
-
/** Трансформация значения */
|
|
83
|
-
transform?: (value: TSource) => unknown;
|
|
84
|
-
/** Debounce в мс */
|
|
85
|
-
debounce?: number;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Опции для enableWhen/disableWhen
|
|
89
|
-
*
|
|
90
|
-
* @group Behaviors
|
|
91
|
-
* @category Behavior Types
|
|
92
|
-
*/
|
|
93
|
-
export interface EnableWhenOptions {
|
|
94
|
-
/** Сбросить значение при disable */
|
|
95
|
-
resetOnDisable?: boolean;
|
|
96
|
-
/** Debounce в мс */
|
|
97
|
-
debounce?: number;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Опции для computeFrom
|
|
101
|
-
*
|
|
102
|
-
* @group Behaviors
|
|
103
|
-
* @category Behavior Types
|
|
104
|
-
*/
|
|
105
|
-
export interface ComputeFromOptions<TForm> {
|
|
106
|
-
/** Когда вычислять */
|
|
107
|
-
trigger?: 'change' | 'blur';
|
|
108
|
-
/** Debounce в мс */
|
|
109
|
-
debounce?: number;
|
|
110
|
-
/** Условие применения */
|
|
111
|
-
condition?: (form: TForm) => boolean;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Опции для watchField
|
|
115
|
-
*
|
|
116
|
-
* @group Behaviors
|
|
117
|
-
* @category Behavior Types
|
|
118
|
-
*/
|
|
119
|
-
export interface WatchFieldOptions {
|
|
120
|
-
/** Debounce в мс */
|
|
121
|
-
debounce?: number;
|
|
122
|
-
/** Вызвать сразу при инициализации */
|
|
123
|
-
immediate?: boolean;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Опции для revalidateWhen
|
|
127
|
-
*
|
|
128
|
-
* @group Behaviors
|
|
129
|
-
* @category Behavior Types
|
|
130
|
-
*/
|
|
131
|
-
export interface RevalidateWhenOptions {
|
|
132
|
-
/** Debounce в мс */
|
|
133
|
-
debounce?: number;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Опции для syncFields
|
|
137
|
-
*
|
|
138
|
-
* @group Behaviors
|
|
139
|
-
* @category Behavior Types
|
|
140
|
-
*/
|
|
141
|
-
export interface SyncFieldsOptions<T> {
|
|
142
|
-
/** Трансформация значения */
|
|
143
|
-
transform?: (value: T) => T;
|
|
144
|
-
/** Debounce в мс */
|
|
145
|
-
debounce?: number;
|
|
146
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { AnyFunction } from './index';
|
|
2
|
-
/**
|
|
3
|
-
* FieldPath предоставляет типобезопасный доступ к путям полей формы
|
|
4
|
-
*
|
|
5
|
-
* Рекурсивно обрабатывает вложенные объекты для поддержки вложенных форм.
|
|
6
|
-
*
|
|
7
|
-
* Использование:
|
|
8
|
-
* ```typescript
|
|
9
|
-
* const validation = (path: FieldPath<MyForm>) => {
|
|
10
|
-
* required(path.email, { message: 'Email обязателен' });
|
|
11
|
-
*
|
|
12
|
-
* // Вложенные объекты
|
|
13
|
-
* required(path.registrationAddress.city);
|
|
14
|
-
* minLength(path.registrationAddress.street, 3);
|
|
15
|
-
*
|
|
16
|
-
* applyWhen(
|
|
17
|
-
* path.loanType,
|
|
18
|
-
* (type) => type === 'mortgage',
|
|
19
|
-
* (path) => {
|
|
20
|
-
* required(path.propertyValue, { message: 'Укажите стоимость' });
|
|
21
|
-
* }
|
|
22
|
-
* );
|
|
23
|
-
* };
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export type FieldPath<T> = {
|
|
27
|
-
[K in keyof T]: NonNullable<T[K]> extends Array<unknown> ? FieldPathNode<T, T[K], K> : NonNullable<T[K]> extends Date | File | Blob | AnyFunction ? FieldPathNode<T, T[K], K> : NonNullable<T[K]> extends object ? FieldPathNode<T, T[K], K> & FieldPath<NonNullable<T[K]>> : FieldPathNode<T, T[K], K>;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Узел в пути поля
|
|
31
|
-
* Содержит метаинформацию о поле для валидации
|
|
32
|
-
*/
|
|
33
|
-
export interface FieldPathNode<TForm, TField, TKey = unknown> {
|
|
34
|
-
/** Ключ поля */
|
|
35
|
-
readonly __key: TKey;
|
|
36
|
-
/** Путь к полю (для вложенных объектов) */
|
|
37
|
-
readonly __path: string;
|
|
38
|
-
/** Тип формы */
|
|
39
|
-
readonly __formType?: TForm;
|
|
40
|
-
/** Тип поля */
|
|
41
|
-
readonly __fieldType?: TField;
|
|
42
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { FormProxy } from './form-proxy';
|
|
2
|
-
import { FieldPathNode } from './field-path';
|
|
3
|
-
import { FormNode } from '../nodes/form-node';
|
|
4
|
-
import { FormValue } from './index';
|
|
5
|
-
/**
|
|
6
|
-
* Единый контекст для работы с формой
|
|
7
|
-
*
|
|
8
|
-
* Предоставляет:
|
|
9
|
-
* - `form` - типизированный Proxy-доступ к полям формы
|
|
10
|
-
* - `setFieldValue` - безопасная установка значения (emitEvent: false)
|
|
11
|
-
*/
|
|
12
|
-
export interface FormContext<TForm> {
|
|
13
|
-
/**
|
|
14
|
-
* Форма с типизированным Proxy-доступом к полям
|
|
15
|
-
*
|
|
16
|
-
* Позволяет обращаться к полям напрямую через точечную нотацию:
|
|
17
|
-
* - `ctx.form.email` → FieldNode
|
|
18
|
-
* - `ctx.form.address.city` → FieldNode (вложенный)
|
|
19
|
-
* - `ctx.form.items` → ArrayNode
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* // Получить значение
|
|
24
|
-
* ctx.form.email.value.value
|
|
25
|
-
*
|
|
26
|
-
* // Установить значение (⚠️ может вызвать цикл в behavior!)
|
|
27
|
-
* ctx.form.email.setValue('new@mail.com')
|
|
28
|
-
*
|
|
29
|
-
* // Безопасно установить значение
|
|
30
|
-
* ctx.form.email.setValue('new@mail.com', { emitEvent: false })
|
|
31
|
-
*
|
|
32
|
-
* // Обновить пропсы компонента
|
|
33
|
-
* ctx.form.city.updateComponentProps({ options: cities })
|
|
34
|
-
*
|
|
35
|
-
* // Валидация поля
|
|
36
|
-
* await ctx.form.email.validate()
|
|
37
|
-
*
|
|
38
|
-
* // Работа с массивами
|
|
39
|
-
* ctx.form.items.push({ title: 'New' })
|
|
40
|
-
* ctx.form.items.clear()
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
readonly form: FormProxy<TForm>;
|
|
44
|
-
/**
|
|
45
|
-
* Безопасно установить значение поля по строковому пути или FieldPath
|
|
46
|
-
*
|
|
47
|
-
* Автоматически использует `emitEvent: false` для предотвращения
|
|
48
|
-
* бесконечных циклов в behavior схемах.
|
|
49
|
-
*
|
|
50
|
-
* @param path - Путь к полю (строка или FieldPath)
|
|
51
|
-
* @param value - Новое значение
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* // Сброс города при смене страны (строковый путь)
|
|
56
|
-
* watchField(path.country, (country, ctx) => {
|
|
57
|
-
* ctx.setFieldValue('city', null);
|
|
58
|
-
* });
|
|
59
|
-
*
|
|
60
|
-
* // Использование FieldPath напрямую (более типобезопасно)
|
|
61
|
-
* watchField(path.country, (country, ctx) => {
|
|
62
|
-
* ctx.setFieldValue(path.city, null);
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
setFieldValue(path: string | FieldPathNode<TForm, unknown>, value: unknown): void;
|
|
67
|
-
/**
|
|
68
|
-
* Получить поле формы по строковому пути
|
|
69
|
-
*
|
|
70
|
-
* Используется для динамического доступа к вложенным полям,
|
|
71
|
-
* особенно в модульных behavior схемах, применяемых через apply().
|
|
72
|
-
*
|
|
73
|
-
* @param path - Строковый путь к полю (например "address.city")
|
|
74
|
-
* @returns FormNode или undefined если поле не найдено
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```typescript
|
|
78
|
-
* // В модульной behavior схеме, применяемой к вложенному полю:
|
|
79
|
-
* // apply([path.registrationAddress, path.residenceAddress], addressBehavior)
|
|
80
|
-
*
|
|
81
|
-
* watchField(path.region, (region, ctx) => {
|
|
82
|
-
* // path.city.__path = "registrationAddress.city" или "residenceAddress.city"
|
|
83
|
-
* const cityField = ctx.getFieldByPath(path.city.__path);
|
|
84
|
-
* cityField?.updateComponentProps({ options: cities });
|
|
85
|
-
* });
|
|
86
|
-
* ```
|
|
87
|
-
*/
|
|
88
|
-
getFieldByPath(path: string): FormNode<FormValue> | undefined;
|
|
89
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
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;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ValidationRegistry } from '../validation/validation-registry';
|
|
2
|
-
import { BehaviorRegistry } from '../behavior/behavior-registry';
|
|
3
|
-
/**
|
|
4
|
-
* Получить текущий активный ValidationRegistry из context stack
|
|
5
|
-
*
|
|
6
|
-
* Используется внутри validation schema функций (validate, validateAsync, required и т.д.)
|
|
7
|
-
* для регистрации валидаторов в активном контексте GroupNode
|
|
8
|
-
*
|
|
9
|
-
* @returns Текущий ValidationRegistry или заглушка в production
|
|
10
|
-
* @throws Error если нет активного контекста (только в DEV режиме)
|
|
11
|
-
*
|
|
12
|
-
* @internal
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* function required(fieldPath, options) {
|
|
17
|
-
* const registry = getCurrentValidationRegistry();
|
|
18
|
-
* registry.registerSync(path, validator, options);
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function getCurrentValidationRegistry(): ValidationRegistry;
|
|
23
|
-
/**
|
|
24
|
-
* Получить текущий активный BehaviorRegistry из context stack
|
|
25
|
-
*
|
|
26
|
-
* Используется внутри behavior schema функций (copyFrom, enableWhen, computeFrom и т.д.)
|
|
27
|
-
* для регистрации поведений в активном контексте GroupNode
|
|
28
|
-
*
|
|
29
|
-
* @returns Текущий BehaviorRegistry или заглушка в production
|
|
30
|
-
* @throws Error если нет активного контекста (только в DEV режиме)
|
|
31
|
-
*
|
|
32
|
-
* @internal
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* function copyFrom(target, source, options) {
|
|
37
|
-
* const registry = getCurrentBehaviorRegistry();
|
|
38
|
-
* const handler = createCopyBehavior(target, source, options);
|
|
39
|
-
* registry.register(handler, { debounce: options?.debounce });
|
|
40
|
-
* }
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export declare function getCurrentBehaviorRegistry(): BehaviorRegistry;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { FieldPath } from '../../types/field-path';
|
|
2
|
-
import { ConditionFn } from '../../types/validation-schema';
|
|
3
|
-
import { FieldPathNode } from '../../types';
|
|
4
|
-
/**
|
|
5
|
-
* Применить валидацию только при выполнении условия
|
|
6
|
-
*
|
|
7
|
-
* @group Validation
|
|
8
|
-
* @category Core Functions
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* applyWhen(
|
|
13
|
-
* path.loanType,
|
|
14
|
-
* (type) => type === 'mortgage',
|
|
15
|
-
* (path) => {
|
|
16
|
-
* required(path.propertyValue, { message: 'Укажите стоимость' });
|
|
17
|
-
* min(path.propertyValue, 1000000);
|
|
18
|
-
* }
|
|
19
|
-
* );
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export declare function applyWhen<TForm, TField>(fieldPath: FieldPathNode<TForm, TField>, condition: ConditionFn<TField>, validationFn: (path: FieldPath<TForm>) => void): void;
|