@reformer/core 1.1.0 → 2.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 (99) hide show
  1. package/dist/behaviors-DzYL8kY_.js +499 -0
  2. package/dist/behaviors.d.ts +6 -2
  3. package/dist/behaviors.js +19 -227
  4. package/dist/core/behavior/behavior-context.d.ts +6 -2
  5. package/dist/core/behavior/create-field-path.d.ts +3 -16
  6. package/dist/core/nodes/group-node.d.ts +14 -193
  7. package/dist/core/types/form-context.d.ts +10 -4
  8. package/dist/core/utils/field-path.d.ts +48 -0
  9. package/dist/core/utils/index.d.ts +1 -0
  10. package/dist/core/validation/core/validate-tree.d.ts +10 -4
  11. package/dist/core/validation/field-path.d.ts +3 -39
  12. package/dist/core/validation/validation-context.d.ts +23 -0
  13. package/dist/hooks/types.d.ts +328 -0
  14. package/dist/hooks/useFormControl.d.ts +13 -37
  15. package/dist/hooks/useFormControlValue.d.ts +167 -0
  16. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  17. package/dist/index.d.ts +6 -1
  18. package/dist/index.js +2886 -8
  19. package/dist/{create-field-path-CdPF3lIK.js → registry-helpers-BRxAr6nG.js} +133 -347
  20. package/dist/validators-gXoHPdqM.js +418 -0
  21. package/dist/validators.d.ts +6 -2
  22. package/dist/validators.js +29 -296
  23. package/llms.txt +1283 -22
  24. package/package.json +8 -4
  25. package/dist/core/behavior/behavior-applicator.d.ts +0 -71
  26. package/dist/core/behavior/behavior-applicator.js +0 -92
  27. package/dist/core/behavior/behavior-context.js +0 -38
  28. package/dist/core/behavior/behavior-registry.js +0 -198
  29. package/dist/core/behavior/behaviors/compute-from.js +0 -84
  30. package/dist/core/behavior/behaviors/copy-from.js +0 -64
  31. package/dist/core/behavior/behaviors/enable-when.js +0 -81
  32. package/dist/core/behavior/behaviors/index.js +0 -11
  33. package/dist/core/behavior/behaviors/reset-when.js +0 -63
  34. package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
  35. package/dist/core/behavior/behaviors/sync-fields.js +0 -66
  36. package/dist/core/behavior/behaviors/transform-value.js +0 -110
  37. package/dist/core/behavior/behaviors/watch-field.js +0 -56
  38. package/dist/core/behavior/compose-behavior.js +0 -166
  39. package/dist/core/behavior/create-field-path.js +0 -69
  40. package/dist/core/behavior/index.js +0 -17
  41. package/dist/core/behavior/types.js +0 -7
  42. package/dist/core/context/form-context-impl.js +0 -37
  43. package/dist/core/factories/index.js +0 -6
  44. package/dist/core/factories/node-factory.js +0 -281
  45. package/dist/core/nodes/array-node.js +0 -534
  46. package/dist/core/nodes/field-node.js +0 -510
  47. package/dist/core/nodes/form-node.js +0 -343
  48. package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
  49. package/dist/core/nodes/group-node/field-registry.js +0 -215
  50. package/dist/core/nodes/group-node/index.d.ts +0 -11
  51. package/dist/core/nodes/group-node/index.js +0 -11
  52. package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
  53. package/dist/core/nodes/group-node/proxy-builder.js +0 -161
  54. package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
  55. package/dist/core/nodes/group-node/state-manager.js +0 -265
  56. package/dist/core/nodes/group-node.js +0 -770
  57. package/dist/core/types/deep-schema.js +0 -11
  58. package/dist/core/types/field-path.js +0 -4
  59. package/dist/core/types/form-context.js +0 -25
  60. package/dist/core/types/group-node-proxy.js +0 -31
  61. package/dist/core/types/index.js +0 -4
  62. package/dist/core/types/validation-schema.js +0 -10
  63. package/dist/core/utils/create-form.js +0 -24
  64. package/dist/core/utils/debounce.js +0 -197
  65. package/dist/core/utils/error-handler.js +0 -226
  66. package/dist/core/utils/field-path-navigator.js +0 -374
  67. package/dist/core/utils/index.js +0 -14
  68. package/dist/core/utils/registry-helpers.js +0 -79
  69. package/dist/core/utils/registry-stack.js +0 -86
  70. package/dist/core/utils/resources.js +0 -69
  71. package/dist/core/utils/subscription-manager.js +0 -214
  72. package/dist/core/utils/type-guards.js +0 -169
  73. package/dist/core/validation/core/apply-when.js +0 -41
  74. package/dist/core/validation/core/apply.js +0 -38
  75. package/dist/core/validation/core/index.js +0 -8
  76. package/dist/core/validation/core/validate-async.js +0 -45
  77. package/dist/core/validation/core/validate-tree.js +0 -37
  78. package/dist/core/validation/core/validate.js +0 -38
  79. package/dist/core/validation/field-path.js +0 -147
  80. package/dist/core/validation/index.js +0 -33
  81. package/dist/core/validation/validate-form.js +0 -152
  82. package/dist/core/validation/validation-applicator.js +0 -217
  83. package/dist/core/validation/validation-context.js +0 -75
  84. package/dist/core/validation/validation-registry.js +0 -298
  85. package/dist/core/validation/validators/array-validators.js +0 -86
  86. package/dist/core/validation/validators/date.js +0 -117
  87. package/dist/core/validation/validators/email.js +0 -60
  88. package/dist/core/validation/validators/index.js +0 -14
  89. package/dist/core/validation/validators/max-length.js +0 -60
  90. package/dist/core/validation/validators/max.js +0 -60
  91. package/dist/core/validation/validators/min-length.js +0 -60
  92. package/dist/core/validation/validators/min.js +0 -60
  93. package/dist/core/validation/validators/number.js +0 -90
  94. package/dist/core/validation/validators/pattern.js +0 -62
  95. package/dist/core/validation/validators/phone.js +0 -58
  96. package/dist/core/validation/validators/required.js +0 -69
  97. package/dist/core/validation/validators/url.js +0 -55
  98. package/dist/hooks/useFormControl.js +0 -298
  99. package/dist/node-factory-D7DOnSSN.js +0 -3200
