Comprehensive asynchronous form validation library with flexible rule-based schemas and built-in validation types.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Internationalization support with customizable error messages for all validation types and scenarios.
Complete structure for customizing all validation messages.
interface ValidateMessages {
default?: ValidateMessage;
required?: ValidateMessage<[FullField]>;
enum?: ValidateMessage<[FullField, EnumString]>;
whitespace?: ValidateMessage<[FullField]>;
date?: {
format?: ValidateMessage;
parse?: ValidateMessage;
invalid?: ValidateMessage;
};
types?: {
string?: ValidateMessage<[FullField, Type]>;
method?: ValidateMessage<[FullField, Type]>;
array?: ValidateMessage<[FullField, Type]>;
object?: ValidateMessage<[FullField, Type]>;
number?: ValidateMessage<[FullField, Type]>;
date?: ValidateMessage<[FullField, Type]>;
boolean?: ValidateMessage<[FullField, Type]>;
integer?: ValidateMessage<[FullField, Type]>;
float?: ValidateMessage<[FullField, Type]>;
regexp?: ValidateMessage<[FullField, Type]>;
email?: ValidateMessage<[FullField, Type]>;
url?: ValidateMessage<[FullField, Type]>;
hex?: ValidateMessage<[FullField, Type]>;
};
string?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
number?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
array?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};
pattern?: {
mismatch?: ValidateMessage<[FullField, Value, Pattern]>;
};
}
type ValidateMessage<T extends any[] = unknown[]> =
| string
| ((...args: T) => string);
interface InternalValidateMessages extends ValidateMessages {
clone: () => InternalValidateMessages;
}Messages can be either static strings or dynamic functions.
type ValidateMessage<T extends any[] = unknown[]> =
| string
| ((...args: T) => string);Usage Examples:
// Static string message
const messages = {
required: "This field is required"
};
// Dynamic function message
const messages = {
required: (field) => `${field} is required`,
string: {
min: (field, min) => `${field} must be at least ${min} characters`
}
};Access and modify default messages through schema instance or static property.
Usage Examples:
// Get current messages
const currentMessages = schema.messages();
// Access default messages statically
const defaultMessages = Schema.messages;
// Set custom messages on schema instance
schema.messages({
required: "This field is mandatory",
types: {
email: "Please enter a valid email address"
}
});The default message templates used by async-validator:
const defaultMessages = {
default: 'Validation error on field %s',
required: '%s is required',
enum: '%s must be one of %s',
whitespace: '%s cannot be empty',
date: {
format: '%s date %s is invalid for format %s',
parse: '%s date could not be parsed, %s is invalid',
invalid: '%s date %s is invalid'
},
types: {
string: '%s is not a %s',
method: '%s is not a %s (function)',
array: '%s is not an %s',
object: '%s is not an %s',
number: '%s is not a %s',
date: '%s is not a %s',
boolean: '%s is not a %s',
integer: '%s is not an %s',
float: '%s is not a %s',
regexp: '%s is not a valid %s',
email: '%s is not a valid %s',
url: '%s is not a valid %s',
hex: '%s is not a valid %s'
},
string: {
len: '%s must be exactly %s characters',
min: '%s must be at least %s characters',
max: '%s cannot be longer than %s characters',
range: '%s must be between %s and %s characters'
},
number: {
len: '%s must equal %s',
min: '%s cannot be less than %s',
max: '%s cannot be greater than %s',
range: '%s must be between %s and %s'
},
array: {
len: '%s must be exactly %s in length',
min: '%s cannot be less than %s in length',
max: '%s cannot be greater than %s in length',
range: '%s must be between %s and %s in length'
},
pattern: {
mismatch: '%s value %s does not match pattern %s'
}
};Create new message instances with the newMessages factory function.
/**
* Create a new messages object with default templates
* @returns Fresh instance of default validation messages
*/
function newMessages(): InternalValidateMessages;Usage Example:
import { newMessages } from "async-validator";
// Create fresh messages instance for customization
const customMessages = newMessages();
customMessages.required = "This field is mandatory";
customMessages.types.email = "Please enter a valid email";
const schema = new Schema(rules);
schema.messages(customMessages);Fallback message for validation errors.
default?: ValidateMessage;Usage Example:
schema.messages({
default: "Validation error occurred"
});Message for required field validation failures.
required?: ValidateMessage<[FullField]>;Usage Examples:
schema.messages({
// Static message
required: "This field is required",
// Dynamic message with field name
required: (field) => `${field} is required`
});Message for enumeration validation failures.
enum?: ValidateMessage<[FullField, EnumString]>;Usage Examples:
schema.messages({
// Static message
enum: "Value must be one of the allowed options",
// Dynamic message with field and enum values
enum: (field, enumValues) => `${field} must be one of: ${enumValues}`
});Message for whitespace-only string validation failures.
whitespace?: ValidateMessage<[FullField]>;Usage Example:
schema.messages({
whitespace: (field) => `${field} cannot be empty or contain only whitespace`
});Messages for type validation failures.
types?: {
string?: ValidateMessage<[FullField, Type]>;
method?: ValidateMessage<[FullField, Type]>;
array?: ValidateMessage<[FullField, Type]>;
object?: ValidateMessage<[FullField, Type]>;
number?: ValidateMessage<[FullField, Type]>;
date?: ValidateMessage<[FullField, Type]>;
boolean?: ValidateMessage<[FullField, Type]>;
integer?: ValidateMessage<[FullField, Type]>;
float?: ValidateMessage<[FullField, Type]>;
regexp?: ValidateMessage<[FullField, Type]>;
email?: ValidateMessage<[FullField, Type]>;
url?: ValidateMessage<[FullField, Type]>;
hex?: ValidateMessage<[FullField, Type]>;
};Usage Examples:
schema.messages({
types: {
string: "Must be text",
number: "Must be a number",
email: "Must be a valid email address",
url: "Must be a valid URL",
array: "Must be a list",
object: "Must be an object",
boolean: "Must be true or false",
date: "Must be a valid date",
// Dynamic messages
integer: (field) => `${field} must be a whole number`,
float: (field) => `${field} must be a decimal number`
}
});Messages for string length validation failures.
string?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
string: {
len: (field, length) => `${field} must be exactly ${length} characters`,
min: (field, min) => `${field} must be at least ${min} characters`,
max: (field, max) => `${field} cannot exceed ${max} characters`,
range: (field, min, max) => `${field} must be between ${min} and ${max} characters`
}
});Messages for number range validation failures.
number?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
number: {
len: (field, value) => `${field} must equal ${value}`,
min: (field, min) => `${field} cannot be less than ${min}`,
max: (field, max) => `${field} cannot be greater than ${max}`,
range: (field, min, max) => `${field} must be between ${min} and ${max}`
}
});Messages for array length validation failures.
array?: {
len?: ValidateMessage<[FullField, Range]>;
min?: ValidateMessage<[FullField, Range]>;
max?: ValidateMessage<[FullField, Range]>;
range?: ValidateMessage<[FullField, Range, Range]>;
};Usage Examples:
schema.messages({
array: {
len: (field, length) => `${field} must contain exactly ${length} items`,
min: (field, min) => `${field} must contain at least ${min} items`,
max: (field, max) => `${field} cannot contain more than ${max} items`,
range: (field, min, max) => `${field} must contain between ${min} and ${max} items`
}
});Messages for pattern matching validation failures.
pattern?: {
mismatch?: ValidateMessage<[FullField, Value, Pattern]>;
};Usage Example:
schema.messages({
pattern: {
mismatch: (field, value, pattern) =>
`${field} value "${value}" does not match required pattern ${pattern}`
}
});Messages for date validation failures.
date?: {
format?: ValidateMessage;
parse?: ValidateMessage;
invalid?: ValidateMessage;
};Usage Examples:
schema.messages({
date: {
format: "Date format is invalid",
parse: "Date could not be parsed",
invalid: "Date is invalid",
// Dynamic messages
format: (field, date, format) => `${field} date ${date} is invalid for format ${format}`,
parse: (field, date) => `${field} date could not be parsed, ${date} is invalid`,
invalid: (field, date) => `${field} date ${date} is invalid`
}
});const englishMessages = {
required: (field) => `${field} is required`,
types: {
string: (field) => `${field} must be text`,
number: (field) => `${field} must be a number`,
email: (field) => `${field} must be a valid email address`
},
string: {
min: (field, min) => `${field} must be at least ${min} characters`,
max: (field, max) => `${field} cannot exceed ${max} characters`
}
};
schema.messages(englishMessages);const spanishMessages = {
required: (field) => `${field} es requerido`,
types: {
string: (field) => `${field} debe ser texto`,
number: (field) => `${field} debe ser un número`,
email: (field) => `${field} debe ser una dirección de email válida`
},
string: {
min: (field, min) => `${field} debe tener al menos ${min} caracteres`,
max: (field, max) => `${field} no puede exceder ${max} caracteres`
}
};
schema.messages(spanishMessages);const frenchMessages = {
required: (field) => `${field} est requis`,
types: {
string: (field) => `${field} doit être du texte`,
number: (field) => `${field} doit être un nombre`,
email: (field) => `${field} doit être une adresse email valide`
},
string: {
min: (field, min) => `${field} doit avoir au moins ${min} caractères`,
max: (field, max) => `${field} ne peut pas dépasser ${max} caractères`
}
};
schema.messages(frenchMessages);Override messages during specific validation calls.
Usage Examples:
// Override messages for specific validation
await schema.validate(data, {
messages: {
required: "Please fill in this field",
types: {
email: "Please enter a valid email"
}
}
});
// Combine global and local messages
schema.messages({
required: "This field is required"
});
await schema.validate(data, {
messages: {
types: {
email: "Email format is incorrect" // Specific override
}
}
});Create independent message copies and merge configurations.
Usage Examples:
// Clone default messages for customization
const customMessages = Schema.messages.clone();
customMessages.required = "Field is mandatory";
// Create new schema with custom messages
const schema = new Schema(rules);
schema.messages(customMessages);
// Deep merge messages
const baseMessages = {
required: "Required field",
types: { string: "Must be text" }
};
const additionalMessages = {
types: { number: "Must be numeric" },
string: { min: "Too short" }
};
// Merge configurations
schema.messages({ ...baseMessages, ...additionalMessages });Override messages at the individual rule level.
Usage Example:
const rules = {
username: {
type: "string",
required: true,
min: 3,
message: "Username must be at least 3 characters and is required"
},
email: [
{ type: "email", message: "Please enter a valid email address" },
{ required: true, message: "Email is required" }
],
age: {
type: "number",
min: 18,
message: (field) => `${field} must be 18 or older`
}
};