### Run Flat Object Benchmark Source: https://github.com/vinejs/vine/blob/4.x/benchmarks.md Execute the benchmark for validating flat objects. Ensure the project is built before running. ```sh npm run build node build/benchmarks/flat_object.js ``` -------------------------------- ### Run Array Benchmark Source: https://github.com/vinejs/vine/blob/4.x/benchmarks.md Execute the benchmark for validating arrays. Ensure the project is built before running. ```sh npm run build node build/benchmarks/array.js ``` -------------------------------- ### Run Union Benchmark Source: https://github.com/vinejs/vine/blob/4.x/benchmarks.md Execute the benchmark for validating unions. Note that Yup does not support unions. Ensure the project is built before running. ```sh npm run build node build/benchmarks/union.js ``` -------------------------------- ### Run Nested Object Benchmark Source: https://github.com/vinejs/vine/blob/4.x/benchmarks.md Execute the benchmark for validating nested objects. Ensure the project is built before running. ```sh npm run build node build/benchmarks/nested_object.js ``` -------------------------------- ### Use Vine.js Helper Functions Source: https://context7.com/vinejs/vine/llms.txt Leverage utility functions for type guards, existence checks, boolean coercion, number coercion, uniqueness checks, and common validators. ```typescript import vine from '@vinejs/vine' const { helpers } = vine // Type guards helpers.isString('hello') // true helpers.isObject({ a: 1 }) // true (excludes null and arrays) helpers.isArray([1, 2, 3]) // true helpers.isNumeric('42.5') // true // Existence checks helpers.exists(null) // false helpers.exists(0) // true helpers.isMissing(undefined) // true // HTML-form boolean semantics helpers.isTrue('on') // true (checkbox checked) helpers.isTrue('1') // true helpers.isFalse('false') // true helpers.asBoolean('on') // true helpers.asBoolean('maybe') // null (ambiguous) // Number coercion helpers.asNumber('42.5') // 42.5 helpers.asNumber(null) // NaN // Uniqueness check helpers.isDistinct([1, 2, 3, 4]) // true helpers.isDistinct([1, 2, 2, 3]) // false helpers.isDistinct( [{ email: 'a@b.com', tenant: 1 }, { email: 'a@b.com', tenant: 2 }], ['email', 'tenant'] ) // true (composite key) // Validators helpers.isEmail('user@example.com') // true helpers.isUUID('550e8400-e29b-41d4-a716-446655440000') // true helpers.isULID('01ARZ3NDEKTSV4RRFFQ69G5FAV') // true helpers.isHexColor('#FF5733') // true // DNS check (async) await helpers.isActiveURL('https://example.com') // true // Make all schema properties optional at once const baseProps = { name: vine.string(), email: vine.string().email() } const optionalProps = helpers.optional(baseProps) // { name: OptionalModifier, email: OptionalModifier } ``` -------------------------------- ### vine.string() Source: https://context7.com/vinejs/vine/llms.txt Creates a `VineString` schema with a rich set of built-in string validation and transformation rules. By default accepts any non-empty string. ```APIDOC ## `vine.string()` — String schema Creates a `VineString` schema with a rich set of built-in string validation and transformation rules. By default accepts any non-empty string. ```typescript import vine from '@vinejs/vine' const profileValidator = vine.create({ // Basic constraints username: vine.string().minLength(3).maxLength(20).alphaNumeric({ allowUnderscores: true }), bio: vine.string().maxLength(500).optional(), // Email with normalization email: vine.string().email().normalizeEmail({ gmail_remove_dots: true }), // URL with normalization website: vine.string().url({ require_protocol: true }).normalizeUrl({ stripWWW: true }).optional(), // Pattern matching postalCode: vine.string().postalCode({ countryCode: ['US', 'CA'] }), phone: vine.string().mobile({ locale: ['en-US'], strictMode: true }), // Identity strings apiKey: vine.string().uuid({ version: [4] }), sessionId: vine.string().ulid(), token: vine.string().jwt(), // Transformations slug: vine.string().toLowerCase().trim(), displayName: vine.string().trim().escape(), // HTML-encodes < > & etc. // Conditional fields promoCode: vine.string().optional().requiredWhen('isPro', '=', true), }) ``` ``` -------------------------------- ### Create Date Schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.date() to create schemas for Date objects. Supports custom formats, comparison rules like 'after'/'before', and timestamp/ISO 8601 parsing. ```typescript import vine from '@vinejs/vine' // Optional global transform: all dates become ISO strings // VineDate.transform((value) => value.toISOString()) const eventValidator = vine.create({ // Custom format parsing eventDate: vine.date({ formats: ['DD/MM/YYYY', 'YYYY-MM-DD'] }) .after('today') .before('2030-12-31'), // Timestamp support startAt: vine.date({ formats: ['x'] }), // Unix ms timestamp // ISO 8601 support endAt: vine.date({ formats: ['iso8601'] }).afterField('startAt'), // Relative and field comparisons bookingDate: vine.date().afterOrEqual('today').weekend().optional(), checkIn: vine.date(), checkOut: vine.date().afterField('checkIn', { compare: 'day' }), }) const result = await eventValidator.validate({ eventDate: '25/06/2026', startAt: '1750000000000', endAt: '2026-06-26T10:00:00Z', checkIn: '2026-06-25', checkOut: '2026-06-28', }) // result.eventDate, result.checkIn, etc. are Date objects ``` -------------------------------- ### Create a record schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.record() to define schemas for objects with string keys and uniformly typed values. You can also apply length constraints to the record itself. ```typescript import vine from '@vinejs/vine' const configValidator = vine.create({ // { [key: string]: string } envVars: vine.record(vine.string()), // { [key: string]: number } with length constraints scores: vine.record(vine.number().min(0).max(100)) .minLength(1) .maxLength(50), }) const result = await configValidator.validate({ envVars: { DATABASE_URL: 'postgres://...', PORT: '3000' }, scores: { alice: 95, bob: 87, carol: 92 }, }) // result.envVars: Record // result.scores: Record ``` -------------------------------- ### Pre-compiled Validator with vine.create() Source: https://context7.com/vinejs/vine/llms.txt Pre-compiles a schema for reusable validation. Recommended for route handlers to compile schemas only once. ```typescript import vine from '@vinejs/vine' // Pass an object of properties directly (auto-wraps in vine.object) const createUserValidator = vine.create({ name: vine.string().trim().minLength(2), email: vine.string().email(), password: vine.string().minLength(8).confirmed(), // requires password_confirmation role: vine.enum(['user', 'admin', 'moderator'] as const), }) // Reuse across multiple requests — schema is only compiled once const user1 = await createUserValidator.validate({ name: 'Alice', email: 'alice@example.com', password: 'secret123', password_confirmation: 'secret123', role: 'admin', }) // Pass a full schema object instead const schema = vine.object({ title: vine.string() }) const validator = vine.create(schema) const result = await validator.validate({ title: 'Hello' }) ``` -------------------------------- ### vine.create() — Pre-compiled validator Source: https://context7.com/vinejs/vine/llms.txt Pre-compiles a schema or an object of properties into a reusable `VineValidator` instance. This is the recommended pattern for route handlers where the same schema is used on every request, as the schema is only compiled once. ```APIDOC ## vine.create() ### Description Pre-compiles a schema or object properties into a reusable `VineValidator` instance. This is the recommended pattern for route handlers where the same schema is used on every request. ### Method `vine.create(schemaOrProperties: VineSchema | object): VineValidator ### Parameters #### Request Body - **schemaOrProperties** (VineSchema | object) - Required - Either a full Vine schema object or an object containing schema properties (which will be auto-wrapped in `vine.object`). ### Request Example ```typescript import vine from '@vinejs/vine' // Pass an object of properties directly (auto-wraps in vine.object) const createUserValidator = vine.create({ name: vine.string().trim().minLength(2), email: vine.string().email(), password: vine.string().minLength(8).confirmed(), // requires password_confirmation role: vine.enum(['user', 'admin', 'moderator'] as const), }) // Reuse across multiple requests — schema is only compiled once const user1 = await createUserValidator.validate({ name: 'Alice', email: 'alice@example.com', password: 'secret123', password_confirmation: 'secret123', role: 'admin', }) // Pass a full schema object instead const schema = vine.object({ title: vine.string() }) const validator = vine.create(schema) const result = await validator.validate({ title: 'Hello' }) ``` ### Response #### Success Response (200) - **VineValidator** - An instance of VineValidator that can be used to validate data. #### Usage of VineValidator - **validate(data: any): Promise** - Validates data and throws `ValidationError` on failure. - **tryValidate(data: any): Promise<[ValidationError, null] | [null, any]>** - Validates data and returns a tuple `[error, data]`. ``` -------------------------------- ### Create union schemas with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.union() for discriminated unions based on explicit conditions or vine.unionOfTypes() for auto-discrimination by runtime type. The union.if() helper defines conditional branches, and union.else() provides a fallback. ```typescript import vine from '@vinejs/vine' // Discriminated union using vine.union with conditionals const paymentValidator = vine.create({ payment: vine.union([ vine.union.if( (value) => vine.helpers.isObject(value) && (value as any).type === 'card', vine.object({ type: vine.literal('card'), cardNumber: vine.string().creditCard() }) ), vine.union.if( (value) => vine.helpers.isObject(value) && (value as any).type === 'bank', vine.object({ type: vine.literal('bank'), iban: vine.string().iban() }) ), vine.union.else(vine.object({ type: vine.string() })), ]), }) // unionOfTypes — auto-discriminates by JavaScript type const mixedFieldValidator = vine.create({ value: vine.unionOfTypes([ vine.string(), vine.number(), vine.boolean(), ]), }) const r1 = await paymentValidator.validate({ payment: { type: 'card', cardNumber: '4111111111111111' } }) const r2 = await mixedFieldValidator.validate({ value: 42 }) // r2.value: string | number | boolean ``` -------------------------------- ### Create Tuple Schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.tuple() to define schemas for fixed-length arrays where each position has a specific schema. Useful for coordinates or color values. ```typescript import vine from '@vinejs/vine' const coordinateValidator = vine.create({ // [latitude, longitude] location: vine.tuple([ vine.number().range([-90, 90]), // latitude vine.number().range([-180, 180]), // longitude ]), // RGB color [r, g, b] color: vine.tuple([ vine.number().range([0, 255]).withoutDecimals(), vine.number().range([0, 255]).withoutDecimals(), vine.number().range([0, 255]).withoutDecimals(), ]), }) const result = await coordinateValidator.validate({ location: ['40.7128', '-74.0060'], // strings coerced to numbers color: [255, 128, 0], }) // result.location: [number, number] // result.color: [number, number, number] ``` -------------------------------- ### One-shot Validation with vine.validate() Source: https://context7.com/vinejs/vine/llms.txt Validates data against a schema immediately. Prefer vine.create() for performance-critical paths. Throws a ValidationError on failure. ```typescript import vine, { ValidationError } from '@vinejs/vine' const schema = vine.object({ username: vine.string().minLength(3).maxLength(30).alphaNumeric(), email: vine.string().email().normalizeEmail(), age: vine.number().min(18).max(120).withoutDecimals(), }) try { const data = await vine.validate({ schema, data: { username: 'john_doe', email: 'John.Doe@Gmail.com', age: '25' }, }) // data is fully typed: { username: string; email: string; age: number } console.log(data) // { username: 'john_doe', email: 'john.doe@gmail.com', age: 25 } } catch (error) { if (error instanceof ValidationError) { console.log(error.status) // 422 console.log(error.code) // 'E_VALIDATION_ERROR' console.log(error.messages) // [{ field, rule, message }] } } ``` -------------------------------- ### vine.number() Source: https://context7.com/vinejs/vine/llms.txt Creates a `VineNumber` schema. By default coerces string representations of numbers (e.g., form inputs) to actual numbers. Pass `{ strict: true }` to reject string coercion. ```APIDOC ## `vine.number()` — Number schema Creates a `VineNumber` schema. By default coerces string representations of numbers (e.g., form inputs) to actual numbers. Pass `{ strict: true }` to reject string coercion. ```typescript import vine from '@vinejs/vine' const productValidator = vine.create({ price: vine.number().min(0).decimal([0, 2]), // 0–2 decimal places quantity: vine.number().min(0).withoutDecimals(), // integer only discount: vine.number().range([0, 100]), temperature: vine.number().range([-273.15, 1e6]), rating: vine.number().in([1, 2, 3, 4, 5]), score: vine.number({ strict: true }).nonNegative(), // strict: rejects "42" // Signed constraints balance: vine.number(), debit: vine.number().negative(), credit: vine.number().positive(), }) const result = await productValidator.validate({ price: '19.99', // coerced → 19.99 quantity: '3', // coerced → 3 discount: 10, temperature: 25.5, rating: 4, score: 95, balance: -50, debit: -100, credit: 200, }) ``` ``` -------------------------------- ### Create custom validation rules with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.createRule() to define reusable synchronous or asynchronous validation rules. These rules can accept options and be attached to any schema using the .use() method. ```typescript import vine from '@vinejs/vine' // Synchronous custom rule with options const isEvenRule = vine.createRule<{ strict?: boolean }>((value, options, field) => { if (typeof value !== 'number') return if (value % 2 !== 0) { field.report('The {{ field }} field must be an even number', 'isEven', field) } }, { name: 'isEven' }) // Async custom rule (database uniqueness check) const isUniqueEmailRule = vine.createRule<{ table: string }> async (value, { table }, field) => { if (typeof value !== 'string') return // Simulated DB check const exists = await Promise.resolve(false) if (exists) { field.report('The {{ field }} is already registered', 'uniqueEmail', field) } }, { name: 'uniqueEmail', isAsync: true } ) const signupValidator = vine.create({ userId: vine.number().use(isEvenRule({ strict: true })), email: vine.string().email().use(isUniqueEmailRule({ table: 'users' })), }) const result = await signupValidator.validate({ userId: 4, email: 'new@example.com' }) ``` -------------------------------- ### vine.boolean() Source: https://context7.com/vinejs/vine/llms.txt Creates a `VineBoolean` schema. By default coerces HTML form boolean representations (`'1'`, `'true'`, `'on'`, `true`, `1` → `true`; `'0'`, `'false'`, `false`, `0` → `false`). Pass `{ strict: true }` to accept only actual booleans. ```APIDOC ## `vine.boolean()` — Boolean schema Creates a `VineBoolean` schema. By default coerces HTML form boolean representations (`'1'`, `'true'`, `'on'`, `true`, `1` → `true`; `'0'`, `'false'`, `false`, `0` → `false`). Pass `{ strict: true }` to accept only actual booleans. ```typescript import vine from '@vinejs/vine' const settingsValidator = vine.create({ notifications: vine.boolean(), // accepts 'on', '1', true, etc. strictToggle: vine.boolean({ strict: true }), // only true/false termsAccepted: vine.accepted(), // must be truthy (checkbox checked) darkMode: vine.boolean().optional(), }) const result = await settingsValidator.validate({ notifications: 'on', // → true strictToggle: true, termsAccepted: 'on', // accepted // darkMode omitted → undefined }) ``` ``` -------------------------------- ### Create Array Schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.array() to validate elements within an array against a specified schema. Supports constraints like minLength, maxLength, distinct, fixedLength, and compact. ```typescript import vine from '@vinejs/vine' const tagsValidator = vine.create({ tags: vine.array(vine.string().toLowerCase().trim()) .minLength(1) .maxLength(10) .distinct(), // no duplicate tags scores: vine.array(vine.number().min(0).max(100)) .fixedLength(5), // exactly 5 elements contacts: vine.array( vine.object({ email: vine.string().email(), name: vine.string() }) ) .distinct('email') // unique by email field .compact(), // removes null/undefined/empty-string elements files: vine.array(vine.nativeFile().maxSize(5 * 1024 * 1024).mimeTypes(['image/png', 'image/jpeg'])) .notEmpty(), }) const result = await tagsValidator.validate({ tags: [' Node.js ', 'typescript', 'Node.js'], // fails: duplicate 'node.js' after trim scores: [90, 85, 78, 92, 88], contacts: [{ email: 'a@b.com', name: 'Alice' }, { email: 'c@d.com', name: 'Bob' }], files: [], // fails: notEmpty }) ``` -------------------------------- ### vine.tuple() — Tuple schema Source: https://context7.com/vinejs/vine/llms.txt Creates a VineTuple schema for fixed-length arrays where each position has its own schema type. ```APIDOC ## vine.tuple() ### Description Creates a `VineTuple` schema for fixed-length arrays where each position has its own schema type. ### Usage ```typescript import vine from '@vinejs/vine' const coordinateValidator = vine.create({ // [latitude, longitude] location: vine.tuple([ vine.number().range([-90, 90]), // latitude vine.number().range([-180, 180]), // longitude ]), // RGB color [r, g, b] color: vine.tuple([ vine.number().range([0, 255]).withoutDecimals(), vine.number().range([0, 255]).withoutDecimals(), vine.number().range([0, 255]).withoutDecimals(), ]), }) const result = await coordinateValidator.validate({ location: ['40.7128', '-74.0060'], // strings coerced to numbers color: [255, 128, 0], }) // result.location: [number, number] // result.color: [number, number, number] ``` ``` -------------------------------- ### vine.array() — Array schema Source: https://context7.com/vinejs/vine/llms.txt Creates a VineArray schema where every element is validated against the provided element schema. ```APIDOC ## vine.array() ### Description Creates a `VineArray` schema where every element is validated against the provided element schema. ### Usage ```typescript import vine from '@vinejs/vine' const tagsValidator = vine.create({ tags: vine.array(vine.string().toLowerCase().trim()) .minLength(1) .maxLength(10) .distinct(), // no duplicate tags scores: vine.array(vine.number().min(0).max(100)) .fixedLength(5), // exactly 5 elements contacts: vine.array( vine.object({ email: vine.string().email(), name: vine.string() }) ) .distinct('email') // unique by email field .compact(), // removes null/undefined/empty-string elements files: vine.array(vine.nativeFile().maxSize(5 * 1024 * 1024).mimeTypes(['image/png', 'image/jpeg'])) .notEmpty(), }) const result = await tagsValidator.validate({ tags: [' Node.js ', 'typescript', 'Node.js'], // fails: duplicate 'node.js' after trim scores: [90, 85, 78, 92, 88], contacts: [{ email: 'a@b.com', name: 'Alice' }, { email: 'c@d.com', name: 'Bob' }], files: [], // fails: notEmpty }) ``` ``` -------------------------------- ### vine.date() — Date schema Source: https://context7.com/vinejs/vine/llms.txt Creates a VineDate schema that parses strings/numbers into Date objects using dayjs. Supports custom formats, comparison rules, and a global date transformer. ```APIDOC ## vine.date() ### Description Creates a `VineDate` schema that parses strings/numbers into `Date` objects using `dayjs`. Supports custom formats, comparison rules, and a global date transformer. ### Usage ```typescript import vine from '@vinejs/vine' // Optional global transform: all dates become ISO strings // VineDate.transform((value) => value.toISOString()) const eventValidator = vine.create({ // Custom format parsing eventDate: vine.date({ formats: ['DD/MM/YYYY', 'YYYY-MM-DD'] }) .after('today') .before('2030-12-31'), // Timestamp support startAt: vine.date({ formats: ['x'] }), // Unix ms timestamp // ISO 8601 support endAt: vine.date({ formats: ['iso8601'] }).afterField('startAt'), // Relative and field comparisons bookingDate: vine.date().afterOrEqual('today').weekend().optional(), checkIn: vine.date(), checkOut: vine.date().afterField('checkIn', { compare: 'day' }), }) const result = await eventValidator.validate({ eventDate: '25/06/2026', startAt: '1750000000000', endAt: '2026-06-26T10:00:00Z', checkIn: '2026-06-25', checkOut: '2026-06-28', }) // result.eventDate, result.checkIn, etc. are Date objects ``` ``` -------------------------------- ### Define Optional and Nullable Schema Fields Source: https://context7.com/vinejs/vine/llms.txt Use `.optional()` to allow `undefined` and `.nullable()` to allow `null`. These can be combined for fields that accept both. ```typescript import vine from '@vinejs/vine' const profileValidator = vine.create({ name: vine.string(), // required nickname: vine.string().optional(), // string | undefined middleName: vine.string().nullable(), // string | null bio: vine.string().optional().nullable(), // string | undefined | null website: vine.string().url().nullable().optional() // also works in this order }) ``` ```typescript // Optional fields support conditional requirement const contactValidator = vine.create({ phone: vine.string().optional().requiredWhen('email', '!=', ''), email: vine.string().optional().requiredIfMissing('phone'), country: vine.string().optional().requiredIfExists('phone'), address: vine.string().optional().requiredIfAnyExists(['city', 'zip']) }) ``` -------------------------------- ### Create an enum schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.enum() to create schemas for array-based enums, TypeScript native enums, or dynamic enums based on field metadata. The callback for dynamic enums receives the field context. ```typescript import vine from '@vinejs/vine' enum UserRole { ADMIN = 'admin', USER = 'user', MOD = 'moderator', } const permissionsValidator = vine.create({ // Array-based enum status: vine.enum(['active', 'inactive', 'pending'] as const), // TypeScript native enum role: vine.enum(UserRole), // Dynamic enum based on metadata permission: vine.enum((field) => { const allowedPerms: string[] = field.meta.allowedPermissions ?? [] return allowedPerms }), }) const result = await permissionsValidator.validate( { status: 'active', role: 'admin', permission: 'read' }, { meta: { allowedPermissions: ['read', 'write'] } } ) // result.status: 'active' | 'inactive' | 'pending' // result.role: UserRole ``` -------------------------------- ### Create Object Schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.object() to define nested object schemas with property-level validation. Supports transformations like toCamelCase, partial schemas, and picking/omitting fields. ```typescript import vine from '@vinejs/vine' const addressSchema = vine.object({ street: vine.string().minLength(5), city: vine.string(), country: vine.enum(['US', 'CA', 'GB'] as const), zip: vine.string().postalCode({ countryCode: ['US', 'CA', 'GB'] }), }) const userSchema = vine.object({ first_name: vine.string(), last_name: vine.string(), email: vine.string().email(), address: addressSchema, meta: vine.object({}).allowUnknownProperties(), // pass-through extra keys }) // .toCamelCase() converts snake_case keys to camelCase in the output const camelSchema = userSchema.toCamelCase() // Output type: { firstName: string; lastName: string; email: string; ... } // .partial() makes all (or specific) properties optional — useful for PATCH routes const updateSchema = userSchema.partial(['first_name', 'last_name']) // .pick() / .omit() create sub-schemas const publicFields = userSchema.pick(['first_name', 'email']) const withoutEmail = userSchema.omit(['email']) const validator = vine.create(userSchema) const result = await validator.validate({ first_name: 'Jane', last_name: 'Doe', email: 'jane@example.com', address: { street: '123 Main St', city: 'New York', country: 'US', zip: '10001' }, }) ``` -------------------------------- ### vine.validate() — One-shot validation Source: https://context7.com/vinejs/vine/llms.txt Validates data against a schema immediately. This method compiles the schema internally on every call, making it less performant for repeated validations compared to vine.create(). It throws a ValidationError when validation fails. ```APIDOC ## vine.validate() ### Description Validates data against a schema immediately. Compiles the schema internally on every call, so prefer `vine.create()` for hot paths. Throws a `ValidationError` when validation fails. ### Method `vine.validate(options: { schema: VineSchema, data: any }): Promise ### Parameters #### Request Body - **schema** (VineSchema) - Required - The schema to validate against. - **data** (any) - Required - The data to validate. ### Request Example ```typescript import vine, { ValidationError } from '@vinejs/vine' const schema = vine.object({ username: vine.string().minLength(3).maxLength(30).alphaNumeric(), email: vine.string().email().normalizeEmail(), age: vine.number().min(18).max(120).withoutDecimals(), }) try { const data = await vine.validate({ schema, data: { username: 'john_doe', email: 'John.Doe@Gmail.com', age: '25' }, }) // data is fully typed: { username: string; email: string; age: number } console.log(data) // { username: 'john_doe', email: 'john.doe@gmail.com', age: 25 } } catch (error) { if (error instanceof ValidationError) { console.log(error.status) // 422 console.log(error.code) // 'E_VALIDATION_ERROR' console.log(error.messages) // [{ field, rule, message }] } } ``` ### Response #### Success Response (200) - **data** (any) - The validated and transformed data. #### Error Response - **ValidationError** - Thrown when validation fails. Contains `status`, `code`, and `messages` properties. ``` -------------------------------- ### vine.object() — Object schema Source: https://context7.com/vinejs/vine/llms.txt Creates a VineObject schema with property-level validation. Supports camelCase conversion, merging conditional groups, partial schemas, and picking/omitting fields. ```APIDOC ## vine.object() ### Description Creates a `VineObject` schema with property-level validation. Supports camelCase conversion, merging conditional groups, partial schemas, and picking/omitting fields. ### Usage ```typescript import vine from '@vinejs/vine' const addressSchema = vine.object({ street: vine.string().minLength(5), city: vine.string(), country: vine.enum(['US', 'CA', 'GB'] as const), zip: vine.string().postalCode({ countryCode: ['US', 'CA', 'GB'] }), }) const userSchema = vine.object({ first_name: vine.string(), last_name: vine.string(), email: vine.string().email(), address: addressSchema, meta: vine.object({}).allowUnknownProperties(), // pass-through extra keys }) // .toCamelCase() converts snake_case keys to camelCase in the output const camelSchema = userSchema.toCamelCase() // Output type: { firstName: string; lastName: string; email: string; ... } // .partial() makes all (or specific) properties optional — useful for PATCH routes const updateSchema = userSchema.partial(['first_name', 'last_name']) // .pick() / .omit() create sub-schemas const publicFields = userSchema.pick(['first_name', 'email']) const withoutEmail = userSchema.omit(['email']) const validator = vine.create(userSchema) const result = await validator.validate({ first_name: 'Jane', last_name: 'Doe', email: 'jane@example.com', address: { street: '123 Main St', city: 'New York', country: 'US', zip: '10001' }, }) ``` ``` -------------------------------- ### vine.withMetaData() Source: https://context7.com/vinejs/vine/llms.txt Adds strongly-typed metadata to the validation context, available inside custom rules via `field.meta`. Optionally accepts a metadata validator to enforce runtime constraints on the meta object. ```APIDOC ## `vine.withMetaData()` — Typed metadata context Adds strongly-typed metadata to the validation context, available inside custom rules via `field.meta`. Optionally accepts a metadata validator to enforce runtime constraints on the meta object. ```typescript import vine from '@vinejs/vine' // Define a unique rule that checks database uniqueness using metadata const isUnique = vine.createRule(async (value: unknown, _, field) => { const { db, table } = field.meta as { db: any; table: string } const exists = await db.exists(table, String(value)) if (exists) { field.report('The {{ field }} is already taken', 'unique', field) } }) const registerValidator = vine .withMetaData<{ db: any; table: string }>((meta) => { if (!meta.db) throw new Error('db is required in meta') }) .create({ username: vine.string().use(isUnique()), email: vine.string().email(), }) // meta is required and typed const data = await registerValidator.validate( { username: 'alice', email: 'alice@example.com' }, { meta: { db: myDatabase, table: 'users' } } ) ``` ``` -------------------------------- ### Create a literal schema with Vine.js Source: https://context7.com/vinejs/vine/llms.txt Use vine.literal() to validate that a value exactly matches a specific primitive value. This is useful for ensuring exact matches for constants, versions, or specific states. ```typescript import vine from '@vinejs/vine' const ackValidator = vine.create({ version: vine.literal(1), type: vine.literal('ping'), active: vine.literal(true), deleted: vine.literal(null), }) const result = await ackValidator.validate({ version: 1, type: 'ping', active: true, deleted: null }) // result.version: 1 (not number — the literal type 1) ``` -------------------------------- ### Convert empty strings to null for HTML forms Source: https://context7.com/vinejs/vine/llms.txt Set `vine.convertEmptyStringsToNull = true` to automatically convert empty strings from form submissions to `null`. This is useful for fields that are nullable or optional. ```typescript import vine from '@vinejs/vine' vine.convertEmptyStringsToNull = true const formValidator = vine.create({ name: vine.string(), nickname: vine.string().nullable().optional(), // empty string → null → undefined (optional) website: vine.string().url().nullable(), // empty string → null }) const result = await formValidator.validate({ name: 'Alice', nickname: '', // → null → satisfies nullable().optional() website: '', // → null }) // result.website === null ``` -------------------------------- ### Add Typed Metadata with vine.withMetaData() Source: https://context7.com/vinejs/vine/llms.txt Use `vine.withMetaData()` to add strongly-typed metadata to the validation context. This metadata is accessible within custom rules via `field.meta`. Optionally, provide a metadata validator to enforce runtime constraints on the meta object. ```typescript import vine from '@vinejs/vine' // Define a unique rule that checks database uniqueness using metadata const isUnique = vine.createRule(async (value: unknown, _, field) => { const { db, table } = field.meta as { db: any; table: string } const exists = await db.exists(table, String(value)) if (exists) { field.report('The {{ field }} is already taken', 'unique', field) } }) const registerValidator = vine .withMetaData<{ db: any; table: string }>((meta) => { if (!meta.db) throw new Error('db is required in meta') }) .create({ username: vine.string().use(isUnique()), email: vine.string().email(), }) // meta is required and typed const data = await registerValidator.validate( { username: 'alice', email: 'alice@example.com' }, { meta: { db: myDatabase, table: 'users' } } ) ``` -------------------------------- ### Unit test validation rules with factories Source: https://context7.com/vinejs/vine/llms.txt Use `ValidatorFactory` and `FieldFactory` from `@vinejs/vine/factories` to unit test individual validation rules in isolation. This avoids the need to set up full schemas for testing. ```typescript import { validator, fieldContext } from '@vinejs/vine/factories' import vine from '@vinejs/vine' // Create a standalone rule to test const isSlug = vine.createRule((value, _, field) => { if (typeof value !== 'string' || !/^[a-z0-9-]+$/.test(value)) { field.report('The {{ field }} must be a valid slug', 'slug', field) } }) // Build a fake field context const fakeField = fieldContext.create('username', 'hello world', { data: { username: 'hello world' }, }) // Run the rule in isolation await validator.execute(isSlug(), 'hello world', fakeField) // fakeField.errors → [{ message: 'The username must be a valid slug', ... }] await validator.execute(isSlug(), 'hello-world', fieldContext.create('username', 'hello-world', {})) // No errors ``` -------------------------------- ### Validate Numeric Data with vine.number() Source: https://context7.com/vinejs/vine/llms.txt The `vine.number()` schema handles numeric validation and coercion. By default, it coerces string representations of numbers to actual numbers. Use `{ strict: true }` to reject string coercion. Supports range, decimal place, integer, and specific value constraints. ```typescript import vine from '@vinejs/vine' const productValidator = vine.create({ price: vine.number().min(0).decimal([0, 2]), // 0–2 decimal places quantity: vine.number().min(0).withoutDecimals(), // integer only discount: vine.number().range([0, 100]), temperature: vine.number().range([-273.15, 1e6]), rating: vine.number().in([1, 2, 3, 4, 5]), score: vine.number({ strict: true }).nonNegative(), // strict: rejects "42" // Signed constraints balance: vine.number(), debit: vine.number().negative(), credit: vine.number().positive(), }) const result = await productValidator.validate({ price: '19.99', // coerced → 19.99 quantity: '3', // coerced → 3 discount: 10, temperature: 25.5, rating: 4, score: 95, balance: -50, debit: -100, credit: 200, }) ``` -------------------------------- ### Validate String Formats with vine.string() Source: https://context7.com/vinejs/vine/llms.txt The `vine.string()` schema provides extensive built-in rules for validating and transforming string data. It supports length constraints, character set validation, email and URL formatting, pattern matching, identity string formats (UUID, ULID, JWT), and various transformations like trimming and case conversion. ```typescript import vine from '@vinejs/vine' const profileValidator = vine.create({ // Basic constraints username: vine.string().minLength(3).maxLength(20).alphaNumeric({ allowUnderscores: true }), bio: vine.string().maxLength(500).optional(), // Email with normalization email: vine.string().email().normalizeEmail({ gmail_remove_dots: true }), // URL with normalization website: vine.string().url({ require_protocol: true }).normalizeUrl({ stripWWW: true }).optional(), // Pattern matching postalCode: vine.string().postalCode({ countryCode: ['US', 'CA'] }), phone: vine.string().mobile({ locale: ['en-US'], strictMode: true }), // Identity strings apiKey: vine.string().uuid({ version: [4] }), sessionId: vine.string().ulid(), token: vine.string().jwt(), // Transformations slug: vine.string().toLowerCase().trim(), displayName: vine.string().trim().escape(), // HTML-encodes < > & etc. // Conditional fields promoCode: vine.string().optional().requiredWhen('isPro', '=', true), }) ``` -------------------------------- ### vine.tryValidate() — Non-throwing validation Source: https://context7.com/vinejs/vine/llms.txt Returns a `[error, null] | [null, data]` tuple instead of throwing an error. This is useful when validation failure is an expected part of the code flow, allowing for cleaner error handling without try-catch blocks. ```APIDOC ## vine.tryValidate() ### Description Returns a `[error, null] | [null, data]` tuple instead of throwing. Useful when validation failure is an expected code path. ### Method `vine.tryValidate(data: any): Promise<[ValidationError, null] | [null, any]> ### Parameters #### Request Body - **data** (any) - Required - The data to validate. ### Request Example ```typescript import vine from '@vinejs/vine' const loginValidator = vine.create({ email: vine.string().email(), password: vine.string().minLength(6), }) async function handleLogin(body: unknown) { const [error, data] = await loginValidator.tryValidate(body) if (error) { // error.messages is an array of { field, rule, message } return { success: false, errors: error.messages } } // data is typed: { email: string; password: string } return { success: true, email: data.email } } const result = await handleLogin({ email: 'bad', password: '123' }) console.log(result.errors) // [ // { field: 'email', rule: 'email', message: 'The email field must be a valid email address' }, // { field: 'password', rule: 'minLength', message: 'The password field must have at least 6 characters' } // ] ``` ### Response #### Success Response - **[null, data]** - A tuple where the first element is null and the second element is the validated data. #### Error Response - **[ValidationError, null]** - A tuple where the first element is a `ValidationError` object and the second element is null. ``` -------------------------------- ### Validate Boolean Values with vine.boolean() Source: https://context7.com/vinejs/vine/llms.txt The `vine.boolean()` schema validates boolean values. It can coerce common HTML form representations of booleans (e.g., 'on', 'true', '1' to `true`; 'false', '0' to `false`). Use `{ strict: true }` to accept only actual boolean types. `vine.accepted()` specifically checks for truthy values, suitable for checkboxes. ```typescript import vine from '@vinejs/vine' const settingsValidator = vine.create({ notifications: vine.boolean(), // accepts 'on', '1', true, etc. strictToggle: vine.boolean({ strict: true }), // only true/false termsAccepted: vine.accepted(), // must be truthy (checkbox checked) darkMode: vine.boolean().optional(), }) const result = await settingsValidator.validate({ notifications: 'on', // → true strictToggle: true, termsAccepted: 'on', // accepted // darkMode omitted → undefined }) ``` -------------------------------- ### Export validator as JSON Schema Draft 7 Source: https://context7.com/vinejs/vine/llms.txt Use the `toJSONSchema()` method to export a compiled validator into a JSON Schema Draft 7 representation. The schema is computed lazily and cached for performance. ```typescript import vine from '@vinejs/vine' const validator = vine.create({ name: vine.string().minLength(2).maxLength(50), age: vine.number().min(0).max(150).withoutDecimals().optional(), email: vine.string().email().nullable(), tags: vine.array(vine.string()).minLength(1).maxLength(10), }) const jsonSchema = validator.toJSONSchema() console.log(JSON.stringify(jsonSchema, null, 2)) // { // "type": "object", // "properties": { // "name": { "type": "string", "minLength": 2, "maxLength": 50 }, // "age": { "type": ["integer", "null"] }, // "email": { "type": ["string", "null"], "format": "email" }, // "tags": { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 } // }, // "required": ["name", "email", "tags"], // "additionalProperties": false // } ``` -------------------------------- ### Non-throwing Validation with vine.tryValidate() Source: https://context7.com/vinejs/vine/llms.txt Returns a [error, null] | [null, data] tuple instead of throwing. Useful when validation failure is an expected code path. ```typescript import vine from '@vinejs/vine' const loginValidator = vine.create({ email: vine.string().email(), password: vine.string().minLength(6), }) async function handleLogin(body: unknown) { const [error, data] = await loginValidator.tryValidate(body) if (error) { // error.messages is an array of { field, rule, message } return { success: false, errors: error.messages } } // data is typed: { email: string; password: string } return { success: true, email: data.email } } const result = await handleLogin({ email: 'bad', password: '123' }) console.log(result.errors) // [ // { field: 'email', rule: 'email', message: 'The email field must be a valid email address' }, // { field: 'password', rule: 'minLength', message: 'The password field must have at least 6 characters' } // ] ```