adaptform 2.0.3 → 2.0.5

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.
@@ -170,7 +170,7 @@ type FieldTypeConstructor<T, O extends FieldOptions = FieldOptions> = new (optio
170
170
  declare class Field<T = any, O extends FieldOptions = FieldOptions> {
171
171
  protected _rawValue: any;
172
172
  protected _valueClear: T | null;
173
- protected filed_type: FieldType<T, O>;
173
+ protected fieldType: FieldType<T, O>;
174
174
  protected defaultValue: T | null;
175
175
  protected _errors: string[];
176
176
  isValid: boolean | null;
@@ -192,15 +192,95 @@ declare class Field<T = any, O extends FieldOptions = FieldOptions> {
192
192
  reset(): void;
193
193
  }
194
194
 
195
+ interface ParsedError {
196
+ fieldName: string;
197
+ message: string;
198
+ sourceKey: string;
199
+ matchedBy: 'static' | 'dynamic' | 'fallback';
200
+ }
201
+ declare class ErrorsSchema {
202
+ private _staticRules;
203
+ private _dynamicRules;
204
+ private _fallbackHandler?;
205
+ private _valueTransformers;
206
+ /**
207
+ * Добавляет статическое правило - точное соответствие ключа ошибки
208
+ * @param errorKey - точный ключ ошибки из ответа сервера
209
+ * @param fieldName - имя поля в форме или функция для динамического определения
210
+ */
211
+ staticKey(errorKey: string, fieldName: string | ((errorValue: any) => string)): this;
212
+ /**
213
+ * Добавляет динамическое правило с регулярным выражением
214
+ * @param pattern - регулярное выражение для сопоставления ключа ошибки
215
+ * @param mapping - имя поля или функция для извлечения имени поля из совпадения
216
+ * @param options - дополнительные опции (приоритет и т.д.)
217
+ */
218
+ dynamicKey(pattern: RegExp, mapping: string | ((match: RegExpMatchArray) => string), options?: {
219
+ priority?: number;
220
+ }): this;
221
+ /**
222
+ * Устанавливает обработчик для ошибок, которые не подошли ни под одно правило
223
+ */
224
+ fallback(handler: (key: string, value: any) => string | null): this;
225
+ /**
226
+ * Добавляет трансформер для значений ошибок
227
+ * Полезно для нормализации сообщений (например, если сервер возвращает массив ошибок)
228
+ */
229
+ transformValue(transformer: (value: any) => any): this;
230
+ /**
231
+ * Быстрый метод для создания схемы из простого объекта маппинга
232
+ */
233
+ static fromObject(mapping: Record<string, string>): ErrorsSchema;
234
+ /**
235
+ * Создает схему для массива однотипных форм
236
+ */
237
+ static forArray(itemSchema: ErrorsSchema, arrayFieldName: string, indexExtractor?: (key: string) => number): ErrorsSchema;
238
+ /**
239
+ * Основной метод парсинга ошибок с поддержкой трансформеров
240
+ * Поддерживает вложенные структуры через точечную нотацию
241
+ */
242
+ parseErrors(errors: Record<string, any>, prefix?: string): Record<string, string>;
243
+ /**
244
+ * Парсит ошибки сервера и возвращает расширенную информацию
245
+ */
246
+ parseErrorsDetailed(errors: Record<string, any>, prefix?: string): Record<string, ParsedError>;
247
+ /**
248
+ * Создает схему для вложенной формы
249
+ */
250
+ nest(prefix: string): ErrorsSchema;
251
+ /**
252
+ * Клонирует текущую схему
253
+ */
254
+ clone(): ErrorsSchema;
255
+ /**
256
+ * Объединяет текущую схему с другой
257
+ */
258
+ merge(other: ErrorsSchema): ErrorsSchema;
259
+ private isNestedObject;
260
+ private findMappingDetailed;
261
+ private findMapping;
262
+ }
263
+
195
264
  declare abstract class Form {
196
265
  private _globalErrors;
266
+ errorsShema: ErrorsSchema;
197
267
  protected get _fields(): Record<string, Field<any> | ArrayField<any> | ArrayFormField<any>>;
198
268
  checkValid(form?: this): boolean;
199
269
  get fieldsValue(): Record<string, any>;
200
270
  set fields(data: Record<string, any>);
201
271
  get allErrors(): Record<string, string[]>;
272
+ /**
273
+ * Рекурсивно собирает все ошибки из ArrayFormField
274
+ */
275
+ private collectArrayFormErrors;
202
276
  get globalErrors(): Record<string, string>;
203
- set errors(errors: Record<string, string>);
277
+ set errors(errors: Record<string, any>);
278
+ /**
279
+ * Применяет ошибку к соответствующему полю
280
+ * Поддерживает вложенные поля через точечную нотацию
281
+ */
282
+ private applyErrorToField;
283
+ private applyNestedError;
204
284
  setGlobalError(key: string, message: string): void;
205
285
  clearGlobalErrors(): void;
206
286
  reset(): void;
@@ -210,4 +290,4 @@ declare abstract class Form {
210
290
  toJSON(): Record<string, any>;
211
291
  }
212
292
 
213
- export { type ArrayFieldOptions as A, BasePlugin as B, type DecimalOptions as D, Field as F, type MaskPluginOptions as M, type NumberOptions as N, type PluginOptions as P, type StringOptions as S, FieldType as a, type BooleanOptions as b, type DateOptions as c, Form as d, type messagesStringOptions as e, type messagesNumberOptions as f, type messagesBooleanOptions as g, type messagesDateOptions as h, type messagesDecimalOptions as i, type messagesArrayFieldOptions as j, type messagesArrayFormFieldOptions as k, type FieldOptions as l, type messagesOptions as m, type ArrayFormFieldOptions as n, ArrayField as o, ArrayFormField as p, type FieldPlugin as q };
293
+ export { ArrayField as A, BasePlugin as B, type DecimalOptions as D, Field as F, type MaskPluginOptions as M, type NumberOptions as N, type PluginOptions as P, type StringOptions as S, FieldType as a, type BooleanOptions as b, type DateOptions as c, type ArrayFieldOptions as d, ArrayFormField as e, type ArrayFormFieldOptions as f, type FieldOptions as g, type FieldPlugin as h, Form as i, type messagesArrayFormFieldOptions as j, type messagesBooleanOptions as k, type messagesDateOptions as l, type messagesArrayFieldOptions as m, type messagesDecimalOptions as n, type messagesNumberOptions as o, type messagesOptions as p, type messagesStringOptions as q };
package/dist/index.cjs CHANGED
@@ -8,7 +8,7 @@ var Field = class {
8
8
  this._errors = [];
9
9
  this.isValid = null;
10
10
  this.isTouched = false;
11
- this.filed_type = new TypeConstructor(options ?? {});
11
+ this.fieldType = new TypeConstructor(options ?? {});
12
12
  this.defaultValue = defaultValue ?? null;
13
13
  for (const plugin of this.options.plugins ?? []) {
14
14
  plugin.init?.(this);
@@ -28,11 +28,11 @@ var Field = class {
28
28
  });
29
29
  }
30
30
  get options() {
31
- return this.filed_type.options;
31
+ return this.fieldType.options;
32
32
  }
33
33
  set options(options) {
34
- let cur_options = this.filed_type.options;
35
- this.filed_type.options = Object.assign(cur_options, options);
34
+ let cur_options = this.fieldType.options;
35
+ this.fieldType.options = Object.assign(cur_options, options);
36
36
  }
37
37
  get rawValue() {
38
38
  return this._rawValue;
@@ -51,7 +51,7 @@ var Field = class {
51
51
  }
52
52
  }
53
53
  this._rawValue = rawValue;
54
- this._valueClear = this.filed_type.cast(valueClear);
54
+ this._valueClear = this.fieldType.cast(valueClear);
55
55
  this._errors = [];
56
56
  this.isTouched = true;
57
57
  this.checkAndSetValid();
@@ -94,11 +94,11 @@ var Field = class {
94
94
  }
95
95
  if (this._valueClear === null) {
96
96
  this._errors.push(
97
- this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.filed_type.getTypeName()}`
97
+ this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.fieldType.getTypeName()}`
98
98
  );
99
99
  return false;
100
100
  }
101
- const typeErrors = this.filed_type.validate(this._valueClear, form);
101
+ const typeErrors = this.fieldType.validate(this._valueClear, form);
102
102
  if (typeErrors.length > 0) {
103
103
  this._errors.push(...typeErrors);
104
104
  return false;
@@ -131,7 +131,6 @@ var Field = class {
131
131
  reset() {
132
132
  if (this.defaultValue !== null && this.defaultValue !== void 0) {
133
133
  this.rawValue = this.defaultValue;
134
- this.isValid = true;
135
134
  } else {
136
135
  this._rawValue = null;
137
136
  this._valueClear = null;
@@ -155,6 +154,7 @@ var ArrayField = class {
155
154
  ...options
156
155
  };
157
156
  this._items = initial.map((v) => this.factory(v));
157
+ this.checkValid();
158
158
  }
159
159
  // ===== value =====
160
160
  set itemsValue(items) {
@@ -222,7 +222,8 @@ var ArrayField = class {
222
222
  if (!ok) valid = false;
223
223
  }
224
224
  if (this.options.validate) {
225
- const result = this.options.validate(this._items, form);
225
+ const values = this._items.map((i) => i.valueClear);
226
+ const result = this.options.validate(values, form);
226
227
  if (result === false) {
227
228
  this._errors.push(
228
229
  this.options.messages?.validate ?? "\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u0438"
@@ -240,7 +241,8 @@ var ArrayField = class {
240
241
  return this.checkValid(form);
241
242
  }
242
243
  get isValid() {
243
- return this._errors.length === 0 && this._items.every((i) => i.isValid === true);
244
+ if (this._errors.length > 0) return false;
245
+ return this._items.every((i) => i.isValid === true);
244
246
  }
245
247
  get error() {
246
248
  return this._errors[0] ?? "";
@@ -275,6 +277,7 @@ var ArrayFormField = class {
275
277
  form.fields = data;
276
278
  return form;
277
279
  });
280
+ this.checkValid();
278
281
  }
279
282
  // ===== value =====
280
283
  set forms(forms) {
@@ -366,7 +369,8 @@ var ArrayFormField = class {
366
369
  return this.checkValid(form);
367
370
  }
368
371
  get isValid() {
369
- return this._errors.length === 0 && this._forms.every((i) => i.checkValid() === true);
372
+ if (this._errors.length > 0) return false;
373
+ return this._forms.every((i) => i.checkValid() === true);
370
374
  }
371
375
  get errors() {
372
376
  return this._errors;
@@ -383,10 +387,255 @@ var ArrayFormField = class {
383
387
  }
384
388
  };
385
389
 
390
+ // src/core/ErrorsShema.ts
391
+ var ErrorsSchema = class _ErrorsSchema {
392
+ constructor() {
393
+ this._staticRules = /* @__PURE__ */ new Map();
394
+ this._dynamicRules = [];
395
+ this._valueTransformers = [];
396
+ }
397
+ /**
398
+ * Добавляет статическое правило - точное соответствие ключа ошибки
399
+ * @param errorKey - точный ключ ошибки из ответа сервера
400
+ * @param fieldName - имя поля в форме или функция для динамического определения
401
+ */
402
+ staticKey(errorKey, fieldName) {
403
+ this._staticRules.set(errorKey, fieldName);
404
+ return this;
405
+ }
406
+ /**
407
+ * Добавляет динамическое правило с регулярным выражением
408
+ * @param pattern - регулярное выражение для сопоставления ключа ошибки
409
+ * @param mapping - имя поля или функция для извлечения имени поля из совпадения
410
+ * @param options - дополнительные опции (приоритет и т.д.)
411
+ */
412
+ dynamicKey(pattern, mapping, options) {
413
+ this._dynamicRules.push({
414
+ pattern,
415
+ mapping,
416
+ priority: options?.priority ?? 0
417
+ });
418
+ this._dynamicRules.sort((a, b) => b.priority - a.priority);
419
+ return this;
420
+ }
421
+ /**
422
+ * Устанавливает обработчик для ошибок, которые не подошли ни под одно правило
423
+ */
424
+ fallback(handler) {
425
+ this._fallbackHandler = handler;
426
+ return this;
427
+ }
428
+ /**
429
+ * Добавляет трансформер для значений ошибок
430
+ * Полезно для нормализации сообщений (например, если сервер возвращает массив ошибок)
431
+ */
432
+ transformValue(transformer) {
433
+ this._valueTransformers.push(transformer);
434
+ return this;
435
+ }
436
+ /**
437
+ * Быстрый метод для создания схемы из простого объекта маппинга
438
+ */
439
+ static fromObject(mapping) {
440
+ const schema = new _ErrorsSchema();
441
+ for (const [errorKey, fieldName] of Object.entries(mapping)) {
442
+ schema.staticKey(errorKey, fieldName);
443
+ }
444
+ return schema;
445
+ }
446
+ /**
447
+ * Создает схему для массива однотипных форм
448
+ */
449
+ static forArray(itemSchema, arrayFieldName, indexExtractor) {
450
+ const schema = new _ErrorsSchema();
451
+ schema.dynamicKey(
452
+ new RegExp(`^${arrayFieldName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\[(\\d+)\\]\\.(.+)$`),
453
+ (match) => {
454
+ const index = match[1];
455
+ const fieldName = match[2];
456
+ return `${arrayFieldName}.${index}.${fieldName}`;
457
+ },
458
+ { priority: 100 }
459
+ );
460
+ return schema;
461
+ }
462
+ /**
463
+ * Основной метод парсинга ошибок с поддержкой трансформеров
464
+ * Поддерживает вложенные структуры через точечную нотацию
465
+ */
466
+ parseErrors(errors, prefix = "") {
467
+ const result = {};
468
+ for (const [key, value] of Object.entries(errors)) {
469
+ const fullKey = prefix ? `${prefix}.${key}` : key;
470
+ if (this.isNestedObject(value)) {
471
+ const nestedErrors = this.parseErrors(value, fullKey);
472
+ Object.assign(result, nestedErrors);
473
+ continue;
474
+ }
475
+ if (value === null || value === void 0) {
476
+ continue;
477
+ }
478
+ let transformedValue = value;
479
+ for (const transformer of this._valueTransformers) {
480
+ transformedValue = transformer(transformedValue);
481
+ }
482
+ const mapping = this.findMapping(fullKey, transformedValue);
483
+ if (mapping) {
484
+ if (typeof mapping === "function") {
485
+ const fieldName = mapping(transformedValue);
486
+ if (fieldName) {
487
+ result[fieldName] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
488
+ }
489
+ } else {
490
+ result[mapping] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
491
+ }
492
+ } else if (this._fallbackHandler) {
493
+ const fieldName = this._fallbackHandler(fullKey, transformedValue);
494
+ if (fieldName) {
495
+ result[fieldName] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
496
+ }
497
+ }
498
+ }
499
+ return result;
500
+ }
501
+ /**
502
+ * Парсит ошибки сервера и возвращает расширенную информацию
503
+ */
504
+ parseErrorsDetailed(errors, prefix = "") {
505
+ const result = {};
506
+ for (const [key, value] of Object.entries(errors)) {
507
+ const fullKey = prefix ? `${prefix}.${key}` : key;
508
+ if (this.isNestedObject(value)) {
509
+ const nestedErrors = this.parseErrorsDetailed(value, fullKey);
510
+ Object.assign(result, nestedErrors);
511
+ continue;
512
+ }
513
+ if (value === null || value === void 0) {
514
+ continue;
515
+ }
516
+ let transformedValue = value;
517
+ for (const transformer of this._valueTransformers) {
518
+ transformedValue = transformer(transformedValue);
519
+ }
520
+ const matchResult = this.findMappingDetailed(fullKey, transformedValue);
521
+ if (matchResult) {
522
+ const message = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
523
+ result[matchResult.fieldName] = {
524
+ fieldName: matchResult.fieldName,
525
+ message,
526
+ sourceKey: fullKey,
527
+ matchedBy: matchResult.matchedBy
528
+ };
529
+ }
530
+ }
531
+ return result;
532
+ }
533
+ /**
534
+ * Создает схему для вложенной формы
535
+ */
536
+ nest(prefix) {
537
+ const nestedSchema = new _ErrorsSchema();
538
+ for (const [key, mapping] of this._staticRules.entries()) {
539
+ nestedSchema.staticKey(`${prefix}.${key}`, mapping);
540
+ }
541
+ for (const rule of this._dynamicRules) {
542
+ const newPattern = new RegExp(`^${prefix}\\.${rule.pattern.source.replace(/^\^/, "")}`);
543
+ nestedSchema.dynamicKey(newPattern, rule.mapping, { priority: rule.priority });
544
+ }
545
+ for (const transformer of this._valueTransformers) {
546
+ nestedSchema.transformValue(transformer);
547
+ }
548
+ if (this._fallbackHandler) {
549
+ nestedSchema.fallback((key, value) => {
550
+ if (key.startsWith(`${prefix}.`)) {
551
+ return this._fallbackHandler(key.slice(prefix.length + 1), value);
552
+ }
553
+ return null;
554
+ });
555
+ }
556
+ return nestedSchema;
557
+ }
558
+ /**
559
+ * Клонирует текущую схему
560
+ */
561
+ clone() {
562
+ const cloned = new _ErrorsSchema();
563
+ for (const [key, mapping] of this._staticRules.entries()) {
564
+ cloned._staticRules.set(key, mapping);
565
+ }
566
+ for (const rule of this._dynamicRules) {
567
+ cloned._dynamicRules.push({ ...rule });
568
+ }
569
+ cloned._fallbackHandler = this._fallbackHandler;
570
+ cloned._valueTransformers = [...this._valueTransformers];
571
+ return cloned;
572
+ }
573
+ /**
574
+ * Объединяет текущую схему с другой
575
+ */
576
+ merge(other) {
577
+ const merged = this.clone();
578
+ for (const [key, mapping] of other._staticRules.entries()) {
579
+ merged._staticRules.set(key, mapping);
580
+ }
581
+ merged._dynamicRules.push(...other._dynamicRules);
582
+ merged._dynamicRules.sort((a, b) => b.priority - a.priority);
583
+ merged._valueTransformers.push(...other._valueTransformers);
584
+ if (other._fallbackHandler) {
585
+ merged._fallbackHandler = other._fallbackHandler;
586
+ }
587
+ return merged;
588
+ }
589
+ isNestedObject(value) {
590
+ return value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
591
+ }
592
+ findMappingDetailed(key, value) {
593
+ if (this._staticRules.has(key)) {
594
+ const mapping = this._staticRules.get(key);
595
+ const fieldName = typeof mapping === "function" ? mapping(value) : mapping;
596
+ return fieldName ? { fieldName, matchedBy: "static" } : null;
597
+ }
598
+ for (const rule of this._dynamicRules) {
599
+ const match = key.match(rule.pattern);
600
+ if (match) {
601
+ const fieldName = typeof rule.mapping === "function" ? rule.mapping(match) : rule.mapping;
602
+ return fieldName ? { fieldName, matchedBy: "dynamic" } : null;
603
+ }
604
+ }
605
+ if (this._fallbackHandler) {
606
+ const fieldName = this._fallbackHandler(key, value);
607
+ return fieldName ? { fieldName, matchedBy: "fallback" } : null;
608
+ }
609
+ return null;
610
+ }
611
+ findMapping(key, value) {
612
+ if (this._staticRules.has(key)) {
613
+ return this._staticRules.get(key);
614
+ }
615
+ for (const rule of this._dynamicRules) {
616
+ const match = key.match(rule.pattern);
617
+ if (match) {
618
+ if (typeof rule.mapping === "function") {
619
+ const fieldName = rule.mapping(match);
620
+ return fieldName;
621
+ }
622
+ return rule.mapping;
623
+ }
624
+ }
625
+ if (this._fallbackHandler) {
626
+ const fieldName = this._fallbackHandler(key, value);
627
+ return fieldName;
628
+ }
629
+ return null;
630
+ }
631
+ };
632
+ var DefaultErrorsSchema = new ErrorsSchema().fallback((key) => key);
633
+
386
634
  // src/core/Form.ts
387
635
  var Form = class {
388
636
  constructor() {
389
637
  this._globalErrors = {};
638
+ this.errorsShema = DefaultErrorsSchema;
390
639
  }
391
640
  get _fields() {
392
641
  const fields = {};
@@ -439,9 +688,17 @@ var Form = class {
439
688
  const errors = {};
440
689
  const fields = this._fields;
441
690
  for (const key of Object.keys(fields)) {
442
- const fieldErrors = fields[key].errors;
443
- if (fieldErrors.length > 0) {
444
- errors[key] = fieldErrors;
691
+ const field = fields[key];
692
+ if (field instanceof ArrayFormField) {
693
+ const formErrors = this.collectArrayFormErrors(field);
694
+ if (formErrors.length > 0) {
695
+ errors[key] = formErrors;
696
+ }
697
+ } else {
698
+ const fieldErrors = field.errors;
699
+ if (fieldErrors.length > 0) {
700
+ errors[key] = fieldErrors;
701
+ }
445
702
  }
446
703
  }
447
704
  for (const key of Object.keys(this._globalErrors)) {
@@ -452,20 +709,84 @@ var Form = class {
452
709
  }
453
710
  return errors;
454
711
  }
712
+ /**
713
+ * Рекурсивно собирает все ошибки из ArrayFormField
714
+ */
715
+ collectArrayFormErrors(arrayField) {
716
+ const allErrors = [];
717
+ allErrors.push(...arrayField.errors);
718
+ for (let i = 0; i < arrayField.forms.length; i++) {
719
+ const form = arrayField.forms[i];
720
+ const formAllErrors = form.allErrors;
721
+ for (const [fieldName, fieldErrors] of Object.entries(formAllErrors)) {
722
+ for (const error of fieldErrors) {
723
+ allErrors.push(`\u0424\u043E\u0440\u043C\u0430 ${i + 1}, ${fieldName}: ${error}`);
724
+ }
725
+ }
726
+ }
727
+ return allErrors;
728
+ }
455
729
  get globalErrors() {
456
730
  return { ...this._globalErrors };
457
731
  }
458
732
  set errors(errors) {
459
733
  const fields = this._fields;
460
734
  this._globalErrors = {};
461
- for (const key of Object.keys(errors)) {
462
- const keys = key.split(".");
463
- const cleanKey = keys.length > 1 ? keys[1] : key;
464
- if (cleanKey in fields && fields[cleanKey]) {
465
- fields[cleanKey].error = errors[key];
735
+ for (const key of Object.keys(fields)) {
736
+ fields[key].error = null;
737
+ }
738
+ const parsedErrors = this.errorsShema.parseErrors(errors);
739
+ for (const [fieldName, errorMessage] of Object.entries(parsedErrors)) {
740
+ this.applyErrorToField(fieldName, errorMessage, fields, this);
741
+ }
742
+ }
743
+ /**
744
+ * Применяет ошибку к соответствующему полю
745
+ * Поддерживает вложенные поля через точечную нотацию
746
+ */
747
+ applyErrorToField(fieldPath, errorMessage, fields, targetForm) {
748
+ if (!targetForm) {
749
+ console.error("applyErrorToField: targetForm is undefined");
750
+ return;
751
+ }
752
+ if (fieldPath in fields && fields[fieldPath]) {
753
+ fields[fieldPath].error = errorMessage;
754
+ return;
755
+ }
756
+ const parts = fieldPath.split(".");
757
+ const rootField = parts[0];
758
+ if (rootField in fields && fields[rootField]) {
759
+ const field = fields[rootField];
760
+ if (parts.length === 1) {
761
+ field.error = errorMessage;
762
+ } else if (parts.length > 1) {
763
+ this.applyNestedError(field, parts.slice(1), errorMessage, fieldPath, targetForm);
764
+ }
765
+ } else {
766
+ targetForm.setGlobalError(fieldPath, errorMessage);
767
+ }
768
+ }
769
+ applyNestedError(field, pathParts, errorMessage, fullPath, targetForm) {
770
+ if (!targetForm) {
771
+ console.error("applyNestedError: targetForm is undefined");
772
+ return;
773
+ }
774
+ const [currentPart, ...remainingParts] = pathParts;
775
+ if (field instanceof ArrayFormField) {
776
+ const index = parseInt(currentPart);
777
+ if (!isNaN(index) && index >= 0 && index < field.forms.length) {
778
+ const form = field.forms[index];
779
+ if (remainingParts.length > 0) {
780
+ const formFields = form["_fields"];
781
+ this.applyErrorToField(remainingParts.join("."), errorMessage, formFields, form);
782
+ } else {
783
+ form.setGlobalError(`index_${index}`, errorMessage);
784
+ }
466
785
  } else {
467
- this._globalErrors[key] = errors[key];
786
+ targetForm.setGlobalError(fullPath, errorMessage);
468
787
  }
788
+ } else {
789
+ targetForm.setGlobalError(fullPath, errorMessage);
469
790
  }
470
791
  }
471
792
  setGlobalError(key, message) {