adaptform 2.0.4 → 2.1.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/CHANGELOG.md +152 -0
- package/CHANGELOG.ru.md +152 -0
- package/LICENSE.md +3 -1
- package/LICENSE.ru.md +25 -0
- package/README.md +388 -1
- package/README.ru.md +388 -0
- package/dist/{Form-DOdrOtbT.d.cts → Form-kPYL4f-n.d.cts} +117 -15
- package/dist/{Form-DOdrOtbT.d.ts → Form-kPYL4f-n.d.ts} +117 -15
- package/dist/index.cjs +483 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -6
- package/dist/index.d.ts +5 -6
- package/dist/index.mjs +482 -81
- package/dist/index.mjs.map +1 -1
- package/dist/luxon.cjs.map +1 -1
- package/dist/luxon.d.cts +1 -1
- package/dist/luxon.d.ts +1 -1
- package/dist/luxon.mjs.map +1 -1
- package/package.json +41 -12
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.
|
|
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);
|
|
@@ -20,24 +20,38 @@ var Field = class {
|
|
|
20
20
|
this._valueClear = null;
|
|
21
21
|
this.isValid = null;
|
|
22
22
|
}
|
|
23
|
+
this.isTouched = false;
|
|
23
24
|
}
|
|
24
|
-
// ==========
|
|
25
|
+
// ========== Getters and setters ==========
|
|
25
26
|
get plugins() {
|
|
26
27
|
return [...this.options.plugins ?? []].sort((a, b) => {
|
|
27
28
|
return (a.pluginOptions?.priority ?? 0) - (b.pluginOptions?.priority ?? 0);
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
31
|
get options() {
|
|
31
|
-
return this.
|
|
32
|
+
return this.fieldType.options;
|
|
32
33
|
}
|
|
33
34
|
set options(options) {
|
|
34
|
-
|
|
35
|
-
this.
|
|
35
|
+
const currentOptions = this.fieldType.options;
|
|
36
|
+
this.fieldType.options = Object.assign(currentOptions, options);
|
|
36
37
|
}
|
|
37
38
|
get rawValue() {
|
|
38
39
|
return this._rawValue;
|
|
39
40
|
}
|
|
40
41
|
set rawValue(input) {
|
|
42
|
+
this.setRawValue(input);
|
|
43
|
+
}
|
|
44
|
+
setRawValue(input, validate = true) {
|
|
45
|
+
this.assignRawValue(input);
|
|
46
|
+
this._errors = [];
|
|
47
|
+
this.isTouched = true;
|
|
48
|
+
if (validate) {
|
|
49
|
+
this.checkAndSetValid();
|
|
50
|
+
} else {
|
|
51
|
+
this.isValid = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
assignRawValue(input) {
|
|
41
55
|
let rawValue = input;
|
|
42
56
|
for (const plugin of this.plugins) {
|
|
43
57
|
if (plugin.toRawValue) {
|
|
@@ -51,10 +65,7 @@ var Field = class {
|
|
|
51
65
|
}
|
|
52
66
|
}
|
|
53
67
|
this._rawValue = rawValue;
|
|
54
|
-
this._valueClear = this.
|
|
55
|
-
this._errors = [];
|
|
56
|
-
this.isTouched = true;
|
|
57
|
-
this.checkAndSetValid();
|
|
68
|
+
this._valueClear = this.fieldType.cast(valueClear);
|
|
58
69
|
}
|
|
59
70
|
get errors() {
|
|
60
71
|
return this._errors;
|
|
@@ -73,7 +84,7 @@ var Field = class {
|
|
|
73
84
|
get valueClear() {
|
|
74
85
|
return this._valueClear;
|
|
75
86
|
}
|
|
76
|
-
// ==========
|
|
87
|
+
// ========== Validation ==========
|
|
77
88
|
isRequired(form) {
|
|
78
89
|
let isRequired;
|
|
79
90
|
if (typeof this.options.isRequired === "function") {
|
|
@@ -94,11 +105,11 @@ var Field = class {
|
|
|
94
105
|
}
|
|
95
106
|
if (this._valueClear === null) {
|
|
96
107
|
this._errors.push(
|
|
97
|
-
this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.
|
|
108
|
+
this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.fieldType.getTypeName()}`
|
|
98
109
|
);
|
|
99
110
|
return false;
|
|
100
111
|
}
|
|
101
|
-
const typeErrors = this.
|
|
112
|
+
const typeErrors = this.fieldType.validate(this._valueClear, form);
|
|
102
113
|
if (typeErrors.length > 0) {
|
|
103
114
|
this._errors.push(...typeErrors);
|
|
104
115
|
return false;
|
|
@@ -123,55 +134,61 @@ var Field = class {
|
|
|
123
134
|
get isEmpty() {
|
|
124
135
|
let isEmpty = false;
|
|
125
136
|
if (this._rawValue === null || this._rawValue === void 0) isEmpty = true;
|
|
126
|
-
else if (this._rawValue === "") isEmpty = true;
|
|
137
|
+
else if (typeof this._rawValue === "string" && this._rawValue.trim() === "") isEmpty = true;
|
|
127
138
|
else if (Array.isArray(this._rawValue) && this._rawValue.length === 0) isEmpty = true;
|
|
128
139
|
return isEmpty;
|
|
129
140
|
}
|
|
130
|
-
// ==========
|
|
141
|
+
// ========== Helper methods ==========
|
|
131
142
|
reset() {
|
|
132
143
|
if (this.defaultValue !== null && this.defaultValue !== void 0) {
|
|
133
|
-
this.
|
|
134
|
-
this.isValid = true;
|
|
144
|
+
this.assignRawValue(this.defaultValue);
|
|
135
145
|
} else {
|
|
136
146
|
this._rawValue = null;
|
|
137
147
|
this._valueClear = null;
|
|
138
|
-
this.isValid = null;
|
|
139
148
|
}
|
|
140
149
|
this._errors = [];
|
|
150
|
+
this.isValid = null;
|
|
141
151
|
this.isTouched = false;
|
|
142
152
|
}
|
|
143
153
|
};
|
|
144
154
|
|
|
155
|
+
// src/core/fields/arrayUtils.ts
|
|
156
|
+
function isValidArrayIndex(index, length) {
|
|
157
|
+
return Number.isInteger(index) && index >= 0 && index < length;
|
|
158
|
+
}
|
|
159
|
+
|
|
145
160
|
// src/core/fields/ArrayField.ts
|
|
146
161
|
var ArrayField = class {
|
|
147
162
|
constructor(factory, options = {}, initial = []) {
|
|
148
163
|
this.factory = factory;
|
|
149
164
|
this._items = [];
|
|
150
165
|
this._errors = [];
|
|
166
|
+
this._hasValidationResult = false;
|
|
151
167
|
this.isTouched = false;
|
|
152
168
|
this.options = {
|
|
153
169
|
isRequired: true,
|
|
154
170
|
messages: {},
|
|
155
171
|
...options
|
|
156
172
|
};
|
|
157
|
-
this._items = initial.map((
|
|
173
|
+
this._items = initial.map((value) => this.factory(value));
|
|
174
|
+
this.checkValid();
|
|
158
175
|
}
|
|
159
176
|
// ===== value =====
|
|
160
177
|
set itemsValue(items) {
|
|
161
178
|
this.clear();
|
|
162
|
-
for (const
|
|
163
|
-
this.add(
|
|
179
|
+
for (const item of items) {
|
|
180
|
+
this.add(item, false);
|
|
164
181
|
}
|
|
165
182
|
this.checkValid();
|
|
166
183
|
}
|
|
167
184
|
get itemsValue() {
|
|
168
|
-
return this._items.map((
|
|
185
|
+
return this._items.map((item) => item.valueClear);
|
|
169
186
|
}
|
|
170
187
|
get items() {
|
|
171
188
|
return this._items;
|
|
172
189
|
}
|
|
173
190
|
// ===== actions =====
|
|
174
|
-
add(value, force_check) {
|
|
191
|
+
add(value, force_check = true) {
|
|
175
192
|
const field = this.factory(value);
|
|
176
193
|
this.isTouched = true;
|
|
177
194
|
this._items.push(field);
|
|
@@ -179,6 +196,7 @@ var ArrayField = class {
|
|
|
179
196
|
return field;
|
|
180
197
|
}
|
|
181
198
|
remove(index) {
|
|
199
|
+
if (!isValidArrayIndex(index, this._items.length)) return;
|
|
182
200
|
this._items.splice(index, 1);
|
|
183
201
|
this.checkValid();
|
|
184
202
|
}
|
|
@@ -197,6 +215,7 @@ var ArrayField = class {
|
|
|
197
215
|
return isRequired;
|
|
198
216
|
}
|
|
199
217
|
checkValid(form) {
|
|
218
|
+
this._hasValidationResult = true;
|
|
200
219
|
this._errors = [];
|
|
201
220
|
if (this.isRequired(form) && this._items.length === 0) {
|
|
202
221
|
this._errors.push(
|
|
@@ -222,7 +241,8 @@ var ArrayField = class {
|
|
|
222
241
|
if (!ok) valid = false;
|
|
223
242
|
}
|
|
224
243
|
if (this.options.validate) {
|
|
225
|
-
const
|
|
244
|
+
const values = this._items.map((item) => item.valueClear);
|
|
245
|
+
const result = this.options.validate(values, form);
|
|
226
246
|
if (result === false) {
|
|
227
247
|
this._errors.push(
|
|
228
248
|
this.options.messages?.validate ?? "\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u0438"
|
|
@@ -240,7 +260,9 @@ var ArrayField = class {
|
|
|
240
260
|
return this.checkValid(form);
|
|
241
261
|
}
|
|
242
262
|
get isValid() {
|
|
243
|
-
|
|
263
|
+
if (!this._hasValidationResult) return false;
|
|
264
|
+
if (this._errors.length > 0) return false;
|
|
265
|
+
return this._items.every((item) => item.isValid === true);
|
|
244
266
|
}
|
|
245
267
|
get error() {
|
|
246
268
|
return this._errors[0] ?? "";
|
|
@@ -248,16 +270,19 @@ var ArrayField = class {
|
|
|
248
270
|
set error(message) {
|
|
249
271
|
if (message) {
|
|
250
272
|
this._errors = [message];
|
|
273
|
+
this._hasValidationResult = true;
|
|
251
274
|
} else {
|
|
252
275
|
this._errors = [];
|
|
276
|
+
this._hasValidationResult = false;
|
|
253
277
|
}
|
|
254
278
|
}
|
|
255
279
|
get errors() {
|
|
256
280
|
return this._errors;
|
|
257
281
|
}
|
|
258
282
|
reset() {
|
|
259
|
-
this._items.forEach((
|
|
283
|
+
this._items.forEach((item) => item.reset());
|
|
260
284
|
this._errors = [];
|
|
285
|
+
this._hasValidationResult = false;
|
|
261
286
|
this.isTouched = false;
|
|
262
287
|
}
|
|
263
288
|
};
|
|
@@ -269,37 +294,45 @@ var ArrayFormField = class {
|
|
|
269
294
|
this.options = options;
|
|
270
295
|
this._forms = [];
|
|
271
296
|
this._errors = [];
|
|
297
|
+
this._hasValidationResult = false;
|
|
272
298
|
this.isTouched = false;
|
|
273
299
|
this._forms = initial.map((data) => {
|
|
274
300
|
const form = new this.FormConstructor();
|
|
275
|
-
form.
|
|
301
|
+
form.setFields(data, false);
|
|
276
302
|
return form;
|
|
277
303
|
});
|
|
304
|
+
this.checkValid();
|
|
278
305
|
}
|
|
279
306
|
// ===== value =====
|
|
280
307
|
set forms(forms) {
|
|
281
|
-
this.
|
|
282
|
-
|
|
283
|
-
|
|
308
|
+
this.setForms(forms);
|
|
309
|
+
}
|
|
310
|
+
setForms(forms, validate = true) {
|
|
311
|
+
this._forms = [];
|
|
312
|
+
for (const formData of forms) {
|
|
313
|
+
this.add(formData, false);
|
|
284
314
|
}
|
|
285
|
-
this.checkValid();
|
|
315
|
+
if (validate) this.checkValid();
|
|
286
316
|
}
|
|
287
317
|
get forms() {
|
|
288
318
|
return this._forms;
|
|
289
319
|
}
|
|
290
320
|
get formsFieldsValue() {
|
|
291
|
-
return this._forms.map((
|
|
321
|
+
return this._forms.map((form) => form.fieldsValue);
|
|
292
322
|
}
|
|
293
323
|
// ===== actions =====
|
|
294
|
-
add(data, force_check) {
|
|
324
|
+
add(data, force_check = true) {
|
|
295
325
|
const form = new this.FormConstructor();
|
|
296
|
-
if (data
|
|
326
|
+
if (data !== void 0 && data !== null) {
|
|
327
|
+
form.setFields(data, false);
|
|
328
|
+
}
|
|
297
329
|
this.isTouched = true;
|
|
298
330
|
this._forms.push(form);
|
|
299
331
|
if (force_check) this.checkValid();
|
|
300
332
|
return form;
|
|
301
333
|
}
|
|
302
334
|
remove(index) {
|
|
335
|
+
if (!isValidArrayIndex(index, this._forms.length)) return;
|
|
303
336
|
this._forms.splice(index, 1);
|
|
304
337
|
this.checkValid();
|
|
305
338
|
}
|
|
@@ -308,8 +341,9 @@ var ArrayFormField = class {
|
|
|
308
341
|
this.checkValid();
|
|
309
342
|
}
|
|
310
343
|
reset() {
|
|
311
|
-
this._forms.forEach((
|
|
344
|
+
this._forms.forEach((form) => form.reset());
|
|
312
345
|
this._errors = [];
|
|
346
|
+
this._hasValidationResult = false;
|
|
313
347
|
this.isTouched = false;
|
|
314
348
|
}
|
|
315
349
|
// ===== validation =====
|
|
@@ -323,8 +357,9 @@ var ArrayFormField = class {
|
|
|
323
357
|
return isRequired;
|
|
324
358
|
}
|
|
325
359
|
checkValid(form) {
|
|
360
|
+
this._hasValidationResult = true;
|
|
326
361
|
this._errors = [];
|
|
327
|
-
if (this.isRequired(form) && this.
|
|
362
|
+
if (this.isRequired(form) && this._forms.length === 0) {
|
|
328
363
|
this._errors.push(
|
|
329
364
|
this.options.messages?.isRequired ?? "\u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u0438\u043D \u044D\u043B\u0435\u043C\u0435\u043D\u0442"
|
|
330
365
|
);
|
|
@@ -343,12 +378,12 @@ var ArrayFormField = class {
|
|
|
343
378
|
return false;
|
|
344
379
|
}
|
|
345
380
|
let valid = true;
|
|
346
|
-
for (const
|
|
347
|
-
const ok =
|
|
381
|
+
for (const nestedForm of this._forms) {
|
|
382
|
+
const ok = nestedForm.checkValid(nestedForm);
|
|
348
383
|
if (!ok) valid = false;
|
|
349
384
|
}
|
|
350
385
|
if (this.options.validate) {
|
|
351
|
-
const result = this.options.validate(this.
|
|
386
|
+
const result = this.options.validate(this._forms, form);
|
|
352
387
|
if (result === false) {
|
|
353
388
|
this._errors.push(
|
|
354
389
|
this.options.messages?.validate ?? "\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u0438"
|
|
@@ -366,7 +401,9 @@ var ArrayFormField = class {
|
|
|
366
401
|
return this.checkValid(form);
|
|
367
402
|
}
|
|
368
403
|
get isValid() {
|
|
369
|
-
|
|
404
|
+
if (!this._hasValidationResult) return false;
|
|
405
|
+
if (this._errors.length > 0) return false;
|
|
406
|
+
return this._forms.every((form) => form.isValid);
|
|
370
407
|
}
|
|
371
408
|
get errors() {
|
|
372
409
|
return this._errors;
|
|
@@ -377,16 +414,269 @@ var ArrayFormField = class {
|
|
|
377
414
|
set error(message) {
|
|
378
415
|
if (message) {
|
|
379
416
|
this._errors = [message];
|
|
417
|
+
this._hasValidationResult = true;
|
|
380
418
|
} else {
|
|
381
419
|
this._errors = [];
|
|
420
|
+
this._hasValidationResult = false;
|
|
382
421
|
}
|
|
383
422
|
}
|
|
384
423
|
};
|
|
385
424
|
|
|
425
|
+
// src/core/ErrorsShema.ts
|
|
426
|
+
var ErrorsSchema = class _ErrorsSchema {
|
|
427
|
+
constructor() {
|
|
428
|
+
this._staticRules = /* @__PURE__ */ new Map();
|
|
429
|
+
this._dynamicRules = [];
|
|
430
|
+
this._valueTransformers = [];
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Add a static rule that matches an exact error key.
|
|
434
|
+
* @param errorKey - Exact error key returned by the server.
|
|
435
|
+
* @param fieldName - Form field name or a function that resolves it dynamically.
|
|
436
|
+
*/
|
|
437
|
+
staticKey(errorKey, fieldName) {
|
|
438
|
+
this._staticRules.set(errorKey, fieldName);
|
|
439
|
+
return this;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Add a dynamic rule using a regular expression.
|
|
443
|
+
* @param pattern - Regular expression used to match an error key.
|
|
444
|
+
* @param mapping - Field name or function that derives it from the match.
|
|
445
|
+
* @param options - Additional options, such as rule priority.
|
|
446
|
+
*/
|
|
447
|
+
dynamicKey(pattern, mapping, options) {
|
|
448
|
+
this._dynamicRules.push({
|
|
449
|
+
pattern,
|
|
450
|
+
mapping,
|
|
451
|
+
priority: options?.priority ?? 0
|
|
452
|
+
});
|
|
453
|
+
this._dynamicRules.sort((a, b) => b.priority - a.priority);
|
|
454
|
+
return this;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Set a handler for errors that do not match any rule.
|
|
458
|
+
*/
|
|
459
|
+
fallback(handler) {
|
|
460
|
+
this._fallbackHandler = handler;
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Add a transformer for error values.
|
|
465
|
+
* Useful for normalizing messages, such as server responses containing arrays.
|
|
466
|
+
*/
|
|
467
|
+
transformValue(transformer) {
|
|
468
|
+
this._valueTransformers.push(transformer);
|
|
469
|
+
return this;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Create a schema from a simple mapping object.
|
|
473
|
+
*/
|
|
474
|
+
static fromObject(mapping) {
|
|
475
|
+
const schema = new _ErrorsSchema();
|
|
476
|
+
for (const [errorKey, fieldName] of Object.entries(mapping)) {
|
|
477
|
+
schema.staticKey(errorKey, fieldName);
|
|
478
|
+
}
|
|
479
|
+
return schema;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Create a schema for an array of similarly structured forms.
|
|
483
|
+
*/
|
|
484
|
+
static forArray(itemSchema, arrayFieldName, indexExtractor) {
|
|
485
|
+
const schema = new _ErrorsSchema();
|
|
486
|
+
for (const transformer of itemSchema._valueTransformers) {
|
|
487
|
+
schema.transformValue(transformer);
|
|
488
|
+
}
|
|
489
|
+
const escapedArrayFieldName = arrayFieldName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
490
|
+
const indexPattern = indexExtractor ? "(.+?)" : "(?:\\[(\\d+)\\]|\\.(\\d+))";
|
|
491
|
+
schema.dynamicKey(
|
|
492
|
+
new RegExp(`^${escapedArrayFieldName}${indexPattern}\\.(.+)$`),
|
|
493
|
+
(match, value) => {
|
|
494
|
+
const sourceKey = match[0];
|
|
495
|
+
const index = indexExtractor ? indexExtractor(sourceKey) : Number(match[1] ?? match[2]);
|
|
496
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
497
|
+
return "";
|
|
498
|
+
}
|
|
499
|
+
const fieldPath = match[indexExtractor ? 2 : 3];
|
|
500
|
+
const itemMapping = itemSchema.findMapping(fieldPath, value);
|
|
501
|
+
const mappedFieldPath = itemMapping ? typeof itemMapping === "function" ? itemMapping(value) : itemMapping : fieldPath;
|
|
502
|
+
return `${arrayFieldName}.${index}.${mappedFieldPath}`;
|
|
503
|
+
},
|
|
504
|
+
{ priority: 100 }
|
|
505
|
+
);
|
|
506
|
+
return schema;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Parse errors while applying configured value transformers.
|
|
510
|
+
* Supports nested structures using dot notation.
|
|
511
|
+
*/
|
|
512
|
+
parseErrors(errors, prefix = "") {
|
|
513
|
+
const result = {};
|
|
514
|
+
for (const [key, value] of Object.entries(errors)) {
|
|
515
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
516
|
+
if (this.isNestedObject(value)) {
|
|
517
|
+
const nestedErrors = this.parseErrors(value, fullKey);
|
|
518
|
+
Object.assign(result, nestedErrors);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
if (value === null || value === void 0) {
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
let transformedValue = value;
|
|
525
|
+
for (const transformer of this._valueTransformers) {
|
|
526
|
+
transformedValue = transformer(transformedValue);
|
|
527
|
+
}
|
|
528
|
+
const mapping = this.findMapping(fullKey, transformedValue);
|
|
529
|
+
if (mapping) {
|
|
530
|
+
if (typeof mapping === "function") {
|
|
531
|
+
const fieldName = mapping(transformedValue);
|
|
532
|
+
if (fieldName) {
|
|
533
|
+
result[fieldName] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
534
|
+
}
|
|
535
|
+
} else {
|
|
536
|
+
result[mapping] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return result;
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Parse server errors and return detailed metadata.
|
|
544
|
+
*/
|
|
545
|
+
parseErrorsDetailed(errors, prefix = "") {
|
|
546
|
+
const result = {};
|
|
547
|
+
for (const [key, value] of Object.entries(errors)) {
|
|
548
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
549
|
+
if (this.isNestedObject(value)) {
|
|
550
|
+
const nestedErrors = this.parseErrorsDetailed(value, fullKey);
|
|
551
|
+
Object.assign(result, nestedErrors);
|
|
552
|
+
continue;
|
|
553
|
+
}
|
|
554
|
+
if (value === null || value === void 0) {
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
let transformedValue = value;
|
|
558
|
+
for (const transformer of this._valueTransformers) {
|
|
559
|
+
transformedValue = transformer(transformedValue);
|
|
560
|
+
}
|
|
561
|
+
const matchResult = this.findMappingDetailed(fullKey, transformedValue);
|
|
562
|
+
if (matchResult) {
|
|
563
|
+
const message = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
564
|
+
result[matchResult.fieldName] = {
|
|
565
|
+
fieldName: matchResult.fieldName,
|
|
566
|
+
message,
|
|
567
|
+
sourceKey: fullKey,
|
|
568
|
+
matchedBy: matchResult.matchedBy
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return result;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Create a schema for a nested form.
|
|
576
|
+
*/
|
|
577
|
+
nest(prefix) {
|
|
578
|
+
const nestedSchema = new _ErrorsSchema();
|
|
579
|
+
for (const [key, mapping] of this._staticRules.entries()) {
|
|
580
|
+
nestedSchema.staticKey(`${prefix}.${key}`, mapping);
|
|
581
|
+
}
|
|
582
|
+
for (const rule of this._dynamicRules) {
|
|
583
|
+
const newPattern = new RegExp(`^${prefix}\\.${rule.pattern.source.replace(/^\^/, "")}`);
|
|
584
|
+
nestedSchema.dynamicKey(newPattern, rule.mapping, { priority: rule.priority });
|
|
585
|
+
}
|
|
586
|
+
for (const transformer of this._valueTransformers) {
|
|
587
|
+
nestedSchema.transformValue(transformer);
|
|
588
|
+
}
|
|
589
|
+
if (this._fallbackHandler) {
|
|
590
|
+
nestedSchema.fallback((key, value) => {
|
|
591
|
+
if (key.startsWith(`${prefix}.`)) {
|
|
592
|
+
return this._fallbackHandler(key.slice(prefix.length + 1), value);
|
|
593
|
+
}
|
|
594
|
+
return null;
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
return nestedSchema;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Clone the current schema.
|
|
601
|
+
*/
|
|
602
|
+
clone() {
|
|
603
|
+
const cloned = new _ErrorsSchema();
|
|
604
|
+
for (const [key, mapping] of this._staticRules.entries()) {
|
|
605
|
+
cloned._staticRules.set(key, mapping);
|
|
606
|
+
}
|
|
607
|
+
for (const rule of this._dynamicRules) {
|
|
608
|
+
cloned._dynamicRules.push({ ...rule });
|
|
609
|
+
}
|
|
610
|
+
cloned._fallbackHandler = this._fallbackHandler;
|
|
611
|
+
cloned._valueTransformers = [...this._valueTransformers];
|
|
612
|
+
return cloned;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Merge the current schema with another schema.
|
|
616
|
+
*/
|
|
617
|
+
merge(other) {
|
|
618
|
+
const merged = this.clone();
|
|
619
|
+
for (const [key, mapping] of other._staticRules.entries()) {
|
|
620
|
+
merged._staticRules.set(key, mapping);
|
|
621
|
+
}
|
|
622
|
+
merged._dynamicRules.push(...other._dynamicRules);
|
|
623
|
+
merged._dynamicRules.sort((a, b) => b.priority - a.priority);
|
|
624
|
+
merged._valueTransformers.push(...other._valueTransformers);
|
|
625
|
+
if (other._fallbackHandler) {
|
|
626
|
+
merged._fallbackHandler = other._fallbackHandler;
|
|
627
|
+
}
|
|
628
|
+
return merged;
|
|
629
|
+
}
|
|
630
|
+
isNestedObject(value) {
|
|
631
|
+
return value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
632
|
+
}
|
|
633
|
+
findMappingDetailed(key, value) {
|
|
634
|
+
if (this._staticRules.has(key)) {
|
|
635
|
+
const mapping = this._staticRules.get(key);
|
|
636
|
+
const fieldName = typeof mapping === "function" ? mapping(value) : mapping;
|
|
637
|
+
return fieldName ? { fieldName, matchedBy: "static" } : null;
|
|
638
|
+
}
|
|
639
|
+
for (const rule of this._dynamicRules) {
|
|
640
|
+
const match = key.match(rule.pattern);
|
|
641
|
+
if (match) {
|
|
642
|
+
const fieldName = typeof rule.mapping === "function" ? rule.mapping(match, value) : rule.mapping;
|
|
643
|
+
return fieldName ? { fieldName, matchedBy: "dynamic" } : null;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (this._fallbackHandler) {
|
|
647
|
+
const fieldName = this._fallbackHandler(key, value);
|
|
648
|
+
return fieldName ? { fieldName, matchedBy: "fallback" } : null;
|
|
649
|
+
}
|
|
650
|
+
return null;
|
|
651
|
+
}
|
|
652
|
+
findMapping(key, value) {
|
|
653
|
+
if (this._staticRules.has(key)) {
|
|
654
|
+
return this._staticRules.get(key);
|
|
655
|
+
}
|
|
656
|
+
for (const rule of this._dynamicRules) {
|
|
657
|
+
const match = key.match(rule.pattern);
|
|
658
|
+
if (match) {
|
|
659
|
+
if (typeof rule.mapping === "function") {
|
|
660
|
+
const fieldName = rule.mapping(match, value);
|
|
661
|
+
return fieldName;
|
|
662
|
+
}
|
|
663
|
+
return rule.mapping;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
if (this._fallbackHandler) {
|
|
667
|
+
const fieldName = this._fallbackHandler(key, value);
|
|
668
|
+
return fieldName;
|
|
669
|
+
}
|
|
670
|
+
return null;
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
var DefaultErrorsSchema = new ErrorsSchema().fallback((key) => key);
|
|
674
|
+
|
|
386
675
|
// src/core/Form.ts
|
|
387
676
|
var Form = class {
|
|
388
677
|
constructor() {
|
|
389
678
|
this._globalErrors = {};
|
|
679
|
+
this.errorsShema = DefaultErrorsSchema;
|
|
390
680
|
}
|
|
391
681
|
get _fields() {
|
|
392
682
|
const fields = {};
|
|
@@ -407,7 +697,7 @@ var Form = class {
|
|
|
407
697
|
isFormValid = false;
|
|
408
698
|
}
|
|
409
699
|
}
|
|
410
|
-
return isFormValid;
|
|
700
|
+
return isFormValid && Object.keys(this._globalErrors).length === 0;
|
|
411
701
|
}
|
|
412
702
|
get fieldsValue() {
|
|
413
703
|
const data = {};
|
|
@@ -424,24 +714,36 @@ var Form = class {
|
|
|
424
714
|
return data;
|
|
425
715
|
}
|
|
426
716
|
set fields(data) {
|
|
717
|
+
this.setFields(data);
|
|
718
|
+
}
|
|
719
|
+
setFields(data, validate = true) {
|
|
427
720
|
const fields = this._fields;
|
|
428
721
|
for (const key of Object.keys(data)) {
|
|
429
722
|
const field = fields[key];
|
|
430
723
|
if (field) {
|
|
431
|
-
if (field instanceof Field) field.
|
|
724
|
+
if (field instanceof Field) field.setRawValue(data[key], false);
|
|
432
725
|
else if (field instanceof ArrayField) field.itemsValue = data[key];
|
|
433
|
-
else if (field instanceof ArrayFormField) field.
|
|
726
|
+
else if (field instanceof ArrayFormField) field.setForms(data[key], false);
|
|
434
727
|
else console.error(`Invalid field "${key}" type`);
|
|
435
728
|
}
|
|
436
729
|
}
|
|
730
|
+
if (validate) this.checkValid();
|
|
437
731
|
}
|
|
438
732
|
get allErrors() {
|
|
439
733
|
const errors = {};
|
|
440
734
|
const fields = this._fields;
|
|
441
735
|
for (const key of Object.keys(fields)) {
|
|
442
|
-
const
|
|
443
|
-
if (
|
|
444
|
-
|
|
736
|
+
const field = fields[key];
|
|
737
|
+
if (field instanceof ArrayFormField) {
|
|
738
|
+
const formErrors = this.collectArrayFormErrors(field);
|
|
739
|
+
if (formErrors.length > 0) {
|
|
740
|
+
errors[key] = formErrors;
|
|
741
|
+
}
|
|
742
|
+
} else {
|
|
743
|
+
const fieldErrors = field.errors;
|
|
744
|
+
if (fieldErrors.length > 0) {
|
|
745
|
+
errors[key] = fieldErrors;
|
|
746
|
+
}
|
|
445
747
|
}
|
|
446
748
|
}
|
|
447
749
|
for (const key of Object.keys(this._globalErrors)) {
|
|
@@ -452,20 +754,95 @@ var Form = class {
|
|
|
452
754
|
}
|
|
453
755
|
return errors;
|
|
454
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* Recursively collect all errors from an ArrayFormField.
|
|
759
|
+
*/
|
|
760
|
+
collectArrayFormErrors(arrayField) {
|
|
761
|
+
const allErrors = [];
|
|
762
|
+
allErrors.push(...arrayField.errors);
|
|
763
|
+
for (let i = 0; i < arrayField.forms.length; i++) {
|
|
764
|
+
const form = arrayField.forms[i];
|
|
765
|
+
const formAllErrors = form.allErrors;
|
|
766
|
+
for (const [fieldName, fieldErrors] of Object.entries(formAllErrors)) {
|
|
767
|
+
for (const error of fieldErrors) {
|
|
768
|
+
allErrors.push(`\u0424\u043E\u0440\u043C\u0430 ${i + 1}, ${fieldName}: ${error}`);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return allErrors;
|
|
773
|
+
}
|
|
455
774
|
get globalErrors() {
|
|
456
775
|
return { ...this._globalErrors };
|
|
457
776
|
}
|
|
458
777
|
set errors(errors) {
|
|
778
|
+
this.clearErrorsRecursively();
|
|
459
779
|
const fields = this._fields;
|
|
780
|
+
const parsedErrors = this.errorsShema.parseErrors(errors);
|
|
781
|
+
for (const [fieldName, errorMessage] of Object.entries(parsedErrors)) {
|
|
782
|
+
this.applyErrorToField(fieldName, errorMessage, fields, this);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
clearErrorsRecursively() {
|
|
460
786
|
this._globalErrors = {};
|
|
461
|
-
for (const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
|
|
787
|
+
for (const field of Object.values(this._fields)) {
|
|
788
|
+
if (field instanceof Field) {
|
|
789
|
+
field.error = null;
|
|
790
|
+
} else if (field instanceof ArrayField) {
|
|
791
|
+
field.error = null;
|
|
792
|
+
for (const item of field.items) item.error = null;
|
|
793
|
+
} else if (field instanceof ArrayFormField) {
|
|
794
|
+
field.error = null;
|
|
795
|
+
for (const nestedForm of field.forms) nestedForm.clearErrorsRecursively();
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Apply an error to the corresponding field.
|
|
801
|
+
* Supports nested fields using dot notation.
|
|
802
|
+
*/
|
|
803
|
+
applyErrorToField(fieldPath, errorMessage, fields, targetForm) {
|
|
804
|
+
if (!targetForm) {
|
|
805
|
+
console.error("applyErrorToField: targetForm is undefined");
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (fieldPath in fields && fields[fieldPath]) {
|
|
809
|
+
fields[fieldPath].error = errorMessage;
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
const parts = fieldPath.split(".");
|
|
813
|
+
const rootField = parts[0];
|
|
814
|
+
if (rootField in fields && fields[rootField]) {
|
|
815
|
+
const field = fields[rootField];
|
|
816
|
+
if (parts.length === 1) {
|
|
817
|
+
field.error = errorMessage;
|
|
818
|
+
} else if (parts.length > 1) {
|
|
819
|
+
this.applyNestedError(field, parts.slice(1), errorMessage, fieldPath, targetForm);
|
|
820
|
+
}
|
|
821
|
+
} else {
|
|
822
|
+
targetForm.setGlobalError(fieldPath, errorMessage);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
applyNestedError(field, pathParts, errorMessage, fullPath, targetForm) {
|
|
826
|
+
if (!targetForm) {
|
|
827
|
+
console.error("applyNestedError: targetForm is undefined");
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const [currentPart, ...remainingParts] = pathParts;
|
|
831
|
+
if (field instanceof ArrayFormField) {
|
|
832
|
+
const index = parseInt(currentPart);
|
|
833
|
+
if (!isNaN(index) && index >= 0 && index < field.forms.length) {
|
|
834
|
+
const form = field.forms[index];
|
|
835
|
+
if (remainingParts.length > 0) {
|
|
836
|
+
const formFields = form["_fields"];
|
|
837
|
+
this.applyErrorToField(remainingParts.join("."), errorMessage, formFields, form);
|
|
838
|
+
} else {
|
|
839
|
+
form.setGlobalError(`index_${index}`, errorMessage);
|
|
840
|
+
}
|
|
466
841
|
} else {
|
|
467
|
-
|
|
842
|
+
targetForm.setGlobalError(fullPath, errorMessage);
|
|
468
843
|
}
|
|
844
|
+
} else {
|
|
845
|
+
targetForm.setGlobalError(fullPath, errorMessage);
|
|
469
846
|
}
|
|
470
847
|
}
|
|
471
848
|
setGlobalError(key, message) {
|
|
@@ -488,7 +865,7 @@ var Form = class {
|
|
|
488
865
|
}
|
|
489
866
|
return false;
|
|
490
867
|
}
|
|
491
|
-
//
|
|
868
|
+
// Check whether the form is valid.
|
|
492
869
|
get isValid() {
|
|
493
870
|
const fields = this._fields;
|
|
494
871
|
for (const key of Object.keys(fields)) {
|
|
@@ -496,32 +873,50 @@ var Form = class {
|
|
|
496
873
|
}
|
|
497
874
|
return Object.keys(this._globalErrors).length === 0;
|
|
498
875
|
}
|
|
499
|
-
//
|
|
876
|
+
// Serialize form values for multipart requests.
|
|
500
877
|
toFormData() {
|
|
501
878
|
const formData = new FormData();
|
|
502
879
|
const data = this.fieldsValue;
|
|
503
880
|
for (const [key, value] of Object.entries(data)) {
|
|
504
|
-
if (value
|
|
881
|
+
if (value === null || value === void 0) continue;
|
|
882
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) {
|
|
883
|
+
formData.append(key, value);
|
|
884
|
+
} else if (value instanceof Date) {
|
|
505
885
|
formData.append(key, value.toISOString());
|
|
506
|
-
} else if (
|
|
886
|
+
} else if (typeof value === "object") {
|
|
887
|
+
const serialized = JSON.stringify(value);
|
|
888
|
+
if (serialized !== void 0) formData.append(key, serialized);
|
|
889
|
+
} else {
|
|
507
890
|
formData.append(key, String(value));
|
|
508
891
|
}
|
|
509
892
|
}
|
|
510
893
|
return formData;
|
|
511
894
|
}
|
|
512
|
-
//
|
|
895
|
+
// Get all values in JSON-compatible form.
|
|
513
896
|
toJSON() {
|
|
514
|
-
const data = this.fieldsValue;
|
|
515
897
|
const json = {};
|
|
516
|
-
for (const [key, value] of Object.entries(
|
|
517
|
-
|
|
518
|
-
json[key] = value.toISOString();
|
|
519
|
-
} else {
|
|
520
|
-
json[key] = value;
|
|
521
|
-
}
|
|
898
|
+
for (const [key, value] of Object.entries(this.fieldsValue)) {
|
|
899
|
+
json[key] = this.serializeJsonValue(value);
|
|
522
900
|
}
|
|
523
901
|
return json;
|
|
524
902
|
}
|
|
903
|
+
serializeJsonValue(value) {
|
|
904
|
+
if (value instanceof Date) {
|
|
905
|
+
return value.toISOString();
|
|
906
|
+
}
|
|
907
|
+
if (Array.isArray(value)) {
|
|
908
|
+
return value.map((item) => this.serializeJsonValue(item));
|
|
909
|
+
}
|
|
910
|
+
if (value !== null && typeof value === "object") {
|
|
911
|
+
const prototype = Object.getPrototypeOf(value);
|
|
912
|
+
if (prototype === Object.prototype || prototype === null) {
|
|
913
|
+
return Object.fromEntries(
|
|
914
|
+
Object.entries(value).map(([key, nestedValue]) => [key, this.serializeJsonValue(nestedValue)])
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
return value;
|
|
919
|
+
}
|
|
525
920
|
};
|
|
526
921
|
|
|
527
922
|
// src/core/plugins/FieldPlugin.ts
|
|
@@ -541,13 +936,13 @@ var MaskPlugin = class extends BasePlugin {
|
|
|
541
936
|
this.maskParts = [];
|
|
542
937
|
this.config = config;
|
|
543
938
|
}
|
|
544
|
-
init(
|
|
939
|
+
init(_field) {
|
|
545
940
|
this.parseMask();
|
|
546
941
|
}
|
|
547
|
-
toRawValue(value,
|
|
942
|
+
toRawValue(value, _field) {
|
|
548
943
|
return this.applyMask(value);
|
|
549
944
|
}
|
|
550
|
-
toValueClear(value,
|
|
945
|
+
toValueClear(value, _field) {
|
|
551
946
|
return this.removeMask(value);
|
|
552
947
|
}
|
|
553
948
|
parseMask() {
|
|
@@ -746,8 +1141,12 @@ var StringType = class extends FieldType {
|
|
|
746
1141
|
this.options.messages?.maxLength ?? `\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u0430\u044F \u0434\u043B\u0438\u043D\u0430 ${this.options.maxLength} \u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432`
|
|
747
1142
|
);
|
|
748
1143
|
}
|
|
749
|
-
if (this.options.pattern != null
|
|
750
|
-
|
|
1144
|
+
if (this.options.pattern != null) {
|
|
1145
|
+
const { source, flags } = this.options.pattern;
|
|
1146
|
+
const stablePattern = new RegExp(source, flags.replace(/[gy]/g, ""));
|
|
1147
|
+
if (!stablePattern.test(value)) {
|
|
1148
|
+
errors.push(this.options.messages?.pattern ?? "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442");
|
|
1149
|
+
}
|
|
751
1150
|
}
|
|
752
1151
|
return errors;
|
|
753
1152
|
}
|
|
@@ -760,15 +1159,21 @@ var StringType = class extends FieldType {
|
|
|
760
1159
|
var NumberType = class extends FieldType {
|
|
761
1160
|
cast(rawValue) {
|
|
762
1161
|
if (rawValue === null || rawValue === void 0) return null;
|
|
763
|
-
if (typeof rawValue === "number"
|
|
1162
|
+
if (typeof rawValue === "number") return Number.isFinite(rawValue) ? rawValue : null;
|
|
764
1163
|
if (typeof rawValue === "string") {
|
|
765
|
-
const
|
|
766
|
-
|
|
1164
|
+
const normalized = rawValue.trim();
|
|
1165
|
+
if (normalized.length === 0) return null;
|
|
1166
|
+
const num = Number(normalized);
|
|
1167
|
+
return Number.isFinite(num) ? num : null;
|
|
767
1168
|
}
|
|
768
1169
|
return null;
|
|
769
1170
|
}
|
|
770
1171
|
validate(value) {
|
|
771
1172
|
const errors = [];
|
|
1173
|
+
if (!Number.isFinite(value)) {
|
|
1174
|
+
errors.push(this.options.messages?.invalid ?? "\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u043A\u043E\u043D\u0435\u0447\u043D\u044B\u043C \u0447\u0438\u0441\u043B\u043E\u043C");
|
|
1175
|
+
return errors;
|
|
1176
|
+
}
|
|
772
1177
|
if (!Number.isInteger(value)) {
|
|
773
1178
|
errors.push(this.options.messages?.invalid ?? "\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0434\u043E\u043B\u0436\u043D\u043E \u0431\u044B\u0442\u044C \u0446\u0435\u043B\u044B\u043C \u0447\u0438\u0441\u043B\u043E\u043C");
|
|
774
1179
|
}
|
|
@@ -813,7 +1218,7 @@ var DecimalType = class extends FieldType {
|
|
|
813
1218
|
if (typeof rawValue === "string") {
|
|
814
1219
|
return this.castString(rawValue);
|
|
815
1220
|
}
|
|
816
|
-
if (typeof rawValue === "number" &&
|
|
1221
|
+
if (typeof rawValue === "number" && Number.isFinite(rawValue)) {
|
|
817
1222
|
return rawValue;
|
|
818
1223
|
}
|
|
819
1224
|
return null;
|
|
@@ -829,13 +1234,13 @@ var DecimalType = class extends FieldType {
|
|
|
829
1234
|
}
|
|
830
1235
|
validate(value) {
|
|
831
1236
|
const errors = [];
|
|
832
|
-
value = typeof value === "number" ?
|
|
1237
|
+
value = typeof value === "number" ? String(value) : value;
|
|
833
1238
|
if (!this.isValidNumberString(value)) {
|
|
834
1239
|
errors.push(this.options.messages?.invalid ?? "\u041F\u0440\u0438\u043C\u0435\u0440: 1.00");
|
|
835
1240
|
return errors;
|
|
836
1241
|
}
|
|
837
|
-
const maxDigits = this.options.maxDigits
|
|
838
|
-
const decimalPlaces = this.options.decimalPlaces
|
|
1242
|
+
const maxDigits = this.options.maxDigits ?? 8;
|
|
1243
|
+
const decimalPlaces = this.options.decimalPlaces ?? 2;
|
|
839
1244
|
const maxIntDigits = maxDigits - decimalPlaces;
|
|
840
1245
|
const isNegative = value.startsWith("-");
|
|
841
1246
|
const normalizedValue = isNegative ? value.substring(1) : value;
|
|
@@ -909,10 +1314,6 @@ var DecimalType = class extends FieldType {
|
|
|
909
1314
|
if (dotCount > 1) return false;
|
|
910
1315
|
return pattern.test(value);
|
|
911
1316
|
}
|
|
912
|
-
numberToString(value) {
|
|
913
|
-
const decimalPlaces = this.options.decimalPlaces;
|
|
914
|
-
return value.toFixed(decimalPlaces);
|
|
915
|
-
}
|
|
916
1317
|
getTypeName() {
|
|
917
1318
|
return "\u0434\u0435\u0441\u044F\u0442\u0438\u0447\u043D\u043E\u0435 \u0447\u0438\u0441\u043B\u043E";
|
|
918
1319
|
}
|
|
@@ -989,7 +1390,7 @@ var DateType = class extends FieldType {
|
|
|
989
1390
|
getTypeName() {
|
|
990
1391
|
return this.options.isDatetime ? "\u0434\u0430\u0442\u0430 \u0438 \u0432\u0440\u0435\u043C\u044F" : "\u0434\u0430\u0442\u0430";
|
|
991
1392
|
}
|
|
992
|
-
//
|
|
1393
|
+
// Compare dates with optional time precision.
|
|
993
1394
|
compareDates(value, boundary, type) {
|
|
994
1395
|
if (this.options.isDatetime) {
|
|
995
1396
|
if (type === "min") {
|
|
@@ -1018,6 +1419,8 @@ exports.BasePlugin = BasePlugin;
|
|
|
1018
1419
|
exports.BooleanType = BooleanType;
|
|
1019
1420
|
exports.DateType = DateType;
|
|
1020
1421
|
exports.DecimalType = DecimalType;
|
|
1422
|
+
exports.DefaultErrorsSchema = DefaultErrorsSchema;
|
|
1423
|
+
exports.ErrorsSchema = ErrorsSchema;
|
|
1021
1424
|
exports.Field = Field;
|
|
1022
1425
|
exports.FieldType = FieldType;
|
|
1023
1426
|
exports.Form = Form;
|