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

"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;
}
});
};