meta-validator is a lightweight (3k gzipped), tree-shakable, zero dependency validation library that uses TypeScript decorators to define validation rules on your classes. It is isomorphic and can be used with NodeJs or in a browser.
Install the meta-validator package from npm.
npm install meta-validator
Define validation rules using the available decorators. Multiple decorators can be used on each property.
export class Widget {
@IsNotEmpty()
@IsAlphanumeric()
name: string;
@IsEmail()
email: string;
}
const myWidget = new Widget();
widget.name = "abc1234";
widget.email = "[email protected]";
const validationErrors = await new MetaValidator().validate(myWidget);
You can also validate arrays of objects in the same way.
const widgetArray: Widget[] = [];
const validationErrorArray = await new MetaValidator().validate(widgetArray);
If an object fails validation then meta-validator returns a ValidationError object with the following structure.:
<property>:[<array of validation error messages>]
Example:
{ email: [ 'email must be a valid email address.' ] }
You can provide custom error messages by using the customErrorMessages
option.
const validationErrors = await new MetaValidator().validate(widget, {
customErrorMessages: {
"IsEqualTo": "$propertyKey must be equal to $option0"
}
});
When using custom error messages the following text replacement codes are available:
Identifier | Description |
---|---|
$propertyKey | The property key that is being validated |
$propertyValue | The value of the property that is being validated |
$option | Any options that are passed to the validator function |
If you require total control over validation error messages you can supply a custom message formatter.
const validationErrors = await new MetaValidator().validate(widget, {
customErrorMessageFormatter: (data: FormatterData) => {
let errorMessage = data.message;
errorMessage = errorMessage.replace("$propertyKey", sentenceCase(data.propertyKey));
errorMessage = errorMessage.replace("$propertyValue", data.propertyValue);
if (data.options) {
for (let i = 0; i < data.options.length; i++) {
errorMessage = errorMessage.replace(`$option${i}`, data.options[i]);
}
}
return errorMessage;
}
});
A custom formatter receives a parameter that has the following values:
interface FormatterData {
decoratorName: string; // The decorator name e.g. IsBoolean()
message: string; // The default validation error message
propertyKey: string; // The key of the property being validated
propertyValue: string; // The value of the property being validated
options?: any[]; // Any options passed to the validator function
}
If you wish to validate an object but skip any properties with values that are undefined you can use the isSkipUndefinedValues
option.
const validationErrors = await new MetaValidator().validate(widget, {isSkipUndefinedValues: true});
You can also create your own validation decorators. Use the existing decorators as examples.
export function IsIp(options?: IsIpOptions): PropertyDecorator {
return (target, propertyKey) => {
MetaValidator.addMetadata({
// Metadata
target: target,
propertyKey: propertyKey.toString(),
// Context
className: target.constructor.name,
validator: {
decoratorName: IsIp.name,
message: "$propertyKey must be a valid ip address.",
method: (input: any) => {
return Promise.resolve(isIp(input, options));
}
}
});
};
}
Decorator | Description |
---|---|
IsAlpha() | Only contains letters |
IsAlphanumeric() | Only contains letters or numbers |
IsBoolean() | Is of type boolean |
IsEmail() | Is a valid email address |
IsEmpty() | Is null, undefined, an empty string or object |
IsEqualTo() | Is equal to specified property |
IsFqDn() | Is a fully qualified domain name (URL) |
IsIp() | Is a valid v4 or v6 IP address |
IsMaxLength() | Has a max length of x |
IsMinLength() | Has a minimum length of x |
IsNested() | Also validate decorated child object |
IsNotEmpty() | Is not null, undefined, an empty string or object |
IsNotEqualTo() | Is not equal to specified property |
IsNumber() | Is of type number |
IsRegEx() | Is of type Regex (regular expression) |
IsString() | Is of type string |
IsUrl() | Is a valid URL (uniform resource locator) |
IsValid() | Property is always valid (useful for skipping validation) |