@rsuite/validation
Validate like a boss.
npm install -S @rsuite/validation
Features
- Rich built-in validation rules called with a single expression.
- Auto-detects objects and arrays.
- Easy to extend.
rsuite/schema-typed
as data validation.
Usage
Validate data
import { Validator } from "@rsuite/validation";
const checkResult = Validator.check(data, {
name: "required",
email: "required|email",
age: "number|between:18,30",
});
<Form>
component
Create SchemaModel for import { Validator } from "@rsuite/validation";
const model = Validator.SchemaModel({
name: "required",
email: "required|email",
age: "number|between:18,30",
});
Validate array items and object properties
import { Validator } from "@rsuite/validation";
const validator = Validator.make({
"pet.name": "required", // Auto-detects `pet` as an object of shape { name: string }
"luckyNumbers.*": "number", // Auto-detects `luckyNumbers` as an array, whose items should be numbers
"cars.*.price": "number|min:1000000000", // Auto-detects `cars` as an array of objects of shape { price: number }
});
On the other hand, if your field name contains a literal period, you can explicitly prevent this from being interpreted as "dot" syntax by escaping the period with a backslash:
import { Validator } from "@rsuite/validation";
const validator = Validator.make({
"v1\\.0": "required",
"object\\.withDot.property": "required", // { 'object.withDot' : { property }}
"anotherObject.withDot\\.inProperty": "required", // { anotherObject: { 'withDot.inProperty' }}
});
Custom error messages
You can override error message for any rule, or for any rule on any field specifically.
import { Validator } from "@rsuite/validation";
const validator = Validator.make(
{
name: "required",
email: "required|email",
age: "required|number|between:18,30",
},
{
required: "You should not omit {field}!",
"email.required"(field) {
return "Email is a must.";
},
"age.between": "Age should be between {min} and {max}",
fields: {
email: "Email address",
},
}
);
Learn more in Error messages.
Custom rules
import { Validator } from "@rsuite/validation";
const validator = Validator.make({
name: [
"required",
{
check(field, value, data) {
return value === "Tom";
},
errorMessage: "Only whose {field} is Tom shall pass.",
},
],
});
Learn more in Custom validation rules.
API
Validator
import { Validator } from '@rsuite/validation
-
static make(rules: object, messages?: object): Validator
Create a validator from given rules and custom message if necessary.
-
static message(messages: object): void
Define custom error messages for all Validators.
-
static SchemaModel(rules: object, messages?: object): Schema
Equivalent toValidator.make(rules, messages).getSchemaModel()
, -
static check(data: any, rules: object): CheckResult
Equivalent to
Validator.make(rules).check()
-
getSchemaModel(): Schema
Return the
SchemaModel
instance inside theValidator
. -
check(data: any): CheckResult
Equivalent tovalidator.getSchemaModel().check()
Error messages
@rsuite/validation
is packed with predefined messages for every built-in rules.
You can define your own messages for Validator, either per rule or per rule per field.
const validator = Validator.make(
{
name: "required",
email: "required|email",
age: "required|number|between:18,30",
},
{
required: customMessage1,
"age.between": customMessage2,
}
);
A custom message should be either a string or a ErrorMessageFormatter
.
interface ErrorMessageFormatter {
(field: string, placeholderValues?: any): string;
}
If you want to customize how your field names are displayed in the error messages (by default is capitalized), set them in field
property of the message bag.
const validator = Validator.make(
{
name: "required",
email: "required|email",
age: "required|number|between:18,30",
},
{
required: "Please enter {field}",
fields: {
email: "Email address",
},
}
);
Defined messages globally
Use Validator.messages()
to register message bag globally.
Validator.messages({
required: "Please enter {field}.",
});
Placeholders
You can use placeholders (marked with brackets) in your error message string. Note that you can only use them when your error message is a string, not a formatter function.
const messages = {
required: "{field} is required.",
min: "{field} must be no smaller than {value}.",
};
Each rule has different placeholders available, while {field}
is available across all rules, representing the field name declared in your rules object.
Most placeholders have the same name as the rule signature.
Here is a full list of built-in rules that have placeholders in messages.
Rule signature | Placeholders |
---|---|
size:value |
{value} |
max:value |
{value} |
min:value |
{value} |
between:min,max |
{min} , {max} |
gt:other |
{other} , {value} |
gte:other |
{other} , {value} |
lt:other |
{other} , {value} |
lte:other |
{other} , {value} |
same:other |
{other} |
different:other |
{other} |
in:value1,value2... |
{values} |
notIn:value1,value2... |
{values} |
unique:by? |
{by} |
regex:pattern |
{pattern} |
after:date |
{date} |
afterOrEqual:date |
{date} |
before:date |
{date} |
beforeOrEqual:date |
{date} |
endsWith:value1,value2... |
{values} |
startsWith:value1,value2... |
{values} |
If you use ErrorMessageFormatter
, placeholders values are passed in as an object to its second argument.
Available rules
Type rules
@rsuite/validation
has 6 supported types.
Some rules are effective among all these types, some are only effective under specific types.
-
string
Equivalent to
StringType()
. Most of time you can omit this becausestring
is the default type. -
number
Equivalent toNumberType()
. -
array
Equivalent to
ArrayType()
. -
date
Equivalent to
DateType()
. -
object
Equivalent to
ObjectType()
. -
boolean
Equivalent to
BooleanType()
.
Validation rules
-
required
for all types The field under validation must be present and have a non-empty value. ApplyisRequired()
from@rsuite/schema-typed
. -
size:value
forstring
,number
,array
The field under validation must have a 'size' of
value
, where size is:string
's length.number
's value.array
's length.
-
max:value
forstring
,number
,array
The field under validation must have a 'size' no larger than
value
. Seesize
rule for more about 'size'. -
min:value
forstring
,number
,array
The field under validation must have a 'size' no smaller than
value
. Seesize
rule for more about 'size'. -
between:min,max
forstring
,number
,array
The field under validation must have a 'size' between
min
andmax
. Seesize
rule for more about 'size'. -
same:other
for all typesThe field under validation must have the same value with
other
field. -
different:other
for all typesThe field under validation must have the different value from
other
field. -
lt:other
forstring
,number
,array
The field under validation must have a 'size' less than the
other
field. Seesize
rule for more about 'size'. -
lte:other
forstring
,number
,array
The field under validation must have a 'size' less than or equal the
other
field. Seesize
rule for more about 'size'. -
gt:other
forstring
,number
,array
The field under validation must have a 'size' greater than the
other
field. Seesize
rule for more about 'size'. -
gte:other
forstring
,number
,array
The field under validation must have a 'size' greater than or equal the
other
field. Seesize
rule for more about 'size'. -
in:value1,value2...
forstring
,number
The field under validation must be included in the given list of values.
-
notIn:value1,value2...
forstring
,number
The field under validation must not be included in the given list of values.
-
email
forstring
The field under validation must be formatted as an e-mail address.
-
url
forstring
The field under validation must be a valid URL.
-
unique:by?
forarray
The array under validation must not have any duplicate items. If
by
is provided for array of objects, duplication is checked by object property. -
integer
fornumber
The field under validation must be an integer.
-
regex:pattern
forstring
,number
The field under validation must match the given regular expression.
Note: When using the
regex
patterns, it may be necessary to specify rules in an array instead of using pipe delimiters, especially if the regular expression contains a pipe character. -
after:date
fordate
The field under validation must be a value after a given date. The dates will be passed into
new Date(date)
. -
afterOrEqual:date
fordate
The field under validation must be a value after or equal to the given date. The dates will be passed into
new Date(date)
. -
before:date
fordate
The field under validation must be a value preceding the given date. The dates will be passed into
new Date(date)
. -
beforeOrEqual:date
fordate
The field under validation must be a value preceding or equal to the given date. The dates will be passed into
new Date(date)
. -
endsWith:value1,value2...
forstring
The field under validation must end with one of the given values.
-
startsWith:value1,value2...
forstring
The field under validation must start with one of the given values.
Custom validation rules
In addition to built-in validation rules, you can also define you own validation rules.
Validator.make({
name: ["required", customRule1, customRule2],
email: ["required", "email", customRule3],
});
A custom rule must implement Rule
interface.
interface Rule {
/**
* Check whether the value passes this rule
*/
check(field: string, value: any, data: any): boolean;
/**
* Message to show when this rule fails.
*/
errorMessage: string | ErrorMessageFormatter;
}
@rsuite/schema-typed
API coverage
The table below shows @rsuite/schema-typed
API and their equivalent rules in @rsuite/validation
.
Note that equivalent means equivalent, which is, implementation of the rule is calling the according API or copies its underlying implementation.
Those APIs that don't have an equivalent rule for now (marked as -
) can still be achieved using Custom validation rules.
- Common
API | Rule |
---|---|
.isRequired() |
required |
.addRule() |
Custom validation rules |
StringType()
API | Rule |
---|---|
StringType() |
string |
.isEmail() |
email |
.isURL() |
url |
.isOneOf(items) |
in:value1,value2... |
.containsLetter() |
regex:[a-zA-Z] |
.containsUppercaseLetter() |
regex:[A-Z] |
.containsLowercaseLetter() |
regex:[a-z] |
.containsLetterOnly() |
regex:^[a-zA-Z]+$ |
.containsNumber() |
regex:[0-9] |
.pattern(regExp) |
regex:pattern |
.rangeLength(minLength, maxLength) |
between:min,max |
.minLength(minLength) |
min:value |
.maxLength(maxLength) |
max:value |
NumberType()
API | Rule |
---|---|
NumberType() |
number |
.isInteger() |
integer |
.isOneOf(items) |
in:value1,value2... |
.pattern(regExp) |
regex:pattern |
.range(min, max) |
between:min,max |
.min(min) |
min:value |
.max(max) |
max:value |
ArrayType()
API | Rule |
---|---|
ArrayType() |
array or auto-detect from field expression |
.rangeLength(minLength, maxLength) |
between:min,max |
.minLength(minLength) |
min:value |
.maxLength(maxLength) |
max:value |
.unrepeatable() |
unique |
.of(type) |
Wildcard field expression |
DateType()
API | Rule |
---|---|
DateType() |
date |
.range(min,max) |
`afterOrEqual:min |
.min(min) |
afterOrEqual:date |
.max(max) |
beforeOrEqual:date |
ObjectType()
API | Rule |
---|---|
ObjectType() |
object or auto-detect from field expression |
.shape(type) |
Auto-detect from field expression |
BooleanType()
API | Rule |
---|---|
BooleanType() |
boolean |
Philosophy
-
@rsuite/validation
supposes default type for a field to bestring
, respecting HTML<input>
s' value definition, so you can get rid of callingStringType()
every time. -
@rsuite/validation
normalizes error messages for rules, so you don't need to declare error messages for every call of a rule, but only when you need to customize them. -
@rsuite/validation
extracts common rules across different types likemin
,max
, etc. so you remember them easily.
Prior Art
- Inspired by Laravel Validation.
- Implemented with
rsuite/schema-typed
.
License
MIT Licensed.