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.
40 lines
1.4 KiB
JavaScript
40 lines
1.4 KiB
JavaScript
"use strict";
|
|
|
|
// TODO: Rename this to something more appropriate, like any/anyOf? How to make sure that doesn't cause confusion with `oneOf`?
|
|
|
|
const ValidationError = require("@validatem/error");
|
|
const combinator = require("@validatem/combinator");
|
|
|
|
module.exports = function (alternatives) {
|
|
if (!Array.isArray(alternatives)) {
|
|
throw new Error(`Must specify an array of alternatives`);
|
|
} else if (alternatives.length < 2) {
|
|
// This doesn't interfere with conditionally-specified alternatives using ternary expressions, because in those cases there is still *some* item specified, it's just going to have a value of `undefined` (and will subsequently be filtered out)
|
|
throw new Error("Must specify at least two alternatives");
|
|
} else if (arguments.length > 1) {
|
|
throw new Error(`Only one argument is accepted; maybe you forgot to wrap the different alternatives into an array?`);
|
|
} else {
|
|
return combinator((value, applyValidators) => {
|
|
let allErrors = [];
|
|
|
|
for (let alternative of alternatives) {
|
|
let { errors, newValue } = applyValidators(value, alternative);
|
|
|
|
if (errors.length === 0) {
|
|
return newValue;
|
|
} else {
|
|
allErrors.push(...errors);
|
|
}
|
|
}
|
|
|
|
let errorList = allErrors
|
|
.map((error) => {
|
|
return `"${error.message}"`;
|
|
})
|
|
.join(", ");
|
|
|
|
throw new ValidationError(`Must satisfy at least one of: ${errorList}`, { errors: allErrors });
|
|
});
|
|
}
|
|
};
|