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