isvalid 3.2.7 → 4.0.2
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/{.eslintrc.js → .eslintrc.cjs} +2 -1
- package/History.md +9 -0
- package/README.md +0 -14
- package/index.js +11 -2
- package/lib/equals.js +11 -5
- package/lib/errors/schema.js +9 -3
- package/lib/errors/validation.js +9 -3
- package/lib/formalize.js +43 -28
- package/lib/index.js +17 -7
- package/lib/key-paths.js +21 -13
- package/lib/merge.js +16 -10
- package/lib/middleware.js +18 -12
- package/lib/plugins.js +17 -9
- package/lib/ranges.js +5 -6
- package/lib/unique.js +9 -3
- package/lib/utils.js +15 -9
- package/lib/validate.js +28 -22
- package/package.json +5 -4
- package/test/equals.js +9 -4
- package/test/formalize.js +13 -4
- package/test/index.js +22 -16
- package/test/key-paths.js +9 -3
- package/test/merge.js +9 -3
- package/test/middleware/index.js +11 -8
- package/test/middleware/tools/server.js +16 -10
- package/test/ranges.js +11 -5
- package/test/unique.js +9 -4
- package/test/validate.js +36 -40
- package/test/utils.js +0 -17
package/History.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
NOTICE: If your version number is not explicitly specified, it contains bug fixes or changes to internal workings.
|
|
4
4
|
|
|
5
|
+
## Version 4.0.0
|
|
6
|
+
|
|
7
|
+
* Converted to use ES modules.
|
|
8
|
+
* The `allowNull` validator has been changed to `null`.
|
|
9
|
+
|
|
10
|
+
## Version 3.0.0
|
|
11
|
+
|
|
12
|
+
* The minimum ECMAScript version supported has been bumped to 2018.
|
|
13
|
+
|
|
5
14
|
## Version 2.7.0
|
|
6
15
|
|
|
7
16
|
* The ability for custom errors has been under the hood for some time - just not very well tested. Now it's official.
|
package/README.md
CHANGED
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
* [Synchronous Functions](#synchronous-functions)
|
|
23
23
|
- [`required`](#required)
|
|
24
24
|
* [Implicitly Required](#implicitly-required)
|
|
25
|
-
- [`allowNull`](#allownull)
|
|
26
25
|
- [`equal`](#equal)
|
|
27
26
|
- [`errors` (Custom Error Messages)](#errors-custom-error-messages)
|
|
28
27
|
* [Error Shortcuts](#error-shortcuts)
|
|
@@ -280,19 +279,6 @@ In the above example the data will validate if the object is not present in the
|
|
|
280
279
|
|
|
281
280
|
> If `required` is not specified, then `Object` and `Array` types are by default `'implicit'`. All other types are by default non-required. Also `required` is ignored if `default` is specified.
|
|
282
281
|
|
|
283
|
-
#### `allowNull`
|
|
284
|
-
Type: `Boolean`
|
|
285
|
-
|
|
286
|
-
This validator allows for `null`-values to pass through - even if the input is required.
|
|
287
|
-
|
|
288
|
-
````javascript
|
|
289
|
-
{ type: String, required: true, allowNull: true }
|
|
290
|
-
````
|
|
291
|
-
|
|
292
|
-
In the above example input must be of type `String`, it is required, but a value of `null` is allowed.
|
|
293
|
-
|
|
294
|
-
> By default `allowNull` is set to `false`.
|
|
295
|
-
|
|
296
282
|
#### `equal`
|
|
297
283
|
Type: Any
|
|
298
284
|
|
package/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// index.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-02
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
import validate, { formalize, keyPaths, merge, plugins } from './lib/index.js';
|
|
10
|
+
|
|
11
|
+
export default validate;
|
|
12
|
+
export { formalize, keyPaths, merge, plugins };
|
package/lib/equals.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// equals.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
import { instanceTypeName } from './utils.js';
|
|
4
10
|
|
|
5
11
|
const objectEquals = async (obj1, obj2) => {
|
|
6
12
|
|
|
@@ -41,12 +47,12 @@ const equals = async (obj1, obj2) => {
|
|
|
41
47
|
if (typeof obj2.is === 'function') return obj2.is(obj1);
|
|
42
48
|
|
|
43
49
|
if (typeof obj1 === 'object') {
|
|
44
|
-
if (
|
|
45
|
-
if (
|
|
50
|
+
if (instanceTypeName(obj1) === 'object') return await objectEquals(obj1, obj2);
|
|
51
|
+
if (instanceTypeName(obj1) === 'array') return await arrayEquals(obj1, obj2);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
return obj1 === obj2;
|
|
49
55
|
|
|
50
56
|
};
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
export default equals;
|
package/lib/errors/schema.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// schema.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
export default class SchemaError extends Error {
|
|
4
10
|
|
|
5
11
|
constructor(schema, message) {
|
|
6
12
|
super();
|
|
@@ -15,4 +21,4 @@ module.exports = exports = class SchemaError extends Error {
|
|
|
15
21
|
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
}
|
|
24
|
+
}
|
package/lib/errors/validation.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// validation.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
export default class ValidationError extends Error {
|
|
4
10
|
|
|
5
11
|
constructor(keyPath, schema, validator, message) {
|
|
6
12
|
super();
|
|
@@ -23,4 +29,4 @@ module.exports = exports = class ValidationError extends Error {
|
|
|
23
29
|
return validationError;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
}
|
|
32
|
+
}
|
package/lib/formalize.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
//
|
|
2
|
+
// formalize.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-09
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import merge from 'merge';
|
|
10
|
+
import SchemaError from './errors/schema.js';
|
|
11
|
+
import { instanceTypeName, typeName, isSameType } from './utils.js';
|
|
12
|
+
import { formalize as _formalize } from './ranges.js';
|
|
13
|
+
import { all as allPlugins } from './plugins.js';
|
|
8
14
|
|
|
9
15
|
const finalize = (formalizedSchema, nonFormalizedSchema) => {
|
|
10
16
|
|
|
@@ -27,7 +33,7 @@ const formalizeObject = (formalizedSchema, nonFormalizedSchema, options) => {
|
|
|
27
33
|
|
|
28
34
|
formalizedSchema.schema = formalizedSchema.schema || {};
|
|
29
35
|
|
|
30
|
-
if (
|
|
36
|
+
if (instanceTypeName(formalizedSchema.schema) !== 'object') {
|
|
31
37
|
throw new SchemaError(formalizedSchema.schema, 'Object schemas must be an object.');
|
|
32
38
|
}
|
|
33
39
|
|
|
@@ -77,14 +83,14 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
77
83
|
if (typeof schema._nonFormalizedSchema !== 'undefined') return schema;
|
|
78
84
|
|
|
79
85
|
if (!schema.type && !schema.post && !schema.pre && !schema.equal) {
|
|
80
|
-
if ('object' ==
|
|
86
|
+
if ('object' == instanceTypeName(schema)) {
|
|
81
87
|
return formalizeAny({ type: Object, schema: schema }, options);
|
|
82
88
|
}
|
|
83
|
-
if ('array' ==
|
|
89
|
+
if ('array' == instanceTypeName(schema)) {
|
|
84
90
|
if (schema.length === 0) return formalizeAny({ type: Array }, options);
|
|
85
91
|
return formalizeAny({ type: Array, schema: schema[0] }, options);
|
|
86
92
|
}
|
|
87
|
-
if ((typeof schema === 'string' && schema.length) || (typeof schema === 'function' &&
|
|
93
|
+
if ((typeof schema === 'string' && schema.length) || (typeof schema === 'function' && typeName(schema) !== undefined)) {
|
|
88
94
|
return formalizeAny({ type: schema }, options);
|
|
89
95
|
}
|
|
90
96
|
throw new SchemaError(schema, 'Schemas must have at least on validator of `type`, `post`/`pre` and/or `equal`.');
|
|
@@ -102,7 +108,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
102
108
|
'equal': 'any',
|
|
103
109
|
'required': ['boolean', 'string'],
|
|
104
110
|
'default': 'any',
|
|
105
|
-
'
|
|
111
|
+
'null': ['string'],
|
|
106
112
|
'errors': ['object'],
|
|
107
113
|
'pre': ['function', 'array', 'asyncfunction'],
|
|
108
114
|
'post': ['function', 'array', 'asyncfunction'],
|
|
@@ -112,23 +118,23 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
112
118
|
// Validators specific to type.
|
|
113
119
|
const type = Array.isArray(formalizedSchema.type) ? formalizedSchema.type[0] : formalizedSchema.type;
|
|
114
120
|
if (type !== undefined) {
|
|
115
|
-
if (
|
|
121
|
+
if (isSameType('object', typeName(type))) merge(validators, {
|
|
116
122
|
'schema': 'any',
|
|
117
123
|
'unknownKeys': [ 'string' ]
|
|
118
124
|
});
|
|
119
|
-
if (
|
|
125
|
+
if (isSameType('array', typeName(type))) merge(validators, {
|
|
120
126
|
'schema': 'any',
|
|
121
127
|
'len': [ 'string', 'number' ],
|
|
122
128
|
'unique': [ 'boolean' ],
|
|
123
129
|
'autowrap': [ 'boolean' ]
|
|
124
130
|
});
|
|
125
|
-
if (
|
|
131
|
+
if (isSameType('string', typeName(type))) merge(validators, {
|
|
126
132
|
'len': [ 'string', 'number' ],
|
|
127
133
|
'match': [ 'regexp' ],
|
|
128
134
|
'trim': [ 'boolean' ],
|
|
129
135
|
'enum': [ 'array' ]
|
|
130
136
|
});
|
|
131
|
-
if (
|
|
137
|
+
if (isSameType('number', typeName(type))) merge(validators, {
|
|
132
138
|
'range': [ 'string', 'number' ],
|
|
133
139
|
'float': [ 'string' ]
|
|
134
140
|
});
|
|
@@ -157,7 +163,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
157
163
|
if (Object.keys(validators).includes(key)) {
|
|
158
164
|
validators = validators[key];
|
|
159
165
|
if (!Array.isArray(validators)) validators = [validators];
|
|
160
|
-
return [plugin, validators.map((validator) =>
|
|
166
|
+
return [plugin, validators.map((validator) => typeName(validator))];
|
|
161
167
|
}
|
|
162
168
|
return plugins;
|
|
163
169
|
}, []);
|
|
@@ -177,7 +183,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
177
183
|
if (Array.isArray(test) &&
|
|
178
184
|
|
|
179
185
|
test.length === 2 &&
|
|
180
|
-
validator.includes(
|
|
186
|
+
validator.includes(instanceTypeName(test[0]))) {
|
|
181
187
|
|
|
182
188
|
formalizedSchema.errors = formalizedSchema.errors || {};
|
|
183
189
|
formalizedSchema.errors[key] = test[1];
|
|
@@ -191,7 +197,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
191
197
|
}
|
|
192
198
|
|
|
193
199
|
// Ensure validator is of correct type.
|
|
194
|
-
if (typeof validator !== 'undefined' && validator !== 'any' && validator.indexOf(
|
|
200
|
+
if (typeof validator !== 'undefined' && validator !== 'any' && validator.indexOf(instanceTypeName(test)) == -1) {
|
|
195
201
|
throw new SchemaError(
|
|
196
202
|
schema,
|
|
197
203
|
`Validator '${key}' must be of type(s) ${validators[key].join(', ')}.`
|
|
@@ -214,7 +220,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
214
220
|
}
|
|
215
221
|
|
|
216
222
|
// Check for supported type.
|
|
217
|
-
if (typeof formalizedSchema.type !== 'undefined' &&
|
|
223
|
+
if (typeof formalizedSchema.type !== 'undefined' && typeName(formalizedSchema.type) === undefined) {
|
|
218
224
|
throw new SchemaError(formalizedSchema, `Cannot validate schema of type ${formalizedSchema.type}.`);
|
|
219
225
|
}
|
|
220
226
|
|
|
@@ -245,6 +251,15 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
245
251
|
);
|
|
246
252
|
}
|
|
247
253
|
|
|
254
|
+
// Check null
|
|
255
|
+
if (typeof formalizedSchema.null === 'string' &&
|
|
256
|
+
['allow', 'deny', 'undefine'].indexOf(formalizedSchema.null) == -1) {
|
|
257
|
+
throw new SchemaError(
|
|
258
|
+
schema,
|
|
259
|
+
'Validator `null` must have value `\'allow\'`, `\'deny\'`, `\'undefined\'`.'
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
|
|
248
263
|
// Check number float
|
|
249
264
|
if (typeof formalizedSchema.float === 'string' &&
|
|
250
265
|
['allow', 'deny', 'round', 'floor', 'ceil'].indexOf(formalizedSchema.float) == -1) {
|
|
@@ -256,7 +271,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
256
271
|
|
|
257
272
|
// Check len
|
|
258
273
|
if (typeof formalizedSchema.len !== 'undefined') {
|
|
259
|
-
formalizedSchema.len =
|
|
274
|
+
formalizedSchema.len = _formalize(formalizedSchema.len, {
|
|
260
275
|
allowNegative: false,
|
|
261
276
|
allowNonIntegers: false
|
|
262
277
|
});
|
|
@@ -264,7 +279,7 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
264
279
|
|
|
265
280
|
// Check range
|
|
266
281
|
if (typeof formalizedSchema.range !== 'undefined') {
|
|
267
|
-
formalizedSchema.range =
|
|
282
|
+
formalizedSchema.range = _formalize(formalizedSchema.range, {
|
|
268
283
|
allowNegative: true,
|
|
269
284
|
allowNonIntegers: true
|
|
270
285
|
});
|
|
@@ -293,10 +308,10 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
293
308
|
|
|
294
309
|
// Finalize objects and arrays if necessary.
|
|
295
310
|
if (formalizedSchema.type) {
|
|
296
|
-
if (
|
|
311
|
+
if (isSameType('object', typeName(formalizedSchema.type))) {
|
|
297
312
|
formalizedSchema = formalizeObject(formalizedSchema, schema, options);
|
|
298
313
|
}
|
|
299
|
-
else if (
|
|
314
|
+
else if (isSameType('array', typeName(formalizedSchema.type))) {
|
|
300
315
|
formalizedSchema = formalizeArray(formalizedSchema, options);
|
|
301
316
|
}
|
|
302
317
|
}
|
|
@@ -305,17 +320,17 @@ const formalizeAny = (schema, options = {}) => {
|
|
|
305
320
|
|
|
306
321
|
};
|
|
307
322
|
|
|
308
|
-
|
|
323
|
+
export default (schema, options = {}) => {
|
|
309
324
|
return formalizeAny(schema, Object.assign({}, options, {
|
|
310
|
-
plugins:
|
|
325
|
+
plugins: allPlugins().concat((options.plugins || []).map((plugin) => plugin({ instanceTypeName, typeName, isSameType })))
|
|
311
326
|
}));
|
|
312
327
|
};
|
|
313
328
|
|
|
314
|
-
|
|
329
|
+
export function strip(schema) {
|
|
315
330
|
return Object.keys(schema)
|
|
316
331
|
.filter((key) => key !== '_nonFormalizedSchema')
|
|
317
332
|
.reduce((result, key) => {
|
|
318
333
|
result[key] = schema[key];
|
|
319
334
|
return result;
|
|
320
335
|
}, {});
|
|
321
|
-
}
|
|
336
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// index.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2021-08-18
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
import validate from './validate.js';
|
|
10
|
+
import formalize from './formalize.js';
|
|
11
|
+
import keyPaths from './key-paths.js';
|
|
12
|
+
import merge from './merge.js';
|
|
13
|
+
import { use } from './plugins.js';
|
|
14
|
+
|
|
15
|
+
const plugins = { use };
|
|
16
|
+
|
|
17
|
+
export default validate;
|
|
18
|
+
export { formalize, keyPaths, merge, plugins };
|
package/lib/key-paths.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// key-paths.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2021-08-18
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
import formalize from './formalize.js';
|
|
10
|
+
import { typeName as _typeName } from './utils.js';
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
const keyPaths = (schema, formalizeOptions) => {
|
|
7
13
|
|
|
8
14
|
schema = formalize(schema, formalizeOptions);
|
|
9
15
|
|
|
@@ -23,11 +29,11 @@ exports = module.exports = (schema, formalizeOptions) => {
|
|
|
23
29
|
if (!types) types = [];
|
|
24
30
|
if (!Array.isArray(types)) types = [types];
|
|
25
31
|
|
|
26
|
-
types = types.map((type) =>
|
|
32
|
+
types = types.map((type) => _typeName(type));
|
|
27
33
|
|
|
28
34
|
let result = [];
|
|
29
35
|
|
|
30
|
-
const typeName =
|
|
36
|
+
const typeName = _typeName(schema.type);
|
|
31
37
|
|
|
32
38
|
if (types.length == 0 || types.includes(typeName)) result.push(keyPath.join('.'));
|
|
33
39
|
|
|
@@ -36,11 +42,11 @@ exports = module.exports = (schema, formalizeOptions) => {
|
|
|
36
42
|
switch (typeName) {
|
|
37
43
|
case 'object':
|
|
38
44
|
result = result.concat(...Object.keys(schema.schema).map((key) => {
|
|
39
|
-
return
|
|
45
|
+
return keyPaths(schema.schema[key]).all(types, options, keyPath.concat([key]), level + 1);
|
|
40
46
|
}));
|
|
41
47
|
break;
|
|
42
48
|
case 'array':
|
|
43
|
-
result = result.concat(
|
|
49
|
+
result = result.concat(keyPaths(schema.schema).all(types, options, keyPath, level + 1));
|
|
44
50
|
break;
|
|
45
51
|
}
|
|
46
52
|
|
|
@@ -60,13 +66,13 @@ exports = module.exports = (schema, formalizeOptions) => {
|
|
|
60
66
|
|
|
61
67
|
if (keyPath.length === 0) return schema;
|
|
62
68
|
|
|
63
|
-
const typeName =
|
|
69
|
+
const typeName = _typeName(schema.type).toLowerCase();
|
|
64
70
|
|
|
65
71
|
switch (typeName) {
|
|
66
72
|
case 'object':
|
|
67
|
-
return
|
|
73
|
+
return keyPaths(schema.schema[keyPath[0]]).get(keyPath.slice(1));
|
|
68
74
|
case 'array':
|
|
69
|
-
return
|
|
75
|
+
return keyPaths(schema.schema).get(keyPath);
|
|
70
76
|
default:
|
|
71
77
|
throw new Error(`Cannot get key '${[keyPath[0]].concat(keyPath).join('.')}' from type '${typeName}'.`);
|
|
72
78
|
}
|
|
@@ -81,9 +87,9 @@ exports = module.exports = (schema, formalizeOptions) => {
|
|
|
81
87
|
|
|
82
88
|
if (keyPath.length === 0) return newSchema;
|
|
83
89
|
|
|
84
|
-
let parent =
|
|
90
|
+
let parent = keyPaths(schema).get(keyPath.slice(0, -1));
|
|
85
91
|
|
|
86
|
-
if (
|
|
92
|
+
if (_typeName(parent.type).toLowerCase() !== 'object') throw new Error('Cannot set keys on non-object types.');
|
|
87
93
|
|
|
88
94
|
parent.schema[keyPath.slice(-1)[0]] = newSchema;
|
|
89
95
|
|
|
@@ -93,3 +99,5 @@ exports = module.exports = (schema, formalizeOptions) => {
|
|
|
93
99
|
};
|
|
94
100
|
|
|
95
101
|
};
|
|
102
|
+
|
|
103
|
+
export default keyPaths;
|
package/lib/merge.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// merge.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2021-10-02
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
import merge from 'merge';
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
import formalize, { strip } from './formalize.js';
|
|
12
|
+
import { typeName } from './utils.js';
|
|
7
13
|
|
|
8
14
|
const mergeSchema = (dest, src, formalizeOptions) => {
|
|
9
15
|
|
|
10
16
|
dest = formalize(dest, formalizeOptions);
|
|
11
17
|
src = formalize(src, formalizeOptions);
|
|
12
18
|
|
|
13
|
-
const destType =
|
|
14
|
-
const srcType =
|
|
19
|
+
const destType = typeName(dest.type).toLowerCase();
|
|
20
|
+
const srcType = typeName(src.type).toLowerCase();
|
|
15
21
|
|
|
16
22
|
if (destType !== srcType) return src;
|
|
17
23
|
|
|
@@ -34,21 +40,21 @@ const mergeSchema = (dest, src, formalizeOptions) => {
|
|
|
34
40
|
else schema[key] = mergeSchema(destSchema[key], srcSchema[key]);
|
|
35
41
|
});
|
|
36
42
|
|
|
37
|
-
return formalize(merge(
|
|
43
|
+
return formalize(merge(strip(dest), strip(src), { schema }), formalizeOptions);
|
|
38
44
|
|
|
39
45
|
}
|
|
40
46
|
case 'array': {
|
|
41
47
|
return merge(dest, src, {
|
|
42
|
-
schema: formalize(mergeSchema(
|
|
48
|
+
schema: formalize(mergeSchema(strip(dest.schema), strip(src.schema)), formalizeOptions)
|
|
43
49
|
});
|
|
44
50
|
}
|
|
45
51
|
default:
|
|
46
|
-
return formalize(merge(
|
|
52
|
+
return formalize(merge(strip(dest), strip(src)), formalizeOptions);
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
};
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
export default (dest, formalizeOptions) => {
|
|
52
58
|
return {
|
|
53
59
|
with: (...sources) => {
|
|
54
60
|
return sources.reduce((result, current) => {
|
package/lib/middleware.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// middleware.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2015-06-28
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
import formalize from './formalize.js';
|
|
10
|
+
import isvalid from './validate.js';
|
|
11
|
+
import merge from 'merge';
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
export function body(schema, options) {
|
|
8
14
|
|
|
9
15
|
let formalizedSchema = formalize(schema, options);
|
|
10
16
|
|
|
@@ -23,9 +29,9 @@ exports.body = module.exports.body = function(schema, options) {
|
|
|
23
29
|
});
|
|
24
30
|
};
|
|
25
31
|
|
|
26
|
-
}
|
|
32
|
+
}
|
|
27
33
|
|
|
28
|
-
|
|
34
|
+
export function query(schema, options) {
|
|
29
35
|
|
|
30
36
|
let formalizedSchema = formalize(schema, options);
|
|
31
37
|
|
|
@@ -44,9 +50,9 @@ exports.query = module.exports.query = function(schema, options) {
|
|
|
44
50
|
});
|
|
45
51
|
};
|
|
46
52
|
|
|
47
|
-
}
|
|
53
|
+
}
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
export function param(schema, options) {
|
|
50
56
|
|
|
51
57
|
let formalizedSchema = formalize(schema, options);
|
|
52
58
|
|
|
@@ -65,9 +71,9 @@ exports.param = module.exports.param = function(schema, options) {
|
|
|
65
71
|
});
|
|
66
72
|
};
|
|
67
73
|
|
|
68
|
-
}
|
|
74
|
+
}
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
export function parameter(id, schema, options) {
|
|
71
77
|
|
|
72
78
|
let formalizedSchema = formalize(schema, options);
|
|
73
79
|
|
|
@@ -86,4 +92,4 @@ exports.parameter = module.exports.parameter = function(id, schema, options) {
|
|
|
86
92
|
});
|
|
87
93
|
};
|
|
88
94
|
|
|
89
|
-
}
|
|
95
|
+
}
|
package/lib/plugins.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// plugins.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2022-04-13
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
const
|
|
4
|
-
utils = require('./utils');
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
_plugins: []
|
|
8
|
-
};
|
|
10
|
+
import { isSameType, instanceTypeName, typeName } from './utils.js';
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
const plugins = [];
|
|
13
|
+
|
|
14
|
+
export function use(plugin) {
|
|
15
|
+
plugins.push(plugin({ isSameType, instanceTypeName, typeName }));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function all() {
|
|
19
|
+
return plugins;
|
|
20
|
+
}
|
package/lib/ranges.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
SchemaError = require('./errors/schema.js');
|
|
3
|
+
import SchemaError from './errors/schema.js';
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
export function testIndex(ranges, value) {
|
|
7
6
|
return ranges.some(({ lower, upper }) => {
|
|
8
7
|
return lower <= value && upper >= value;
|
|
9
8
|
});
|
|
10
|
-
}
|
|
9
|
+
}
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
export function formalize(ranges, options) {
|
|
13
12
|
|
|
14
13
|
// Convert to string if ranges is a Number.
|
|
15
14
|
if (ranges !== undefined && typeof ranges === 'number') {
|
|
@@ -67,4 +66,4 @@ module.exports.formalize = function(ranges, options) {
|
|
|
67
66
|
|
|
68
67
|
});
|
|
69
68
|
|
|
70
|
-
}
|
|
69
|
+
}
|
package/lib/unique.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// unique.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
import equals from './equals.js';
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
export default async (arr) => {
|
|
6
12
|
|
|
7
13
|
if (arr.length <= 1) return true;
|
|
8
14
|
|
package/lib/utils.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// utils.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2017-01-18
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
export function typeName(obj) {
|
|
4
10
|
if (typeof obj === 'string') return obj;
|
|
5
11
|
return (obj.name || (this.toString().match(/function\s*([^\s(]+)/) || [])[1]).toLowerCase();
|
|
6
|
-
}
|
|
12
|
+
}
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
return
|
|
10
|
-
}
|
|
14
|
+
export function instanceTypeName(obj) {
|
|
15
|
+
return typeName(obj.constructor);
|
|
16
|
+
}
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
export function isSameType(obj1, obj2) {
|
|
13
19
|
if (typeof obj1 === 'undefined' || typeof obj2 === 'undefined') {
|
|
14
20
|
return typeof obj1 === typeof obj2;
|
|
15
21
|
}
|
|
16
|
-
return
|
|
17
|
-
}
|
|
22
|
+
return typeName(obj1).toLowerCase() == typeName(obj2).toLowerCase();
|
|
23
|
+
}
|
package/lib/validate.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
//
|
|
2
|
+
// validate.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import ValidationError from './errors/validation.js';
|
|
10
|
+
import { testIndex } from './ranges.js';
|
|
11
|
+
import unique from './unique.js';
|
|
12
|
+
import formalize from './formalize.js';
|
|
13
|
+
import { isSameType, instanceTypeName, typeName } from './utils.js';
|
|
14
|
+
import equals from './equals.js';
|
|
9
15
|
|
|
10
16
|
const checkBoolValue = (name, schema, defaults) => {
|
|
11
17
|
if (schema[name] === undefined) return defaults[name] === true;
|
|
@@ -96,7 +102,7 @@ const validateArray = async (data, schema, options, keyPath, validatedData) => {
|
|
|
96
102
|
}));
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
if ((schema.len || options.defaults.len) && !
|
|
105
|
+
if ((schema.len || options.defaults.len) && !testIndex((schema.len || options.defaults.len), data.length)) {
|
|
100
106
|
throw new ValidationError(
|
|
101
107
|
keyPath,
|
|
102
108
|
schema._nonFormalizedSchema,
|
|
@@ -136,7 +142,7 @@ const validateString = async (data, schema, options, keyPath) => {
|
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
if (schema.len || options.defaults.len) {
|
|
139
|
-
if (!
|
|
145
|
+
if (!testIndex(schema.len || options.defaults.len, data.length)) {
|
|
140
146
|
throw new ValidationError(
|
|
141
147
|
keyPath,
|
|
142
148
|
schema._nonFormalizedSchema,
|
|
@@ -196,7 +202,7 @@ const validateNumber = async (data, schema, options, keyPath) => {
|
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
if (schema.range || options.defaults.range) {
|
|
199
|
-
if (!
|
|
205
|
+
if (!testIndex(schema.range || options.defaults.range, data)) {
|
|
200
206
|
throw new ValidationError(
|
|
201
207
|
keyPath,
|
|
202
208
|
schema._nonFormalizedSchema,
|
|
@@ -262,7 +268,7 @@ const validateDate = async (data, schema, options, keyPath) => {
|
|
|
262
268
|
|
|
263
269
|
}
|
|
264
270
|
|
|
265
|
-
if (!
|
|
271
|
+
if (!isSameType('date', instanceTypeName(data))) {
|
|
266
272
|
throw new ValidationError(
|
|
267
273
|
keyPath,
|
|
268
274
|
schema._nonFormalizedSchema,
|
|
@@ -277,12 +283,12 @@ const validateDate = async (data, schema, options, keyPath) => {
|
|
|
277
283
|
|
|
278
284
|
const validateOther = async (data, schema, options, keyPath) => {
|
|
279
285
|
|
|
280
|
-
if (!
|
|
286
|
+
if (!isSameType(typeName(schema.type), instanceTypeName(data))) {
|
|
281
287
|
throw new ValidationError(
|
|
282
288
|
keyPath,
|
|
283
289
|
schema._nonFormalizedSchema,
|
|
284
290
|
'type',
|
|
285
|
-
(schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).other || {}).type || ((type) => `Is not of type ${type}.`),
|
|
291
|
+
(schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).other || {}).type || ((type) => `Is not of type ${type}.`), typeName(schema.type))
|
|
286
292
|
);
|
|
287
293
|
}
|
|
288
294
|
|
|
@@ -351,14 +357,14 @@ const validateAny = async (data, schema, options, keyPath, validatedData) => {
|
|
|
351
357
|
|
|
352
358
|
if (typeof data === 'undefined' || data === null) {
|
|
353
359
|
if (data === null) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
throw new ValidationError(
|
|
360
|
+
let nul = schema.null || options.defaults.null || 'deny';
|
|
361
|
+
if (nul === 'undefine') data = undefined;
|
|
362
|
+
else if (nul === 'allow') return await validatePost(data, schema, options, keyPath, validatedData);
|
|
363
|
+
else throw new ValidationError(
|
|
358
364
|
keyPath,
|
|
359
365
|
schema._nonFormalizedSchema,
|
|
360
|
-
'
|
|
361
|
-
(schema.errors || {}).
|
|
366
|
+
'null',
|
|
367
|
+
(schema.errors || {}).null || customErrorMessage((options.errorMessages || {}).null || 'Cannot be null.')
|
|
362
368
|
);
|
|
363
369
|
}
|
|
364
370
|
if (typeof schema.default !== 'undefined') {
|
|
@@ -395,7 +401,7 @@ const validateAny = async (data, schema, options, keyPath, validatedData) => {
|
|
|
395
401
|
}
|
|
396
402
|
|
|
397
403
|
if (schema.type !== undefined) {
|
|
398
|
-
switch (
|
|
404
|
+
switch (typeName(schema.type).toLowerCase()) {
|
|
399
405
|
case 'object':
|
|
400
406
|
data = await validateObject(data, schema, options, keyPath, validatedData);
|
|
401
407
|
break;
|
|
@@ -424,7 +430,7 @@ const validateAny = async (data, schema, options, keyPath, validatedData) => {
|
|
|
424
430
|
|
|
425
431
|
};
|
|
426
432
|
|
|
427
|
-
|
|
433
|
+
export default async (data, schema, options = {}, keyPath = '') => {
|
|
428
434
|
|
|
429
435
|
if (typeof schema === 'undefined') throw new Error('Missing parameter schema.');
|
|
430
436
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isvalid",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Async JSON validation library for node.js.",
|
|
5
5
|
"main": "./index.js",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"keywords": [
|
|
7
8
|
"schema",
|
|
8
9
|
"validation",
|
|
@@ -23,12 +24,12 @@
|
|
|
23
24
|
"chai": "^4.3.6",
|
|
24
25
|
"chai-as-promised": "^7.1.1",
|
|
25
26
|
"eslint": "^8.13.0",
|
|
26
|
-
"express": "^4.
|
|
27
|
-
"mocha": "^
|
|
27
|
+
"express": "^4.18.1",
|
|
28
|
+
"mocha": "^10.0.0",
|
|
28
29
|
"supertest": "^6.2.2"
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
31
|
-
"test": "./node_modules/mocha/bin/mocha ./test/index.js"
|
|
32
|
+
"test": "./node_modules/mocha/bin/mocha.js ./test/index.js"
|
|
32
33
|
},
|
|
33
34
|
"repository": {
|
|
34
35
|
"type": "git",
|
package/test/equals.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//
|
|
2
|
+
// equals.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2015-08-30
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import equals from '../lib/equals.js';
|
|
6
11
|
|
|
7
12
|
describe('equals', function() {
|
|
8
13
|
it('should return false if data is not of the same type (null).', () => {
|
package/test/formalize.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// formalize.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2018-12-12
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import formalize from '../lib/formalize.js';
|
|
11
|
+
import SchemaError from '../lib/errors/schema.js';
|
|
6
12
|
|
|
7
13
|
const f = (...args) => {
|
|
8
14
|
return () => {
|
|
@@ -49,6 +55,9 @@ describe('schema', function() {
|
|
|
49
55
|
it('should throw an error if unknownKeys is not \'allow\', \'deny\' or \'remove\'.', () => {
|
|
50
56
|
expect(f({ type: Object, unknownKeys: 'test' })).to.throw(SchemaError);
|
|
51
57
|
});
|
|
58
|
+
it('should throw an error if null is not \'allow\', \'deny\' or \'undefine\'.', () => {
|
|
59
|
+
expect(f({ type: String, null: 'test' })).to.throw(SchemaError);
|
|
60
|
+
});
|
|
52
61
|
it('should throw an error if object schema is unknown type.', () => {
|
|
53
62
|
expect(f({ type: Object, schema: RegExp })).to.throw(SchemaError);
|
|
54
63
|
});
|
package/test/index.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// index.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2015-09-27
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
9
|
+
import { use as chaiUse } from 'chai';
|
|
10
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
11
|
+
import caseit, { supported } from '@trenskow/caseit';
|
|
12
|
+
import { use } from '../lib/plugins.js';
|
|
7
13
|
|
|
8
|
-
|
|
14
|
+
chaiUse(chaiAsPromised);
|
|
9
15
|
|
|
10
|
-
|
|
16
|
+
use(function (utils) {
|
|
11
17
|
return {
|
|
12
18
|
supportsType: (type) => utils.isSameType(type, String),
|
|
13
19
|
validatorsForType: () => { return { ensureCase: String }; },
|
|
14
20
|
formalize: (config) => {
|
|
15
|
-
if (config && !
|
|
21
|
+
if (config && !supported.includes(config)) throw new Error(`Only case types: ${supported.map((casing) => `\`${casing}\``).join(', ')} are supported.`);
|
|
16
22
|
},
|
|
17
23
|
validate: (data, config) => {
|
|
18
24
|
if (caseit(data, config) !== data) throw new Error(`Is not ${config} case.`);
|
|
@@ -21,11 +27,11 @@ isvalid.plugins.use(function (utils) {
|
|
|
21
27
|
};
|
|
22
28
|
});
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
import './ranges.js';
|
|
31
|
+
import './equals.js';
|
|
32
|
+
import './unique.js';
|
|
33
|
+
import './formalize.js';
|
|
34
|
+
import './validate.js';
|
|
35
|
+
import './middleware/index.js';
|
|
36
|
+
import './key-paths.js';
|
|
37
|
+
import './merge.js';
|
package/test/key-paths.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// key-paths.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2021-08-18
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import keyPaths from '../lib/key-paths.js';
|
|
5
11
|
|
|
6
12
|
describe('keyPaths', () => {
|
|
7
13
|
it ('should come back with empty key paths', () => {
|
package/test/merge.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// merge.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2021-10-02
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import merge from '../lib/merge.js';
|
|
5
11
|
|
|
6
12
|
describe('merge', () => {
|
|
7
13
|
it ('should come back with destination type.', () => {
|
package/test/middleware/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// index.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2015-08-25
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
import request from 'supertest';
|
|
10
|
+
import { expect } from 'chai';
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
import app from './tools/server.js';
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
before(function() {
|
|
10
|
-
app = require('./tools/server.js');
|
|
11
|
-
});
|
|
14
|
+
describe('middleware', function() {
|
|
12
15
|
|
|
13
16
|
describe('param validator', function() {
|
|
14
17
|
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// server.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2015-07-27
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
import { param, parameter, query, body } from '../../../lib/middleware.js';
|
|
10
|
+
import express from 'express';
|
|
11
|
+
import bodyParser from 'body-parser';
|
|
6
12
|
|
|
7
13
|
// We build a simple express test in order to test the middleware
|
|
8
14
|
//
|
|
@@ -10,11 +16,11 @@ var app = express();
|
|
|
10
16
|
|
|
11
17
|
app.use(bodyParser.json());
|
|
12
18
|
|
|
13
|
-
app.param('testParam',
|
|
19
|
+
app.param('testParam', param({
|
|
14
20
|
type: Number, required: true
|
|
15
21
|
}));
|
|
16
22
|
|
|
17
|
-
app.param('cbTestParam',
|
|
23
|
+
app.param('cbTestParam', param({
|
|
18
24
|
type: String,
|
|
19
25
|
required: true,
|
|
20
26
|
post: (data, schema, { options }) => {
|
|
@@ -23,7 +29,7 @@ app.param('cbTestParam', validate.param({
|
|
|
23
29
|
}));
|
|
24
30
|
|
|
25
31
|
app.get('/parameter/:testParam',
|
|
26
|
-
|
|
32
|
+
parameter('testParam', {
|
|
27
33
|
type: Number,
|
|
28
34
|
post: (data) => data + 1
|
|
29
35
|
}),
|
|
@@ -38,7 +44,7 @@ app.get('/param/:testParam', function(req, res) {
|
|
|
38
44
|
app.get('/cbParam/:cbTestParam', function() {});
|
|
39
45
|
|
|
40
46
|
app.get('/query',
|
|
41
|
-
|
|
47
|
+
query({
|
|
42
48
|
'test': { type: String, match: /^.*?test$/i }
|
|
43
49
|
}),
|
|
44
50
|
function(req, res) {
|
|
@@ -47,7 +53,7 @@ app.get('/query',
|
|
|
47
53
|
);
|
|
48
54
|
|
|
49
55
|
app.post('/post',
|
|
50
|
-
|
|
56
|
+
body({
|
|
51
57
|
'test': [ { type: String, match: /^.*?test$/i } ]
|
|
52
58
|
}),
|
|
53
59
|
function(req, res) {
|
|
@@ -68,4 +74,4 @@ app.use(function(err, req, res, _) {
|
|
|
68
74
|
res.status(500).json({error: 'internal-server-error'});
|
|
69
75
|
});
|
|
70
76
|
|
|
71
|
-
|
|
77
|
+
export default app;
|
package/test/ranges.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
//
|
|
2
|
+
// ranges.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
2
8
|
|
|
3
|
-
|
|
4
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import { formalize, testIndex } from '../lib/ranges.js';
|
|
5
11
|
|
|
6
12
|
function r(range, value) {
|
|
7
|
-
const formalized =
|
|
8
|
-
return
|
|
13
|
+
const formalized = formalize(range);
|
|
14
|
+
return testIndex(formalized, value);
|
|
9
15
|
}
|
|
10
16
|
|
|
11
17
|
describe('ranges', function() {
|
package/test/unique.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//
|
|
2
|
+
// unique.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
9
|
+
import { expect } from 'chai';
|
|
10
|
+
import unique from '../lib/unique.js';
|
|
6
11
|
|
|
7
12
|
describe('unique', function() {
|
|
8
13
|
it('should return false if array of objects is not unique.', () => {
|
package/test/validate.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//
|
|
2
|
+
// validate.js
|
|
3
|
+
//
|
|
4
|
+
// Created by Kristian Trenskow on 2014-06-06
|
|
5
|
+
//
|
|
6
|
+
// See license in LICENSE
|
|
7
|
+
//
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
isvalid = require('../'),
|
|
9
|
-
utils = require('../lib/utils.js');
|
|
9
|
+
import { expect, assert } from 'chai';
|
|
10
|
+
import ValidationError from '../lib/errors/validation.js';
|
|
11
|
+
import isvalid from '../index.js';
|
|
12
|
+
import { typeName, instanceTypeName, isSameType } from '../lib/utils.js';
|
|
10
13
|
|
|
11
14
|
class Test {
|
|
12
15
|
constructor() {
|
|
@@ -17,21 +20,21 @@ class Test {
|
|
|
17
20
|
const commonTests = {
|
|
18
21
|
type: function(type, validData, invalidData) {
|
|
19
22
|
describe('type', function() {
|
|
20
|
-
it(`should come back with an error if input is not a(n) ${
|
|
23
|
+
it(`should come back with an error if input is not a(n) ${typeName(type)}.`, () => {
|
|
21
24
|
return expect(isvalid(invalidData, type))
|
|
22
|
-
.to.eventually.be.rejectedWith(`Is not of type ${
|
|
25
|
+
.to.eventually.be.rejectedWith(`Is not of type ${typeName(type)}.`)
|
|
23
26
|
.and.to.be.instanceOf(ValidationError)
|
|
24
27
|
.and.to.have.property('validator', 'type');
|
|
25
28
|
});
|
|
26
|
-
it(`should come back with no error if input is a(n) ${
|
|
29
|
+
it(`should come back with no error if input is a(n) ${typeName(type)}.`, () => {
|
|
27
30
|
return expect(isvalid(validData, {
|
|
28
31
|
type: type
|
|
29
32
|
})).to.eventually.satisfy((data) => {
|
|
30
|
-
return
|
|
33
|
+
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
|
|
31
34
|
});
|
|
32
35
|
});
|
|
33
36
|
describe('#errors', function() {
|
|
34
|
-
it(`should come back with an error of custom message if input is not a(n) ${
|
|
37
|
+
it(`should come back with an error of custom message if input is not a(n) ${typeName(type)}.`, () => {
|
|
35
38
|
return expect(isvalid(invalidData, {
|
|
36
39
|
type: type,
|
|
37
40
|
errors: {
|
|
@@ -59,7 +62,7 @@ const commonTests = {
|
|
|
59
62
|
type: type,
|
|
60
63
|
required: true
|
|
61
64
|
})).to.eventually.satisfy((data) => {
|
|
62
|
-
return
|
|
65
|
+
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
|
|
63
66
|
});
|
|
64
67
|
});
|
|
65
68
|
it('should prioritize concrete over defaults.', () => {
|
|
@@ -83,43 +86,36 @@ const commonTests = {
|
|
|
83
86
|
});
|
|
84
87
|
});
|
|
85
88
|
},
|
|
86
|
-
|
|
87
|
-
describe('
|
|
89
|
+
null: function(type) {
|
|
90
|
+
describe('null', function() {
|
|
88
91
|
it('should come back with an error if required and does not allow null and input is null.', () => {
|
|
89
92
|
return expect(isvalid(null, {
|
|
90
93
|
type: type,
|
|
94
|
+
null: 'deny',
|
|
91
95
|
required: true}))
|
|
92
96
|
.to.eventually.be.rejectedWith('Cannot be null.')
|
|
93
97
|
.and.to.be.instanceOf(ValidationError)
|
|
94
|
-
.and.to.have.property('validator', '
|
|
98
|
+
.and.to.have.property('validator', 'null');
|
|
95
99
|
});
|
|
96
|
-
it('should come back with no error if required and
|
|
100
|
+
it('should come back with no error if required and null is allowed and input is null.', () => {
|
|
97
101
|
return expect(isvalid(null, {
|
|
98
102
|
type: type,
|
|
99
103
|
required: true,
|
|
100
|
-
|
|
104
|
+
null: 'allow'
|
|
101
105
|
})).to.eventually.be.null;
|
|
102
106
|
});
|
|
103
|
-
it('should
|
|
107
|
+
it('should come back with no error if required and null is allowed and input is null.', () => {
|
|
104
108
|
return expect(isvalid(null, {
|
|
105
109
|
type: type,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.and.to.have.property('validator', 'allowNull');
|
|
110
|
+
required: true,
|
|
111
|
+
null: 'allow'
|
|
112
|
+
})).to.eventually.be.null;
|
|
110
113
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
errors: {
|
|
117
|
-
allowNull: 'Allow null custom error message.'
|
|
118
|
-
}}))
|
|
119
|
-
.to.eventually.be.rejectedWith('Allow null custom error message.')
|
|
120
|
-
.and.to.be.instanceOf(ValidationError)
|
|
121
|
-
.and.has.property('validator', 'allowNull');
|
|
122
|
-
});
|
|
114
|
+
it('should come back with no error and undefined if null is set to undefine input and input is null.', () => {
|
|
115
|
+
return expect(isvalid(null, {
|
|
116
|
+
type: type,
|
|
117
|
+
null: 'undefine'
|
|
118
|
+
})).to.eventually.be.undefined;
|
|
123
119
|
});
|
|
124
120
|
});
|
|
125
121
|
},
|
|
@@ -129,19 +125,19 @@ const commonTests = {
|
|
|
129
125
|
return expect(isvalid(undefined, { type: type, default: async () => {
|
|
130
126
|
return validData;
|
|
131
127
|
}})).to.eventually.satisfy((data) => {
|
|
132
|
-
return
|
|
128
|
+
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
|
|
133
129
|
});
|
|
134
130
|
});
|
|
135
131
|
it('should call default if default is a function.', () => {
|
|
136
132
|
return expect(isvalid(undefined, { type: type, default: () => {
|
|
137
133
|
return validData;
|
|
138
134
|
}})).to.eventually.satisfy((data) => {
|
|
139
|
-
return
|
|
135
|
+
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
|
|
140
136
|
});
|
|
141
137
|
});
|
|
142
138
|
it('should call default if default is a value.', () => {
|
|
143
139
|
return expect(isvalid(undefined, { type: type, default: validData })).to.eventually.satisfy((data) => {
|
|
144
|
-
return
|
|
140
|
+
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
|
|
145
141
|
});
|
|
146
142
|
});
|
|
147
143
|
it('should call default with options if options are provided.', () => {
|
|
@@ -314,7 +310,7 @@ const commonTests = {
|
|
|
314
310
|
});
|
|
315
311
|
},
|
|
316
312
|
all: function(type, validData, invalidData) { var self = this;
|
|
317
|
-
['type', 'required', '
|
|
313
|
+
['type', 'required', 'null', 'default', 'equal', 'post'].forEach(function(test) {
|
|
318
314
|
self[test](type, validData, invalidData);
|
|
319
315
|
});
|
|
320
316
|
}
|
package/test/utils.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = exports = {};
|
|
4
|
-
|
|
5
|
-
exports.testPromise = (method, desc, s, expects) => {
|
|
6
|
-
it ('[promise] ' + desc, (done) => {
|
|
7
|
-
method(s)
|
|
8
|
-
.then((res) => {
|
|
9
|
-
expects(res);
|
|
10
|
-
done();
|
|
11
|
-
})
|
|
12
|
-
.catch((err) => {
|
|
13
|
-
expects(err);
|
|
14
|
-
done();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
};
|