isvalid 4.0.23 → 4.1.1
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/index.js +1 -1
- package/lib/errors/aggregated.js +18 -0
- package/lib/validate.js +63 -6
- package/package.json +3 -3
- package/test/validate.js +14 -7
package/index.js
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//
|
|
2
|
+
// aggregated.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2024-03-05
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import ValidationError from './validation.js';
|
|
10
|
+
|
|
11
|
+
export default class AggregatedError extends ValidationError {
|
|
12
|
+
|
|
13
|
+
constructor(keyPath, schema, validator, message, errors) {
|
|
14
|
+
super(keyPath, schema, validator, message);
|
|
15
|
+
this.errors = errors;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
package/lib/validate.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
|
|
9
9
|
import ValidationError from './errors/validation.js';
|
|
10
|
+
import AggregatedError from './errors/aggregated.js';
|
|
10
11
|
import { testIndex } from './ranges.js';
|
|
11
12
|
import unique from './unique.js';
|
|
12
13
|
import formalize from './formalize.js';
|
|
@@ -64,11 +65,39 @@ const validateObject = async (data, schema, options, keyPath, validatedData) =>
|
|
|
64
65
|
return schema.schema[key1].priority - schema.schema[key2].priority;
|
|
65
66
|
});
|
|
66
67
|
|
|
68
|
+
let errors = [];
|
|
69
|
+
|
|
67
70
|
for (let key of keys) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
data[key]
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
let value = await validateAny(data[key], schema.schema[key], options, keyPath.concat([key]), validatedData);
|
|
74
|
+
if (typeof value !== 'undefined') {
|
|
75
|
+
data[key] = value;
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
|
|
79
|
+
if (options.stopOnFirstError !== false) {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
errors.push(error);
|
|
84
|
+
|
|
71
85
|
}
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (errors.length) {
|
|
90
|
+
|
|
91
|
+
if (errors.length === 1) throw errors[0];
|
|
92
|
+
|
|
93
|
+
throw new AggregatedError(
|
|
94
|
+
keyPath,
|
|
95
|
+
schema._nonFormalizedSchema,
|
|
96
|
+
'object',
|
|
97
|
+
(schema.errors || {}).object || customErrorMessage(((options.errorMessages || {}).object || {}).object || 'Multiple errors occurred.'),
|
|
98
|
+
errors
|
|
99
|
+
);
|
|
100
|
+
|
|
72
101
|
}
|
|
73
102
|
|
|
74
103
|
}
|
|
@@ -97,9 +126,37 @@ const validateArray = async (data, schema, options, keyPath, validatedData) => {
|
|
|
97
126
|
}
|
|
98
127
|
|
|
99
128
|
if (typeof schema.schema !== 'undefined') {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
|
|
130
|
+
let errors = [];
|
|
131
|
+
|
|
132
|
+
for (let idx in data) {
|
|
133
|
+
try {
|
|
134
|
+
data[idx] = await validateAny(data[idx], schema.schema, options, keyPath.concat([idx]), validatedData);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
|
|
137
|
+
if (options.stopOnFirstError !== false) {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
errors.push(error);
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (errors.length) {
|
|
147
|
+
|
|
148
|
+
if (errors.length === 1) throw errors[0];
|
|
149
|
+
|
|
150
|
+
throw new AggregatedError(
|
|
151
|
+
keyPath,
|
|
152
|
+
schema._nonFormalizedSchema,
|
|
153
|
+
'array',
|
|
154
|
+
(schema.errors || {}).array || customErrorMessage(((options.errorMessages || {}).array || {}).array || 'Multiple errors occurred.'),
|
|
155
|
+
errors
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
}
|
|
159
|
+
|
|
103
160
|
}
|
|
104
161
|
|
|
105
162
|
if ((schema.len || options.defaults.len) && !testIndex((schema.len || options.defaults.len), data.length)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isvalid",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Async JSON validation library for node.js.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@trenskow/caseit": "^1.3.11",
|
|
23
23
|
"body-parser": "^1.20.2",
|
|
24
|
-
"chai": "^5.0
|
|
24
|
+
"chai": "^5.1.0",
|
|
25
25
|
"chai-as-promised": "^7.1.1",
|
|
26
26
|
"eslint": "^8.56.0",
|
|
27
27
|
"express": "^4.18.2",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"url": "https://github.com/trenskow"
|
|
43
43
|
},
|
|
44
44
|
"overrides": {
|
|
45
|
-
"chai": "^5.0
|
|
45
|
+
"chai": "^5.1.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
package/test/validate.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { expect, assert } from 'chai';
|
|
10
10
|
import ValidationError from '../lib/errors/validation.js';
|
|
11
|
+
import AggregatedError from '../lib/errors/aggregated.js';
|
|
11
12
|
import isvalid from '../index.js';
|
|
12
13
|
import { typeName, instanceTypeName, isSameType } from '../lib/utils.js';
|
|
13
14
|
|
|
@@ -476,17 +477,23 @@ describe('validate', function() {
|
|
|
476
477
|
})).to.eventually.not.have.property('why');
|
|
477
478
|
});
|
|
478
479
|
describe('required', function() {
|
|
479
|
-
it ('should come back with object key path when implicit.', () => {
|
|
480
|
+
it ('should come back with object key path when implicit (aggregated error).', () => {
|
|
480
481
|
return expect(isvalid(undefined, {
|
|
481
482
|
'myObject': {
|
|
482
|
-
'
|
|
483
|
+
'myFirstKey': {
|
|
484
|
+
type: String,
|
|
485
|
+
required: true
|
|
486
|
+
},
|
|
487
|
+
'mySecondKey': {
|
|
483
488
|
type: String,
|
|
484
489
|
required: true
|
|
485
490
|
}
|
|
486
|
-
}}))
|
|
487
|
-
.to.eventually.be.rejectedWith('
|
|
488
|
-
.and.to.be.instanceOf(
|
|
489
|
-
.and.have.property('
|
|
491
|
+
}}, { keyPath: ['root'], stopOnFirstError: false }))
|
|
492
|
+
.to.eventually.be.rejectedWith('Multiple errors occurred.')
|
|
493
|
+
.and.to.be.instanceOf(AggregatedError)
|
|
494
|
+
.and.have.property('errors')
|
|
495
|
+
.and.have.property(0)
|
|
496
|
+
.and.have.property('message', 'Data is required.');
|
|
490
497
|
});
|
|
491
498
|
});
|
|
492
499
|
describe('#errors', function() {
|
|
@@ -541,7 +548,7 @@ describe('validate', function() {
|
|
|
541
548
|
}}, { keyPath: 'root'}))
|
|
542
549
|
.to.eventually.be.rejectedWith('Is not of type string.')
|
|
543
550
|
.and.to.be.instanceOf(ValidationError)
|
|
544
|
-
.and.have.property('keyPath').eql(['root', 0]);
|
|
551
|
+
.and.have.property('keyPath').eql(['root', '0']);
|
|
545
552
|
});
|
|
546
553
|
});
|
|
547
554
|
describe('len', function() {
|