const toString = require('../utils/to-string'); const selectFields = require('../utils/select-fields'); module.exports = (req, context) => { const validationErrors = []; const promises = selectFields(req, context).map(field => { const { location, path, value } = field; return context.validators.reduce((promise, validatorCfg) => promise.then(() => { const result = validatorCfg.custom ? validatorCfg.validator(value, { req, location, path }) : validatorCfg.validator(toString(value), ...validatorCfg.options); return getActualResult(result).then(result => { if ((!validatorCfg.negated && !result) || (validatorCfg.negated && result)) { return Promise.reject(); } }); }).catch(err => { validationErrors.push({ location, param: path, value: field.originalValue, msg: getDynamicMessage([ validatorCfg.message, err && err.message, err, context.message, 'Invalid value' ], field, req) }); }), Promise.resolve()); }); return Promise.all(promises).then(() => validationErrors); }; function getActualResult(result) { const promiseLike = result && !!result.then; return Promise.resolve(result).then(result => { return result === undefined && promiseLike ? true : result; }); } function getDynamicMessage(messageSources, field, req) { const message = messageSources.find(message => !!message); if (typeof message !== 'function') { return message; } return message(field.originalValue, { req, location: field.location, path: field.path }); }