You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.4 KiB
JavaScript
80 lines
2.4 KiB
JavaScript
"use strict";
|
|
|
|
const defaultValue = require("default-value");
|
|
const asExpression = require("as-expression");
|
|
const splitFilterN = require("split-filter-n");
|
|
|
|
const combinator = require("@validatem/combinator");
|
|
const ValidationError = require("@validatem/error");
|
|
const matchValidationError = require("@validatem/match-validation-error");
|
|
const validationResult = require("@validatem/validation-result");
|
|
|
|
// TODO: Document that this passes on context
|
|
|
|
function concat(arrays) {
|
|
return arrays.slice(1).reduce((combined, array) => {
|
|
return combined.concat(array);
|
|
}, arrays[0]);
|
|
}
|
|
|
|
module.exports = function wrapError(message, rules, options = {}) {
|
|
let preserveOriginalErrors = defaultValue(options.preserveOriginalErrors, false);
|
|
|
|
return combinator((value, applyValidators, context) => {
|
|
let result = applyValidators(value, rules, context);
|
|
|
|
if (result.errors.length > 0) {
|
|
let { errors, newValue } = result;
|
|
|
|
let errorsByType = splitFilterN(errors, [ "validationRoot", "validationPath", "other" ], (error) => {
|
|
if (matchValidationError(error)) {
|
|
if (error.path.length === 0) {
|
|
return "validationRoot";
|
|
} else {
|
|
return "validationPath";
|
|
}
|
|
} else {
|
|
return "other";
|
|
}
|
|
});
|
|
|
|
let hasRootValidationErrors = errorsByType.validationRoot.length > 0;
|
|
let hasPathValidationErrors = errorsByType.validationPath.length > 0;
|
|
let hasValidationErrors = hasRootValidationErrors || hasPathValidationErrors;
|
|
|
|
let transformedValidationErrors = asExpression(() => {
|
|
if (hasValidationErrors) {
|
|
if (!preserveOriginalErrors) {
|
|
return [ new ValidationError(message) ];
|
|
} else {
|
|
let newRootErrors = (hasRootValidationErrors)
|
|
? errorsByType.validationRoot.map((error) => {
|
|
// TODO: Currently we cannot set `originalError` due to a bug in `create-error`; switch to a better error implementation
|
|
// return new ValidationError(`${message} (${error.message})`, { originalError: error })
|
|
return new ValidationError(`${message} (${error.message})`)
|
|
})
|
|
: [ new ValidationError(message) ];
|
|
|
|
return concat([
|
|
newRootErrors,
|
|
errorsByType.validationPath
|
|
]);
|
|
}
|
|
} else {
|
|
return [];
|
|
}
|
|
});
|
|
|
|
return validationResult({
|
|
newValue: newValue,
|
|
errors: concat([
|
|
transformedValidationErrors,
|
|
errorsByType.other
|
|
])
|
|
});
|
|
} else {
|
|
return result;
|
|
}
|
|
});
|
|
};
|