@reformer/core 1.1.0 → 2.0.0-beta.11

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 (221) hide show
  1. package/dist/behaviors/compute-from.d.ts +2 -0
  2. package/dist/behaviors/compute-from.js +31 -0
  3. package/dist/behaviors/copy-from.d.ts +2 -0
  4. package/dist/behaviors/copy-from.js +29 -0
  5. package/dist/behaviors/enable-when.d.ts +2 -0
  6. package/dist/behaviors/enable-when.js +25 -0
  7. package/dist/behaviors/reset-when.d.ts +2 -0
  8. package/dist/behaviors/reset-when.js +24 -0
  9. package/dist/behaviors/revalidate-when.d.ts +2 -0
  10. package/dist/behaviors/revalidate-when.js +18 -0
  11. package/dist/behaviors/sync-fields.d.ts +2 -0
  12. package/dist/behaviors/sync-fields.js +41 -0
  13. package/dist/behaviors/transform-value.d.ts +2 -0
  14. package/dist/behaviors/transform-value.js +45 -0
  15. package/dist/behaviors/watch-field.d.ts +2 -0
  16. package/dist/behaviors/watch-field.js +21 -0
  17. package/dist/behaviors.d.ts +6 -2
  18. package/dist/behaviors.js +27 -228
  19. package/dist/core/behavior/behavior-context.d.ts +32 -14
  20. package/dist/core/behavior/behavior-registry.d.ts +15 -27
  21. package/dist/core/behavior/behaviors/compute-from.d.ts +50 -21
  22. package/dist/core/behavior/behaviors/copy-from.d.ts +39 -14
  23. package/dist/core/behavior/behaviors/enable-when.d.ts +88 -19
  24. package/dist/core/behavior/behaviors/reset-when.d.ts +31 -18
  25. package/dist/core/behavior/behaviors/revalidate-when.d.ts +40 -17
  26. package/dist/core/behavior/behaviors/sync-fields.d.ts +34 -14
  27. package/dist/core/behavior/behaviors/transform-value.d.ts +116 -44
  28. package/dist/core/behavior/behaviors/watch-field.d.ts +66 -21
  29. package/dist/core/behavior/compose-behavior.d.ts +2 -12
  30. package/dist/core/behavior/index.d.ts +0 -1
  31. package/dist/core/behavior/types.d.ts +2 -8
  32. package/dist/core/factories/node-factory.d.ts +6 -29
  33. package/dist/core/nodes/array-node.d.ts +42 -22
  34. package/dist/core/nodes/field-node.d.ts +51 -26
  35. package/dist/core/nodes/form-node.d.ts +18 -20
  36. package/dist/core/nodes/group-node.d.ts +37 -212
  37. package/dist/core/types/deep-schema.d.ts +2 -12
  38. package/dist/core/types/field-path.d.ts +1 -1
  39. package/dist/core/types/form-context.d.ts +36 -30
  40. package/dist/core/types/{group-node-proxy.d.ts → form-proxy.d.ts} +12 -42
  41. package/dist/core/types/index.d.ts +52 -6
  42. package/dist/core/types/validation-schema.d.ts +3 -12
  43. package/dist/core/utils/abstract-registry.d.ts +74 -0
  44. package/dist/core/utils/aggregate-signals.d.ts +71 -0
  45. package/dist/core/utils/create-form.d.ts +3 -20
  46. package/dist/core/utils/error-handler.d.ts +1 -18
  47. package/dist/core/utils/field-path-navigator.d.ts +1 -1
  48. package/dist/core/{validation → utils}/field-path.d.ts +23 -6
  49. package/dist/core/utils/form-observer.d.ts +176 -0
  50. package/dist/core/utils/form-proxy-builder.d.ts +25 -0
  51. package/dist/core/utils/form-submitter.d.ts +121 -0
  52. package/dist/core/utils/index.d.ts +10 -2
  53. package/dist/core/utils/registry-helpers.d.ts +0 -7
  54. package/dist/core/utils/safe-effect.d.ts +73 -0
  55. package/dist/core/utils/status-machine.d.ts +153 -0
  56. package/dist/core/utils/type-guards.d.ts +5 -23
  57. package/dist/core/utils/unique-id.d.ts +53 -0
  58. package/dist/core/validation/core/apply-when.d.ts +3 -9
  59. package/dist/core/validation/core/apply.d.ts +2 -13
  60. package/dist/core/validation/core/validate-async.d.ts +2 -8
  61. package/dist/core/validation/core/validate-tree.d.ts +10 -10
  62. package/dist/core/validation/core/validate.d.ts +1 -7
  63. package/dist/core/validation/index.d.ts +8 -2
  64. package/dist/core/validation/validate-form.d.ts +1 -38
  65. package/dist/core/validation/validation-applicator.d.ts +2 -21
  66. package/dist/core/validation/validation-context.d.ts +67 -28
  67. package/dist/core/validation/validation-registry.d.ts +11 -25
  68. package/dist/core/validation/validators/array-validators.d.ts +2 -12
  69. package/dist/core/validation/validators/date-utils.d.ts +26 -0
  70. package/dist/core/validation/validators/email.d.ts +2 -9
  71. package/dist/core/validation/validators/future-date.d.ts +35 -0
  72. package/dist/core/validation/validators/index.d.ts +7 -1
  73. package/dist/core/validation/validators/is-date.d.ts +36 -0
  74. package/dist/core/validation/validators/max-age.d.ts +36 -0
  75. package/dist/core/validation/validators/max-date.d.ts +36 -0
  76. package/dist/core/validation/validators/max-length.d.ts +3 -10
  77. package/dist/core/validation/validators/max.d.ts +3 -10
  78. package/dist/core/validation/validators/min-age.d.ts +36 -0
  79. package/dist/core/validation/validators/min-date.d.ts +36 -0
  80. package/dist/core/validation/validators/min-length.d.ts +3 -10
  81. package/dist/core/validation/validators/min.d.ts +3 -10
  82. package/dist/core/validation/validators/number.d.ts +2 -9
  83. package/dist/core/validation/validators/past-date.d.ts +35 -0
  84. package/dist/core/validation/validators/pattern.d.ts +2 -9
  85. package/dist/core/validation/validators/phone.d.ts +2 -9
  86. package/dist/core/validation/validators/required.d.ts +2 -9
  87. package/dist/core/validation/validators/url.d.ts +2 -9
  88. package/dist/date-utils-xUWFslTj.js +29 -0
  89. package/dist/field-path-DuKdGcIE.js +66 -0
  90. package/dist/hooks/types.d.ts +328 -0
  91. package/dist/hooks/useArrayLength.d.ts +31 -0
  92. package/dist/hooks/useFormControl.d.ts +15 -39
  93. package/dist/hooks/useFormControlValue.d.ts +167 -0
  94. package/dist/hooks/useHiddenCondition.d.ts +25 -0
  95. package/dist/hooks/useSignalSubscription.d.ts +17 -0
  96. package/dist/index-D25LsbRm.js +73 -0
  97. package/dist/index.d.ts +8 -1
  98. package/dist/index.js +3271 -8
  99. package/dist/registry-helpers-Bv_BJ1s-.js +615 -0
  100. package/dist/safe-effect-Dh8uw81c.js +20 -0
  101. package/dist/validate-C3XiA_zf.js +10 -0
  102. package/dist/validators/email.d.ts +2 -0
  103. package/dist/validators/email.js +13 -0
  104. package/dist/validators/future-date.d.ts +2 -0
  105. package/dist/validators/future-date.js +20 -0
  106. package/dist/validators/is-date.d.ts +2 -0
  107. package/dist/validators/is-date.js +12 -0
  108. package/dist/validators/max-age.d.ts +2 -0
  109. package/dist/validators/max-age.js +20 -0
  110. package/dist/validators/max-date.d.ts +2 -0
  111. package/dist/validators/max-date.js +20 -0
  112. package/dist/validators/max-length.d.ts +2 -0
  113. package/dist/validators/max-length.js +11 -0
  114. package/dist/validators/max.d.ts +2 -0
  115. package/dist/validators/max.js +11 -0
  116. package/dist/validators/min-age.d.ts +2 -0
  117. package/dist/validators/min-age.js +20 -0
  118. package/dist/validators/min-date.d.ts +2 -0
  119. package/dist/validators/min-date.js +20 -0
  120. package/dist/validators/min-length.d.ts +2 -0
  121. package/dist/validators/min-length.js +11 -0
  122. package/dist/validators/min.d.ts +2 -0
  123. package/dist/validators/min.js +11 -0
  124. package/dist/validators/number.d.ts +2 -0
  125. package/dist/validators/number.js +35 -0
  126. package/dist/validators/past-date.d.ts +2 -0
  127. package/dist/validators/past-date.js +20 -0
  128. package/dist/validators/pattern.d.ts +2 -0
  129. package/dist/validators/pattern.js +11 -0
  130. package/dist/validators/phone.d.ts +2 -0
  131. package/dist/validators/phone.js +35 -0
  132. package/dist/validators/required.d.ts +2 -0
  133. package/dist/validators/required.js +15 -0
  134. package/dist/validators/url.d.ts +2 -0
  135. package/dist/validators/url.js +19 -0
  136. package/dist/validators-BGsNOgT1.js +207 -0
  137. package/dist/validators.d.ts +6 -2
  138. package/dist/validators.js +54 -296
  139. package/llms.txt +8887 -59
  140. package/package.json +87 -8
  141. package/dist/core/behavior/behavior-applicator.d.ts +0 -71
  142. package/dist/core/behavior/behavior-applicator.js +0 -92
  143. package/dist/core/behavior/behavior-context.js +0 -38
  144. package/dist/core/behavior/behavior-registry.js +0 -198
  145. package/dist/core/behavior/behaviors/compute-from.js +0 -84
  146. package/dist/core/behavior/behaviors/copy-from.js +0 -64
  147. package/dist/core/behavior/behaviors/enable-when.js +0 -81
  148. package/dist/core/behavior/behaviors/index.js +0 -11
  149. package/dist/core/behavior/behaviors/reset-when.js +0 -63
  150. package/dist/core/behavior/behaviors/revalidate-when.js +0 -51
  151. package/dist/core/behavior/behaviors/sync-fields.js +0 -66
  152. package/dist/core/behavior/behaviors/transform-value.js +0 -110
  153. package/dist/core/behavior/behaviors/watch-field.js +0 -56
  154. package/dist/core/behavior/compose-behavior.js +0 -166
  155. package/dist/core/behavior/create-field-path.d.ts +0 -20
  156. package/dist/core/behavior/create-field-path.js +0 -69
  157. package/dist/core/behavior/index.js +0 -17
  158. package/dist/core/behavior/types.js +0 -7
  159. package/dist/core/context/form-context-impl.d.ts +0 -29
  160. package/dist/core/context/form-context-impl.js +0 -37
  161. package/dist/core/factories/index.js +0 -6
  162. package/dist/core/factories/node-factory.js +0 -281
  163. package/dist/core/nodes/array-node.js +0 -534
  164. package/dist/core/nodes/field-node.js +0 -510
  165. package/dist/core/nodes/form-node.js +0 -343
  166. package/dist/core/nodes/group-node/field-registry.d.ts +0 -191
  167. package/dist/core/nodes/group-node/field-registry.js +0 -215
  168. package/dist/core/nodes/group-node/index.d.ts +0 -11
  169. package/dist/core/nodes/group-node/index.js +0 -11
  170. package/dist/core/nodes/group-node/proxy-builder.d.ts +0 -71
  171. package/dist/core/nodes/group-node/proxy-builder.js +0 -161
  172. package/dist/core/nodes/group-node/state-manager.d.ts +0 -184
  173. package/dist/core/nodes/group-node/state-manager.js +0 -265
  174. package/dist/core/nodes/group-node.js +0 -770
  175. package/dist/core/types/deep-schema.js +0 -11
  176. package/dist/core/types/field-path.js +0 -4
  177. package/dist/core/types/form-context.js +0 -25
  178. package/dist/core/types/group-node-proxy.js +0 -31
  179. package/dist/core/types/index.js +0 -4
  180. package/dist/core/types/validation-schema.js +0 -10
  181. package/dist/core/utils/create-form.js +0 -24
  182. package/dist/core/utils/debounce.d.ts +0 -160
  183. package/dist/core/utils/debounce.js +0 -197
  184. package/dist/core/utils/error-handler.js +0 -226
  185. package/dist/core/utils/field-path-navigator.js +0 -374
  186. package/dist/core/utils/index.js +0 -14
  187. package/dist/core/utils/registry-helpers.js +0 -79
  188. package/dist/core/utils/registry-stack.js +0 -86
  189. package/dist/core/utils/resources.d.ts +0 -41
  190. package/dist/core/utils/resources.js +0 -69
  191. package/dist/core/utils/subscription-manager.js +0 -214
  192. package/dist/core/utils/type-guards.js +0 -169
  193. package/dist/core/validation/core/apply-when.js +0 -41
  194. package/dist/core/validation/core/apply.js +0 -38
  195. package/dist/core/validation/core/index.js +0 -8
  196. package/dist/core/validation/core/validate-async.js +0 -45
  197. package/dist/core/validation/core/validate-tree.js +0 -37
  198. package/dist/core/validation/core/validate.js +0 -38
  199. package/dist/core/validation/field-path.js +0 -147
  200. package/dist/core/validation/index.js +0 -33
  201. package/dist/core/validation/validate-form.js +0 -152
  202. package/dist/core/validation/validation-applicator.js +0 -217
  203. package/dist/core/validation/validation-context.js +0 -75
  204. package/dist/core/validation/validation-registry.js +0 -298
  205. package/dist/core/validation/validators/array-validators.js +0 -86
  206. package/dist/core/validation/validators/date.d.ts +0 -38
  207. package/dist/core/validation/validators/date.js +0 -117
  208. package/dist/core/validation/validators/email.js +0 -60
  209. package/dist/core/validation/validators/index.js +0 -14
  210. package/dist/core/validation/validators/max-length.js +0 -60
  211. package/dist/core/validation/validators/max.js +0 -60
  212. package/dist/core/validation/validators/min-length.js +0 -60
  213. package/dist/core/validation/validators/min.js +0 -60
  214. package/dist/core/validation/validators/number.js +0 -90
  215. package/dist/core/validation/validators/pattern.js +0 -62
  216. package/dist/core/validation/validators/phone.js +0 -58
  217. package/dist/core/validation/validators/required.js +0 -69
  218. package/dist/core/validation/validators/url.js +0 -55
  219. package/dist/create-field-path-CdPF3lIK.js +0 -704
  220. package/dist/hooks/useFormControl.js +0 -298
  221. package/dist/node-factory-D7DOnSSN.js +0 -3200
