Add support for callIfNull
This commit is contained in:
parent
8ed6ad0abe
commit
50b49dc9a8
|
@ -17,36 +17,25 @@ module.exports.compose = function composeValidators(validators) {
|
|||
let isRequired = validators.some((rule) => isRequiredMarker(rule));
|
||||
let nonMarkerRules = validators.filter((rule) => !isRequiredMarker(rule));
|
||||
|
||||
return function composedValidator(value, context) {
|
||||
if (isRequired && value == null) {
|
||||
return validationResult({
|
||||
errors: [ new ValidationError(`Required value is missing`) ],
|
||||
newValue: value
|
||||
});
|
||||
} else if (value != null) {
|
||||
let lastValue = value;
|
||||
|
||||
let errors = [];
|
||||
|
||||
for (let rule of nonMarkerRules) {
|
||||
function callRule({ rule, value, context }) {
|
||||
try {
|
||||
let result = isCombinator(rule)
|
||||
? rule.callback(lastValue, applyValidators, context)
|
||||
: rule(lastValue, context);
|
||||
? rule.callback(value, applyValidators, context)
|
||||
: rule(value, context);
|
||||
|
||||
if (result !== undefined) {
|
||||
let transformedValue;
|
||||
|
||||
if (isValidationResult(result)) {
|
||||
if (Array.isArray(result.errors)) {
|
||||
let nonValidationErrors = result.errors.filter((error) => !matchValidationError(error));
|
||||
|
||||
if (nonValidationErrors.length === 0) {
|
||||
errors = result.errors;
|
||||
transformedValue = result.newValue;
|
||||
return {
|
||||
errors: result.errors,
|
||||
newValue: result.newValue
|
||||
};
|
||||
} else {
|
||||
// We should never reach this point, but it could possibly occur if someone erroneously includes non-ValidationError errors in a validationResult. Note that this is a last-ditch handler, and so we only throw the first non-ValidationError error and let the user sort out the rest, if any.
|
||||
throw result.errors[0];
|
||||
throw nonValidationErrors[0];
|
||||
}
|
||||
} else {
|
||||
throw new Error(`The 'errors' in a validationResult must be an array`);
|
||||
|
@ -55,24 +44,59 @@ module.exports.compose = function composeValidators(validators) {
|
|||
// We could interpret returned Errors as either values or a throw substitute. Let's wait for users to file issues, so that we know what people *actually* need here.
|
||||
throw new Error(`It is currently not allowed to return an Error object from a validator. If you have a reason to need this, please file a bug!`);
|
||||
} else {
|
||||
transformedValue = result;
|
||||
}
|
||||
|
||||
if (transformedValue != null) {
|
||||
lastValue = transformedValue;
|
||||
return {
|
||||
errors: [],
|
||||
newValue: result
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
errors: [],
|
||||
newValue: undefined
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
if (matchValidationError(error)) {
|
||||
errors = [ error ];
|
||||
return {
|
||||
errors: [ error ],
|
||||
newValue: undefined
|
||||
};
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
return function composedValidator(value, context) {
|
||||
if (isRequired && value == null) {
|
||||
return validationResult({
|
||||
errors: [ new ValidationError(`Required value is missing`) ],
|
||||
newValue: value
|
||||
});
|
||||
} else {
|
||||
let lastValue = value;
|
||||
|
||||
let errors = [];
|
||||
|
||||
for (let rule of nonMarkerRules) {
|
||||
if (value != null || rule.callIfNull === true) {
|
||||
let result = callRule({
|
||||
rule: rule,
|
||||
value: lastValue,
|
||||
context: context
|
||||
});
|
||||
|
||||
if (result.newValue != null) {
|
||||
lastValue = result.newValue;
|
||||
}
|
||||
|
||||
if (result.errors.length > 0) {
|
||||
errors = result.errors;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return validationResult({
|
||||
|
@ -82,8 +106,6 @@ module.exports.compose = function composeValidators(validators) {
|
|||
? lastValue
|
||||
: undefined
|
||||
});
|
||||
} else {
|
||||
return validationResult({ newValue: undefined });
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue