@validatem/core
Advanced tools
Comparing version 0.3.2 to 0.3.3
@@ -31,2 +31,3 @@ "use strict"; | ||
three: [ required, isBoolean ], | ||
optional: [ isString ], | ||
array: [ required, arrayOf([ required, isString ]) ], | ||
@@ -33,0 +34,0 @@ mapping: [ required, anyProperty({ |
@@ -10,3 +10,3 @@ { | ||
], | ||
"version": "0.3.2", | ||
"version": "0.3.3", | ||
"main": "index.js", | ||
@@ -13,0 +13,0 @@ "repository": "http://git.cryto.net/validatem/core.git", |
@@ -7,2 +7,5 @@ "use strict"; | ||
// TODO: Omit the "At (root)" for path-less errors, to avoid confusion when singular values are being compared? | ||
// TODO: Move out the path generating logic into a separate module, to better support custom error formatting code | ||
module.exports = function aggregrateAndThrowErrors(errors) { | ||
@@ -9,0 +12,0 @@ let rephrasedErrors = errors.map((error) => { |
@@ -20,2 +20,52 @@ "use strict"; | ||
function callRule({ rule, value, context }) { | ||
try { | ||
let result = isCombinator(rule) | ||
? rule.callback(value, applyValidators, context) | ||
: rule(value, context); | ||
if (result !== undefined) { | ||
if (isValidationResult(result)) { | ||
if (Array.isArray(result.errors)) { | ||
let nonValidationErrors = result.errors.filter((error) => !matchValidationError(error)); | ||
if (nonValidationErrors.length === 0) { | ||
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 nonValidationErrors[0]; | ||
} | ||
} else { | ||
throw new Error(`The 'errors' in a validationResult must be an array`); | ||
} | ||
} else if (result instanceof Error) { | ||
// 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 { | ||
return { | ||
errors: [], | ||
newValue: result | ||
}; | ||
} | ||
} else { | ||
return { | ||
errors: [], | ||
newValue: undefined | ||
}; | ||
} | ||
} catch (error) { | ||
if (matchValidationError(error)) { | ||
return { | ||
errors: [ error ], | ||
newValue: undefined | ||
}; | ||
} else { | ||
throw error; | ||
} | ||
} | ||
} | ||
return function composedValidator(value, context) { | ||
@@ -27,3 +77,3 @@ if (isRequired && value == null) { | ||
}); | ||
} else if (value != null) { | ||
} else { | ||
let lastValue = value; | ||
@@ -34,46 +84,20 @@ | ||
for (let rule of nonMarkerRules) { | ||
try { | ||
let result = isCombinator(rule) | ||
? rule.callback(lastValue, applyValidators, context) | ||
: rule(lastValue, 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; | ||
} 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]; | ||
} | ||
} else { | ||
throw new Error(`The 'errors' in a validationResult must be an array`); | ||
} | ||
} else if (result instanceof Error) { | ||
// 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; | ||
} | ||
if (value != null || rule.callIfNull === true) { | ||
let result = callRule({ | ||
rule: rule, | ||
value: lastValue, | ||
context: context | ||
}); | ||
if (result.newValue != null) { | ||
lastValue = result.newValue; | ||
} | ||
} catch (error) { | ||
if (matchValidationError(error)) { | ||
errors = [ error ]; | ||
} else { | ||
throw error; | ||
if (result.errors.length > 0) { | ||
errors = result.errors; | ||
break; | ||
} | ||
} else { | ||
continue; | ||
} | ||
if (errors.length > 0) { | ||
break; | ||
} | ||
} | ||
@@ -88,6 +112,4 @@ | ||
}); | ||
} else { | ||
return validationResult({ newValue: undefined }); | ||
} | ||
}; | ||
}; |
21414
308