valgen 4.0.0-alpha.6 → 4.0.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 +13 -2
- package/cjs/core/context.js +29 -23
- package/cjs/core/validator.js +9 -8
- package/cjs/helpers/omit-undefined.js +15 -0
- package/cjs/rules/is-array.js +12 -10
- package/cjs/rules/is-bigint.js +2 -2
- package/cjs/rules/is-boolean.js +2 -2
- package/cjs/rules/is-date.js +7 -13
- package/cjs/rules/is-empty.js +4 -4
- package/cjs/rules/is-enum.js +2 -5
- package/cjs/rules/is-integer.js +2 -2
- package/cjs/rules/is-matches.js +2 -6
- package/cjs/rules/is-null.js +6 -6
- package/cjs/rules/is-number.js +2 -2
- package/cjs/rules/is-object-id.js +2 -2
- package/cjs/rules/is-object.js +16 -18
- package/cjs/rules/is-record.js +13 -13
- package/cjs/rules/is-string.js +2 -2
- package/cjs/rules/is-tuple.js +12 -9
- package/cjs/rules/length.js +2 -2
- package/cjs/rules/optional.js +8 -8
- package/cjs/rules/pipe.js +2 -4
- package/cjs/rules/range.js +10 -10
- package/cjs/rules/string-formats.js +48 -48
- package/cjs/rules/union.js +10 -5
- package/cjs/rules/utilities.js +2 -2
- package/esm/core/context.js +29 -23
- package/esm/core/validator.js +9 -8
- package/esm/helpers/omit-undefined.js +11 -0
- package/esm/rules/is-array.js +13 -11
- package/esm/rules/is-bigint.js +2 -2
- package/esm/rules/is-boolean.js +2 -2
- package/esm/rules/is-date.js +7 -13
- package/esm/rules/is-empty.js +4 -4
- package/esm/rules/is-enum.js +2 -5
- package/esm/rules/is-integer.js +2 -2
- package/esm/rules/is-matches.js +2 -6
- package/esm/rules/is-null.js +6 -6
- package/esm/rules/is-number.js +2 -2
- package/esm/rules/is-object-id.js +2 -2
- package/esm/rules/is-object.js +17 -19
- package/esm/rules/is-record.js +14 -14
- package/esm/rules/is-string.js +2 -2
- package/esm/rules/is-tuple.js +13 -10
- package/esm/rules/length.js +2 -2
- package/esm/rules/optional.js +9 -9
- package/esm/rules/pipe.js +3 -5
- package/esm/rules/range.js +10 -10
- package/esm/rules/string-formats.js +48 -48
- package/esm/rules/union.js +10 -5
- package/esm/rules/utilities.js +3 -3
- package/package.json +4 -4
- package/typings/core/context.d.ts +11 -19
- package/typings/core/types.d.ts +4 -1
- package/typings/core/validator.d.ts +1 -1
- package/typings/helpers/omit-undefined.d.ts +1 -0
- package/typings/rules/is-object.d.ts +1 -1
package/esm/rules/is-array.js
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validator, } from '../core/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Validates if value is "array" and applies validation for each item.
|
|
4
4
|
* Converts input value to array if coerce option is set to 'true'.
|
|
5
5
|
* @validator isArray
|
|
6
6
|
*/
|
|
7
7
|
export function isArray(itemValidator, options) {
|
|
8
|
-
return validator('isArray', function (input, context) {
|
|
8
|
+
return validator('isArray', function (input, context, _this) {
|
|
9
9
|
if (input != null && context.coerce && !Array.isArray(input))
|
|
10
10
|
input = [input];
|
|
11
11
|
if (!Array.isArray(input)) {
|
|
12
|
-
context.
|
|
12
|
+
context.fail(_this, `{{label}} is not an array`, input);
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
if (!itemValidator)
|
|
16
16
|
return input;
|
|
17
|
-
const location = context.
|
|
18
|
-
const itemContext = context.extend(
|
|
17
|
+
const location = context.location || '';
|
|
18
|
+
const itemContext = context.extend();
|
|
19
19
|
let i;
|
|
20
20
|
let v;
|
|
21
21
|
const l = input.length;
|
|
22
22
|
const out = [];
|
|
23
23
|
for (i = 0; i < l; i++) {
|
|
24
24
|
v = input[i];
|
|
25
|
-
itemContext.
|
|
26
|
-
itemContext.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
itemContext.scope = input;
|
|
26
|
+
itemContext.location = location + '[' + i + ']';
|
|
27
|
+
itemContext.label = context.label
|
|
28
|
+
? context.label + `[${i}]`
|
|
29
|
+
: `Item at (${i})`;
|
|
30
|
+
itemContext.index = i;
|
|
31
|
+
v = itemValidator(v, itemContext);
|
|
32
|
+
out.push(v);
|
|
31
33
|
}
|
|
32
34
|
return out;
|
|
33
35
|
}, options);
|
package/esm/rules/is-bigint.js
CHANGED
|
@@ -5,13 +5,13 @@ import { validator } from '../core/index.js';
|
|
|
5
5
|
* @validator isNumber
|
|
6
6
|
*/
|
|
7
7
|
export function isBigint(options) {
|
|
8
|
-
return validator('isBigint', function (input, context) {
|
|
8
|
+
return validator('isBigint', function (input, context, _this) {
|
|
9
9
|
if (input != null && typeof input !== 'bigint' && context.coerce) {
|
|
10
10
|
if (typeof input === 'string' || typeof input === 'number')
|
|
11
11
|
input = BigInt(input);
|
|
12
12
|
}
|
|
13
13
|
if (typeof input === 'bigint')
|
|
14
14
|
return input;
|
|
15
|
-
context.
|
|
15
|
+
context.fail(_this, `{{label}} is not a valid BigInt`, input);
|
|
16
16
|
}, options);
|
|
17
17
|
}
|
package/esm/rules/is-boolean.js
CHANGED
|
@@ -7,7 +7,7 @@ const FALSE_PATTERN = /^false|f|0|no|n$/i;
|
|
|
7
7
|
* @validator isBoolean
|
|
8
8
|
*/
|
|
9
9
|
export function isBoolean(options) {
|
|
10
|
-
return validator('isBoolean', function (input, context) {
|
|
10
|
+
return validator('isBoolean', function (input, context, _this) {
|
|
11
11
|
if (input != null && typeof input !== 'boolean' && context.coerce) {
|
|
12
12
|
if (typeof input === 'string') {
|
|
13
13
|
if (TRUE_PATTERN.test(input))
|
|
@@ -21,6 +21,6 @@ export function isBoolean(options) {
|
|
|
21
21
|
}
|
|
22
22
|
if (typeof input === 'boolean')
|
|
23
23
|
return input;
|
|
24
|
-
context.
|
|
24
|
+
context.fail(_this, `{{label}} is not a valid boolean`, input);
|
|
25
25
|
}, options);
|
|
26
26
|
}
|
package/esm/rules/is-date.js
CHANGED
|
@@ -9,7 +9,7 @@ dayjs.extend(customParseFormat);
|
|
|
9
9
|
* @validator isDate
|
|
10
10
|
*/
|
|
11
11
|
export function isDate(options) {
|
|
12
|
-
return validator('isDate', function (input, context) {
|
|
12
|
+
return validator('isDate', function (input, context, _this) {
|
|
13
13
|
if (input != null && !(input instanceof Date) && context.coerce) {
|
|
14
14
|
if (typeof input === 'string') {
|
|
15
15
|
const d = dayjs(input, options?.format);
|
|
@@ -21,13 +21,10 @@ export function isDate(options) {
|
|
|
21
21
|
}
|
|
22
22
|
if (input && input instanceof Date && !isNaN(input.getTime()))
|
|
23
23
|
return input;
|
|
24
|
-
context.
|
|
25
|
-
|
|
26
|
-
(
|
|
27
|
-
|
|
28
|
-
: ''),
|
|
29
|
-
format: options?.format
|
|
30
|
-
});
|
|
24
|
+
context.fail(_this, `{{label}} is not a valid Date instance` +
|
|
25
|
+
(context.coerce
|
|
26
|
+
? ` or a date formatted${options?.format ? " (" + options.format + ")" : ''} string`
|
|
27
|
+
: ''), input, { format: options?.format });
|
|
31
28
|
}, omitKeys(options || {}, ['format']));
|
|
32
29
|
}
|
|
33
30
|
/**
|
|
@@ -38,7 +35,7 @@ export function isDate(options) {
|
|
|
38
35
|
export function isDateString(options) {
|
|
39
36
|
const inputFormat = options?.format;
|
|
40
37
|
const coerceFormat = Array.isArray(options?.format) ? options?.format[0] : options?.format;
|
|
41
|
-
return validator('isDateString', function (input, context) {
|
|
38
|
+
return validator('isDateString', function (input, context, _this) {
|
|
42
39
|
if (input instanceof Date) {
|
|
43
40
|
const d = dayjs(input);
|
|
44
41
|
if (d.isValid())
|
|
@@ -52,9 +49,6 @@ export function isDateString(options) {
|
|
|
52
49
|
return input;
|
|
53
50
|
}
|
|
54
51
|
}
|
|
55
|
-
context.
|
|
56
|
-
message: `{{label}} is not a valid date formatted${options?.format ? " (" + options.format + ")" : ''} string`,
|
|
57
|
-
format: options?.format
|
|
58
|
-
});
|
|
52
|
+
context.fail(_this, `{{label}} is not a valid date formatted${options?.format ? " (" + options.format + ")" : ''} string`, input, { format: options?.format });
|
|
59
53
|
}, omitKeys(options || {}, ['format']));
|
|
60
54
|
}
|
package/esm/rules/is-empty.js
CHANGED
|
@@ -4,7 +4,7 @@ import { validator } from '../core/index.js';
|
|
|
4
4
|
* @validator isEmpty
|
|
5
5
|
*/
|
|
6
6
|
export function isEmpty(options) {
|
|
7
|
-
return validator('isEmpty', function (input, context) {
|
|
7
|
+
return validator('isEmpty', function (input, context, _this) {
|
|
8
8
|
if (input != null) {
|
|
9
9
|
if (typeof input === 'string') {
|
|
10
10
|
if (!input)
|
|
@@ -27,7 +27,7 @@ export function isEmpty(options) {
|
|
|
27
27
|
return input;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
context.
|
|
30
|
+
context.fail(_this, `{{label}} is not empty`, input);
|
|
31
31
|
}, options);
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
@@ -35,7 +35,7 @@ export function isEmpty(options) {
|
|
|
35
35
|
* @validator isNotEmpty
|
|
36
36
|
*/
|
|
37
37
|
export function isNotEmpty(options) {
|
|
38
|
-
return validator('isNotEmpty', function (input, context) {
|
|
38
|
+
return validator('isNotEmpty', function (input, context, _this) {
|
|
39
39
|
if (input != null) {
|
|
40
40
|
if (typeof input === 'string') {
|
|
41
41
|
if (input)
|
|
@@ -58,6 +58,6 @@ export function isNotEmpty(options) {
|
|
|
58
58
|
return input;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
context.
|
|
61
|
+
context.fail(_this, `{{label}} is empty`, input);
|
|
62
62
|
}, options);
|
|
63
63
|
}
|
package/esm/rules/is-enum.js
CHANGED
|
@@ -15,12 +15,9 @@ export function isEnum(values, options) {
|
|
|
15
15
|
a[v] = true;
|
|
16
16
|
return a;
|
|
17
17
|
}, {});
|
|
18
|
-
return validator('isEnum', function (input, context) {
|
|
18
|
+
return validator('isEnum', function (input, context, _this) {
|
|
19
19
|
if (input != null && valObj[typeof input === 'string' && caseInSensitive ? input.toUpperCase() : input])
|
|
20
20
|
return input;
|
|
21
|
-
context.
|
|
22
|
-
message: `Value must be one of enumeration member${enumName ? ` (${enumName})` : ''}`,
|
|
23
|
-
enum: enumName
|
|
24
|
-
});
|
|
21
|
+
context.fail(_this, `Value must be one of enumeration member${enumName ? ` (${enumName})` : ''}`, input, { enum: enumName });
|
|
25
22
|
}, options);
|
|
26
23
|
}
|
package/esm/rules/is-integer.js
CHANGED
|
@@ -5,7 +5,7 @@ import { validator } from '../core/index.js';
|
|
|
5
5
|
* @validator isInteger
|
|
6
6
|
*/
|
|
7
7
|
export function isInteger(options) {
|
|
8
|
-
return validator('isInteger', function (input, context) {
|
|
8
|
+
return validator('isInteger', function (input, context, _this) {
|
|
9
9
|
if (input != null && typeof input !== 'number' && context.coerce) {
|
|
10
10
|
if (typeof input === 'string')
|
|
11
11
|
input = parseFloat(input);
|
|
@@ -17,6 +17,6 @@ export function isInteger(options) {
|
|
|
17
17
|
}
|
|
18
18
|
if (typeof input === 'number' && !isNaN(input) && Number.isInteger(input))
|
|
19
19
|
return input;
|
|
20
|
-
context.
|
|
20
|
+
context.fail(_this, `{{label}} is not a valid integer number`, input);
|
|
21
21
|
}, options);
|
|
22
22
|
}
|
package/esm/rules/is-matches.js
CHANGED
|
@@ -6,15 +6,11 @@ import { validator } from '../core/index.js';
|
|
|
6
6
|
export function isMatches(format, options) {
|
|
7
7
|
const regExp = format instanceof RegExp ? format : new RegExp(format);
|
|
8
8
|
const formatName = options?.formatName;
|
|
9
|
-
return validator('matches', function (input, context) {
|
|
9
|
+
return validator('matches', function (input, context, _this) {
|
|
10
10
|
if (input == null)
|
|
11
11
|
return;
|
|
12
12
|
if (typeof input === 'string' && regExp.test(input))
|
|
13
13
|
return input;
|
|
14
|
-
context.
|
|
15
|
-
message: `{{label}} does not match ${formatName || 'requested'} format`,
|
|
16
|
-
format,
|
|
17
|
-
formatName
|
|
18
|
-
});
|
|
14
|
+
context.fail(_this, `{{label}} does not match ${formatName || 'requested'} format`, input, { format, formatName });
|
|
19
15
|
}, options);
|
|
20
16
|
}
|
package/esm/rules/is-null.js
CHANGED
|
@@ -4,10 +4,10 @@ import { validator } from '../core/index.js';
|
|
|
4
4
|
* @validator isNull
|
|
5
5
|
*/
|
|
6
6
|
export function isNull(options) {
|
|
7
|
-
return validator('isNull', function (input, context) {
|
|
7
|
+
return validator('isNull', function (input, context, _this) {
|
|
8
8
|
if (input === null)
|
|
9
9
|
return input;
|
|
10
|
-
context.
|
|
10
|
+
context.fail(_this, `{{label}} is not null`, input);
|
|
11
11
|
}, options);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -15,10 +15,10 @@ export function isNull(options) {
|
|
|
15
15
|
* @validator isDefined
|
|
16
16
|
*/
|
|
17
17
|
export function isDefined(options) {
|
|
18
|
-
return validator('is-defined', function (input, context) {
|
|
18
|
+
return validator('is-defined', function (input, context, _this) {
|
|
19
19
|
if (input !== undefined)
|
|
20
20
|
return input;
|
|
21
|
-
context.
|
|
21
|
+
context.fail(_this, `{{label}} is not defined`, input);
|
|
22
22
|
}, options);
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
@@ -26,9 +26,9 @@ export function isDefined(options) {
|
|
|
26
26
|
* @validator isNotDefined
|
|
27
27
|
*/
|
|
28
28
|
export function isUndefined(options) {
|
|
29
|
-
return validator('isUndefined', function (input, context) {
|
|
29
|
+
return validator('isUndefined', function (input, context, _this) {
|
|
30
30
|
if (input === undefined)
|
|
31
31
|
return;
|
|
32
|
-
context.
|
|
32
|
+
context.fail(_this, `{{label}} defined`, input);
|
|
33
33
|
}, options);
|
|
34
34
|
}
|
package/esm/rules/is-number.js
CHANGED
|
@@ -5,7 +5,7 @@ import { validator } from '../core/index.js';
|
|
|
5
5
|
* @validator isNumber
|
|
6
6
|
*/
|
|
7
7
|
export function isNumber(options) {
|
|
8
|
-
return validator('isNumber', function (input, context) {
|
|
8
|
+
return validator('isNumber', function (input, context, _this) {
|
|
9
9
|
if (input != null && typeof input !== 'number' && context.coerce) {
|
|
10
10
|
if (typeof input === 'string')
|
|
11
11
|
input = parseFloat(input);
|
|
@@ -17,6 +17,6 @@ export function isNumber(options) {
|
|
|
17
17
|
}
|
|
18
18
|
if (typeof input === 'number' && !isNaN(input))
|
|
19
19
|
return input;
|
|
20
|
-
context.
|
|
20
|
+
context.fail(_this, `{{label}} is not a valid number`, input);
|
|
21
21
|
}, options);
|
|
22
22
|
}
|
|
@@ -5,14 +5,14 @@ import { validator } from '../core/index.js';
|
|
|
5
5
|
* @validator isObjectId
|
|
6
6
|
*/
|
|
7
7
|
export function isObjectId(options) {
|
|
8
|
-
return validator('isObjectId', function (input, context) {
|
|
8
|
+
return validator('isObjectId', function (input, context, _this) {
|
|
9
9
|
if (input != null &&
|
|
10
10
|
(_isObjectIdValue(input) ||
|
|
11
11
|
(typeof input === 'object' &&
|
|
12
12
|
typeof input.toHexString === 'function' &&
|
|
13
13
|
_isObjectIdValue(input.toHexString()))))
|
|
14
14
|
return input;
|
|
15
|
-
context.
|
|
15
|
+
context.fail(_this, `{{label}} is not a valid ObjectId`, input);
|
|
16
16
|
}, options);
|
|
17
17
|
}
|
|
18
18
|
function _isObjectIdValue(input) {
|
package/esm/rules/is-object.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isValidator,
|
|
1
|
+
import { isValidator, validator } from '../core/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Validates object according to schema
|
|
4
4
|
* Converts properties according to schema rules if coerce option is set to 'true'.
|
|
@@ -28,9 +28,9 @@ export function isObject(schema, options) {
|
|
|
28
28
|
else
|
|
29
29
|
throw new TypeError(`Invalid definition in validation schema (${k})`);
|
|
30
30
|
});
|
|
31
|
-
const _rule = validator('isObject', function (input, context) {
|
|
31
|
+
const _rule = validator('isObject', function (input, context, _this) {
|
|
32
32
|
if (!(input && typeof input === 'object')) {
|
|
33
|
-
context.
|
|
33
|
+
context.fail(_this, `{{label}} is not an object`, input);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
const keys = [...Object.keys(input), ...Object.keys(schema)];
|
|
@@ -49,8 +49,9 @@ export function isObject(schema, options) {
|
|
|
49
49
|
return context.circMap.get(input);
|
|
50
50
|
context.circMap.set(input, out);
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
if (context.root == null)
|
|
53
|
+
context.root = context.root || ctorName || '';
|
|
54
|
+
const location = context.location || '';
|
|
54
55
|
const processedSchemaKeys = {};
|
|
55
56
|
// Iterate object keys and perform rules
|
|
56
57
|
for (i = 0; i < l; i++) {
|
|
@@ -63,23 +64,20 @@ export function isObject(schema, options) {
|
|
|
63
64
|
if (processedSchemaKeys[schemaKey])
|
|
64
65
|
continue;
|
|
65
66
|
processedSchemaKeys[schemaKey] = true;
|
|
66
|
-
const subCtx = context.extend(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
subCtx.input.location = location + (location ? '.' : '') + schemaKey;
|
|
75
|
-
subCtx.input.property = schemaKey;
|
|
76
|
-
v = _propRule[kValidatorFn](v, subCtx, _propRule);
|
|
67
|
+
const subCtx = context.extend();
|
|
68
|
+
subCtx.scope = input;
|
|
69
|
+
subCtx.context = ctorName;
|
|
70
|
+
subCtx.location = location + (location ? '.' : '') + schemaKey;
|
|
71
|
+
subCtx.property = schemaKey;
|
|
72
|
+
if (propertyOptions[schemaKey]?.label)
|
|
73
|
+
subCtx.label = propertyOptions[schemaKey]?.label;
|
|
74
|
+
v = _propRule(v, subCtx);
|
|
77
75
|
}
|
|
78
76
|
else if (v !== undefined) {
|
|
79
|
-
if (additionalFields === 'ignore')
|
|
80
|
-
continue;
|
|
81
77
|
if (!additionalFields)
|
|
82
|
-
|
|
78
|
+
continue;
|
|
79
|
+
if (additionalFields === 'error')
|
|
80
|
+
context.fail(_propRule, `${ctorName || 'Object'} has no field '${inputKey}' and does not accept additional fields`, v);
|
|
83
81
|
}
|
|
84
82
|
if (v !== undefined)
|
|
85
83
|
out[propertyOptions[schemaKey]?.as || schemaKey] = v;
|
package/esm/rules/is-record.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validator, } from '../core/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Validates record object according to given "key" and "value" rules
|
|
4
4
|
* Converts properties according to rules if coerce option is set to 'true'.
|
|
5
5
|
* @validator isRecord
|
|
6
6
|
*/
|
|
7
7
|
export function isRecord(keyRule, valueRule, options) {
|
|
8
|
-
return validator('isRecord', function (input, context) {
|
|
8
|
+
return validator('isRecord', function (input, context, _this) {
|
|
9
9
|
if (!(input && typeof input === 'object')) {
|
|
10
|
-
context.
|
|
10
|
+
context.fail(_this, `{{label}} is not an object`, input);
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
13
|
+
const keyContext = context.extend();
|
|
14
|
+
const valueContext = context.extend();
|
|
15
|
+
const location = context.location || '';
|
|
16
16
|
const keys = Object.keys(input);
|
|
17
17
|
const l = keys.length;
|
|
18
18
|
let i;
|
|
@@ -22,14 +22,14 @@ export function isRecord(keyRule, valueRule, options) {
|
|
|
22
22
|
for (i = 0; i < l; i++) {
|
|
23
23
|
k = keys[i];
|
|
24
24
|
v = input[k];
|
|
25
|
-
|
|
26
|
-
keyContext.
|
|
27
|
-
keyContext.
|
|
28
|
-
k = keyRule
|
|
29
|
-
|
|
30
|
-
valueContext.
|
|
31
|
-
valueContext.
|
|
32
|
-
v = valueRule
|
|
25
|
+
// Validate key
|
|
26
|
+
keyContext.property = '@' + k;
|
|
27
|
+
keyContext.location = location + (location ? '.@' : '@') + k;
|
|
28
|
+
k = keyRule(k, keyContext);
|
|
29
|
+
// Validate value
|
|
30
|
+
valueContext.property = k;
|
|
31
|
+
valueContext.location = location + (location ? '.' : '') + k;
|
|
32
|
+
v = valueRule(v, valueContext);
|
|
33
33
|
out[k] = v;
|
|
34
34
|
}
|
|
35
35
|
return context.errors.length ? undefined : out;
|
package/esm/rules/is-string.js
CHANGED
|
@@ -5,7 +5,7 @@ import { validator } from '../core/index.js';
|
|
|
5
5
|
* @validator isString
|
|
6
6
|
*/
|
|
7
7
|
export function isString(options) {
|
|
8
|
-
return validator('isString', function (input, context) {
|
|
8
|
+
return validator('isString', function (input, context, _this) {
|
|
9
9
|
if (input != null && typeof input !== 'string' && context.coerce) {
|
|
10
10
|
if (typeof input === 'object') {
|
|
11
11
|
if (typeof input.toJSON === 'function')
|
|
@@ -18,7 +18,7 @@ export function isString(options) {
|
|
|
18
18
|
}
|
|
19
19
|
if (typeof input === 'string')
|
|
20
20
|
return input;
|
|
21
|
-
context.
|
|
21
|
+
context.fail(_this, `{{label}} is not a string`, input);
|
|
22
22
|
}, options);
|
|
23
23
|
}
|
|
24
24
|
export function stringReplace(searchValue, replacer) {
|
package/esm/rules/is-tuple.js
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validator } from '../core/index.js';
|
|
2
2
|
export function isTuple(items, options) {
|
|
3
|
-
return validator('isTuple', function (input, context) {
|
|
3
|
+
return validator('isTuple', function (input, context, _this) {
|
|
4
4
|
if (input != null && context.coerce && !Array.isArray(input))
|
|
5
5
|
input = [input];
|
|
6
6
|
if (!Array.isArray(input)) {
|
|
7
|
-
context.
|
|
7
|
+
context.fail(_this, `{{label}} is not a tuple`, input);
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
|
-
const location = context.
|
|
10
|
+
const location = context.location || '';
|
|
11
11
|
let itemRule;
|
|
12
12
|
let i;
|
|
13
|
+
let v;
|
|
13
14
|
const l = input.length;
|
|
14
15
|
const out = [];
|
|
15
16
|
const nl = items.length;
|
|
17
|
+
const itemContext = context.extend();
|
|
16
18
|
for (i = 0; i < l && i < nl; i++) {
|
|
17
19
|
itemRule = items[i];
|
|
18
|
-
|
|
19
|
-
itemContext.
|
|
20
|
-
itemContext.
|
|
20
|
+
itemContext.scope = input;
|
|
21
|
+
itemContext.label = context.label ? context.label + `[${i}]` : undefined;
|
|
22
|
+
itemContext.index = i;
|
|
23
|
+
itemContext.location = location + '[' + i + ']';
|
|
24
|
+
itemContext.label = (itemContext.label || itemContext.property || 'Value at ') +
|
|
21
25
|
`[${i}]`;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
out.push(itemRule[kValidatorFn](input[i], itemContext, itemRule) ?? null);
|
|
26
|
+
v = itemRule(input[i], itemContext);
|
|
27
|
+
out.push(v);
|
|
25
28
|
}
|
|
26
29
|
return context.errors.length ? undefined : out;
|
|
27
30
|
}, options);
|
package/esm/rules/length.js
CHANGED
|
@@ -6,7 +6,7 @@ import { isGte, isLte } from './range.js';
|
|
|
6
6
|
* @validator getLength
|
|
7
7
|
*/
|
|
8
8
|
export const extractLength = () => extractLengthRule;
|
|
9
|
-
const extractLengthRule = validator('extractLength', function (input, context) {
|
|
9
|
+
const extractLengthRule = validator('extractLength', function (input, context, _this) {
|
|
10
10
|
if (typeof input === 'string')
|
|
11
11
|
return input.length;
|
|
12
12
|
if (Array.isArray(input))
|
|
@@ -17,7 +17,7 @@ const extractLengthRule = validator('extractLength', function (input, context) {
|
|
|
17
17
|
return input.length;
|
|
18
18
|
if (input && typeof input === 'object' && typeof input.size === 'number')
|
|
19
19
|
return input.size;
|
|
20
|
-
context.
|
|
20
|
+
context.fail(_this, `Unable to extract length of {{label}}`, input);
|
|
21
21
|
});
|
|
22
22
|
/**
|
|
23
23
|
* Checks the length is at least "minValue"
|
package/esm/rules/optional.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validator } from '../core/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Makes sub-rule optional
|
|
4
4
|
* @validator optional
|
|
@@ -7,7 +7,7 @@ export function optional(nested, options) {
|
|
|
7
7
|
return validator('optional', function (input, context) {
|
|
8
8
|
if (input == null)
|
|
9
9
|
return input;
|
|
10
|
-
return nested
|
|
10
|
+
return nested(input, context);
|
|
11
11
|
}, options);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -15,12 +15,12 @@ export function optional(nested, options) {
|
|
|
15
15
|
* @validator required
|
|
16
16
|
*/
|
|
17
17
|
export function required(nested, options) {
|
|
18
|
-
return validator('required', function (input, context) {
|
|
18
|
+
return validator('required', function (input, context, _this) {
|
|
19
19
|
if (input == null) {
|
|
20
|
-
context.
|
|
20
|
+
context.fail(_this, `{{label}} is required`, input);
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
return nested
|
|
23
|
+
return nested(input, context);
|
|
24
24
|
}, options);
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
@@ -28,11 +28,11 @@ export function required(nested, options) {
|
|
|
28
28
|
* @validator exists
|
|
29
29
|
*/
|
|
30
30
|
export function exists(options) {
|
|
31
|
-
return validator('exists', function (input, context) {
|
|
31
|
+
return validator('exists', function (input, context, _this) {
|
|
32
32
|
if (input !== undefined ||
|
|
33
|
-
(context.
|
|
34
|
-
Object.getOwnPropertyDescriptor(context.
|
|
33
|
+
(context.scope &&
|
|
34
|
+
Object.getOwnPropertyDescriptor(context.scope, input)))
|
|
35
35
|
return input;
|
|
36
|
-
context.
|
|
36
|
+
context.fail(_this, `{{label}} must exist`, input);
|
|
37
37
|
}, options);
|
|
38
38
|
}
|
package/esm/rules/pipe.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validator } from '../core/index.js';
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
4
|
* @validator pipe
|
|
@@ -11,8 +11,7 @@ export function pipe(...rules) {
|
|
|
11
11
|
let v = input;
|
|
12
12
|
for (i = 0; i < l; i++) {
|
|
13
13
|
c = rules[i];
|
|
14
|
-
|
|
15
|
-
v = c[kValidatorFn](v, subContext, c);
|
|
14
|
+
v = c(v, context);
|
|
16
15
|
if (context.errors.length)
|
|
17
16
|
return;
|
|
18
17
|
}
|
|
@@ -30,8 +29,7 @@ export function allOf(...rules) {
|
|
|
30
29
|
const l = rules.length;
|
|
31
30
|
for (i = 0; i < l; i++) {
|
|
32
31
|
c = rules[i];
|
|
33
|
-
|
|
34
|
-
c[kValidatorFn](input, subContext, c);
|
|
32
|
+
c(input, context);
|
|
35
33
|
}
|
|
36
34
|
return input;
|
|
37
35
|
});
|
package/esm/rules/range.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { validator } from '../core/index.js';
|
|
2
2
|
export function isGt(minValue, options) {
|
|
3
|
-
return validator('isGt', function (input, context) {
|
|
3
|
+
return validator('isGt', function (input, context, _this) {
|
|
4
4
|
if ((typeof minValue === 'number' || typeof minValue === 'bigint') &&
|
|
5
5
|
(typeof input === 'number' || typeof input === 'bigint') &&
|
|
6
6
|
input > minValue)
|
|
@@ -11,11 +11,11 @@ export function isGt(minValue, options) {
|
|
|
11
11
|
(input > minValue ||
|
|
12
12
|
(options?.caseInsensitive && input.toLowerCase() > minValue.toLowerCase())))
|
|
13
13
|
return input;
|
|
14
|
-
context.
|
|
14
|
+
context.fail(_this, `{{label}} must be greater than ${(typeof minValue === 'string' ? `"${minValue}"` : minValue)}`, input);
|
|
15
15
|
}, options);
|
|
16
16
|
}
|
|
17
17
|
export function isGte(minValue, options) {
|
|
18
|
-
return validator('isGte', function (input, context) {
|
|
18
|
+
return validator('isGte', function (input, context, _this) {
|
|
19
19
|
if ((typeof minValue === 'number' || typeof minValue === 'bigint') &&
|
|
20
20
|
(typeof input === 'number' || typeof input === 'bigint') &&
|
|
21
21
|
input >= minValue)
|
|
@@ -26,11 +26,11 @@ export function isGte(minValue, options) {
|
|
|
26
26
|
(input >= minValue ||
|
|
27
27
|
(options?.caseInsensitive && input.toLowerCase() >= minValue.toLowerCase())))
|
|
28
28
|
return input;
|
|
29
|
-
context.
|
|
29
|
+
context.fail(_this, `{{label}} must be greater than or equal to ${(typeof minValue === 'string' ? `"${minValue}"` : minValue)}`, input);
|
|
30
30
|
}, options);
|
|
31
31
|
}
|
|
32
32
|
export function isLt(maxValue, options) {
|
|
33
|
-
return validator('isLt', function (input, context) {
|
|
33
|
+
return validator('isLt', function (input, context, _this) {
|
|
34
34
|
if ((typeof maxValue === 'number' || typeof maxValue === 'bigint') &&
|
|
35
35
|
(typeof input === 'number' || typeof input === 'bigint') &&
|
|
36
36
|
input < maxValue)
|
|
@@ -41,11 +41,11 @@ export function isLt(maxValue, options) {
|
|
|
41
41
|
(input < maxValue ||
|
|
42
42
|
(options?.caseInsensitive && input.toLowerCase() < maxValue.toLowerCase())))
|
|
43
43
|
return input;
|
|
44
|
-
context.
|
|
44
|
+
context.fail(_this, `{{label}} must be lover than ${(typeof maxValue === 'string' ? `"${maxValue}"` : maxValue)}`, input);
|
|
45
45
|
}, options);
|
|
46
46
|
}
|
|
47
47
|
export function isLte(maxValue, options) {
|
|
48
|
-
return validator('isLt', function (input, context) {
|
|
48
|
+
return validator('isLt', function (input, context, _this) {
|
|
49
49
|
if ((typeof maxValue === 'number' || typeof maxValue === 'bigint') &&
|
|
50
50
|
(typeof input === 'number' || typeof input === 'bigint') &&
|
|
51
51
|
input <= maxValue)
|
|
@@ -56,7 +56,7 @@ export function isLte(maxValue, options) {
|
|
|
56
56
|
(input <= maxValue ||
|
|
57
57
|
(options?.caseInsensitive && input.toLowerCase() <= maxValue.toLowerCase())))
|
|
58
58
|
return input;
|
|
59
|
-
context.
|
|
59
|
+
context.fail(_this, `{{label}} must be lover than or equal to ${(typeof maxValue === 'string' ? `"${maxValue}"` : maxValue)}`, input);
|
|
60
60
|
}, options);
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
@@ -64,7 +64,7 @@ export function isLte(maxValue, options) {
|
|
|
64
64
|
* @validator range
|
|
65
65
|
*/
|
|
66
66
|
export function range(minValue, maxValue, options) {
|
|
67
|
-
return validator('range', function (input, context) {
|
|
67
|
+
return validator('range', function (input, context, _this) {
|
|
68
68
|
if ((typeof minValue === 'number' || typeof minValue === 'bigint') &&
|
|
69
69
|
(typeof maxValue === 'number' || typeof maxValue === 'bigint') &&
|
|
70
70
|
(typeof input === 'number' || typeof input === 'bigint') &&
|
|
@@ -76,6 +76,6 @@ export function range(minValue, maxValue, options) {
|
|
|
76
76
|
if (typeof minValue === 'string' && typeof maxValue === 'string' &&
|
|
77
77
|
typeof input === 'string' && input >= minValue && input <= maxValue)
|
|
78
78
|
return input;
|
|
79
|
-
context.
|
|
79
|
+
context.fail(_this, `{{label}} must be between ${minValue} and ${maxValue}`, input);
|
|
80
80
|
}, options);
|
|
81
81
|
}
|