Support object syntax for validateArguments as well

pull/4/head
Sven Slootweg 4 years ago
parent 88630602c3
commit b82a7d359d

@ -2,6 +2,7 @@
const isArguments = require("is-arguments"); const isArguments = require("is-arguments");
const flatten = require("flatten"); const flatten = require("flatten");
const asExpression = require("as-expression");
const ValidationError = require("@validatem/error"); const ValidationError = require("@validatem/error");
const annotateErrors = require("@validatem/annotate-errors"); const annotateErrors = require("@validatem/annotate-errors");
@ -17,42 +18,68 @@ module.exports = createValidationMethod((args, argumentDefinitions) => {
throw new Error(`First argument is not an 'arguments' object; maybe you forgot to put it before the validation rules?`); throw new Error(`First argument is not an 'arguments' object; maybe you forgot to put it before the validation rules?`);
} else if (argumentDefinitions == null) { } else if (argumentDefinitions == null) {
throw new Error(`Validation rules (second argument) are missing; maybe you forgot to specify them?`); throw new Error(`Validation rules (second argument) are missing; maybe you forgot to specify them?`);
} else if (args.length > argumentDefinitions.length) {
return {
errors: [ new ValidationError(`Got ${args.length} arguments, but only expected ${argumentDefinitions.length}`) ],
// Cast the below to an array, for consistency with *success* output, in case we ever want to expose the new values to the user in an error case too.
newValue: Array.from(args)
};
} else { } else {
let results = argumentDefinitions.map((definition, i) => { let usesArrayAPI = (Array.isArray(argumentDefinitions));
let argument = args[i];
let [ argumentName, ...argumentRules ] = definition;
if (typeof argumentName !== "string") { let definitionCount = (usesArrayAPI)
throw new Error("First item in the argument rules list must be the argument name"); ? argumentDefinitions.length
} else { : Object.keys(argumentDefinitions).length;
let validatorResult = applyValidators(argument, argumentRules);
if (args.length > definitionCount) {
return {
errors: [ new ValidationError(`Got ${args.length} arguments, but only expected ${definitionCount}`) ],
// Cast the below to an array, for consistency with *success* output, in case we ever want to expose the new values to the user in an error case too.
newValue: Array.from(args)
};
} else {
let normalizedDefinitions = asExpression(() => {
if (usesArrayAPI) {
return argumentDefinitions.map((definition) => {
let [ name, ...rules ] = definition;
if (typeof name !== "string") {
throw new Error("First item in the argument rules list must be the argument name");
} else {
return {
name: name,
rules: rules
};
}
});
} else {
return Object.entries(argumentDefinitions).map(([ key, value ]) => {
return {
name: key,
rules: value
};
});
}
});
let results = normalizedDefinitions.map(({ name, rules }, i) => {
let argument = args[i];
let validatorResult = applyValidators(argument, rules);
return { return {
errors: annotateErrors({ errors: annotateErrors({
pathSegments: [ argumentName ], pathSegments: [ name ],
errors: validatorResult.errors errors: validatorResult.errors
}), }),
newValue: (validatorResult.newValue !== undefined) newValue: (validatorResult.newValue !== undefined)
? validatorResult.newValue ? validatorResult.newValue
: argument : argument
}; };
} });
});
let combinedErrors = results.map((result) => result.errors);
let combinedErrors = results.map((result) => result.errors); let flattenedErrors = flatten(combinedErrors); // TODO: Switch to `Array#flat` once Node 10.x goes EOL (April 2021)
let flattenedErrors = flatten(combinedErrors); // TODO: Switch to `Array#flat` once Node 10.x goes EOL (April 2021)
let newValues = results.map((result) => result.newValue);
let newValues = results.map((result) => result.newValue);
return {
return { errors: flattenedErrors,
errors: flattenedErrors, newValue: newValues
newValue: newValues };
}; }
} }
}); });

Loading…
Cancel
Save