bsy-validation
Light validation utilities for TypeScript classes. With bsy-validation, class properties are decorated with validators, and then plain objects can be validated against a class's validation schema.
Note that version 2 is a complete rewrite, and is not backwards compatible.
Installation
With yarn:
yarn add bsy-validation@2.x.x
With npm:
npm install --save bsy-validation@2.x.x
Ensure that you have experimentalDecorators
and emitDecoratorMetadata
enabled in your tsconfig.json
.
Usage
First, decorate a class's properties with the @Validate
decorator, supplying
one or more
Validators
as arguments. All of the
Validator
classes can be found in the
validator directory.
For example, here is a decorated Person
class.
;
An object can be checked against this class's validation schema using an
ObjectValidator
instance. This class's validate
method takes two arguments: An object to
validate, and a the constructor of a @Validate
-decorated class. It returns a
promise that is resolved if the object is valid, or rejected with one or more
errors if the object is invalid.
Here's an example of a valid Person
object.
; ; ; // Joe Dirt is valid.; validator .validatejoeDirt, Person .thenconsole.log'Joe Dirt is valid.';
The above logs "Joe Dirt is valid." Here's an example of an invalid object.
; ; ; // Donald Trump is invalid.;validator .validateemperorTrump, Person .catchconsole.errorJSON.stringifyerr, null, 2;
The above logs an error that describes why the object is invalid.
{
"code": "VAL_ERROR_LIST",
"name": "ValidationErrorList",
"detail": "Validation errors occurred.",
"errors": [
{
"code": "VALIDATION_ERROR",
"name": "ValidationError",
"detail": "\"name\" must be at most 50 characters long.",
"field": "name"
},
{
"code": "VALIDATION_ERROR",
"name": "ValidationError",
"detail": "\"id\" must be a valid integer.",
"field": "id"
}
]
}
Validator Call Order
For a given @Validate
-decorated property, validators are applied in order.
If one of the validators fails, then execution halts. For example, in the
Person
class defined above, Person.name
has two validators:
StringValidator
and
MaxLengthValidator.
StringValidator
is applied first, then
MaxLengthValidator
is called if
StringValidator
passes.
; validator .validatearyaStark, Person .catchconsole.errorJSON.stringifyerr, null, 2;
In the above example, aryaStark.name
is not a string, so MaxLengthValidator is never executed. The above logs the following error.
{
"code": "VAL_ERROR_LIST",
"name": "ValidationErrorList",
"detail": "Validation errors occurred.",
"errors": [
{
"code": "VALIDATION_ERROR",
"name": "ValidationError",
"detail": "\"name\" must be a string.",
"field": "name"
}
]
}
Null and Undefined
The built-in validators consider null
and undefined
properties to be valid.
So, for example, an empty object is considered to be a valid Person
. To
ensure that a property is present and/or non-null, use the
DefinedValidator
and
NotNullValidator.
In the following class, the message
property must be defined, cannot be null, and must be a string.
When defining custom validators, null
and undefined
values should be considered valid.
Custom Validators
To create a custom validator, implement the
Validator
interface. You must define a validate
method that returns a boolean or a
promise, and a getErrorMessage
method that's used when validation fails.
Here's an example.
// File: ./odd-number-validator.ts;
Then, use the validator as follows.
; ; new ObjectValidator .validate, Preferences .catchconsole.errorJSON.stringifyerr, null, 2;
When run, the above prints the following error.
{
"code": "VAL_ERROR_LIST",
"name": "ValidationErrorList",
"detail": "Validation errors occurred.",
"errors": [
{
"code": "VALIDATION_ERROR",
"name": "ValidationError",
"detail": "\"favoriteNumber\" must be an odd number.",
"field": "favoriteNumber"
}
]
}