### NPM Installation for LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Provides the command to install the LIVR validation library using npm, the Node Package Manager. This is the standard method for incorporating LIVR into a Node.js project or a project managed with a package manager. ```bash npm install livr ``` -------------------------------- ### Quick Start: Basic Validation with LIVR in TypeScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates how to set up a LIVR validator with a TypeScript schema, perform validation, and leverage type inference for the output. It shows automatic type coercion and stripping of unknown fields. ```typescript import LIVR from 'livr'; import type { InferFromSchema } from 'livr/types'; const schema = { email: ['required', 'email'], age: ['required', 'positiveInteger'], role: { oneOf: ['admin', 'user'] } as const, } as const; type User = InferFromSchema; // Inferred: { email: string; age: number; role: 'admin' | 'user' } const validator = new LIVR.Validator(schema); const result = validator.validate({ email: 'user@example.com', age: '25', // String from form → automatically becomes number role: 'admin', hackAttempt: true, // Unknown field → automatically stripped }); if (result) { console.log(result.role); // TypeScript knows: 'admin' | 'user' } // result: { email: 'user@example.com', age: 25, role: 'admin' } ``` -------------------------------- ### LIVR Input Immutability Example in JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates LIVR's design principle of input immutability. The example shows that the `validate` method returns a new object with validated and transformed data, leaving the original input object unchanged, unlike some other validators that might mutate the input. ```javascript const input = { name: ' John ', email: 'JOHN@EXAMPLE.COM', extraField: 'will be stripped', }; const result = validator.validate(input); // Result (new object): // { name: 'John', email: 'john@example.com' } // Input UNCHANGED: console.log(input.extraField); // 'will be stripped' - still there! console.log(input.name); // ' John ' - still has whitespace! ``` -------------------------------- ### LIVR Validation Example with Web Form Data Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates how LIVR handles web form input, where all data is initially strings. It shows the validation process and the resulting output with proper type coercion and string transformations. ```javascript const validator = new LIVR.Validator({ age: ['required', 'positiveInteger'], price: ['required', 'decimal'], name: ['required', 'trim'], email: ['required', 'email', 'toLc'], }); // Input from web form (all strings) const input = { age: '25', price: '19.99', name: ' John Doe ', email: 'JOHN@EXAMPLE.COM', }; const result = validator.validate(input); // Output (properly typed): // { // age: 25, // number (coerced from string) // price: 19.99, // number (coerced from string) // name: 'John Doe', // string (trimmed) // email: 'john@example.com' // string (lowercased) // } ``` -------------------------------- ### LIVR Schema Serialization and Validation Example (JavaScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates how LIVR schemas, represented as pure JSON, can be stored in a database, retrieved, and used for validation. This highlights LIVR's portability and ease of use with external data sources. ```javascript const schema = { username: ['required', { minLength: 3 }, { maxLength: 50 }], email: ['required', 'email'], role: { oneOf: ['admin', 'user', 'guest'] }, }; // Store in database await db.saveSchema('user-registration', JSON.stringify(schema)); // Load and validate const loadedSchema = JSON.parse(await db.getSchema('user-registration')); const validator = new LIVR.Validator(loadedSchema); ``` -------------------------------- ### JavaScript: Validate Input and Strip Unknown Fields with LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates how to use LIVR to validate input data. By default, LIVR strips any fields not defined in the schema, enhancing security against mass assignment and prototype pollution. The example shows a validator setup and how it processes an input object containing both valid and malicious fields. ```javascript const LIVR = require('livr-validator'); const validator = new LIVR.Validator({ username: 'required', email: 'email', }); const input = { username: 'john', email: 'john@example.com', isAdmin: true, // Attacker-injected role: 'superuser', // Attacker-injected __proto__: { hack: 1 }, // Prototype pollution attempt }; const result = validator.validate(input); // Expected output: { username: 'john', email: 'john@example.com' } // Malicious fields are automatically stripped. ``` -------------------------------- ### Examples of RuleTypeDef Usage (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md This code provides various examples of `RuleTypeDef` usage, illustrating how to define rules that produce different output types (string, number, object), make fields required, or provide default values. These examples cover common scenarios for custom rule definition. ```typescript // Simple string output RuleTypeDef // Makes field required (like 'required' rule) RuleTypeDef // Provides default value (like 'default' rule) RuleTypeDef // Number output RuleTypeDef // Object output RuleTypeDef<{ id: number; name: string }, false, false> ``` -------------------------------- ### Perform Asynchronous Validation with Custom Rules Source: https://context7.com/koorchik/js-validator-livr/llms.txt Illustrates asynchronous validation using LIVR.AsyncValidator. This example demonstrates registering a custom asynchronous rule ('unique_username') that simulates a database check. The validate method returns a Promise that resolves with valid data or rejects with errors. ```javascript import LIVR from 'livr/async'; // Register async custom rule LIVR.AsyncValidator.registerDefaultRules({ unique_username() { return async (value) => { if (value === undefined || value === null || value === '') return; // Simulate database check const exists = await checkUsernameInDatabase(value); if (exists) return 'USERNAME_ALREADY_EXISTS'; }; } }); const validator = new LIVR.AsyncValidator({ username: ['required', 'unique_username'], email: ['required', 'email'] }); async function validateUser(data) { try { const validData = await validator.validate(data); console.log('Valid:', validData); return validData; } catch (errors) { console.log('Validation errors:', errors); // Example: { username: 'USERNAME_ALREADY_EXISTS' } throw errors; } } // Usage validateUser({ username: 'existing_user', email: 'test@example.com' }); ``` -------------------------------- ### Get Registered Rules - JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Retrieves all validation rules that are currently registered for a specific LIVR validator instance. ```javascript validator.getRules(); ``` -------------------------------- ### TypeScript Type Inference from Schema Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Illustrates how LIVR can infer TypeScript types directly from a validation schema. By using `as const` on the schema, you enable `InferFromSchema` to generate precise types for your validated data, improving type safety in your application. This example defines a user schema and demonstrates type inference for basic types and literal unions. ```typescript import LIVR from 'livr'; import type { InferFromSchema } from 'livr/types'; const userSchema = { name: ['required', 'string'], email: ['required', 'email'], age: 'positive_integer', role: { one_of: ['admin', 'user'] as const }, } as const; // Automatically infer type from schema type User = InferFromSchema; // Result: { name: string; email: string; age?: number; role?: 'admin' | 'user' } const validator = new LIVR.Validator(userSchema); // Validate data from external source (API request, form submission, etc.) const input = getUserInput(); const validData = validator.validate(input); if (validData) { // validData is typed as User console.log(validData.name); // string console.log(validData.age); // number | undefined } ``` -------------------------------- ### Create Custom InstanceOf Rule Template (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md This example defines a custom template named 'my_instance' for LIVR's type inference. It extracts the `InstanceType` from a constructor provided as an argument to the rule. This allows inferring types for class instances within the schema. ```typescript // my-rules/instance_of.d.ts import type { ParameterizedRuleDef } from 'livr/types/inference'; declare module 'livr/types/inference' { // Step 1: Define custom template computation interface TemplateOutputRegistry { // Extract instance type from constructor argument my_instance: Args extends abstract new (...args: any) => any ? InstanceType : unknown; } // Step 2: Register rule using the template interface ParameterizedRuleRegistry { my_instance_of: ParameterizedRuleDef<'my_instance', false, false>; } } ``` -------------------------------- ### JavaScript LIVR Rule Aliasing for Healthcare Domain Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Illustrates the creation of domain-specific validation rules for the healthcare industry using LIVR's `registerAliasedRule`. This example defines aliases for medical record numbers, diagnosis codes, and NPI numbers, complete with custom error codes. ```javascript validator.registerAliasedRule({ name: 'patientMrn', rules: ['required', { lengthEqual: 10 }, { like: '^MRN\\d{7}$' }], error: 'INVALID_MEDICAL_RECORD_NUMBER', }); validator.registerAliasedRule({ name: 'diagnosisCode', rules: ['required', { like: '^[A-Z]\\d{2}\\യ്\d{0,4}$' }], error: 'INVALID_ICD10_CODE', }); validator.registerAliasedRule({ name: 'npiNumber', rules: ['required', { lengthEqual: 10 }, 'integer'], error: 'INVALID_NPI', }); const patientSchema = { mrn: 'patientMrn', diagnosis: 'diagnosisCode', provider: 'npiNumber', }; ``` -------------------------------- ### Infer Type from Schema with External Rule Packages (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md This example demonstrates how users of a package can automatically benefit from type inference when importing custom rules. It shows importing LIVR, a custom rule set ('my-livr-rules'), and then using `InferFromSchema` to derive the TypeScript type for a given schema. This enhances type safety by reflecting the validation rules in the application's types. ```typescript import LIVR from 'livr'; import type { InferFromSchema } from 'livr/types'; import 'my-livr-rules'; // Imports rules and type augmentations const schema = { id: ['required', 'uuid'], createdAt: 'iso_timestamp', } as const; type Record = InferFromSchema; // { id: string; createdAt?: string } ``` -------------------------------- ### fastest-validator RCE Vulnerability Example Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates a Remote Code Execution (RCE) vulnerability in fastest-validator. An attacker can inject malicious JavaScript code into schema parameters, which gets executed when the schema is compiled and used. This occurs because the validator compiles schemas into JavaScript code without proper sanitization of user-controlled inputs. ```javascript const Validator = require('fastest-validator'); const v = new Validator(); // Attacker controls schema (e.g., from database, API, user input) const maliciousSchema = { id: { type: 'number', max: 'console.log(process.env) || 999', // Injected code! }, }; const check = v.compile(maliciousSchema); check({ id: 123 }); // Executes: console.log(process.env) - RCE! ``` -------------------------------- ### Tree-Shaking LIVR Rules for Bundle Size Reduction Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Shows how to import only specific rules from LIVR to reduce the final bundle size. This involves importing the `Validator` class and then registering individual rule functions from their respective modules. ```javascript import Validator from 'livr/lib/Validator'; Validator.registerDefaultRules({ required: require('livr/lib/rules/common/required'), email: require('livr/lib/rules/special/email'), min_length: require('livr/lib/rules/string/min_length'), max_length: require('livr/lib/rules/string/max_length'), equal_to_field: require('livr/lib/rules/special/equal_to_field'), }); const validator = new Validator({ /* schema */ }); ``` -------------------------------- ### Implementing Async Custom Rules in LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Demonstrates how to create asynchronous custom validation rules using `registerRules` with the `LIVR.AsyncValidator`. These rules can perform operations like database lookups and return a Promise that resolves to an error code or undefined. ```javascript import LIVR from 'livr/async'; const validator = new LIVR.AsyncValidator({ username: ['required', 'unique_username'], }); validator.registerRules({ unique_username() { return async (value) => { if (value === undefined || value === null || value === '') return; const exists = await db.users.exists({ username: value }); if (exists) return 'USERNAME_TAKEN'; }; } }); ``` -------------------------------- ### Creating a New LIVR Validator Instance Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Demonstrates the instantiation of a new `LIVR.Validator` object with a schema and optional configuration. The `autoTrim` option can be set to automatically trim whitespace from string values before validation. ```javascript const validator = new LIVR.Validator(schema, { autoTrim: true }); ``` -------------------------------- ### Running Tests and Builds with npm and npx Source: https://github.com/koorchik/js-validator-livr/blob/master/CLAUDE.md This section details common command-line operations for managing the js-validator-livr project, including running tests, type checking, and building browser bundles. It utilizes npm and npx for script execution. ```bash npm test npx ava npx ava t/tests-sync/01-test_suite.js npx ava t/tests-async/01-test_suite.js npx tsc --noEmit npm run build ``` -------------------------------- ### Retrieving Validation Errors from LIVR Sync Validator Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Explains how to get the errors object from the last synchronous validation using `validator.getErrors()`. This method is only available for sync validators and returns an object detailing the validation failures. ```javascript // Example output: { email: 'WRONG_EMAIL', password: 'TOO_SHORT', address: { zip: 'NOT_POSITIVE_INTEGER' } } ``` -------------------------------- ### Validate Arrays with Nested Objects in LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Provides an example of how to define validation schemas for arrays, including arrays of strings and arrays of nested objects, using LIVR's `listOf` rule. ```javascript const schema = { tags: { listOf: 'string' }, items: { listOf: { nestedObject: { id: ['required', 'positiveInteger'], name: 'string', }, }, }, }; // Input: { tags: ["js", "node"], items: [{ id: 1, name: "Item" }] } ``` -------------------------------- ### Writing Custom LIVR Rule Functions Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Explains how to implement complex validation logic by writing custom rule functions using `registerRules`. These functions receive the value and can return an error code string if validation fails, enabling highly specific checks. ```javascript const validator = new LIVR.Validator({ password: ['required', 'strong_password'], }); validator.registerRules({ strong_password() { return (value) => { // Empty values are handled by 'required' rule if (value === undefined || value === null || value === '') return; if (!/[A-Z]/.test(value)) return 'MISSING_UPPERCASE'; if (!/[a-z]/.test(value)) return 'MISSING_LOWERCASE'; if (!/[0-9]/.test(value)) return 'MISSING_DIGIT'; if (value.length < 8) return 'TOO_SHORT'; }; } }); ``` -------------------------------- ### Zod Schema Definition Example (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Illustrates how Zod schemas are defined using function chains and code, making them non-serializable and difficult to share across different programming languages or store as plain data. ```typescript const schema = z.object({ username: z.string().min(3).max(50), email: z.string().email(), role: z.enum(['admin', 'user', 'guest']), }); // Cannot store in database // Cannot send over API // Cannot share with Python/Java services ``` -------------------------------- ### Registering LIVR Rules Globally Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Illustrates how to register custom rules and aliased rules globally using `LIVR.Validator.registerDefaultRules` and `LIVR.Validator.registerAliasedDefaultRule`. These globally registered rules are available to all subsequent validator instances. ```javascript // Register for all future validator instances LIVR.Validator.registerDefaultRules({ my_rule(arg1, arg2) { return (value, allValues, outputArr) => { // Return error code on failure, undefined on success if (invalid) return 'ERROR_CODE'; }; } }); LIVR.Validator.registerAliasedDefaultRule({ name: 'valid_address', rules: { nested_object: { country: 'required', city: 'required' }} }); ``` -------------------------------- ### Tree-Shaking for Minimal Bundle Size in LIVR.js Source: https://context7.com/koorchik/js-validator-livr/llms.txt Explains how to import only necessary validation rules to minimize the final JavaScript bundle size for browser applications. This technique significantly reduces the footprint by selectively registering rules using `Validator.registerDefaultRules`. ```javascript import Validator from 'livr/lib/Validator'; // Register only the rules you need Validator.registerDefaultRules({ required: require('livr/lib/rules/common/required'), email: require('livr/lib/rules/special/email'), string: require('livr/lib/rules/string/string'), min_length: require('livr/lib/rules/string/min_length'), max_length: require('livr/lib/rules/string/max_length'), positive_integer: require('livr/lib/rules/numeric/positive_integer'), trim: require('livr/lib/rules/modifiers/trim'), default: require('livr/lib/rules/modifiers/default'), nested_object: require('livr/lib/rules/meta/nested_object'), list_of: require('livr/lib/rules/meta/list_of') }); // Now use the validator with only registered rules const validator = new Validator({ name: ['required', 'trim', 'string', { min_length: 1 }, { max_length: 100 }], email: ['required', 'trim', 'email'], age: [{ default: 0 }, 'positive_integer'], preferences: { nested_object: { notifications: { default: true } } }, tags: { list_of: 'string' } }); const result = validator.validate({ name: ' John Doe ', email: 'john@example.com', tags: ['premium', 'verified'] }); console.log(result); // Output: { name: 'John Doe', email: 'john@example.com', age: 0, preferences: { notifications: true }, tags: ['premium', 'verified'] } ``` -------------------------------- ### Define Union Types with 'or' in TypeScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md Demonstrates how to define a schema where a field can accept multiple types using the `or` operator in LIVR. This example shows a field that can be either a string or an integer, along with its inferred TypeScript union type. ```typescript const schema = { // Can be either a string or a number value: { or: ['string', 'integer'] }, } as const; type Data = InferFromSchema; // { value?: string | number } ``` -------------------------------- ### Importing LIVR Synchronous and Asynchronous Validators Source: https://github.com/koorchik/js-validator-livr/blob/master/CLAUDE.md Shows how to import the main LIVR validator classes. Use the default import for the synchronous validator and a specific path for the asynchronous validator. ```javascript import LIVR from 'livr' import LIVR from 'livr/async' ``` -------------------------------- ### Register Custom Validation Rule with Transformation in JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Illustrates registering a custom rule 'toDate' that not only validates but also transforms the input value. In this example, it converts a date string into a JavaScript Date object, pushing the transformed value into the output array. ```javascript LIVR.Validator.registerDefaultRules({ toDate: () => (value, _, outputArr) => { if (!value) return; const date = new Date(value); if (isNaN(date.getTime())) return 'INVALID_DATE'; outputArr.push(date); // Transform string to Date object }, }); const schema = { birthDate: ['required', 'toDate'] }; // Input: { birthDate: '1990-05-15' } // Output: { birthDate: Date object } ``` -------------------------------- ### Prepare Validator Rules - JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Pre-compiles validation rules for a LIVR validator instance. This can be called automatically on the first validation or manually for performance warm-up. ```javascript const validator = new LIVR.Validator(schema).prepare(); ``` -------------------------------- ### Create Synchronous Validator Instance with Schema Source: https://context7.com/koorchik/js-validator-livr/llms.txt Demonstrates how to create a synchronous validator instance using the LIVR.Validator class. It takes a schema object defining rules for each field and an optional options object. The validate method returns validated data or null if validation fails, with errors retrievable via getErrors(). ```javascript import LIVR from 'livr'; // Create validator with schema const validator = new LIVR.Validator({ name: 'required', email: ['required', 'email'], age: 'positive_integer', gender: { one_of: ['male', 'female', 'other'] }, password: ['required', { min_length: 8 }], password2: { equal_to_field: 'password' } }); // Validate input data const userData = { name: 'John Doe', email: 'john@example.com', age: 30, gender: 'male', password: 'secret123', password2: 'secret123' }; const validData = validator.validate(userData); if (validData) { console.log('Valid:', validData); // Output: { name: 'John Doe', email: 'john@example.com', age: 30, gender: 'male', password: 'secret123', password2: 'secret123' } } else { console.log('Errors:', validator.getErrors()); // Example error: { email: 'WRONG_EMAIL', password: 'TOO_SHORT' } } ``` -------------------------------- ### Pre-Compile Validators for Performance in LIVR.js Source: https://context7.com/koorchik/js-validator-livr/llms.txt Utilizes the `prepare` method to pre-compile validation rules before the first validation call. This is beneficial for 'warm-up' scenarios, reducing latency on initial requests. The validator is ready for immediate, high-speed validation after calling `.prepare()`. ```javascript import LIVR from 'livr'; // Create and immediately prepare the validator const validator = new LIVR.Validator({ name: ['required', 'string', { max_length: 100 }], email: ['required', 'email'], items: { list_of_objects: { id: ['required', 'positive_integer'], quantity: ['required', 'positive_integer'] } } }).prepare(); // Pre-compile rules // Validator is now ready for fast validation // Useful during application startup or module initialization const items = [ { id: 1, name: 'Item 1', email: 'a@test.com', items: [{ id: 1, quantity: 5 }] }, { id: 2, name: 'Item 2', email: 'b@test.com', items: [{ id: 2, quantity: 3 }] }, { id: 3, name: 'Item 3', email: 'c@test.com', items: [{ id: 3, quantity: 7 }] } ]; // All validations run at full speed - no first-call overhead for (const item of items) { const result = validator.validate(item); if (result) { console.log(`Validated: ${result.name}`); } } ``` -------------------------------- ### Loading and Registering Aliases from JSON in JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Illustrates how to read a JSON configuration file containing aliases and register them with the validator instance in JavaScript. This enables dynamic loading of validation rules. ```javascript const config = JSON.parse(fs.readFileSync('rules-config.json')); config.aliases.forEach((alias) => validator.registerAliasedRule(alias)); ``` -------------------------------- ### Basic JavaScript Validation with LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Demonstrates basic data validation using LIVR's Validator class. It defines a schema with various rules like 'required', 'email', 'positive_integer', 'min_length', and 'equal_to_field'. The `validate` method returns validated data or null if validation fails, with errors accessible via `getErrors()`. ```javascript import LIVR from 'livr'; const validator = new LIVR.Validator({ name: 'required', email: ['required', 'email'], age: 'positive_integer', password: ['required', { min_length: 8 }], password2: { equal_to_field: 'password' } }); const validData = validator.validate(userData); if (validData) { // Use validated & sanitized data saveUser(validData); } else { // Handle validation errors console.log(validator.getErrors()); // { email: 'WRONG_EMAIL', password: 'TOO_SHORT' } } ``` -------------------------------- ### Alternative Schema Definition using 'one_of' (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md This example shows an alternative way to define an enumerated type in LIVR by using the built-in 'one_of' rule. This approach leverages existing LIVR functionality for simpler cases and ensures proper type inference without custom template definitions. ```typescript // Use one_of which already has proper type inference const schema = { status: { one_of: ['pending', 'active', 'closed'] } as const, } as const; ``` -------------------------------- ### Performance Optimization: Reuse Validator - JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Illustrates the recommended approach for performance by creating a LIVR validator instance once and reusing it for multiple validations. ```javascript // Good: Create once, use many times const validator = new LIVR.Validator(schema); for (const item of items) { const result = validator.validate(item); } ``` -------------------------------- ### Implement and Use Custom Validation Rule with Type Inference (JavaScript/TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md Provides a step-by-step guide to creating a custom validation rule (`phone_number`) in JavaScript and integrating it with LIVR for type inference in TypeScript. It covers rule implementation, type definition file creation, rule registration, and usage with inferred types. ```javascript // my-rules/phone_number.js module.exports = function phoneNumber(countryCode) { return (value) => { if (value === undefined || value === null || value === '') return; // Your validation logic here const phoneRegex = /^\+?[\d\s-]{10,}$/; if (!phoneRegex.test(value)) { return 'INVALID_PHONE_NUMBER'; } }; }; ``` ```typescript // my-rules/phone_number.d.ts import type { RuleTypeDef } from 'livr/types/inference'; declare module 'livr/types/inference' { interface RuleTypeRegistry { // Simple rule that outputs string phone_number: RuleTypeDef; // Also register camelCase version phoneNumber: RuleTypeRegistry['phone_number']; } } ``` ```typescript import LIVR from 'livr'; import type { InferFromSchema } from 'livr/types'; import phoneNumber from './my-rules/phone_number'; // Register the rule LIVR.Validator.registerDefaultRules({ phone_number: phoneNumber }); const schema = { name: ['required', 'string'], phone: ['required', 'phone_number'], } as const; type Contact = InferFromSchema; // { name: string; phone: string } // Pass the inferred type as a generic parameter const validator = new LIVR.Validator(schema); // Validate data from external source const input = getContactInput(); const result = validator.validate(input); // result is typed as Contact | false ``` -------------------------------- ### Registering LIVR Aliased Rules for Reusability Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Shows how to define reusable validation rules using aliases with `registerAliasedRule`. This allows combining existing rules into a named rule for cleaner schemas and better maintainability. Custom error messages can also be specified. ```javascript const validator = new LIVR.Validator({ password: ['required', 'strong_password'], age: ['required', 'adult_age'], }); validator.registerAliasedRule({ name: 'strong_password', rules: { min_length: 8 }, error: 'WEAK_PASSWORD' }); validator.registerAliasedRule({ name: 'adult_age', rules: ['positive_integer', { min_number: 18 }], error: 'MUST_BE_ADULT' }); ``` -------------------------------- ### Asynchronous Validation with LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Demonstrates asynchronous validation using LIVR's `AsyncValidator`. This is suitable for rules that require I/O operations like database lookups or API calls (e.g., 'unique_username'). The `validate` method returns a Promise, and errors are handled via rejection. Fields are validated in parallel, while rules within a field are processed sequentially. ```javascript import LIVR from 'livr/async'; const validator = new LIVR.AsyncValidator({ username: ['required', 'unique_username'], // custom async rule email: ['required', 'email'], }); try { const validData = await validator.validate(userData); saveUser(validData); } catch (errors) { console.log(errors); } ``` -------------------------------- ### Multi-Tenant SaaS Validation with LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Shows how to implement tenant-specific validation rules using LIVR. By maintaining a collection of schemas keyed by tenant ID, applications can enforce different validation policies for different customers, ensuring data integrity across a multi-tenant environment. ```javascript // Each tenant has customized validation requirements const tenantSchemas = { 'tenant-acme': { order: { amount: ['required', { maxNumber: 10000 }], // Conservative limit approver: 'required', // Requires approval }, }, 'tenant-bigcorp': { order: { amount: ['required', { maxNumber: 1000000 }], // Higher limit // No approver required }, }, }; function validateForTenant(tenantId, entityType, data) { const schema = tenantSchemas[tenantId]?.[entityType]; if (!schema) throw new Error('Unknown entity type'); return new LIVR.Validator(schema).validate(data); } ``` -------------------------------- ### Validate with Async Rules in LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Shows how to register asynchronous default rules with LIVR, enabling validation logic that requires I/O operations, such as checking for unique email addresses in a database. ```javascript LIVR.Validator.registerDefaultRules({ uniqueEmail: () => async (email) => { const exists = await db.users.findByEmail(email); if (exists) return 'EMAIL_ALREADY_TAKEN'; }, }); ``` -------------------------------- ### Registering Custom Validation Rules in LIVR Source: https://context7.com/koorchik/js-validator-livr/llms.txt Explains how to extend LIVR's validation capabilities by registering custom rules. This can be done globally using `registerDefaultRules` or instance-specifically using `registerRules`. Custom rules are functions that return validator functions, allowing for reusable and complex validation logic. ```javascript import LIVR from 'livr'; // Register globally for all validators LIVR.Validator.registerDefaultRules({ // Simple rule: no arguments strong_password() { return (value) => { if (value === undefined || value === null || value === '') return; if (!/[A-Z]/.test(value)) return 'MISSING_UPPERCASE'; if (!/[a-z]/.test(value)) return 'MISSING_LOWERCASE'; if (!/[0-9]/.test(value)) return 'MISSING_DIGIT'; if (!/[!@#$%^&*]/.test(value)) return 'MISSING_SPECIAL_CHAR'; if (value.length < 8) return 'TOO_SHORT'; }; }, // Rule with arguments starts_with(prefix) { return (value) => { if (value === undefined || value === null || value === '') return; if (typeof value !== 'string') return 'FORMAT_ERROR'; if (!value.startsWith(prefix)) return 'WRONG_PREFIX'; }; } }); const validator = new LIVR.Validator({ password: ['required', 'strong_password'], product_code: ['required', { starts_with: 'PROD-' }] }); // Register instance-specific rule validator.registerRules({ divisible_by(divisor) { return (value) => { if (value === undefined || value === null || value === '') return; if (typeof value !== 'number') return 'FORMAT_ERROR'; if (value % divisor !== 0) return 'NOT_DIVISIBLE'; }; } }); const result = validator.validate({ password: 'SecurePass123!', product_code: 'PROD-12345' }); console.log(result); // Output: { password: 'SecurePass123!', product_code: 'PROD-12345' } ``` -------------------------------- ### Implement Async Custom Validation Rule in JavaScript Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Details how to create and use asynchronous custom validation rules, such as 'uniqueEmail', which requires an external check (e.g., database lookup). It uses LIVR's `AsyncValidator` and demonstrates that async rules follow the same pattern but return Promises. ```javascript import LIVR from 'livr/async'; // Use async version // Register an async rule LIVR.Validator.registerDefaultRules({ uniqueEmail: () => async (email) => { if (!email) return; const exists = await db.users.findByEmail(email); if (exists) return 'EMAIL_ALREADY_TAKEN'; }, }); // Use like any other rule const validator = new LIVR.AsyncValidator({ email: ['required', 'email', 'uniqueEmail'], }); // Validate returns a Promise const result = await validator.validate({ email: 'test@example.com' }); ``` -------------------------------- ### JavaScript LIVR Rule Aliasing for E-commerce Domain Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Shows how to use LIVR's `registerAliasedRule` to create custom, domain-specific validation rules for an e-commerce context. This includes defining rules for product SKUs, prices, and quantities, and assigning custom error codes for better domain vocabulary. ```javascript const validator = new LIVR.Validator(schema); // E-commerce domain rules validator.registerAliasedRule({ name: 'productSku', rules: ['required', { like: '^[A-Z]{3}-\\d{6}$' }], error: 'INVALID_PRODUCT_SKU', // Custom error code! }); validator.registerAliasedRule({ name: 'priceUsd', rules: ['required', 'positiveDecimal', { maxNumber: 999999.99 }], error: 'INVALID_PRICE', }); validator.registerAliasedRule({ name: 'quantity', rules: ['required', 'positiveInteger', { maxNumber: 10000 }], error: 'INVALID_QUANTITY', }); // Clean, domain-focused schema const orderSchema = { sku: 'productSku', price: 'priceUsd', qty: 'quantity', }; ``` -------------------------------- ### Registering Aliased Rules Globally in LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Demonstrates how to register a rule alias globally using `LIVR.Validator.registerAliasedDefaultRule(alias)`. This allows defining a named alias for a set of rules, optionally with a custom error message, making it accessible to all validator instances. ```javascript LIVR.Validator.registerAliasedDefaultRule({ name: 'adult_age', rules: ['positive_integer', { min_number: 18 }], error: 'MUST_BE_ADULT' // optional custom error }); ``` -------------------------------- ### Defining Aliases in JSON Configuration Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Shows how to define validation aliases using a JSON configuration object. This allows for non-developers to define validation rules and enables environment-specific or tenant-specific rule sets. ```json { "aliases": [ { "name": "productSku", "rules": ["required", { "like": "^[A-Z]{3}-\\d{6}$" }], "error": "INVALID_SKU" }, { "name": "priceUsd", "rules": ["required", "positiveDecimal", { "maxNumber": 999999.99 }], "error": "INVALID_PRICE" } ] } ``` -------------------------------- ### Registering Default Rules Globally in LIVR Source: https://github.com/koorchik/js-validator-livr/blob/master/README.md Illustrates the use of `LIVR.Validator.registerDefaultRules(rules)` to add custom validation rules that will be available to all validator instances. The `rules` argument is an object where keys are rule names and values are rule functions. ```javascript LIVR.Validator.registerDefaultRules({ my_rule(arg) { return (value) => { /* ... */ }; } }); ``` -------------------------------- ### Usage of Custom InstanceOf Rule (TypeScript) Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md This code demonstrates using the custom 'my_instance_of' rule with a Temporal.Instant constructor. LIVR infers the type of the 'createdAt' field as `Temporal.Instant`, leveraging the custom template defined earlier for accurate type generation. ```typescript // Usage import { Temporal } from '@js-temporal/polyfill'; const schema = { createdAt: { my_instance_of: Temporal.Instant } as const, } as const; type Data = InferFromSchema; // { createdAt?: Temporal.Instant } ``` -------------------------------- ### Create Domain-Specific Rules with LIVR Aliasing Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/DESIGN.md Demonstrates how to create custom, reusable validation rules using LIVR's `registerAliasedRule` function. This allows for defining domain-specific validation logic with custom error messages. ```javascript validator.registerAliasedRule({ name: 'productSku', rules: ['required', { like: '^[A-Z]{3}-\d{6}$' }], error: 'INVALID_PRODUCT_SKU', // Semantic error code }); // Now use it like a built-in rule const schema = { sku: 'productSku' }; ``` -------------------------------- ### Basic LIVR TypeScript Type Inference Source: https://github.com/koorchik/js-validator-livr/blob/master/docs/TYPESCRIPT.md Demonstrates how to import LIVR and InferFromSchema, define a schema with 'as const', infer a TypeScript type, and create a typed LIVR Validator. It also shows how to validate input data and access validated results with type safety. ```typescript import LIVR from 'livr'; import type { InferFromSchema } from 'livr/types'; const userSchema = { name: ['required', 'string'], email: ['required', 'email'], age: 'positive_integer', } as const; // Infer the type from the schema type User = InferFromSchema; // Result: { name: string; email: string; age?: number } // Pass the inferred type as a generic parameter const validator = new LIVR.Validator(userSchema); // Validate data from external source (API request, form submission, etc.) const input = getUserInput(); const result = validator.validate(input); if (result) { // result is typed as User console.log(result.name); // string console.log(result.age); // number | undefined } ```