### Install async-validator using npm Source: https://github.com/yiminghe/async-validator/blob/master/README.md Instructions for installing the async-validator package using npm. This is the primary method for adding the library to a Node.js project. ```bash npm i async-validator ``` -------------------------------- ### Define Multiple Rules for a Field Source: https://github.com/yiminghe/async-validator/blob/master/README.md Illustrates how to apply multiple validation rules to a single field ('email') by providing an array of rule objects. This example includes a built-in type validation (string, required, pattern) and a custom validator function. ```javascript const descriptor = { email: [ { type: 'string', required: true, pattern: Schema.pattern.email }, { validator(rule, value, callback, source, options) { const errors = []; // test if email address already exists in a database // and add a validation error to the errors array if it does return errors; }, }, ], }; ``` -------------------------------- ### Array Deep Rule Validation Source: https://github.com/yiminghe/async-validator/blob/master/README.md Demonstrates deep validation for array elements using the 'fields' property, where keys can be indices. This example shows validation for an array of strings, checking both the array's length and the type/required status of its elements. ```javascript const descriptor = { roles: { type: 'array', required: true, len: 3, fields: { 0: { type: 'string', required: true }, 1: { type: 'string', required: true }, 2: { type: 'string', required: true }, }, }, }; // Example usage: // const source = { roles: ['admin', 'user'] }; // validator.validate(source) will produce errors for length and missing index 2. ``` -------------------------------- ### Registering Custom Validators in async-validator Source: https://context7.com/yiminghe/async-validator/llms.txt Explains how to register custom type validators globally for reuse across multiple schemas using Schema.register in async-validator. This example shows registration for 'phone', 'zipcode', and 'creditcard' types with custom validation logic. ```javascript import Schema from 'async-validator'; // Register a custom 'phone' type validator Schema.register('phone', (rule, value, callback, source, options) => { const errors = []; const phoneRegex = /^\+?[1-9]\d{1,14}$/; if (value && !phoneRegex.test(value)) { errors.push( new Error(rule.message || `${rule.field} is not a valid phone number`) ); } callback(errors); }); // Register a custom 'zipcode' type validator Schema.register('zipcode', (rule, value, callback) => { const errors = []; const zipRegex = /^\d{5}(-\d{4})?$/; if (value && !zipRegex.test(value)) { errors.push(new Error(`${rule.field} must be a valid ZIP code`)); } callback(errors); }); // Register a custom 'creditcard' type validator Schema.register('creditcard', (rule, value, callback) => { const errors = []; // Luhn algorithm for credit card validation const luhnCheck = (num) => { let sum = 0; let isEven = false; for (let i = num.length - 1; i >= 0; i--) { let digit = parseInt(num[i], 10); if (isEven) { digit *= 2; if (digit > 9) digit -= 9; } sum += digit; isEven = !isEven; } return sum % 10 === 0; }; const cleanValue = value.replace(/\s/g, ''); if (value && (!luhnCheck(cleanValue) || cleanValue.length < 13)) { errors.push(new Error(`${rule.field} is not a valid credit card number`)); } callback(errors); }); // Use custom validators in schema const descriptor = { phone: { type: 'phone', required: true }, zip: { type: 'zipcode', required: true }, cardNumber: { type: 'creditcard', required: true } }; const validator = new Schema(descriptor); validator.validate({ phone: '+1234567890', zip: '12345', cardNumber: '4532015112830366' }).then(() => { console.log('Custom validation passed'); }).catch(({ errors }) => { console.error('Custom validation failed:', errors); }); ``` -------------------------------- ### JavaScript: Controlling Validation Behavior with Options Source: https://context7.com/yiminghe/async-validator/llms.txt Illustrates various options available in async-validator to customize the validation process. This includes stopping at the first error ('first'), getting the first error per field ('firstFields'), suppressing warnings ('suppressWarning'), providing custom error messages, and validating only specific fields ('keys'). ```javascript import Schema from 'async-validator'; const descriptor = { email: [ { type: 'string', required: true }, { type: 'email' }, { validator(rule, value) { return value.length <= 100; }, message: 'Email too long' } ], password: [ { type: 'string', required: true }, { min: 8, message: 'Password too short' }, { pattern: /[A-Z]/, message: 'Must contain uppercase' }, { pattern: /[0-9]/, message: 'Must contain number' } ] }; const validator = new Schema(descriptor); // Option 1: Stop at first error across all fields validator.validate( { email: '', password: 'weak' }, { first: true }, (errors) => { console.log('First error only:', errors.length); // 1 } ); // Option 2: Get first error per field validator.validate( { email: '', password: 'weak' }, { firstFields: true }, (errors) => { // Gets first error for email and first error for password console.log('First error per field:', errors.length); // 2 } ); // Option 3: Get first error for specific fields only validator.validate( { email: '', password: 'weak' }, { firstFields: ['email'] }, (errors) => { // First error for email, all errors for password console.log('Mixed mode:', errors); } ); // Option 4: Suppress internal warnings validator.validate( { email: 'test', password: 'pass' }, { suppressWarning: true }, (errors) => { // No console warnings for invalid values } ); // Option 5: Custom error messages validator.validate( { email: 'invalid', password: 'short' }, { messages: { required: 'Field %s is mandatory', types: { email: '%s must be a valid email address' } } }, (errors) => { console.log('Custom messages:', errors); } ); // Option 6: Validate specific fields only validator.validate( { email: 'test@example.com', password: 'weak' }, { keys: ['email'] }, // Only validate email field (errors) => { // Password validation is skipped } ); ``` -------------------------------- ### JavaScript: Field Value Transformation Before Validation Source: https://context7.com/yiminghe/async-validator/llms.txt Demonstrates using the 'transform' property in async-validator to modify field values prior to validation. This is useful for cleaning input like trimming whitespace, converting to lowercase, or coercing string numbers to actual numbers. It shows examples for string, number, email, and array types. ```javascript import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, pattern: /^[a-z]+$/, transform(value) { // Trim whitespace and convert to lowercase return value.trim().toLowerCase(); } }, age: { type: 'number', required: true, min: 0, transform(value) { // Convert string to number return typeof value === 'string' ? parseInt(value, 10) : value; } }, email: { type: 'email', transform(value) { // Normalize email to lowercase return value.toLowerCase().trim(); } }, tags: { type: 'array', defaultField: { type: 'string', transform(value) { // Normalize each tag return value.trim().toLowerCase(); } } } }; const validator = new Schema(descriptor); // Input with extra whitespace and mixed case validator.validate({ name: ' JOHN ', age: '25', email: 'JOHN@EXAMPLE.COM ', tags: [' JavaScript ', 'NODE.JS', 'react '] }).then((data) => { // Transformed data is returned on successful validation console.log(data); // Output: // { // name: 'john', // age: 25, // email: 'john@example.com', // tags: ['javascript', 'node.js', 'react'] // } }); ``` -------------------------------- ### Create and Use Schema Validator Source: https://github.com/yiminghe/async-validator/blob/master/README.md Shows how to import the Schema class, define a validation descriptor with a custom rule for a 'name' field, create a validator instance, and then use it to validate a data object. It includes handling validation results and errors. ```javascript import Schema from 'async-validator'; const descriptor = { name(rule, value, callback, source, options) { const errors = []; if (!/^[a-z0-9]+$/.test(value)) { errors.push(new Error( util.format('%s must be lowercase alphanumeric characters', rule.field), )); } return errors; }, }; const validator = new Schema(descriptor); validator.validate({ name: 'Firstname' }, (errors, fields) => { if (errors) { return handleErrors(errors, fields); } // validation passed }); ``` -------------------------------- ### Validation Options Source: https://github.com/yiminghe/async-validator/blob/master/README.md Configuration options that can be passed to the `validate` method to customize its behavior. ```APIDOC ## Validation Options ### Description Options to control the validation process, such as error suppression and early exit. ### Method These options are passed as the second argument to the `validate` method. ### Options - **suppressWarning** (Boolean) - Optional - If true, suppresses internal warnings about invalid values. - **first** (Boolean) - Optional - If true, stops validation on the first error encountered across all rules and fields. - **firstFields** (Boolean | String[]) - Optional - If true or an array of field names, stops validation for a specific field once the first error is found for that field. `true` applies this behavior to all fields. ``` -------------------------------- ### Basic and Promise Usage of async-validator in JavaScript Source: https://github.com/yiminghe/async-validator/blob/master/README.md Demonstrates how to use the async-validator library for form validation. It covers both callback-based and Promise-based approaches for validating an object against a defined schema. Dependencies include the 'Schema' class from 'async-validator'. ```javascript import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, validator: (rule, value) => value === 'muji', }, age: { type: 'number', asyncValidator: (rule, value) => { return new Promise((resolve, reject) => { if (value < 18) { reject('too young'); // reject with error message } else { resolve(); } }); }, }, }; const validator = new Schema(descriptor); validator.validate({ name: 'muji' }, (errors, fields) => { if (errors) { // validation failed, errors is an array of all errors // fields is an object keyed by field name with an array of // errors per field return handleErrors(errors, fields); } // validation passed }); // PROMISE USAGE validator.validate({ name: 'muji', age: 16 }).then(() => { // validation passed or without error message }).catch(({ errors, fields }) => { return handleErrors(errors, fields); }); ``` -------------------------------- ### Validate Enum Values Source: https://github.com/yiminghe/async-validator/blob/master/README.md Shows how to use the 'enum' type to validate that a field's value is present in a predefined list of allowed values. This is useful for fields with a fixed set of options, such as user roles. ```javascript const descriptor = { role: { type: 'enum', enum: ['admin', 'user', 'guest'] }, }; ``` -------------------------------- ### Define Custom Validation Function Source: https://github.com/yiminghe/async-validator/blob/master/README.md Demonstrates how to define a custom validation function that receives rule, value, callback, source, and options. The function should return an array of Error instances for validation failures. This is useful for complex validation logic not covered by built-in types. ```javascript function(rule, value, callback, source, options) { // Validation logic here const errors = []; // If validation fails, add an error to the errors array // errors.push(new Error('Validation failed')); return errors; } ``` -------------------------------- ### Custom Async Validation with Callbacks and Promises Source: https://github.com/yiminghe/async-validator/blob/master/README.md Demonstrates how to define asynchronous validation functions for fields. This includes using a callback for traditional async operations and returning a Promise for Promise-based async operations. Ensure your AJAX function correctly resolves or rejects. ```javascript const fields = { asyncField: { asyncValidator(rule, value, callback) { ajax({ url: 'xx', value: value, }).then(function(data) { callback(); }, function(error) { callback(new Error(error)); }); }, }, promiseField: { asyncValidator(rule, value) { return ajax({ url: 'xx', value: value, }); }, }, }; ``` -------------------------------- ### JavaScript/TypeScript: Schema Creation and Basic Validation Source: https://context7.com/yiminghe/async-validator/llms.txt Demonstrates how to create a validator instance using a descriptor object and perform validation using both callback and Promise-based APIs. Handles required fields and basic type checks like string, number, and email. Errors are reported if validation fails. ```javascript import Schema from 'async-validator'; // Define validation rules const descriptor = { name: { type: 'string', required: true, min: 3, max: 50 }, age: { type: 'number', required: true, min: 18 }, email: { type: 'email', required: true } }; // Create validator instance const validator = new Schema(descriptor); // Validate with callback validator.validate({ name: 'John', age: 25, email: 'john@example.com' }, (errors, fields) => { if (errors) { // errors: array of all validation errors // fields: object with errors grouped by field name console.error('Validation failed:', errors); return; } console.log('Validation passed'); }); // Validate with Promise validator.validate({ name: 'Jo', age: 16, email: 'invalid' }) .then(() => { console.log('Validation passed'); }) .catch(({ errors, fields }) => { console.error('Validation failed'); // Expected errors: // - name: must be at least 3 characters // - age: cannot be less than 18 // - email: not a valid email }); ``` -------------------------------- ### Validate API Source: https://github.com/yiminghe/async-validator/blob/master/README.md The primary method for validating an object against a defined schema. It supports both callback and Promise-based usage. ```APIDOC ## Validate API ### Description Validates an object against a defined schema using asynchronous rules. Supports callback and Promise-based execution. ### Method `validate(source, [options], callback): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **source** (object) - Required - The object to validate. - **options** (object) - Optional - An object describing processing options for the validation. - **callback** (function) - Optional - A callback function to invoke when validation completes. ### Request Example ```javascript import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true }, age: { type: 'number' } }; const validator = new Schema(descriptor); // Callback usage validator.validate({ name: 'test' }, (errors, fields) => { if (errors) { console.error('Validation failed:', errors); } else { console.log('Validation passed'); } }); // Promise usage validator.validate({ name: 'test', age: 25 }) .then(() => console.log('Validation passed')) .catch(({ errors, fields }) => console.error('Validation failed:', errors)); ``` ### Response #### Success Response (Promise.then or callback with no errors) Validation passed. #### Error Response (Promise.catch or callback with errors) - **errors** (Array) - An array of all validation errors. - **fields** (Object) - An object keyed by field name, with an array of errors for each field. #### Response Example ```json { "errors": [ { "message": "name is required", "field": "name", "rule": "required", "type": "async-validator" } ], "fields": { "name": [ { "message": "name is required", "field": "name", "rule": "required", "type": "async-validator" } ] } } ``` ``` -------------------------------- ### Customizing Validation Error Messages Source: https://github.com/yiminghe/async-validator/blob/master/README.md Allows for customization of validation error messages. Messages can be simple strings, HTML strings, or functions, facilitating i18n integration. Custom messages can be assigned directly to a rule or merged globally with the schema's messages. ```javascript { name: { type: 'string', required: true, message: 'Name is required' } } ``` ```javascript { name: { type: 'string', required: true, message: 'Name is required' } } ``` ```javascript { name: { type: 'string', required: true, message: () => this.$t( 'name is required' ) } } ``` ```javascript import Schema from 'async-validator'; const cn = { required: '%s 必填', }; const descriptor = { name: { type: 'string', required: true } }; const validator = new Schema(descriptor); // deep merge with defaultMessages validator.messages(cn); // ... validation logic ... ``` -------------------------------- ### Apply Multiple Rules Per Field with Async Validator Source: https://context7.com/yiminghe/async-validator/llms.txt Demonstrates how to apply multiple validation rules to a single field by defining rules as an array in the descriptor. This includes synchronous validators, asynchronous validators, and custom validation logic. Dependencies include the 'async-validator' library. ```javascript import Schema from 'async-validator'; const descriptor = { email: [ { type: 'string', required: true, message: 'Email is required' }, { type: 'email', message: 'Invalid email format' }, { max: 100, message: 'Email is too long' }, { validator(rule, value) { const domain = value.split('@')[1]; return ['company.com', 'example.com'].includes(domain); }, message: 'Email must be from company.com or example.com' }, { asyncValidator(rule, value) { return fetch(`/api/validate-email?email=${value}`) .then(res => res.json()) .then(data => { if (!data.valid) { return Promise.reject('Email validation failed'); } }); } } ], username: [ { type: 'string', required: true }, { min: 3, max: 20 }, { pattern: /^[a-zA-Z0-9_]+$/, message: 'Only alphanumeric and underscore allowed' }, { validator(rule, value) { const reserved = ['admin', 'root', 'system']; return !reserved.includes(value.toLowerCase()); }, message: 'Username is reserved' } ] }; const validator = new Schema(descriptor); validator.validate({ email: 'user@gmail.com', username: 'admin' }).catch(({ errors, fields }) => { // All failing rules are reported console.log('Email errors:', fields.email); // Domain not allowed console.log('Username errors:', fields.username); // Reserved name console.log('Total errors:', errors.length); }); ``` -------------------------------- ### Value Transformation Before Validation Source: https://github.com/yiminghe/async-validator/blob/master/README.md Applies a `transform` function to a field's value before validation occurs. This is useful for sanitizing or coercing data, such as trimming whitespace from a string before applying a pattern match. The transformed value is used in subsequent validation and returned in the results. ```javascript import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, pattern: /^[a-z]+$/, transform(value) { return value.trim(); }, }, }; const validator = new Schema(descriptor); const source = { name: ' user ' }; validator.validate(source) .then((data) => { // assert.equal(data.name, 'user'); console.log('Validation passed, transformed name:', data.name); }) .catch(errors => { console.error('Validation failed:', errors); }); validator.validate(source, (errors, data) => { if (errors) { console.error('Validation failed (callback):', errors); } else { // assert.equal(data.name, 'user'); console.log('Validation passed (callback), transformed name:', data.name); } }); ``` -------------------------------- ### Custom Synchronous Validation Source: https://github.com/yiminghe/async-validator/blob/master/README.md Shows how to implement synchronous validation for fields. Validators can return a boolean, an Error object, an array of Error objects, or simply not return anything if validation passes. This is useful for simple, immediate checks. ```javascript const fields = { field: { validator(rule, value, callback) { return value === 'test'; }, message: 'Value is not equal to "test".', }, field2: { validator(rule, value, callback) { return new Error(`${value} is not equal to 'test'.`); }, }, arrField: { validator(rule, value) { return [ new Error('Message 1'), new Error('Message 2'), ]; }, }, }; ``` -------------------------------- ### Enum Validation for Boolean True Source: https://github.com/yiminghe/async-validator/blob/master/README.md Illustrates how to configure a field to validate specifically for the boolean value `true` using the `enum` type. This is useful for enforcing a specific truthy condition for a field. ```javascript { type: 'enum', enum: [true], message: '', } ``` -------------------------------- ### Range and Length Validation with Async Validator (JavaScript) Source: https://context7.com/yiminghe/async-validator/llms.txt Validates string length, array length, and numeric ranges using `min`, `max`, and `len` properties in the descriptor. It requires the `async-validator` library. The input is a data object, and the output is either a resolved promise or a rejected promise with validation errors. ```javascript import Schema from 'async-validator'; const descriptor = { username: { type: 'string', required: true, min: 3, max: 20, message: 'Username must be between 3 and 20 characters' }, password: { type: 'string', len: 8, message: 'Password must be exactly 8 characters' }, age: { type: 'number', min: 18, max: 120, message: 'Age must be between 18 and 120' }, tags: { type: 'array', min: 1, max: 5, message: 'Must have between 1 and 5 tags' }, score: { type: 'number', min: 0, max: 100 } }; const validator = new Schema(descriptor); validator.validate({ username: 'jo', // Too short password: 'pass123', // Not exactly 8 characters age: 150, // Out of range tags: [], // Too few items score: -10 // Below minimum }).catch(({ errors, fields }) => { // Fields object groups errors by field name console.log('Username errors:', fields.username); console.log('All errors:', errors.length); }); ``` -------------------------------- ### JavaScript/TypeScript: Required and Pattern Validation Source: https://context7.com/yiminghe/async-validator/llms.txt Shows how to use the 'required' property to ensure a field is present and the 'pattern' property with regular expressions to validate string formats. Custom 'message' properties can be provided for specific error feedback. ```javascript import Schema from 'async-validator'; const descriptor = { username: { type: 'string', required: true, pattern: /^[a-zA-Z0-9_]+$/, message: 'Username is required and must contain only alphanumeric characters and underscores' }, password: { type: 'string', required: true, pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/, message: 'Password must be at least 8 characters with uppercase, lowercase, and number' }, phone: { type: 'string', pattern: /^\+?[1-9]\d{1,14}$/, message: 'Invalid phone number format' } }; const validator = new Schema(descriptor); // Valid data validator.validate({ username: 'john_doe123', password: 'SecurePass1' }).then(() => { console.log('Validation passed'); }); // Invalid data validator.validate({ username: 'john-doe!', // Invalid: contains special characters password: 'weak', // Invalid: too short, no uppercase/number phone: 'abc123' // Invalid: not a valid phone format }).catch(({ errors, fields }) => { // errors array contains all validation failures errors.forEach(err => { console.log(`${err.field}: ${err.message}`); }); }); ``` -------------------------------- ### Suppressing Global Warnings Source: https://github.com/yiminghe/async-validator/blob/master/README.md Provides two methods to disable global warnings generated by the async-validator library. The first method overrides the default warning function, while the second uses a global flag. Choose the method that best fits your project's needs for managing validation feedback. ```javascript import Schema from 'async-validator'; Schema.warning = function(){}; ``` ```javascript globalThis.ASYNC_VALIDATOR_NO_WARNING = 1; ``` -------------------------------- ### Deep Validation with Options in async-validator Source: https://context7.com/yiminghe/async-validator/llms.txt Demonstrates how to pass validation options to nested schema validators for fine-grained control over deep validation behavior in async-validator. This includes options like 'first: true' to stop at the first error in nested validation and 'firstFields: true' to stop at the first error per nested field. ```javascript import Schema from 'async-validator'; const descriptor = { user: { type: 'object', required: true, options: { first: true }, // Stop at first error in nested validation fields: { name: { type: 'string', required: true }, email: { type: 'email', required: true }, phone: { type: 'string', required: true } } }, addresses: { type: 'array', required: true, options: { firstFields: true }, // First error per nested field defaultField: { type: 'object', fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zip: { type: 'string', required: true } } } }, preferences: { type: 'object', fields: { notifications: { type: 'boolean' }, theme: { type: 'enum', enum: ['light', 'dark'] } } } }; const validator = new Schema(descriptor); validator.validate({ user: { name: '', email: 'invalid', phone: '' }, addresses: [ { street: '', city: '', zip: '' }, { street: '123 Main', city: '', zip: '' } ], preferences: { notifications: 'yes', theme: 'blue' } }).catch(({ errors, fields }) => { // user validation stops at first error (name) // addresses validation returns first error per field console.log('Validation errors:', errors); console.log('Fields with errors:', Object.keys(fields)); // Error fields will include deep paths like: // - user.name // - user.email // - addresses.0.street // - preferences.theme }); ``` -------------------------------- ### Custom Validator Functions with Async Validator (JavaScript) Source: https://context7.com/yiminghe/async-validator/llms.txt Defines custom synchronous validation logic using the `validator` property within the descriptor. This allows for complex checks, including cross-field validation. It requires the `async-validator` library. Input is a data object, and output is a promise that resolves or rejects with errors. ```javascript import Schema from 'async-validator'; const descriptor = { email: { type: 'string', required: true, validator(rule, value, callback, source, options) { const errors = []; // Custom validation: check if email domain is allowed const allowedDomains = ['example.com', 'company.com']; const domain = value.split('@')[1]; if (!allowedDomains.includes(domain)) { errors.push(new Error(`Email domain must be one of: ${allowedDomains.join(', ')}`)); } return errors; } }, password: { validator(rule, value, callback) { // Return false for validation failure if (value && value.includes('password')) { return false; // Will use default or rule.message } return true; // Validation passed }, message: 'Password cannot contain the word "password"' }, confirmPassword: { validator(rule, value, callback, source) { // Access other fields via source parameter if (value !== source.password) { return new Error('Passwords do not match'); } return true; } }, username: { validator(rule, value) { // Return array of errors for multiple validation issues const errors = []; if (value.length < 3) { errors.push(new Error('Username too short')); } if (!/^[a-zA-Z]/.test(value)) { errors.push(new Error('Username must start with a letter')); } return errors; } } }; const validator = new Schema(descriptor); validator.validate({ email: 'user@gmail.com', password: 'mypassword123', confirmPassword: 'different', username: '1user' }).catch(({ errors, fields }) => { console.log('Validation errors:', errors); // Expected errors: // - email: domain not allowed // - password: contains "password" // - confirmPassword: doesn't match // - username: starts with number }); ``` -------------------------------- ### JavaScript/TypeScript: Type Validation for Various Data Types Source: https://context7.com/yiminghe/async-validator/llms.txt Illustrates how to define a descriptor object to validate various data types including string, number, boolean, array, object, date, URL, email, hex, and enum. The validator checks if the provided data conforms to the specified types. ```javascript import Schema from 'async-validator'; const descriptor = { username: { type: 'string' }, age: { type: 'integer' }, score: { type: 'float' }, active: { type: 'boolean' }, tags: { type: 'array' }, profile: { type: 'object' }, callback: { type: 'method' }, pattern: { type: 'regexp' }, birthdate: { type: 'date' }, website: { type: 'url' }, email: { type: 'email' }, color: { type: 'hex' }, role: { type: 'enum', enum: ['admin', 'user', 'guest'] } }; const validator = new Schema(descriptor); validator.validate({ username: 'john_doe', age: 25, score: 95.5, active: true, tags: ['javascript', 'nodejs'], profile: { bio: 'Developer' }, callback: () => {}, pattern: /^test$/, birthdate: new Date('1998-01-01'), website: 'https://example.com', email: 'john@example.com', color: '#FF5733', role: 'admin' }).then(() => { console.log('All types validated successfully'); }).catch(({ errors }) => { console.error('Type validation errors:', errors); }); ``` -------------------------------- ### Whitespace Validation with Async Validator Source: https://context7.com/yiminghe/async-validator/llms.txt Illustrates how to use the 'whitespace: true' option in async-validator to ensure string fields contain non-whitespace characters. This can be combined with 'transform' to clean user input before validation. Requires the 'async-validator' library. ```javascript import Schema from 'async-validator'; const descriptor = { name: { type: 'string', required: true, whitespace: true, message: 'Name cannot be empty or only whitespace' }, description: { type: 'string', required: true, whitespace: true, min: 10 }, comment: { type: 'string', whitespace: true, // Combine with transform to handle user input transform(value) { return value ? value.trim() : value; } } }; const validator = new Schema(descriptor); // Invalid: whitespace-only strings validator.validate({ name: ' ', description: ' ', comment: ' ' }).catch(({ errors }) => { console.log('Whitespace validation failed:', errors); // name and description will fail whitespace validation }); // Valid: actual content validator.validate({ name: 'John Doe', description: 'This is a valid description with content', comment: 'A real comment' }).then(() => { console.log('Validation passed'); }); ``` -------------------------------- ### Async Validation with Callbacks and Promises in JavaScript Source: https://context7.com/yiminghe/async-validator/llms.txt Implement asynchronous validation rules for fields using callbacks or Promises. This is useful for operations like checking email availability in a database or verifying username uniqueness via an API. It requires the 'async-validator' library. ```javascript import Schema from 'async-validator'; const descriptor = { email: { type: 'email', required: true, asyncValidator(rule, value, callback) { // Simulate checking if email exists in database setTimeout(() => { fetch(`/api/check-email?email=${value}`) .then(response => response.json()) .then(data => { if (data.exists) { callback(new Error('Email already registered')); } else { callback(); // Validation passed } }) .catch(error => { callback(new Error('Could not verify email')); }); }, 100); } }, username: { asyncValidator(rule, value) { // Return a Promise for cleaner async handling return new Promise((resolve, reject) => { fetch(`/api/check-username?username=${value}`) .then(response => response.json()) .then(data => { if (data.available) { resolve(); } else { reject('Username is taken'); } }) .catch(() => reject('Could not verify username')); }); } }, age: { type: 'number', asyncValidator(rule, value) { return new Promise((resolve, reject) => { if (value < 18) { reject('Must be 18 or older'); } else if (value > 120) { reject('Invalid age'); } else { resolve(); } }); } } }; const validator = new Schema(descriptor); // Async validation with async/await async function validateUser(userData) { try { await validator.validate(userData); console.log('All validations passed'); return true; } catch ({ errors, fields }) { console.error('Validation failed:', errors); return false; } } validateUser({ email: 'newuser@example.com', username: 'john_doe', age: 25 }); ``` -------------------------------- ### Deep Object Validation with Nested Rules Source: https://github.com/yiminghe/async-validator/blob/master/README.md Defines validation rules for nested object properties using the 'fields' property. If the parent rule is not marked as 'required', the nested validation is skipped if the parent field is missing. The 'options' property on the parent rule can pass arguments to the schema.validate() method for nested validation. ```javascript const descriptor = { address: { type: 'object', required: true, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zip: { type: 'string', required: true, len: 8, message: 'invalid zip' }, }, }, name: { type: 'string', required: true }, }; const validator = new Schema(descriptor); validator.validate({ address: {} }, (errors, fields) => { // errors for address.street, address.city, address.zip }); ``` ```javascript const descriptor = { address: { type: 'object', required: true, options: { first: true }, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zip: { type: 'string', required: true, len: 8, message: 'invalid zip' }, }, }, name: { type: 'string', required: true }, }; const validator = new Schema(descriptor); validator.validate({ address: {} }) .catch(({ errors, fields }) => { // now only errors for street and name }); ``` -------------------------------- ### Customize Error Messages with Async Validator Source: https://context7.com/yiminghe/async-validator/llms.txt Explains how to customize error messages in async-validator using the 'message' property. Messages can be static strings or dynamic functions that receive field context. Global messages can also be set for common error types. Requires the 'async-validator' library. ```javascript import Schema from 'async-validator'; const descriptor = { username: { type: 'string', required: true, min: 3, max: 20, message: 'Username must be between 3 and 20 characters' }, email: { type: 'email', required: true, message: 'Please provide a valid email address' }, age: [ { type: 'number', required: true, message: 'Age is required' }, { validator(rule, value) { return value >= 18; }, message: (field) => `${field} must be at least 18` } ], password: { type: 'string', required: true, validator(rule, value) { const hasUpper = /[A-Z]/.test(value); const hasLower = /[a-z]/.test(value); const hasNumber = /[0-9]/.test(value); if (!hasUpper || !hasLower || !hasNumber) { return false; } return true; }, // Message can be a function for dynamic content message: () => { return 'Password must contain uppercase, lowercase, and numbers'; } } }; const validator = new Schema(descriptor); // Set global messages for all validators validator.messages({ required: '%s is required', types: { string: '%s must be a string', number: '%s must be a number', email: '%s must be a valid email' }, string: { min: '%s must be at least %s characters', max: '%s cannot exceed %s characters' } }); validator.validate({ username: 'ab', email: 'invalid', age: 16, password: 'weak' }).catch(({ errors }) => { errors.forEach(error => { console.log(`${error.field}: ${error.message}`); }); // Output: // username: Username must be between 3 and 20 characters // email: Please provide a valid email address // age: age must be at least 18 // password: Password must contain uppercase, lowercase, and numbers }); ``` -------------------------------- ### Array/Object Default Field Validation Source: https://github.com/yiminghe/async-validator/blob/master/README.md Utilizes the `defaultField` property for array or object types to define validation rules applicable to all elements or properties. This is particularly useful for ensuring uniformity across all items in a collection, such as validating all URLs in an array. ```javascript const descriptor = { urls: { type: 'array', required: true, defaultField: { type: 'url' }, }, }; // Note: defaultField is expanded to fields, refer to deep rules. ``` -------------------------------- ### Deep Object and Array Validation with async-validator in JavaScript Source: https://context7.com/yiminghe/async-validator/llms.txt Validate nested object structures and arrays using the 'fields' and 'defaultField' properties. This allows for granular control over the expected structure and types within complex data. Requires the 'async-validator' library. ```javascript import Schema from 'async-validator'; // Validate nested object with specific fields const userDescriptor = { name: { type: 'string', required: true }, address: { type: 'object', required: true, fields: { street: { type: 'string', required: true }, city: { type: 'string', required: true }, zipCode: { type: 'string', required: true, len: 5, pattern: /^\d{5}$/ }, country: { type: 'string', required: true } } }, contacts: { type: 'array', required: true, fields: { 0: { type: 'string', pattern: /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/ }, 1: { type: 'string', pattern: /^\+?[1-9]\d{1,14}$/ } } } }; const userValidator = new Schema(userDescriptor); userValidator.validate({ name: 'John Doe', address: { street: '123 Main St', city: 'New York', zipCode: '10001', country: 'USA' }, contacts: ['john@example.com', '+1234567890'] }).then(() => { console.log('User validation passed'); }); // Validate arrays with uniform element validation using defaultField const listDescriptor = { emails: { type: 'array', required: true, defaultField: { type: 'email' } }, scores: { type: 'array', defaultField: { type: 'number', min: 0, max: 100 } }, users: { type: 'array', defaultField: { type: 'object', fields: { name: { type: 'string', required: true }, age: { type: 'number', required: true } } } } }; const listValidator = new Schema(listDescriptor); listValidator.validate({ emails: ['user1@example.com', 'user2@example.com', 'user3@example.com'], scores: [85, 92, 78, 95], users: [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 30 } ] }).catch(({ errors, fields }) => { // Deep validation errors include full field path // e.g., "users.0.name", "emails.1" console.error('Validation errors:', errors); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.