@@ -1,298 +0,0 @@
1
- /**
2
- * ValidationRegistry - система регистрации и применения валидаторов
3
- *
4
- * Работает как стек контекстов:
5
- * 1. При вызове validation schema функции создается новый контекст
6
- * 2. Все вызовы validate(), applyWhen() и т.д. регистрируют валидаторы в текущем контексте
7
- * 3. После завершения схемы валидаторы применяются к GroupNode
8
- */
9
- import { RegistryStack } from '../utils/registry-stack';
10
- /**
11
- * Контекст регистрации валидаторов
12
- */
13
- class RegistrationContext {
14
- validators = [];
15
- conditionStack = [];
16
- /**
17
- * Добавить валидатор в контекст
18
- */
19
- addValidator(registration) {
20
- // Если есть активные условия, добавляем их к валидатору
21
- if (this.conditionStack.length > 0) {
22
- const condition = this.conditionStack[this.conditionStack.length - 1];
23
- registration.condition = condition;
24
- }
25
- this.validators.push(registration);
26
- }
27
- /**
28
- * Войти в условный блок
29
- */
30
- enterCondition(fieldPath, conditionFn) {
31
- this.conditionStack.push({ fieldPath, conditionFn });
32
- }
33
- /**
34
- * Выйти из условного блока
35
- */
36
- exitCondition() {
37
- this.conditionStack.pop();
38
- }
39
- /**
40
- * Получить все зарегистрированные валидаторы
41
- */
42
- getValidators() {
43
- return this.validators;
44
- }
45
- }
46
- /**
47
- * Реестр валидаторов для формы
48
- *
49
- * Каждый экземпляр GroupNode создает собственный реестр (композиция).
50
- * Устраняет race conditions и изолирует формы друг от друга.
51
- *
52
- * Context stack используется для tracking текущего активного реестра:
53
- * - beginRegistration() помещает this в global stack
54
- * - endRegistration() извлекает из global stack
55
- * - getCurrent() возвращает текущий активный реестр
56
- *
57
- * @example
58
- * ```typescript
59
- * class GroupNode {
60
- * private readonly validationRegistry = new ValidationRegistry();
61
- *
62
- * applyValidationSchema(schemaFn) {
63
- * this.validationRegistry.beginRegistration(); // Pushes this to global stack
64
- * schemaFn(createFieldPath(this)); // Uses getCurrent()
65
- * this.validationRegistry.endRegistration(this); // Pops from global stack
66
- * }
67
- * }
68
- * ```
69
- */
70
- export class ValidationRegistry {
71
- /**
72
- * Global stack активных реестров
73
- * Используется для изоляции форм друг от друга
74
- */
75
- static registryStack = new RegistryStack();
76
- contextStack = [];
77
- validators = [];
78
- /**
79
- * Получить текущий активный реестр из global stack
80
- *
81
- * @returns Текущий активный реестр или null
82
- *
83
- * @example
84
- * ```typescript
85
- * // В schema-validators.ts
86
- * export function required(...) {
87
- * const registry = ValidationRegistry.getCurrent();
88
- * if (registry) {
89
- * registry.registerSync(...);
90
- * }
91
- * }
92
- * ```
93
- */
94
- static getCurrent() {
95
- return ValidationRegistry.registryStack.getCurrent();
96
- }
97
- /**
98
- * Начать регистрацию валидаторов для формы
99
- *
100
- * Помещает this в global stack для изоляции форм
101
- */
102
- beginRegistration() {
103
- const context = new RegistrationContext();
104
- this.contextStack.push(context);
105
- // Помещаем this в global stack для tracking текущего активного реестра
106
- ValidationRegistry.registryStack.push(this);
107
- return context;
108
- }
109
- /**
110
- * Завершить регистрацию и применить валидаторы к GroupNode
111
- *
112
- * Извлекает this из global stack
113
- *
114
- * Сохраняет валидаторы в локальном состоянии (this.validators) вместо глобального WeakMap.
115
- */
116
- endRegistration(form) {
117
- const context = this.contextStack.pop();
118
- if (!context) {
119
- throw new Error('No active registration context');
120
- }
121
- // Извлекаем из global stack с проверкой
122
- ValidationRegistry.registryStack.verify(this, 'ValidationRegistry');
123
- // Сохраняем валидаторы в локальном состоянии
124
- this.validators = context.getValidators();
125
- // Применяем валидаторы к полям
126
- this.applyValidators(form, this.validators);
127
- // Применяем array-items validators к ArrayNode элементам
128
- this.applyArrayItemValidators(form, this.validators);
129
- }
130
- /**
131
- * Отменить регистрацию без применения валидаторов
132
- * Используется для временной валидации (например, в validateForm)
133
- *
134
- * Извлекает this из global stack
135
- */
136
- cancelRegistration() {
137
- const context = this.contextStack.pop();
138
- if (!context) {
139
- throw new Error('No active registration context to cancel');
140
- }
141
- // Извлекаем из global stack с проверкой
142
- ValidationRegistry.registryStack.verify(this, 'ValidationRegistry');
143
- // Просто выбрасываем контекст без сохранения
144
- }
145
- /**
146
- * Получить текущий контекст регистрации
147
- */
148
- getCurrentContext() {
149
- return this.contextStack[this.contextStack.length - 1];
150
- }
151
- /**
152
- * Зарегистрировать синхронный валидатор
153
- */
154
- registerSync(fieldPath, validator, options) {
155
- const context = this.getCurrentContext();
156
- if (!context) {
157
- throw new Error('Validators can only be registered inside a validation schema function');
158
- }
159
- context.addValidator({
160
- fieldPath,
161
- type: 'sync',
162
- validator: validator,
163
- options,
164
- });
165
- }
166
- /**
167
- * Зарегистрировать асинхронный валидатор
168
- */
169
- registerAsync(fieldPath, validator, options) {
170
- const context = this.getCurrentContext();
171
- if (!context) {
172
- throw new Error('Validators can only be registered inside a validation schema function');
173
- }
174
- context.addValidator({
175
- fieldPath,
176
- type: 'async',
177
- validator: validator,
178
- options,
179
- });
180
- }
181
- /**
182
- * Зарегистрировать tree валидатор
183
- */
184
- registerTree(validator, options) {
185
- const context = this.getCurrentContext();
186
- if (!context) {
187
- throw new Error('Validators can only be registered inside a validation schema function');
188
- }
189
- context.addValidator({
190
- fieldPath: options?.targetField || '__tree__',
191
- type: 'tree',
192
- validator: validator,
193
- options,
194
- });
195
- }
196
- /**
197
- * Войти в условный блок
198
- */
199
- enterCondition(fieldPath, conditionFn) {
200
- const context = this.getCurrentContext();
201
- if (!context) {
202
- throw new Error('Conditions can only be used inside a validation schema function');
203
- }
204
- context.enterCondition(fieldPath, conditionFn);
205
- }
206
- /**
207
- * Выйти из условного блока
208
- */
209
- exitCondition() {
210
- const context = this.getCurrentContext();
211
- if (!context) {
212
- throw new Error('No active condition');
213
- }
214
- context.exitCondition();
215
- }
216
- /**
217
- * Зарегистрировать validation schema для элементов массива
218
- *
219
- * Используется функцией validateItems() для регистрации схемы валидации,
220
- * которая будет применяться к каждому элементу ArrayNode.
221
- *
222
- * @param fieldPath - Путь к ArrayNode полю
223
- * @param itemSchemaFn - Validation schema для элемента массива
224
- */
225
- registerArrayItemValidation(fieldPath, itemSchemaFn // ValidationSchemaFn<TItem>
226
- ) {
227
- const context = this.getCurrentContext();
228
- if (!context) {
229
- throw new Error('Array item validators can only be registered inside a validation schema function');
230
- }
231
- context.addValidator({
232
- fieldPath,
233
- type: 'array-items',
234
- validator: itemSchemaFn,
235
- options: {},
236
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
237
- });
238
- }
239
- /**
240
- * Получить зарегистрированные валидаторы для этого реестра
241
- *
242
- * Возвращает локальный массив валидаторов (без аргумента form).
243
- */
244
- getValidators() {
245
- return this.validators;
246
- }
247
- /**
248
- * Применить зарегистрированные валидаторы к GroupNode
249
- * @private
250
- */
251
- applyValidators(form, validators) {
252
- // Группируем валидаторы по полям
253
- const validatorsByField = new Map();
254
- for (const registration of validators) {
255
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
256
- if (registration.type === 'tree' || registration.type === 'array-items') {
257
- // Tree и array-items валидаторы обрабатываются отдельно
258
- continue;
259
- }
260
- const existing = validatorsByField.get(registration.fieldPath) || [];
261
- existing.push(registration);
262
- validatorsByField.set(registration.fieldPath, existing);
263
- }
264
- // Валидаторы сохранены в локальном массиве this.validators
265
- // Они будут применяться при вызове GroupNode.validate()
266
- if (import.meta.env.DEV) {
267
- console.log(`Registered ${validators.length} validators for GroupNode`);
268
- }
269
- }
270
- /**
271
- * Применить array-items validators к ArrayNode элементам
272
- * @private
273
- */
274
- applyArrayItemValidators(form, validators) {
275
- // Фильтруем array-items validators
276
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
277
- const arrayItemValidators = validators.filter((v) => v.type === 'array-items');
278
- if (arrayItemValidators.length === 0) {
279
- return;
280
- }
281
- // Применяем validation schema к каждому ArrayNode
282
- for (const registration of arrayItemValidators) {
283
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
284
- const arrayNode = form[registration.fieldPath.split('.')[0]];
285
- if (arrayNode && 'applyValidationSchema' in arrayNode) {
286
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
- const itemSchemaFn = registration.validator;
288
- arrayNode.applyValidationSchema(itemSchemaFn);
289
- if (import.meta.env.DEV) {
290
- console.log(`Applied validation schema to ArrayNode: ${registration.fieldPath}`);
291
- }
292
- }
293
- else if (import.meta.env.DEV) {
294
- console.warn(`Field ${registration.fieldPath} is not an ArrayNode or doesn't exist`);
295
- }
296
- }
297
- }
298
- }
@@ -1,86 +0,0 @@
1
- /**
2
- * Валидаторы для массивов
3
- *
4
- * Предоставляет специализированные функции для валидации ArrayNode:
5
- * - notEmpty: проверка что массив не пустой
6
- * - validateItems: применение validation schema к каждому элементу
7
- *
8
- * @group Validation
9
- * @category Validators
10
- */
11
- import { getCurrentValidationRegistry } from '../../utils/registry-helpers';
12
- import { extractPath } from '../field-path';
13
- import { minLength } from './min-length';
14
- // ============================================================================
15
- // notEmpty - Проверка что массив не пустой
16
- // ============================================================================
17
- /**
18
- * Проверить что массив содержит хотя бы один элемент
19
- *
20
- * Это удобный алиас для `minLength(field, 1)`, оптимизированный для массивов.
21
- *
22
- * @group Validation
23
- * @category Validators
24
- *
25
- * @param fieldPath - Поле-массив для валидации
26
- * @param options - Опции валидации (message, params и т.д.)
27
- *
28
- * @example
29
- * ```typescript
30
- * // Простая проверка
31
- * notEmpty(path.properties, { message: 'Добавьте хотя бы один объект имущества' });
32
- *
33
- * // С дополнительными параметрами
34
- * notEmpty(path.coBorrowers, {
35
- * message: 'Требуется хотя бы один созаемщик',
36
- * params: { minItems: 1 }
37
- * });
38
- * ```
39
- */
40
- export function notEmpty(fieldPath, options) {
41
- if (!fieldPath)
42
- return;
43
- // Используем minLength как базовую реализацию
44
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
- minLength(fieldPath, 1, {
46
- message: options?.message || 'Массив не должен быть пустым',
47
- params: { minLength: 1, ...options?.params },
48
- });
49
- }
50
- // ============================================================================
51
- // validateItems - Валидация элементов массива
52
- // ============================================================================
53
- /**
54
- * Применить validation schema к каждому элементу массива
55
- *
56
- * Регистрирует схему валидации, которая будет автоматически применяться
57
- * к каждому элементу ArrayNode (как существующим, так и новым).
58
- *
59
- * @group Validation
60
- * @category Validators
61
- *
62
- * @param fieldPath - Поле-массив для валидации элементов
63
- * @param itemSchemaFn - Validation schema для одного элемента
64
- *
65
- * @example
66
- * ```typescript
67
- * import { propertyValidation } from './property-validation';
68
- *
69
- * // В additionalValidation
70
- * applyWhen(path.hasProperty, (value) => value === true, (path) => {
71
- * // Проверка что массив не пустой
72
- * notEmpty(path.properties, { message: 'Добавьте хотя бы один объект имущества' });
73
- *
74
- * // Валидация каждого элемента
75
- * validateItems(path.properties, propertyValidation);
76
- * });
77
- * ```
78
- */
79
- export function validateItems(fieldPath, itemSchemaFn) {
80
- if (!fieldPath)
81
- return;
82
- const path = extractPath(fieldPath);
83
- // Регистрируем схему валидации для элементов массива
84
- // Используем текущий активный реестр из context stack
85
- getCurrentValidationRegistry().registerArrayItemValidation(path, itemSchemaFn);
86
- }
@@ -1,117 +0,0 @@
1
- /**
2
- * Валидатор даты
3
- *
4
- * @group Validation
5
- * @category Validators
6
- * @module validators/date
7
- */
8
- import { validate } from '../core/validate';
9
- /**
10
- * Адаптер для date валидатора
11
- * Проверяет, что значение является валидной датой и соответствует ограничениям
12
- *
13
- * @group Validation
14
- * @category Validators
15
- *
16
- * @example
17
- * ```typescript
18
- * date(path.birthDate);
19
- * date(path.birthDate, { maxDate: new Date() }); // Не позже сегодня
20
- * date(path.eventDate, { minDate: new Date(), message: 'Дата не может быть в прошлом' });
21
- * date(path.age, { minAge: 18, maxAge: 100 });
22
- * ```
23
- */
24
- export function date(fieldPath, options) {
25
- if (!fieldPath)
26
- return; // Защита от undefined fieldPath
27
- validate(fieldPath, (value) => {
28
- // Пропускаем null/undefined
29
- if (!value) {
30
- return null;
31
- }
32
- // Конвертируем в Date
33
- let dateValue;
34
- if (value instanceof Date) {
35
- dateValue = value;
36
- }
37
- else if (typeof value === 'string') {
38
- dateValue = new Date(value);
39
- }
40
- else {
41
- return {
42
- code: 'date_invalid',
43
- message: options?.message || 'Неверный формат даты',
44
- params: options?.params,
45
- };
46
- }
47
- // Проверка на валидность даты
48
- if (isNaN(dateValue.getTime())) {
49
- return {
50
- code: 'date_invalid',
51
- message: options?.message || 'Неверный формат даты',
52
- params: options?.params,
53
- };
54
- }
55
- const now = new Date();
56
- now.setHours(0, 0, 0, 0);
57
- // Проверка минимальной даты
58
- if (options?.minDate) {
59
- const minDate = new Date(options.minDate);
60
- minDate.setHours(0, 0, 0, 0);
61
- if (dateValue < minDate) {
62
- return {
63
- code: 'date_min',
64
- message: options?.message || `Дата должна быть не ранее ${minDate.toLocaleDateString()}`,
65
- params: { minDate: options.minDate, ...options?.params },
66
- };
67
- }
68
- }
69
- // Проверка максимальной даты
70
- if (options?.maxDate) {
71
- const maxDate = new Date(options.maxDate);
72
- maxDate.setHours(0, 0, 0, 0);
73
- if (dateValue > maxDate) {
74
- return {
75
- code: 'date_max',
76
- message: options?.message || `Дата должна быть не позднее ${maxDate.toLocaleDateString()}`,
77
- params: { maxDate: options.maxDate, ...options?.params },
78
- };
79
- }
80
- }
81
- // Проверка на будущую дату
82
- if (options?.noFuture && dateValue > now) {
83
- return {
84
- code: 'date_future',
85
- message: options?.message || 'Дата не может быть в будущем',
86
- params: options?.params,
87
- };
88
- }
89
- // Проверка на прошлую дату
90
- if (options?.noPast && dateValue < now) {
91
- return {
92
- code: 'date_past',
93
- message: options?.message || 'Дата не может быть в прошлом',
94
- params: options?.params,
95
- };
96
- }
97
- // Проверка возраста
98
- if (options?.minAge !== undefined || options?.maxAge !== undefined) {
99
- const age = Math.floor((now.getTime() - dateValue.getTime()) / (365.25 * 24 * 60 * 60 * 1000));
100
- if (options?.minAge !== undefined && age < options.minAge) {
101
- return {
102
- code: 'date_min_age',
103
- message: options?.message || `Минимальный возраст: ${options.minAge} лет`,
104
- params: { minAge: options.minAge, currentAge: age, ...options?.params },
105
- };
106
- }
107
- if (options?.maxAge !== undefined && age > options.maxAge) {
108
- return {
109
- code: 'date_max_age',
110
- message: options?.message || `Максимальный возраст: ${options.maxAge} лет`,
111
- params: { maxAge: options.maxAge, currentAge: age, ...options?.params },
112
- };
113
- }
114
- }
115
- return null;
116
- });
117
- }
@@ -1,60 +0,0 @@
1
- /**
2
- * Валидатор формата email
3
- *
4
- * @group Validation
5
- * @category Validators
6
- * @module validators/email
7
- */
8
- import { validate } from '../core/validate';
9
- /**
10
- * Валидатор формата email
11
- *
12
- * Проверяет, что значение соответствует формату email адреса.
13
- * Пустые значения пропускаются (используйте `required` для обязательности).
14
- *
15
- * @group Validation
16
- * @category Validators
17
- *
18
- * @param fieldPath - Путь к полю для валидации
19
- * @param options - Опции валидации (message, params)
20
- *
21
- * @example
22
- * ```typescript
23
- * // Базовое использование
24
- * validationSchema: (path) => [
25
- * required(path.email),
26
- * email(path.email),
27
- * ]
28
- *
29
- * // С кастомным сообщением
30
- * email(path.email, { message: 'Введите корректный email адрес' })
31
- * ```
32
- *
33
- * @example
34
- * ```typescript
35
- * // Ошибка валидации
36
- * {
37
- * code: 'email',
38
- * message: 'Неверный формат email',
39
- * params: {}
40
- * }
41
- * ```
42
- */
43
- export function email(fieldPath, options) {
44
- if (!fieldPath)
45
- return; // Защита от undefined fieldPath
46
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
47
- validate(fieldPath, (value) => {
48
- if (!value) {
49
- return null;
50
- }
51
- if (!emailRegex.test(value)) {
52
- return {
53
- code: 'email',
54
- message: options?.message || 'Неверный формат email',
55
- params: options?.params,
56
- };
57
- }
58
- return null;
59
- });
60
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Reusable validators
3
- */
4
- export { required } from './required';
5
- export { min } from './min';
6
- export { max } from './max';
7
- export { minLength } from './min-length';
8
- export { maxLength } from './max-length';
9
- export { email } from './email';
10
- export { pattern } from './pattern';
11
- export { url } from './url';
12
- export { phone } from './phone';
13
- export { number } from './number';
14
- export { date } from './date';
@@ -1,60 +0,0 @@
1
- /**
2
- * Валидатор максимальной длины строки
3
- *
4
- * @group Validation
5
- * @category Validators
6
- * @module validators/maxLength
7
- */
8
- import { validate } from '../core/validate';
9
- /**
10
- * Валидатор максимальной длины строки
11
- *
12
- * Проверяет, что длина строки не превышает указанный максимум.
13
- * Пустые значения пропускаются (используйте `required` для обязательности).
14
- *
15
- * @group Validation
16
- * @category Validators
17
- *
18
- * @param fieldPath - Путь к полю для валидации
19
- * @param maxLen - Максимальная допустимая длина строки
20
- * @param options - Опции валидации (message, params)
21
- *
22
- * @example
23
- * ```typescript
24
- * // Базовое использование
25
- * validationSchema: (path) => [
26
- * maxLength(path.name, 50),
27
- * maxLength(path.bio, 500),
28
- * ]
29
- *
30
- * // С кастомным сообщением
31
- * maxLength(path.bio, 500, { message: 'Максимум 500 символов' })
32
- * ```
33
- *
34
- * @example
35
- * ```typescript
36
- * // Ошибка валидации
37
- * {
38
- * code: 'maxLength',
39
- * message: 'Максимальная длина: 500 символов',
40
- * params: { maxLength: 500, actualLength: 512 }
41
- * }
42
- * ```
43
- */
44
- export function maxLength(fieldPath, maxLen, options) {
45
- if (!fieldPath)
46
- return; // Защита от undefined fieldPath
47
- validate(fieldPath, (value) => {
48
- if (!value) {
49
- return null;
50
- }
51
- if (value.length > maxLen) {
52
- return {
53
- code: 'maxLength',
54
- message: options?.message || `Максимальная длина: ${maxLen} символов`,
55
- params: { maxLength: maxLen, actualLength: value.length, ...options?.params },
56
- };
57
- }
58
- return null;
59
- });
60
- }