@@ -1,75 +0,0 @@
1
- /**
2
- * Реализация контекста валидации
3
- */
4
- import { isFormNode } from '../utils/type-guards';
5
- // ============================================================================
6
- // Field Validation Context (для обычных валидаторов)
7
- // ============================================================================
8
- /**
9
- * Реализация контекста валидации для отдельного поля
10
- * Реализует FormContext
11
- */
12
- export class ValidationContextImpl {
13
- _form;
14
- control;
15
- /**
16
- * Форма с типизированным Proxy-доступом к полям
17
- */
18
- form;
19
- constructor(form, _fieldKey, control) {
20
- this._form = form;
21
- this.control = control;
22
- // Получаем Proxy для типизированного доступа
23
- this.form = (form
24
- ._proxyInstance || form.getProxy());
25
- }
26
- /**
27
- * Получить текущее значение поля (внутренний метод для validation-applicator)
28
- * @internal
29
- */
30
- value() {
31
- return this.control.value.value;
32
- }
33
- /**
34
- * Безопасно установить значение поля по строковому пути
35
- * Автоматически использует emitEvent: false для предотвращения циклов
36
- */
37
- setFieldValue(path, value) {
38
- const node = this._form.getFieldByPath(path);
39
- if (node && isFormNode(node)) {
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- node.setValue(value, { emitEvent: false });
42
- }
43
- }
44
- }
45
- // ============================================================================
46
- // Tree Validation Context (для cross-field валидаторов)
47
- // ============================================================================
48
- /**
49
- * Реализация контекста для cross-field валидации
50
- * Реализует FormContext
51
- */
52
- export class TreeValidationContextImpl {
53
- _form;
54
- /**
55
- * Форма с типизированным Proxy-доступом к полям
56
- */
57
- form;
58
- constructor(form) {
59
- this._form = form;
60
- // Получаем Proxy для типизированного доступа
61
- this.form = (form
62
- ._proxyInstance || form.getProxy());
63
- }
64
- /**
65
- * Безопасно установить значение поля по строковому пути
66
- * Автоматически использует emitEvent: false для предотвращения циклов
67
- */
68
- setFieldValue(path, value) {
69
- const node = this._form.getFieldByPath(path);
70
- if (node && isFormNode(node)) {
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- node.setValue(value, { emitEvent: false });
73
- }
74
- }
75
- }
@@ -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,38 +0,0 @@
1
- /**
2
- * Валидатор даты
3
- *
4
- * @group Validation
5
- * @category Validators
6
- * @module validators/date
7
- */
8
- import type { ValidateOptions } from '../../types/validation-schema';
9
- import type { FieldPathNode } from '../../types';
10
- /**
11
- * Адаптер для date валидатора
12
- * Проверяет, что значение является валидной датой и соответствует ограничениям
13
- *
14
- * @group Validation
15
- * @category Validators
16
- *
17
- * @example
18
- * ```typescript
19
- * date(path.birthDate);
20
- * date(path.birthDate, { maxDate: new Date() }); // Не позже сегодня
21
- * date(path.eventDate, { minDate: new Date(), message: 'Дата не может быть в прошлом' });
22
- * date(path.age, { minAge: 18, maxAge: 100 });
23
- * ```
24
- */
25
- export declare function date<TForm, TField extends string | Date | undefined = string | Date>(fieldPath: FieldPathNode<TForm, TField> | undefined, options?: ValidateOptions & {
26
- /** Минимальная дата (включительно) */
27
- minDate?: Date;
28
- /** Максимальная дата (включительно) */
29
- maxDate?: Date;
30
- /** Минимальный возраст (для дат рождения) */
31
- minAge?: number;
32
- /** Максимальный возраст (для дат рождения) */
33
- maxAge?: number;
34
- /** Не разрешать будущие даты */
35
- noFuture?: boolean;
36
- /** Не разрешать прошлые даты */
37
- noPast?: boolean;
38
- }): void;
@@ -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';