https://github.com/rsuite/validation
:sunglasses: Validate like a boss.
https://github.com/rsuite/validation
Last synced: 5 months ago
JSON representation
:sunglasses: Validate like a boss.
- Host: GitHub
- URL: https://github.com/rsuite/validation
- Owner: rsuite
- Created: 2019-11-08T04:49:21.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-07-19T00:17:32.000Z (over 2 years ago)
- Last Synced: 2025-07-21T15:47:37.186Z (6 months ago)
- Language: TypeScript
- Homepage:
- Size: 799 KB
- Stars: 11
- Watchers: 2
- Forks: 4
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @rsuite/validation
> Validate like a boss.

[](https://badge.fury.io/js/%40rsuite%2Fvalidation)
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`](https://github.com/rsuite/schema-typed) as data validation.
## Usage
### Validate data
```js
import { Validator } from "@rsuite/validation";
const checkResult = Validator.check(data, {
name: "required",
email: "required|email",
age: "number|between:18,30",
});
```
### Create SchemaModel for `` component
```js
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
```js
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:
```js
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.
```js
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
```js
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 to `Validator.make(rules, messages).getSchemaModel()`,
- `static check(data: any, rules: object): CheckResult`
Equivalent to `Validator.make(rules).check()`
- `getSchemaModel(): Schema`
Return the `SchemaModel` instance inside the `Validator`.
- `check(data: any): CheckResult`
Equivalent to `validator.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.
```js
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`.
```typescript
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.
```typescript
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.
```javascript
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.
```javascript
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 because `string` is the default type.
- `number`
Equivalent to `NumberType()`.
- `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. Apply `isRequired()` from `@rsuite/schema-typed`.
- `size:value` for `string`, `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` for `string`, `number`, `array`
The field under validation must have a 'size' no larger than `value`. See `size` rule for more about 'size'.
- `min:value` for `string`, `number`, `array`
The field under validation must have a 'size' no smaller than `value`. See `size` rule for more about 'size'.
- `between:min,max` for `string`, `number`, `array`
The field under validation must have a 'size' between `min` and `max`. See `size` rule for more about 'size'.
- `same:other` for all types
The field under validation must have the same value with `other` field.
- `different:other` for all types
The field under validation must have the different value from `other` field.
- `lt:other` for `string`, `number`, `array`
The field under validation must have a 'size' less than the `other` field. See `size` rule for more about 'size'.
- `lte:other` for `string`, `number`, `array`
The field under validation must have a 'size' less than or equal the `other` field. See `size` rule for more about 'size'.
- `gt:other` for `string`, `number`, `array`
The field under validation must have a 'size' greater than the `other` field. See `size` rule for more about 'size'.
- `gte:other` for `string`, `number`, `array`
The field under validation must have a 'size' greater than or equal the `other` field. See `size` rule for more about 'size'.
- `in:value1,value2...` for `string`, `number`
The field under validation must be included in the given list of values.
- `notIn:value1,value2...` for `string`, `number`
The field under validation must not be included in the given list of values.
- `email` for `string`
The field under validation must be formatted as an e-mail address.
- `url` for `string`
The field under validation must be a valid URL.
- `unique:by?` for `array`
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` for `number`
The field under validation must be an integer.
- `regex:pattern` for `string`, `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` for `date`
The field under validation must be a value after a given date. The dates will be passed into `new Date(date)`.
- `afterOrEqual:date` for `date`
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` for `date`
The field under validation must be a value preceding the given date. The dates will be passed into `new Date(date)`.
- `beforeOrEqual:date` for `date`
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...` for `string`
The field under validation must end with one of the given values.
- `startsWith:value1,value2...` for `string`
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.
```javascript
Validator.make({
name: ["required", customRule1, customRule2],
email: ["required", "email", customRule3],
});
```
A custom rule must implement `Rule` interface.
```typescript
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` | `beforeOrEqual:max` |
| `.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 be `string`,
respecting HTML ``s' value definition,
so you can get rid of calling `StringType()` 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 like `min`, `max`, etc.
so you remember them easily.
## Prior Art
- Inspired by Laravel Validation.
- Implemented with [`rsuite/schema-typed`](https://github.com/rsuite/schema-typed).
## License
MIT Licensed.