validno 0.2.6 → 0.3.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/README.md +517 -1
- package/dist/Schema.js +7 -5
- package/dist/ValidnoResult.js +12 -7
- package/dist/checkType.js +1 -0
- package/dist/constants/details.js +12 -11
- package/dist/constants/schema.js +10 -10
- package/dist/dev.js +19 -26
- package/dist/engine/ValidateEngine.js +44 -0
- package/dist/engine/ValidnoResult.js +102 -0
- package/dist/engine/index.js +2 -0
- package/dist/engine/methods/finishValidation.js +15 -0
- package/dist/engine/methods/handleKey.js +41 -0
- package/dist/engine/methods/handleMissingKey.js +19 -0
- package/dist/engine/methods/handleMissingKeyValidation.js +9 -0
- package/dist/engine/methods/handleNestedKey.js +19 -0
- package/dist/engine/methods/validate.js +14 -0
- package/dist/engine/methods/validateRules.js +187 -0
- package/dist/engine/methods/validateType.js +135 -0
- package/dist/types/common.js +1 -0
- package/dist/utils/errors.js +30 -21
- package/dist/utils/helpers.js +53 -57
- package/dist/utils/validateType.js +9 -8
- package/dist/utils/validations.js +157 -153
- package/dist/validate/index.js +1 -0
- package/dist/validate/validate.js +151 -0
- package/dist/validate.js +136 -127
- package/dist/validateEngine/ValidateEngine.js +44 -0
- package/dist/validateEngine/index.js +2 -0
- package/dist/validateEngine/methods/ValidateEngine.js +139 -0
- package/dist/validateEngine/methods/checkRulesForKey.js +15 -0
- package/dist/validateEngine/methods/checkValueType.js +134 -0
- package/dist/validateEngine/methods/finalizeValidation.js +15 -0
- package/dist/validateEngine/methods/finishValidation.js +15 -0
- package/dist/validateEngine/methods/handleKey.js +43 -0
- package/dist/validateEngine/methods/handleMissingKey.js +19 -0
- package/dist/validateEngine/methods/handleMissingKeyValidation.js +9 -0
- package/dist/validateEngine/methods/handleNestedKey.js +19 -0
- package/dist/validateEngine/methods/validate.js +14 -0
- package/dist/validateEngine/methods/validateKey.js +31 -0
- package/dist/validateEngine/methods/validateKeyDetails.js +13 -0
- package/dist/validateEngine/methods/validateKeyValue.js +13 -0
- package/dist/validateEngine/methods/validateNestedKey.js +19 -0
- package/dist/validateEngine/methods/validateType.js +134 -0
- package/dist/validateEngine/validate.js +14 -0
- package/dist/validateSchema/ValidateEngine.js +147 -0
- package/dist/validateSchema/index.js +6 -0
- package/dist/validateSchema/validate.js +151 -0
- package/dist/validateSchema.js +6 -0
- package/dist/validateType.js +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import ValidnoResult from "./ValidnoResult.js";
|
|
2
|
+
import validate from "./methods/validate.js";
|
|
3
|
+
import validateType from "./methods/validateType.js";
|
|
4
|
+
import validateRules from "./methods/validateRules.js";
|
|
5
|
+
import handleMissingKey from "./methods/handleMissingKey.js";
|
|
6
|
+
import handleNestedKey from "./methods/handleNestedKey.js";
|
|
7
|
+
import handleKey from "./methods/handleKey.js";
|
|
8
|
+
import handleMissingKeyValidation from "./methods/handleMissingKeyValidation.js";
|
|
9
|
+
import finishValidation from "./methods/finishValidation.js";
|
|
10
|
+
class ValidateEngine {
|
|
11
|
+
constructor(definition) {
|
|
12
|
+
this.definition = definition;
|
|
13
|
+
this.result = new ValidnoResult();
|
|
14
|
+
}
|
|
15
|
+
validate(data, validationKeys) {
|
|
16
|
+
return validate.call(this, data, validationKeys);
|
|
17
|
+
}
|
|
18
|
+
handleKey(input) {
|
|
19
|
+
return handleKey.call(this, input);
|
|
20
|
+
}
|
|
21
|
+
handleNestedKey(input) {
|
|
22
|
+
return handleNestedKey.call(this, input);
|
|
23
|
+
}
|
|
24
|
+
handleMissingKey(schema, input) {
|
|
25
|
+
return handleMissingKey(schema, input);
|
|
26
|
+
}
|
|
27
|
+
handleMissingNestedKey(nestedKey, results) {
|
|
28
|
+
results.setMissing(nestedKey);
|
|
29
|
+
return results;
|
|
30
|
+
}
|
|
31
|
+
handleMissingKeyValidation(params) {
|
|
32
|
+
return handleMissingKeyValidation.call(this, params);
|
|
33
|
+
}
|
|
34
|
+
validateType(input) {
|
|
35
|
+
return validateType(input);
|
|
36
|
+
}
|
|
37
|
+
validateRules(input) {
|
|
38
|
+
return validateRules.call(this, input);
|
|
39
|
+
}
|
|
40
|
+
finishValidation(checks) {
|
|
41
|
+
return finishValidation(checks);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export default ValidateEngine;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import _errors from "../utils/errors.js";
|
|
2
|
+
class ValidnoResult {
|
|
3
|
+
constructor(results) {
|
|
4
|
+
this.ok = (results === null || results === void 0 ? void 0 : results.ok) !== undefined ? results.ok : null;
|
|
5
|
+
this.missed = (results === null || results === void 0 ? void 0 : results.missed) || [];
|
|
6
|
+
this.failed = (results === null || results === void 0 ? void 0 : results.failed) || [];
|
|
7
|
+
this.passed = (results === null || results === void 0 ? void 0 : results.passed) || [];
|
|
8
|
+
this.errors = (results === null || results === void 0 ? void 0 : results.errors) || [];
|
|
9
|
+
this.byKeys = (results === null || results === void 0 ? void 0 : results.byKeys) || {};
|
|
10
|
+
this.errorsByKeys = (results === null || results === void 0 ? void 0 : results.errorsByKeys) || {};
|
|
11
|
+
}
|
|
12
|
+
setNoData(key) {
|
|
13
|
+
this.ok = false;
|
|
14
|
+
this.errors = [`Missing value for '${key}'`];
|
|
15
|
+
}
|
|
16
|
+
setKeyStatus(key, result) {
|
|
17
|
+
this.byKeys[key] = result;
|
|
18
|
+
}
|
|
19
|
+
fixParentByChilds(parentKey, childChecks = []) {
|
|
20
|
+
const isEveryOk = childChecks.every(check => check === true);
|
|
21
|
+
this.setKeyStatus(parentKey, isEveryOk);
|
|
22
|
+
if (isEveryOk) {
|
|
23
|
+
this.setPassed(parentKey);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.setFailed(parentKey);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
setMissing(key, errMsg) {
|
|
30
|
+
const error = errMsg || _errors.getMissingError(key);
|
|
31
|
+
this.missed.push(key);
|
|
32
|
+
this.setFailed(key, error);
|
|
33
|
+
this.setKeyStatus(key, false);
|
|
34
|
+
}
|
|
35
|
+
setPassed(key) {
|
|
36
|
+
this.passed.push(key);
|
|
37
|
+
this.setKeyStatus(key, true);
|
|
38
|
+
}
|
|
39
|
+
setFailed(key, msg) {
|
|
40
|
+
if (!(key in this.errorsByKeys)) {
|
|
41
|
+
this.errorsByKeys[key] = [];
|
|
42
|
+
}
|
|
43
|
+
this.failed.push(key);
|
|
44
|
+
this.setKeyStatus(key, false);
|
|
45
|
+
if (!msg)
|
|
46
|
+
return;
|
|
47
|
+
this.errors.push(msg);
|
|
48
|
+
this.errorsByKeys[key].push(msg);
|
|
49
|
+
}
|
|
50
|
+
joinErrors(separator = '; ') {
|
|
51
|
+
return _errors.joinErrors(this.errors, separator);
|
|
52
|
+
}
|
|
53
|
+
merge(resultsNew) {
|
|
54
|
+
this.failed = [...this.failed, ...resultsNew.failed];
|
|
55
|
+
this.errors = [...this.errors, ...resultsNew.errors];
|
|
56
|
+
this.missed = [...this.missed, ...resultsNew.missed];
|
|
57
|
+
this.passed = [...this.passed, ...resultsNew.passed];
|
|
58
|
+
this.byKeys = Object.assign(Object.assign({}, this.byKeys), resultsNew.byKeys);
|
|
59
|
+
for (const key in resultsNew.errorsByKeys) {
|
|
60
|
+
if (!(key in this.errorsByKeys)) {
|
|
61
|
+
this.errorsByKeys[key] = [];
|
|
62
|
+
}
|
|
63
|
+
this.errorsByKeys[key] = [
|
|
64
|
+
...this.errorsByKeys[key],
|
|
65
|
+
...resultsNew.errorsByKeys[key]
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
clearEmptyErrorsByKeys() {
|
|
71
|
+
for (const key in this.errorsByKeys) {
|
|
72
|
+
if (!this.errorsByKeys[key].length) {
|
|
73
|
+
delete this.errorsByKeys[key];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
finish() {
|
|
78
|
+
if (this.failed.length || this.errors.length) {
|
|
79
|
+
this.ok = false;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this.ok = true;
|
|
83
|
+
}
|
|
84
|
+
this.clearEmptyErrorsByKeys();
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
data() {
|
|
88
|
+
return {
|
|
89
|
+
ok: this.ok,
|
|
90
|
+
missed: this.missed,
|
|
91
|
+
failed: this.failed,
|
|
92
|
+
passed: this.passed,
|
|
93
|
+
errors: this.errors,
|
|
94
|
+
byKeys: this.byKeys,
|
|
95
|
+
errorsByKeys: this.errorsByKeys,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
isValid() {
|
|
99
|
+
return this.ok === true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export default ValidnoResult;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function finishValidation(checks) {
|
|
2
|
+
const { results, nestedKey, missedCheck, typeChecked, rulesChecked } = checks;
|
|
3
|
+
if (missedCheck.length)
|
|
4
|
+
results.setMissing(nestedKey);
|
|
5
|
+
const isPassed = !typeChecked.length && !rulesChecked.length && !missedCheck.length;
|
|
6
|
+
if (!isPassed) {
|
|
7
|
+
results.setFailed(nestedKey);
|
|
8
|
+
results.errorsByKeys[nestedKey] = [...results.errors];
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
results.setPassed(nestedKey);
|
|
12
|
+
}
|
|
13
|
+
return results.finish();
|
|
14
|
+
}
|
|
15
|
+
export default finishValidation;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import _helpers from "../../utils/helpers.js";
|
|
2
|
+
import ValidnoResult from "../ValidnoResult.js";
|
|
3
|
+
function validateKeyValue(params) {
|
|
4
|
+
const { results, key, nestedKey, data, reqs, hasMissing } = params;
|
|
5
|
+
const missedCheck = [];
|
|
6
|
+
const typeChecked = [];
|
|
7
|
+
const rulesChecked = [];
|
|
8
|
+
if (hasMissing) {
|
|
9
|
+
return this.handleMissingKeyValidation({ results, key, nestedKey, data, reqs, missedCheck });
|
|
10
|
+
}
|
|
11
|
+
this.validateType({ results, key, value: data[key], reqs, nestedKey, typeChecked });
|
|
12
|
+
this.validateRules({ results, nestedKey, value: data[key], reqs, data, rulesChecked });
|
|
13
|
+
return this.finishValidation({ results, nestedKey, missedCheck, typeChecked, rulesChecked });
|
|
14
|
+
}
|
|
15
|
+
function validateKey(input) {
|
|
16
|
+
let { results, key, nestedKey, data, reqs } = input;
|
|
17
|
+
if (data === undefined) {
|
|
18
|
+
const noDataResult = new ValidnoResult();
|
|
19
|
+
noDataResult.setNoData(nestedKey);
|
|
20
|
+
}
|
|
21
|
+
if (!results)
|
|
22
|
+
results = new ValidnoResult();
|
|
23
|
+
if (!nestedKey)
|
|
24
|
+
nestedKey = key;
|
|
25
|
+
const hasMissing = _helpers.hasMissing(input);
|
|
26
|
+
if (_helpers.checkNestedIsMissing(reqs, data)) {
|
|
27
|
+
return this.handleMissingNestedKey(nestedKey, results);
|
|
28
|
+
}
|
|
29
|
+
if (_helpers.checkIsNested(reqs)) {
|
|
30
|
+
return this.handleNestedKey({ results, key, data, reqs, nestedKey });
|
|
31
|
+
}
|
|
32
|
+
return validateKeyValue.call(this, {
|
|
33
|
+
results,
|
|
34
|
+
key,
|
|
35
|
+
nestedKey,
|
|
36
|
+
data,
|
|
37
|
+
reqs,
|
|
38
|
+
hasMissing,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export default validateKey;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ValidationIds } from "../../constants/details.js";
|
|
2
|
+
import _errors from "../../utils/errors.js";
|
|
3
|
+
function handleMissingKey(schema, input) {
|
|
4
|
+
const { key, nestedKey, data, reqs } = input;
|
|
5
|
+
const messageKey = nestedKey || key;
|
|
6
|
+
const messageTitle = reqs.title || messageKey;
|
|
7
|
+
if (!reqs.customMessage)
|
|
8
|
+
return _errors.getMissingError(messageKey);
|
|
9
|
+
const errorMessage = reqs.customMessage({
|
|
10
|
+
keyword: ValidationIds.Missing,
|
|
11
|
+
value: data[key],
|
|
12
|
+
key: messageKey,
|
|
13
|
+
title: messageTitle,
|
|
14
|
+
reqs,
|
|
15
|
+
schema,
|
|
16
|
+
});
|
|
17
|
+
return errorMessage;
|
|
18
|
+
}
|
|
19
|
+
export default handleMissingKey;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
function handleMissingKeyValidation(params) {
|
|
2
|
+
const schema = this.definition;
|
|
3
|
+
const { results, key, nestedKey, data, reqs, missedCheck } = params;
|
|
4
|
+
const errMsg = this.handleMissingKey(schema, { key, nestedKey, data, reqs });
|
|
5
|
+
missedCheck.push(false);
|
|
6
|
+
results.setMissing(nestedKey, errMsg);
|
|
7
|
+
return results;
|
|
8
|
+
}
|
|
9
|
+
export default handleMissingKeyValidation;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function handleNestedKey(input) {
|
|
2
|
+
const { results, key, nestedKey, data, reqs } = input;
|
|
3
|
+
const nestedKeys = Object.keys(reqs);
|
|
4
|
+
const nestedResults = [];
|
|
5
|
+
for (const itemKey of nestedKeys) {
|
|
6
|
+
const deepParams = {
|
|
7
|
+
key: itemKey,
|
|
8
|
+
data: data[key],
|
|
9
|
+
reqs: reqs[itemKey],
|
|
10
|
+
nestedKey: `${nestedKey}.${itemKey}`
|
|
11
|
+
};
|
|
12
|
+
const deepResults = this.handleKey(deepParams);
|
|
13
|
+
nestedResults.push(deepResults.ok);
|
|
14
|
+
results.merge(deepResults);
|
|
15
|
+
}
|
|
16
|
+
results.fixParentByChilds(nestedKey, nestedResults);
|
|
17
|
+
return results;
|
|
18
|
+
}
|
|
19
|
+
export default handleNestedKey;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import _helpers from "../../utils/helpers.js";
|
|
2
|
+
function validate(data, validationKeys) {
|
|
3
|
+
const hasKeysToCheck = _helpers.areKeysLimited(validationKeys);
|
|
4
|
+
const schemaKeys = Object.entries(this.definition);
|
|
5
|
+
for (const [key, reqs] of schemaKeys) {
|
|
6
|
+
const toBeValidated = _helpers.needValidation(key, hasKeysToCheck, validationKeys);
|
|
7
|
+
if (!toBeValidated)
|
|
8
|
+
continue;
|
|
9
|
+
const keyResult = this.handleKey({ key, data, reqs });
|
|
10
|
+
this.result.merge(keyResult);
|
|
11
|
+
}
|
|
12
|
+
return this.result.finish();
|
|
13
|
+
}
|
|
14
|
+
export default validate;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import _validations from "../../utils/validations.js";
|
|
2
|
+
import { ValidationDetails } from "../../constants/details.js";
|
|
3
|
+
export const rulesParams = {
|
|
4
|
+
lengthMin: {
|
|
5
|
+
allowedTypes: [String]
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
const ensureRuleHasCorrectType = (value, allowedTypes) => {
|
|
9
|
+
const isInAllowedList = allowedTypes.some(TYPE => {
|
|
10
|
+
const getType = (el) => Object.prototype.toString.call(el);
|
|
11
|
+
return getType(new TYPE()) == getType(value);
|
|
12
|
+
});
|
|
13
|
+
return isInAllowedList;
|
|
14
|
+
};
|
|
15
|
+
const rulesFunctions = {
|
|
16
|
+
custom: (key, val, func, extra) => {
|
|
17
|
+
const customResult = func(val, extra);
|
|
18
|
+
if (typeof customResult === 'object' && 'result' in customResult) {
|
|
19
|
+
return {
|
|
20
|
+
result: customResult.result,
|
|
21
|
+
details: customResult.details || ValidationDetails.CustomRuleFailed,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (typeof customResult === 'boolean') {
|
|
25
|
+
return {
|
|
26
|
+
result: customResult,
|
|
27
|
+
details: customResult ? "" : ValidationDetails.CustomRuleFailed
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
throw new Error(`Custom rule function must return an object with 'result' and 'details' properties or a boolean value. Received: ${typeof customResult}`);
|
|
31
|
+
return;
|
|
32
|
+
},
|
|
33
|
+
isEmail: (key, val) => {
|
|
34
|
+
return {
|
|
35
|
+
result: _validations.isEmail(val),
|
|
36
|
+
details: `Value must be a valid email address`
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
is: (key, val, equalTo) => {
|
|
40
|
+
return {
|
|
41
|
+
result: _validations.is(val, equalTo),
|
|
42
|
+
details: `Value must be equal to "${equalTo}"`
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
isNot: (key, val, notEqualTo) => {
|
|
46
|
+
return {
|
|
47
|
+
result: _validations.isNot(val, notEqualTo),
|
|
48
|
+
details: `Value must not be equal to "${notEqualTo}"`
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
min: (key, val, min) => {
|
|
52
|
+
return {
|
|
53
|
+
result: _validations.isNumberGte(val, min),
|
|
54
|
+
details: `Value must be greater than or equal to ${min}`
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
max: (key, val, max) => {
|
|
58
|
+
return {
|
|
59
|
+
result: _validations.isNumberLte(val, max),
|
|
60
|
+
details: `Value must be less than or equal to ${max}`
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
minMax: (key, val, minMax) => {
|
|
64
|
+
const [min, max] = minMax;
|
|
65
|
+
return {
|
|
66
|
+
result: _validations.isNumberGte(val, min) && _validations.isNumberLte(val, max),
|
|
67
|
+
details: `Value must be between ${min} and ${max}`
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
length: (key, val, length) => {
|
|
71
|
+
return {
|
|
72
|
+
result: _validations.lengthIs(val, length),
|
|
73
|
+
details: `Value must be equal to ${length}`
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
lengthNot: (key, val, lengthNot) => {
|
|
77
|
+
return {
|
|
78
|
+
result: _validations.lengthNot(val, lengthNot),
|
|
79
|
+
details: `Value must not be equal to ${lengthNot}`
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
lengthMinMax: (key, val, minMax) => {
|
|
83
|
+
const [min, max] = minMax;
|
|
84
|
+
return {
|
|
85
|
+
result: _validations.lengthMin(val, min) && _validations.lengthMax(val, max),
|
|
86
|
+
details: `Value must be between ${min} and ${max} characters`
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
lengthMin: (key, val, min) => {
|
|
90
|
+
ensureRuleHasCorrectType(val, rulesParams['lengthMin'].allowedTypes);
|
|
91
|
+
return {
|
|
92
|
+
result: _validations.lengthMin(val, min),
|
|
93
|
+
details: `Value must be at least ${min} characters`
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
lengthMax: (key, val, max) => {
|
|
97
|
+
return {
|
|
98
|
+
result: _validations.lengthMax(val, max),
|
|
99
|
+
details: `Value must not be exceed ${max} characters`
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
regex: (key, val, regex) => {
|
|
103
|
+
return {
|
|
104
|
+
result: _validations.regexTested(val, regex),
|
|
105
|
+
details: `Value must match the format ${regex}`
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
enum: (key, value, allowedList) => {
|
|
109
|
+
const output = {
|
|
110
|
+
result: true,
|
|
111
|
+
details: ''
|
|
112
|
+
};
|
|
113
|
+
if (!Array.isArray(value)) {
|
|
114
|
+
const isCorrect = allowedList.includes(value);
|
|
115
|
+
output.result = isCorrect,
|
|
116
|
+
output.details = isCorrect ? '' : `Value "${value}" is not allowed`;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const incorrectValues = [];
|
|
120
|
+
value.forEach((v) => !allowedList.includes(v) ? incorrectValues.push(v) : {});
|
|
121
|
+
const isCorrect = incorrectValues.length === 0;
|
|
122
|
+
output.result = isCorrect,
|
|
123
|
+
output.details = isCorrect ? '' : `Values are not allowed: "${incorrectValues.join(', ')}"`;
|
|
124
|
+
}
|
|
125
|
+
return output;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
function checkRules(key, value, requirements, inputObj) {
|
|
129
|
+
const result = {
|
|
130
|
+
ok: true,
|
|
131
|
+
details: []
|
|
132
|
+
};
|
|
133
|
+
if (requirements.required !== true && value === undefined)
|
|
134
|
+
return result;
|
|
135
|
+
if (!requirements || !requirements.rules || !Object.keys(requirements.rules).length) {
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
const rules = requirements.rules;
|
|
139
|
+
const title = requirements.title || key;
|
|
140
|
+
const allResults = [];
|
|
141
|
+
const allRulesKeys = Object.keys(rules);
|
|
142
|
+
let i = 0;
|
|
143
|
+
while (i < allRulesKeys.length) {
|
|
144
|
+
const ruleName = allRulesKeys[i];
|
|
145
|
+
if (ruleName in rulesFunctions === false) {
|
|
146
|
+
i++;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const func = rulesFunctions[ruleName];
|
|
150
|
+
const args = rules[ruleName];
|
|
151
|
+
let result = func(key, value, args, { schema: this.schema, input: inputObj });
|
|
152
|
+
if (requirements.customMessage && typeof requirements.customMessage === 'function') {
|
|
153
|
+
result.details = requirements.customMessage({
|
|
154
|
+
keyword: ruleName,
|
|
155
|
+
value: value,
|
|
156
|
+
key: key,
|
|
157
|
+
title: title,
|
|
158
|
+
reqs: requirements,
|
|
159
|
+
schema: this.schema,
|
|
160
|
+
rules: rules,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
allResults.push(result);
|
|
164
|
+
i++;
|
|
165
|
+
}
|
|
166
|
+
const failedResults = allResults.filter(el => el.result === false);
|
|
167
|
+
if (failedResults.length) {
|
|
168
|
+
result.ok = false;
|
|
169
|
+
result.details = failedResults.map(el => el.details);
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
;
|
|
174
|
+
function validateRules(input) {
|
|
175
|
+
const { results, nestedKey, value, reqs, data, rulesChecked } = input;
|
|
176
|
+
const ruleCheck = checkRules.call(this, nestedKey, value, reqs, data);
|
|
177
|
+
if (!ruleCheck.ok) {
|
|
178
|
+
rulesChecked.push(false);
|
|
179
|
+
ruleCheck.details.forEach((el) => {
|
|
180
|
+
if (!(nestedKey in results.errorsByKeys))
|
|
181
|
+
results.errorsByKeys[nestedKey] = [];
|
|
182
|
+
results.errors.push(el);
|
|
183
|
+
results.errorsByKeys[nestedKey] = ['1'];
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
export default validateRules;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ValidationDetails, ValidationIds } from "../../constants/details.js";
|
|
2
|
+
import _validations from "../../utils/validations.js";
|
|
3
|
+
import _errors from "../../utils/errors.js";
|
|
4
|
+
import _validateType from "../../utils/validateType.js";
|
|
5
|
+
const validateUnionType = (key, value, requirements, keyName = key) => {
|
|
6
|
+
const typeList = Array.isArray(requirements.type)
|
|
7
|
+
? requirements.type.map((el) => String((el === null || el === void 0 ? void 0 : el.name) || el))
|
|
8
|
+
: [];
|
|
9
|
+
const results = [];
|
|
10
|
+
for (let i = 0; i < typeList.length; i++) {
|
|
11
|
+
const requirementsRe = Object.assign(Object.assign({}, requirements), { type: requirements.type[i] });
|
|
12
|
+
const result = handleTypeValidation(key, value, requirementsRe);
|
|
13
|
+
results.push(result[0].passed);
|
|
14
|
+
if (results[i] === true)
|
|
15
|
+
return _validateType.getResult(keyName, true);
|
|
16
|
+
}
|
|
17
|
+
const isPassed = results.some((r) => r === true);
|
|
18
|
+
const result = _validateType.getResult(keyName, isPassed, isPassed ? undefined : _errors.getErrorDetails(keyName, typeList.join('/'), value));
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
const handleTypeValidation = (key, value, requirements, keyName = key) => {
|
|
22
|
+
var _a;
|
|
23
|
+
const reqs = Object.assign({ required: true }, requirements);
|
|
24
|
+
const isNotNull = value !== null;
|
|
25
|
+
const keyTitle = 'title' in reqs && reqs.title !== undefined ? reqs.title : keyName;
|
|
26
|
+
const hasCustomMessage = reqs.customMessage && typeof reqs.customMessage === 'function';
|
|
27
|
+
if (value === undefined && reqs.required) {
|
|
28
|
+
return [_validateType.getResult(keyName, false, _errors.getMissingError(keyName))];
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(reqs.type)) {
|
|
31
|
+
return [validateUnionType(key, value, reqs)];
|
|
32
|
+
}
|
|
33
|
+
if (value === undefined && reqs.required === false) {
|
|
34
|
+
return [_validateType.getResult(keyName, true)];
|
|
35
|
+
}
|
|
36
|
+
const customErrDetails = hasCustomMessage ?
|
|
37
|
+
reqs.customMessage({
|
|
38
|
+
keyword: ValidationIds.Type,
|
|
39
|
+
value: value,
|
|
40
|
+
key: keyName,
|
|
41
|
+
title: keyTitle,
|
|
42
|
+
reqs: reqs,
|
|
43
|
+
schema: {}
|
|
44
|
+
}) :
|
|
45
|
+
null;
|
|
46
|
+
const baseErrDetails = _errors.getErrorDetails(keyName, reqs.type, value);
|
|
47
|
+
const getDetails = (isOK, errorText) => isOK ?
|
|
48
|
+
ValidationDetails.OK :
|
|
49
|
+
errorText || customErrDetails || baseErrDetails;
|
|
50
|
+
const typeBySchema = reqs.type;
|
|
51
|
+
const result = [];
|
|
52
|
+
switch (typeBySchema) {
|
|
53
|
+
case 'any': {
|
|
54
|
+
result.push(_validateType.getResult(keyName, true, getDetails(true)));
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case Number: {
|
|
58
|
+
const isNumber = isNotNull && value.constructor === Number;
|
|
59
|
+
result.push(_validateType.getResult(keyName, isNumber, getDetails(isNumber)));
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case String: {
|
|
63
|
+
const isString = isNotNull && value.constructor === String;
|
|
64
|
+
result.push(_validateType.getResult(keyName, isString, getDetails(isString)));
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case Date: {
|
|
68
|
+
const isDate = isNotNull && value.constructor === Date;
|
|
69
|
+
const isValid = isDate && !isNaN(value.getTime());
|
|
70
|
+
const isValidDate = isDate && isValid;
|
|
71
|
+
result.push(_validateType.getResult(keyName, isValidDate, getDetails(isValidDate, ValidationDetails.INVALID_DATE)));
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case Boolean: {
|
|
75
|
+
const isBoolean = isNotNull && value.constructor === Boolean;
|
|
76
|
+
result.push(_validateType.getResult(keyName, isBoolean, getDetails(isBoolean)));
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case Array: {
|
|
80
|
+
const isArray = isNotNull && value.constructor === Array;
|
|
81
|
+
if (!isArray) {
|
|
82
|
+
result.push(_validateType.getResult(keyName, false, getDetails(isArray)));
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
let isEachChecked = { passed: true, details: "" };
|
|
86
|
+
if ('eachType' in reqs) {
|
|
87
|
+
for (const el of value) {
|
|
88
|
+
const result = handleTypeValidation(`each of ${key}`, el, { type: reqs.eachType, required: true });
|
|
89
|
+
if (!result[0].passed) {
|
|
90
|
+
isEachChecked.passed = false;
|
|
91
|
+
isEachChecked.details = result[0].details || '';
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const isOk = isArray && isEachChecked.passed;
|
|
97
|
+
const details = !isEachChecked.passed ? isEachChecked.details : getDetails(isOk);
|
|
98
|
+
result.push(_validateType.getResult(keyName, isOk, details));
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case Object: {
|
|
102
|
+
const isObject = _validations.isObject(value) && value.constructor === Object;
|
|
103
|
+
result.push(_validateType.getResult(keyName, isObject, getDetails(isObject)));
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case RegExp: {
|
|
107
|
+
const isRegex = _validations.isRegex(value);
|
|
108
|
+
result.push(_validateType.getResult(keyName, isRegex, getDetails(isRegex)));
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case null: {
|
|
112
|
+
const isNull = value === null;
|
|
113
|
+
result.push(_validateType.getResult(keyName, isNull, getDetails(isNull)));
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
default: {
|
|
117
|
+
const isInstanceOf = typeof typeBySchema === 'function' && value instanceof typeBySchema;
|
|
118
|
+
const isConstructorSame = typeof typeBySchema === 'function' && ((_a = value.constructor) === null || _a === void 0 ? void 0 : _a.name) === (typeBySchema === null || typeBySchema === void 0 ? void 0 : typeBySchema.name);
|
|
119
|
+
const isOK = isInstanceOf && isConstructorSame;
|
|
120
|
+
result.push(_validateType.getResult(keyName, isOK, getDetails(isOK)));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
};
|
|
125
|
+
function validateType(input) {
|
|
126
|
+
const { results, key, value, reqs, nestedKey, typeChecked } = input;
|
|
127
|
+
const typeCheck = handleTypeValidation(key, value, reqs, nestedKey);
|
|
128
|
+
typeCheck.forEach((res) => {
|
|
129
|
+
if (!res.passed) {
|
|
130
|
+
typeChecked.push(false);
|
|
131
|
+
results.errors.push(res.details || '');
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
export default validateType;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/errors.js
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return '';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
class ErrorUtility {
|
|
2
|
+
getMissingError(key = 'na') {
|
|
3
|
+
return `Missing value for '${key}'`;
|
|
4
|
+
}
|
|
5
|
+
getErrorDetails(key, expectedType, receivedValue) {
|
|
6
|
+
const receivedType = this.getTypeString(receivedValue);
|
|
7
|
+
const expectedOutput = this.getExpectedTypeString(expectedType);
|
|
8
|
+
if (expectedOutput === receivedType) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
return `Check the type of '${key}': expected ${expectedOutput}, received ${receivedType}`;
|
|
12
|
+
}
|
|
13
|
+
joinErrors(errorsArr, separator = '; ') {
|
|
14
|
+
var _a;
|
|
15
|
+
return ((_a = errorsArr === null || errorsArr === void 0 ? void 0 : errorsArr.filter(error => error === null || error === void 0 ? void 0 : error.trim())) === null || _a === void 0 ? void 0 : _a.join(separator)) || '';
|
|
16
|
+
}
|
|
17
|
+
getTypeString(value) {
|
|
18
|
+
var _a;
|
|
19
|
+
if (value === undefined)
|
|
20
|
+
return 'undefined';
|
|
21
|
+
if (value === null)
|
|
22
|
+
return 'null';
|
|
23
|
+
return ((_a = value.constructor) === null || _a === void 0 ? void 0 : _a.name) || typeof value || 'unknown';
|
|
24
|
+
}
|
|
25
|
+
getExpectedTypeString(expectedType) {
|
|
26
|
+
return (expectedType === null || expectedType === void 0 ? void 0 : expectedType.name) || String(expectedType) || 'unknown';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const errors = new ErrorUtility();
|
|
30
|
+
export default errors;
|