Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vinejs/vine

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vinejs/vine - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

3

build/factories/field.d.ts
import { ErrorReporterContract } from '@vinejs/compiler/types';
import type { FieldContext, MessagesProviderContact } from '../src/types.js';
/**
* Exposes API to create a dummy field context
*/
export declare class FieldFactory {

@@ -4,0 +7,0 @@ create(fieldName: string, value: any, messagesProvider?: MessagesProviderContact, errorReporter?: ErrorReporterContract): {

@@ -0,4 +1,15 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from '../src/vine/helpers.js';
import { SimpleErrorReporter } from '../src/reporters/simple_error_reporter.js';
import { SimpleMessagesProvider } from '../src/messages_provider/simple_messages_provider.js';
/**
* Exposes API to create a dummy field context
*/
export class FieldFactory {

@@ -5,0 +16,0 @@ create(fieldName, value, messagesProvider, errorReporter) {

import { FieldFactory } from './field.js';
import { ValidatorFactory } from './validator.js';
/**
* Validator factory is used for unit testing validation
* rules.
*/
export declare const validator: ValidatorFactory;
export declare const fieldContext: FieldFactory;

@@ -0,4 +1,16 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { FieldFactory } from './field.js';
import { ValidatorFactory } from './validator.js';
/**
* Validator factory is used for unit testing validation
* rules.
*/
export const validator = new ValidatorFactory();
export const fieldContext = new FieldFactory();
import type { FieldContext, Validation } from '../src/types.js';
import { SimpleErrorReporter } from '../src/reporters/simple_error_reporter.js';
/**
* Exposes APIs for writing validation assertions
*/
declare class ValidationResult {
#private;
constructor(outputValue: any, reporter: SimpleErrorReporter);
/**
* Returns the validation result output
*/
getOutput(): any;
/**
* Returns an array of errors reported to the
* error reporter
*/
getErrors(): {

@@ -14,16 +24,49 @@ message: string;

}[];
/**
* Assert one or more validation errors have occurred
*/
assertSucceeded(): void;
/**
* Assert the output value of validation. The output value is
* same as the input value, unless "mutate" method is called
*/
assertOutput(expectedOutput: any): void;
/**
* Assert one or more validation errors have occurred
*/
assertFailed(): void;
/**
* Assert the number of errors have occurred
*/
assertErrorsCount(count: number): void;
/**
* Assert error messages to include a given error message
*/
assertError(message: string): void;
}
/**
* Validator factory exposes the API to execute validations
* during tests
*/
export declare class ValidatorFactory {
#private;
constructor(field?: Partial<FieldContext>, bail?: boolean);
/**
* Define field context for the validation
*/
withContext(field: Partial<FieldContext>): ValidatorFactory;
/**
* Toggle bail mode for the validation
*/
bail(state: boolean): ValidatorFactory;
/**
* Executes a validation against the provided value
*/
execute(validation: Validation<any> | Validation<any>[], value: any): ValidationResult;
/**
* Executes an async validation against the provided
* value
*/
executeAsync(validation: Validation<any> | Validation<any>[], value: any): Promise<ValidationResult>;
}
export {};

@@ -0,4 +1,15 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { AssertionError, deepEqual } from 'node:assert';
import { FieldFactory } from './field.js';
import { SimpleErrorReporter } from '../src/reporters/simple_error_reporter.js';
/**
* Exposes APIs for writing validation assertions
*/
class ValidationResult {

@@ -11,2 +22,5 @@ #outputValue;

}
/**
* Creates an assertion error instance
*/
#assertionError(options) {

@@ -17,8 +31,18 @@ const assertion = new AssertionError(options);

}
/**
* Returns the validation result output
*/
getOutput() {
return this.#outputValue;
}
/**
* Returns an array of errors reported to the
* error reporter
*/
getErrors() {
return this.#reporter.errors;
}
/**
* Assert one or more validation errors have occurred
*/
assertSucceeded() {

@@ -34,5 +58,12 @@ if (this.#reporter.hasErrors) {

}
/**
* Assert the output value of validation. The output value is
* same as the input value, unless "mutate" method is called
*/
assertOutput(expectedOutput) {
deepEqual(this.#outputValue, expectedOutput);
}
/**
* Assert one or more validation errors have occurred
*/
assertFailed() {

@@ -47,2 +78,5 @@ if (!this.#reporter.hasErrors) {

}
/**
* Assert the number of errors have occurred
*/
assertErrorsCount(count) {

@@ -61,2 +95,5 @@ const errorsCount = this.#reporter.errors.length;

}
/**
* Assert error messages to include a given error message
*/
assertError(message) {

@@ -76,2 +113,6 @@ const messages = this.#reporter.errors.map((e) => e.message);

}
/**
* Validator factory exposes the API to execute validations
* during tests
*/
export class ValidatorFactory {

@@ -84,11 +125,24 @@ #field;

}
/**
* Creates an instance of the error reporter required
* to report errors.
*/
#getReporter() {
return new SimpleErrorReporter();
}
/**
* Define field context for the validation
*/
withContext(field) {
return new ValidatorFactory(field, this.#bail);
}
/**
* Toggle bail mode for the validation
*/
bail(state) {
return new ValidatorFactory(this.#field, state);
}
/**
* Executes a validation against the provided value
*/
execute(validation, value) {

@@ -112,2 +166,6 @@ const errorReporter = this.#getReporter();

}
/**
* Executes an async validation against the provided
* value
*/
async executeAsync(validation, value) {

@@ -114,0 +172,0 @@ const errorReporter = this.#getReporter();

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Vine } from './src/vine/main.js';

@@ -2,0 +10,0 @@ export { Vine };

@@ -0,1 +1,4 @@

/**
* Collection of default error messages to use
*/
export declare const messages: {

@@ -59,4 +62,7 @@ required: string;

};
/**
* Collection of default fields
*/
export declare const fields: {
'': string;
};

@@ -0,1 +1,12 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Collection of default error messages to use
*/
export const messages = {

@@ -59,4 +70,7 @@ 'required': 'The {{ field }} field must be defined',

};
/**
* Collection of default fields
*/
export const fields = {
'': 'data',
};
import { ValidationError } from './validation_error.js';
/**
* Create an instance of validation error
*/
export declare const E_VALIDATION_ERROR: typeof ValidationError;

@@ -0,2 +1,13 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { ValidationError } from './validation_error.js';
/**
* Create an instance of validation error
*/
export const E_VALIDATION_ERROR = ValidationError;

@@ -0,4 +1,15 @@

/**
* Validation error is a superset of Error class with validation
* error messages
*/
export declare class ValidationError extends Error {
messages: any;
/**
* Http status code for the validation error
*/
status: number;
/**
* Internal code for handling the validation error
* exception
*/
code: string;

@@ -5,0 +16,0 @@ constructor(messages: any, options?: ErrorOptions);

@@ -0,4 +1,23 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Validation error is a superset of Error class with validation
* error messages
*/
export class ValidationError extends Error {
messages;
/**
* Http status code for the validation error
*/
status = 422;
/**
* Internal code for handling the validation error
* exception
*/
code = 'E_VALIDATION_ERROR';

@@ -5,0 +24,0 @@ constructor(messages, options) {

import type { FieldContext, ValidationFields, ValidationMessages, MessagesProviderContact } from '../types.js';
/**
* Default messages provider performs messages lookup inside
* a collection of key-value pair.
*/
export declare class SimpleMessagesProvider implements MessagesProviderContact {
#private;
constructor(messages: ValidationMessages, fields: ValidationFields);
/**
* Returns a validation message for a given field + rule.
*/
getMessage(rawMessage: string, rule: string, field: FieldContext, args?: Record<string, any>): string;
}

@@ -0,1 +1,13 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Default messages provider performs messages lookup inside
* a collection of key-value pair.
*/
export class SimpleMessagesProvider {

@@ -8,2 +20,5 @@ #messages;

}
/**
* Interpolates place holders within error messages
*/
#interpolate(message, data) {

@@ -26,4 +41,10 @@ if (!message.includes('{{')) {

}
/**
* Returns a validation message for a given field + rule.
*/
getMessage(rawMessage, rule, field, args) {
const fieldName = this.#fields[field.name] || field.name;
/**
* 1st priority is given to the field messages
*/
const fieldMessage = this.#messages[`${field.wildCardPath}.${rule}`];

@@ -36,2 +57,5 @@ if (fieldMessage) {

}
/**
* 2nd priority is for rule messages
*/
const ruleMessage = this.#messages[rule];

@@ -44,2 +68,5 @@ if (ruleMessage) {

}
/**
* Fallback to raw message
*/
return this.#interpolate(rawMessage, {

@@ -46,0 +73,0 @@ field: fieldName,

import { ValidationError } from '../errors/validation_error.js';
import type { ErrorReporterContract, FieldContext } from '../types.js';
/**
* Shape of the error message collected by the SimpleErrorReporter
*/
type SimpleError = {

@@ -10,8 +13,30 @@ message: string;

};
/**
* Simple error reporter collects error messages as an array of object.
* Each object has following properties.
*
* - message: string
* - field: string
* - rule: string
* - index?: number (in case of an array member)
* - args?: Record<string, any>
*/
export declare class SimpleErrorReporter implements ErrorReporterContract {
/**
* Boolean to know one or more errors have been reported
*/
hasErrors: boolean;
/**
* Collection of errors
*/
errors: SimpleError[];
/**
* Report an error.
*/
report(message: string, rule: string, field: FieldContext, meta?: Record<string, any> | undefined): void;
/**
* Returns an instance of the validation error
*/
createError(): ValidationError;
}
export {};

@@ -0,5 +1,32 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { E_VALIDATION_ERROR } from '../errors/main.js';
/**
* Simple error reporter collects error messages as an array of object.
* Each object has following properties.
*
* - message: string
* - field: string
* - rule: string
* - index?: number (in case of an array member)
* - args?: Record<string, any>
*/
export class SimpleErrorReporter {
/**
* Boolean to know one or more errors have been reported
*/
hasErrors = false;
/**
* Collection of errors
*/
errors = [];
/**
* Report an error.
*/
report(message, rule, field, meta) {

@@ -20,2 +47,5 @@ const error = {

}
/**
* Returns an instance of the validation error
*/
createError() {

@@ -22,0 +52,0 @@ return new E_VALIDATION_ERROR(this.errors);

import { BaseLiteralType } from '../base/literal.js';
import type { FieldOptions, Validation } from '../../types.js';
/**
* VineAccepted represents a checkbox input that must be checked
*/
export declare class VineAccepted extends BaseLiteralType<true, true> {
/**
* Default collection of accepted rules
*/
static rules: {

@@ -8,3 +14,7 @@ accepted: (options?: undefined) => Validation<undefined>;

constructor(options?: Partial<FieldOptions>, validations?: Validation<any>[]);
/**
* Clones the VineAccepted schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,4 +1,18 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { acceptedRule } from './rules.js';
import { BaseLiteralType } from '../base/literal.js';
/**
* VineAccepted represents a checkbox input that must be checked
*/
export class VineAccepted extends BaseLiteralType {
/**
* Default collection of accepted rules
*/
static rules = {

@@ -10,2 +24,6 @@ accepted: acceptedRule,

}
/**
* Clones the VineAccepted schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -12,0 +30,0 @@ return new VineAccepted(this.cloneOptions(), this.cloneValidations());

@@ -0,1 +1,10 @@

/**
* Validates the value to be present and have one of
* the following values.
*
* - "on"
* - "1"
* - "yes"
* - "true"
*/
export declare const acceptedRule: (options?: undefined) => import("../../types.js").Validation<undefined>;

@@ -0,4 +1,21 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { messages } from '../../defaults.js';
import { createRule } from '../../vine/create_rule.js';
const ACCEPTED_VALUES = ['on', '1', 'yes', 'true', true, 1];
/**
* Validates the value to be present and have one of
* the following values.
*
* - "on"
* - "1"
* - "yes"
* - "true"
*/
export const acceptedRule = createRule((value, _, field) => {

@@ -5,0 +22,0 @@ if (!ACCEPTED_VALUES.includes(value)) {

import { BaseLiteralType } from '../base/literal.js';
import type { FieldOptions, Validation } from '../../types.js';
/**
* VineAny represents a value that can be anything
*/
export declare class VineAny extends BaseLiteralType<any, any> {
constructor(options?: Partial<FieldOptions>, validations?: Validation<any>[]);
/**
* Clones the VineAny schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,2 +1,13 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { BaseLiteralType } from '../base/literal.js';
/**
* VineAny represents a value that can be anything
*/
export class VineAny extends BaseLiteralType {

@@ -6,2 +17,6 @@ constructor(options, validations) {

}
/**
* Clones the VineAny schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -8,0 +23,0 @@ return new VineAny(this.cloneOptions(), this.cloneValidations());

@@ -5,4 +5,11 @@ import { RefsStore, ArrayNode } from '@vinejs/compiler/types';

import type { FieldOptions, ParserOptions, SchemaTypes, Validation } from '../../types.js';
/**
* VineArray represents an array schema type in the validation
* pipeline
*/
export declare class VineArray<Schema extends SchemaTypes> extends BaseType<Schema[typeof OTYPE][], Schema[typeof COTYPE][]> {
#private;
/**
* Default collection of array rules
*/
static rules: {

@@ -32,13 +39,45 @@ compact: (options?: undefined) => Validation<undefined>;

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of array type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(schema: Schema, options?: FieldOptions, validations?: Validation<any>[]);
/**
* Enforce a minimum length on an array field
*/
minLength(expectedLength: number): this;
/**
* Enforce a maximum length on an array field
*/
maxLength(expectedLength: number): this;
/**
* Enforce a fixed length on an array field
*/
fixedLength(expectedLength: number): this;
/**
* Ensure the array is not empty
*/
notEmpty(): this;
/**
* Ensure array elements are distinct/unique
*/
distinct(fields?: string | string[]): this;
/**
* Removes empty strings, null and undefined values from the array
*/
compact(): this;
/**
* Clones the VineArray schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
/**
* Compiles to array data type
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): ArrayNode;
}

@@ -0,1 +1,9 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';

@@ -5,3 +13,10 @@ import { BaseType } from '../base/main.js';

import { compactRule, notEmptyRule, distinctRule, minLengthRule, maxLengthRule, fixedLengthRule, } from './rules.js';
/**
* VineArray represents an array schema type in the validation
* pipeline
*/
export class VineArray extends BaseType {
/**
* Default collection of array rules
*/
static rules = {

@@ -16,3 +31,10 @@ compact: compactRule,

#schema;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.array';
/**
* Checks if the value is of array type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -25,23 +47,48 @@ return Array.isArray(value);

}
/**
* Enforce a minimum length on an array field
*/
minLength(expectedLength) {
return this.use(minLengthRule({ min: expectedLength }));
}
/**
* Enforce a maximum length on an array field
*/
maxLength(expectedLength) {
return this.use(maxLengthRule({ max: expectedLength }));
}
/**
* Enforce a fixed length on an array field
*/
fixedLength(expectedLength) {
return this.use(fixedLengthRule({ size: expectedLength }));
}
/**
* Ensure the array is not empty
*/
notEmpty() {
return this.use(notEmptyRule());
}
/**
* Ensure array elements are distinct/unique
*/
distinct(fields) {
return this.use(distinctRule({ fields }));
}
/**
* Removes empty strings, null and undefined values from the array
*/
compact() {
return this.use(compactRule());
}
/**
* Clones the VineArray schema type. The applied options
* and validations are copied to the new instance
*/
clone() {
return new VineArray(this.#schema.clone(), this.cloneOptions(), this.cloneValidations());
}
/**
* Compiles to array data type
*/
[PARSE](propertyName, refs, options) {

@@ -48,0 +95,0 @@ return {

@@ -0,1 +1,4 @@

/**
* Enforce a minimum length on an array field
*/
export declare const minLengthRule: (options: {

@@ -6,2 +9,5 @@ min: number;

}>;
/**
* Enforce a maximum length on an array field
*/
export declare const maxLengthRule: (options: {

@@ -12,2 +18,5 @@ max: number;

}>;
/**
* Enforce a fixed length on an array field
*/
export declare const fixedLengthRule: (options: {

@@ -18,3 +27,9 @@ size: number;

}>;
/**
* Ensure the array is not empty
*/
export declare const notEmptyRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Ensure array elements are distinct/unique
*/
export declare const distinctRule: (options: {

@@ -25,2 +40,5 @@ fields?: string | string[] | undefined;

}>;
/**
* Removes empty strings, null and undefined values from the array
*/
export declare const compactRule: (options?: undefined) => import("../../types.js").Validation<undefined>;

@@ -0,8 +1,25 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from '../../vine/helpers.js';
import { messages } from '../../defaults.js';
import { createRule } from '../../vine/create_rule.js';
/**
* Enforce a minimum length on an array field
*/
export const minLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an array if the field is valid.
*/
if (value.length < options.min) {

@@ -12,6 +29,15 @@ field.report(messages['array.minLength'], 'array.minLength', field, options);

});
/**
* Enforce a maximum length on an array field
*/
export const maxLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an array if the field is valid.
*/
if (value.length > options.max) {

@@ -21,6 +47,15 @@ field.report(messages['array.maxLength'], 'array.maxLength', field, options);

});
/**
* Enforce a fixed length on an array field
*/
export const fixedLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an array if the field is valid.
*/
if (value.length !== options.size) {

@@ -30,6 +65,15 @@ field.report(messages['array.fixedLength'], 'array.fixedLength', field, options);

});
/**
* Ensure the array is not empty
*/
export const notEmptyRule = createRule((value, _, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an array if the field is valid.
*/
if (value.length <= 0) {

@@ -39,6 +83,15 @@ field.report(messages.notEmpty, 'notEmpty', field);

});
/**
* Ensure array elements are distinct/unique
*/
export const distinctRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an array if the field is valid.
*/
if (!helpers.isDistinct(value, options.fields)) {

@@ -48,3 +101,9 @@ field.report(messages.distinct, 'distinct', field, options);

});
/**
* Removes empty strings, null and undefined values from the array
*/
export const compactRule = createRule((value, _, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -51,0 +110,0 @@ return;

import type { LiteralNode, RefsStore } from '@vinejs/compiler/types';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
import type { Parser, Validation, RuleBuilder, Transformer, FieldOptions, ParserOptions, ConstructableSchema } from '../../types.js';
/**
* Base schema type with only modifiers applicable on all the schema types.
*/
declare abstract class BaseModifiersType<Output, CamelCaseOutput> implements ConstructableSchema<Output, CamelCaseOutput> {
/**
* Each subtype should implement the compile method that returns
* one of the known compiler nodes
*/
abstract [PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): LiteralNode;
/**
* The child class must implement the clone method
*/
abstract clone(): this;
/**
* The output value of the field. The property points to a type only
* and not the real value.
*/
[OTYPE]: Output;
[COTYPE]: CamelCaseOutput;
/**
* Mark the field under validation as optional. An optional
* field allows both null and undefined values.
*/
optional(): OptionalModifier<this>;
/**
* Mark the field under validation to be null. The null value will
* be written to the output as well.
*
* If `optional` and `nullable` are used together, then both undefined
* and null values will be allowed.
*/
nullable(): NullableModifier<this>;
/**
* Apply transform on the final validated value. The transform method may
* convert the value to any new datatype.
*/
transform<TransformedOutput>(transformer: Transformer<this, TransformedOutput>): TransformModifier<this, TransformedOutput>;
}
/**
* Modifies the schema type to allow null values
*/
declare class NullableModifier<Schema extends BaseModifiersType<any, any>> extends BaseModifiersType<Schema[typeof OTYPE] | null, Schema[typeof COTYPE] | null> {
#private;
constructor(parent: Schema);
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the nullable modifier
*/
clone(): this;
/**
* Compiles to compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): LiteralNode;
}
/**
* Modifies the schema type to allow undefined values
*/
declare class OptionalModifier<Schema extends BaseModifiersType<any, any>> extends BaseModifiersType<Schema[typeof OTYPE] | undefined, Schema[typeof COTYPE] | undefined> {
#private;
constructor(parent: Schema);
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the optional modifier
*/
clone(): this;
/**
* Compiles to compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): LiteralNode;
}
/**
* Modifies the schema type to allow custom transformed values
*/
declare class TransformModifier<Schema extends BaseModifiersType<any, any>, Output> extends BaseModifiersType<Output, Output> {
#private;
/**
* The output value of the field. The property points to a type only
* and not the real value.
*/
[OTYPE]: Output;
[COTYPE]: Output;
constructor(transform: Transformer<Schema, Output>, parent: Schema);
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the transform modifier.
*/
clone(): this;
/**
* Compiles to compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): LiteralNode;
}
/**
* The base type for creating a custom literal type. Literal type
* is a schema type that has no children elements.
*/
export declare abstract class BaseLiteralType<Output, CamelCaseOutput> extends BaseModifiersType<Output, CamelCaseOutput> {
/**
* The child class must implement the clone method
*/
abstract clone(): this;
/**
* Field options
*/
protected options: FieldOptions;
/**
* Set of validations to run
*/
protected validations: Validation<any>[];
constructor(options?: Partial<FieldOptions>, validations?: Validation<any>[]);
/**
* Shallow clones the validations. Since, there are no API's to mutate
* the validation options, we can safely copy them by reference.
*/
protected cloneValidations(): Validation<any>[];
/**
* Shallow clones the options
*/
protected cloneOptions(): FieldOptions;
/**
* Compiles validations
*/
protected compileValidations(refs: RefsStore): {

@@ -45,7 +131,23 @@ ruleFnId: `ref://${number}`;

}[];
/**
* Define a method to parse the input value. The method
* is invoked before any validation and hence you must
* perform type-checking to know the value you are
* working it.
*/
parse(callback: Parser): this;
/**
* Push a validation to the validations chain.
*/
use(validation: Validation<any> | RuleBuilder): this;
/**
* Enable/disable the bail mode. In bail mode, the field validations
* are stopped after the first error.
*/
bail(state: boolean): this;
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): LiteralNode;
}
export {};

@@ -0,10 +1,36 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';
import { OTYPE, COTYPE, PARSE, VALIDATION } from '../../symbols.js';
/**
* Base schema type with only modifiers applicable on all the schema types.
*/
class BaseModifiersType {
/**
* Mark the field under validation as optional. An optional
* field allows both null and undefined values.
*/
optional() {
return new OptionalModifier(this);
}
/**
* Mark the field under validation to be null. The null value will
* be written to the output as well.
*
* If `optional` and `nullable` are used together, then both undefined
* and null values will be allowed.
*/
nullable() {
return new NullableModifier(this);
}
/**
* Apply transform on the final validated value. The transform method may
* convert the value to any new datatype.
*/
transform(transformer) {

@@ -14,2 +40,5 @@ return new TransformModifier(transformer, this);

}
/**
* Modifies the schema type to allow null values
*/
class NullableModifier extends BaseModifiersType {

@@ -21,5 +50,12 @@ #parent;

}
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the nullable modifier
*/
clone() {
return new NullableModifier(this.#parent.clone());
}
/**
* Compiles to compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -31,2 +67,5 @@ const output = this.#parent[PARSE](propertyName, refs, options);

}
/**
* Modifies the schema type to allow undefined values
*/
class OptionalModifier extends BaseModifiersType {

@@ -38,5 +77,12 @@ #parent;

}
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the optional modifier
*/
clone() {
return new OptionalModifier(this.#parent.clone());
}
/**
* Compiles to compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -48,2 +94,5 @@ const output = this.#parent[PARSE](propertyName, refs, options);

}
/**
* Modifies the schema type to allow custom transformed values
*/
class TransformModifier extends BaseModifiersType {

@@ -57,5 +106,12 @@ #parent;

}
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the transform modifier.
*/
clone() {
return new TransformModifier(this.#transform, this.#parent.clone());
}
/**
* Compiles to compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -67,4 +123,14 @@ const output = this.#parent[PARSE](propertyName, refs, options);

}
/**
* The base type for creating a custom literal type. Literal type
* is a schema type that has no children elements.
*/
export class BaseLiteralType extends BaseModifiersType {
/**
* Field options
*/
options;
/**
* Set of validations to run
*/
validations;

@@ -81,2 +147,6 @@ constructor(options, validations) {

}
/**
* Shallow clones the validations. Since, there are no API's to mutate
* the validation options, we can safely copy them by reference.
*/
cloneValidations() {

@@ -90,5 +160,11 @@ return this.validations.map((validation) => {

}
/**
* Shallow clones the options
*/
cloneOptions() {
return { ...this.options };
}
/**
* Compiles validations
*/
compileValidations(refs) {

@@ -106,2 +182,8 @@ return this.validations.map((validation) => {

}
/**
* Define a method to parse the input value. The method
* is invoked before any validation and hence you must
* perform type-checking to know the value you are
* working it.
*/
parse(callback) {

@@ -111,2 +193,5 @@ this.options.parse = callback;

}
/**
* Push a validation to the validations chain.
*/
use(validation) {

@@ -116,2 +201,6 @@ this.validations.push(VALIDATION in validation ? validation[VALIDATION]() : validation);

}
/**
* Enable/disable the bail mode. In bail mode, the field validations
* are stopped after the first error.
*/
bail(state) {

@@ -121,2 +210,5 @@ this.options.bail = state;

}
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -123,0 +215,0 @@ return {

import type { CompilerNodes, RefsStore } from '@vinejs/compiler/types';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
import type { Parser, Validation, RuleBuilder, FieldOptions, ParserOptions, ConstructableSchema } from '../../types.js';
/**
* Base schema type with only modifiers applicable on all the schema types.
*/
export declare abstract class BaseModifiersType<Output, CamelCaseOutput> implements ConstructableSchema<Output, CamelCaseOutput> {
/**
* Each subtype should implement the compile method that returns
* one of the known compiler nodes
*/
abstract [PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): CompilerNodes;
/**
* The child class must implement the clone method
*/
abstract clone(): this;
/**
* The output value of the field. The property points to a type only
* and not the real value.
*/
[OTYPE]: Output;
[COTYPE]: CamelCaseOutput;
/**
* Mark the field under validation as optional. An optional
* field allows both null and undefined values.
*/
optional(): OptionalModifier<this>;
/**
* Mark the field under validation to be null. The null value will
* be written to the output as well.
*
* If `optional` and `nullable` are used together, then both undefined
* and null values will be allowed.
*/
nullable(): NullableModifier<this>;
}
/**
* Modifies the schema type to allow null values
*/
declare class NullableModifier<Schema extends BaseModifiersType<any, any>> extends BaseModifiersType<Schema[typeof OTYPE] | null, Schema[typeof COTYPE] | null> {
#private;
constructor(parent: Schema);
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the nullable modifier
*/
clone(): this;
/**
* Compiles to compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): CompilerNodes;
}
/**
* Modifies the schema type to allow undefined values
*/
declare class OptionalModifier<Schema extends BaseModifiersType<any, any>> extends BaseModifiersType<Schema[typeof OTYPE] | undefined, Schema[typeof COTYPE] | undefined> {
#private;
constructor(parent: Schema);
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the optional modifier
*/
clone(): this;
/**
* Compiles to compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): CompilerNodes;
}
/**
* The BaseSchema class abstracts the repetitive parts of creating
* a custom schema type.
*/
export declare abstract class BaseType<Output, CamelCaseOutput> extends BaseModifiersType<Output, CamelCaseOutput> {
/**
* Field options
*/
protected options: FieldOptions;
/**
* Set of validations to run
*/
protected validations: Validation<any>[];
constructor(options?: FieldOptions, validations?: Validation<any>[]);
/**
* Shallow clones the validations. Since, there are no API's to mutate
* the validation options, we can safely copy them by reference.
*/
protected cloneValidations(): Validation<any>[];
/**
* Shallow clones the options
*/
protected cloneOptions(): FieldOptions;
/**
* Compiles validations
*/
protected compileValidations(refs: RefsStore): {

@@ -35,6 +100,19 @@ ruleFnId: `ref://${number}`;

}[];
/**
* Define a method to parse the input value. The method
* is invoked before any validation and hence you must
* perform type-checking to know the value you are
* working it.
*/
parse(callback: Parser): this;
/**
* Push a validation to the validations chain.
*/
use(validation: Validation<any> | RuleBuilder): this;
/**
* Enable/disable the bail mode. In bail mode, the field validations
* are stopped after the first error.
*/
bail(state: boolean): this;
}
export {};

@@ -0,6 +1,28 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { OTYPE, COTYPE, PARSE, VALIDATION } from '../../symbols.js';
/**
* Base schema type with only modifiers applicable on all the schema types.
*/
export class BaseModifiersType {
/**
* Mark the field under validation as optional. An optional
* field allows both null and undefined values.
*/
optional() {
return new OptionalModifier(this);
}
/**
* Mark the field under validation to be null. The null value will
* be written to the output as well.
*
* If `optional` and `nullable` are used together, then both undefined
* and null values will be allowed.
*/
nullable() {

@@ -10,2 +32,5 @@ return new NullableModifier(this);

}
/**
* Modifies the schema type to allow null values
*/
class NullableModifier extends BaseModifiersType {

@@ -17,5 +42,12 @@ #parent;

}
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the nullable modifier
*/
clone() {
return new NullableModifier(this.#parent.clone());
}
/**
* Compiles to compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -29,2 +61,5 @@ const output = this.#parent[PARSE](propertyName, refs, options);

}
/**
* Modifies the schema type to allow undefined values
*/
class OptionalModifier extends BaseModifiersType {

@@ -36,5 +71,12 @@ #parent;

}
/**
* Creates a fresh instance of the underlying schema type
* and wraps it inside the optional modifier
*/
clone() {
return new OptionalModifier(this.#parent.clone());
}
/**
* Compiles to compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -48,4 +90,14 @@ const output = this.#parent[PARSE](propertyName, refs, options);

}
/**
* The BaseSchema class abstracts the repetitive parts of creating
* a custom schema type.
*/
export class BaseType extends BaseModifiersType {
/**
* Field options
*/
options;
/**
* Set of validations to run
*/
validations;

@@ -61,2 +113,6 @@ constructor(options, validations) {

}
/**
* Shallow clones the validations. Since, there are no API's to mutate
* the validation options, we can safely copy them by reference.
*/
cloneValidations() {

@@ -70,5 +126,11 @@ return this.validations.map((validation) => {

}
/**
* Shallow clones the options
*/
cloneOptions() {
return { ...this.options };
}
/**
* Compiles validations
*/
compileValidations(refs) {

@@ -86,2 +148,8 @@ return this.validations.map((validation) => {

}
/**
* Define a method to parse the input value. The method
* is invoked before any validation and hence you must
* perform type-checking to know the value you are
* working it.
*/
parse(callback) {

@@ -91,2 +159,5 @@ this.options.parse = callback;

}
/**
* Push a validation to the validations chain.
*/
use(validation) {

@@ -96,2 +167,6 @@ this.validations.push(VALIDATION in validation ? validation[VALIDATION]() : validation);

}
/**
* Enable/disable the bail mode. In bail mode, the field validations
* are stopped after the first error.
*/
bail(state) {

@@ -98,0 +173,0 @@ this.options.bail = state;

import { BaseLiteralType } from '../base/literal.js';
import { IS_OF_TYPE, UNIQUE_NAME } from '../../symbols.js';
import type { FieldOptions, Validation } from '../../types.js';
/**
* VineBoolean represents a boolean value in the validation schema.
*/
export declare class VineBoolean extends BaseLiteralType<boolean, boolean> {
/**
* Default collection of boolean rules
*/
static rules: {

@@ -15,3 +21,10 @@ boolean: (options: {

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of boolean type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;

@@ -21,3 +34,7 @@ constructor(options?: Partial<FieldOptions> & {

}, validations?: Validation<any>[]);
/**
* Clones the VineBoolean schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,1 +1,9 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { booleanRule } from './rules.js';

@@ -5,7 +13,20 @@ import { helpers } from '../../vine/helpers.js';

import { IS_OF_TYPE, UNIQUE_NAME } from '../../symbols.js';
/**
* VineBoolean represents a boolean value in the validation schema.
*/
export class VineBoolean extends BaseLiteralType {
/**
* Default collection of boolean rules
*/
static rules = {
boolean: booleanRule,
};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.boolean';
/**
* Checks if the value is of boolean type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -18,2 +39,6 @@ const valueAsBoolean = this.options.strict === true ? value : helpers.asBoolean(value);

}
/**
* Clones the VineBoolean schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -20,0 +45,0 @@ return new VineBoolean(this.cloneOptions(), this.cloneValidations());

@@ -0,1 +1,4 @@

/**
* Validates the value to be a boolean
*/
export declare const booleanRule: (options: {

@@ -2,0 +5,0 @@ strict?: boolean | undefined;

@@ -0,4 +1,15 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from '../../vine/helpers.js';
import { messages } from '../../defaults.js';
import { createRule } from '../../vine/create_rule.js';
/**
* Validates the value to be a boolean
*/
export const booleanRule = createRule((value, options, field) => {

@@ -5,0 +16,0 @@ const valueAsBoolean = options.strict === true ? value : helpers.asBoolean(value);

@@ -20,22 +20,73 @@ import Macroable from '@poppinss/macroable';

import type { EnumLike, FieldContext, SchemaTypes } from '../types.js';
/**
* Schema builder exposes methods to construct a Vine schema. You may
* add custom methods to it using macros.
*/
export declare class SchemaBuilder extends Macroable {
/**
* Define a sub-object as a union
*/
group: typeof group;
/**
* Define a union value
*/
union: typeof union;
/**
* Define a string value
*/
string(): VineString;
/**
* Define a boolean value
*/
boolean(options?: {
strict: boolean;
}): VineBoolean;
/**
* Validate a checkbox to be checked
*/
accepted(): VineAccepted;
/**
* Define a number value
*/
number(options?: {
strict: boolean;
}): VineNumber;
/**
* Define a schema type in which the input value
* matches the pre-defined value
*/
literal<const Value>(value: Value): VineLiteral<Value>;
/**
* Define an object with known properties. You may call "allowUnknownProperties"
* to merge unknown properties.
*/
object<Properties extends Record<string, SchemaTypes>>(properties: Properties): VineObject<Properties, { [K in keyof Properties]: Properties[K][typeof OTYPE]; }, { [K_1 in keyof Properties as CamelCase<K_1 & string>]: Properties[K_1][typeof COTYPE]; }>;
/**
* Define an array field and validate its children elements.
*/
array<Schema extends SchemaTypes>(schema: Schema): VineArray<Schema>;
/**
* Define an array field with known length and each children
* element may have its own schema.
*/
tuple<Schema extends SchemaTypes[]>(schemas: [...Schema]): VineTuple<Schema, { [K in keyof Schema]: Schema[K][typeof OTYPE]; }, { [K_1 in keyof Schema]: Schema[K_1][typeof COTYPE]; }>;
/**
* Define an object field with key-value pair. The keys in
* a record are unknown and values can be of a specific
* schema type.
*/
record<Schema extends SchemaTypes>(schema: Schema): VineRecord<Schema>;
/**
* Define a field whose value matches the enum choices.
*/
enum<const Values extends readonly unknown[]>(values: Values | ((field: FieldContext) => Values)): VineEnum<Values>;
enum<Values extends EnumLike>(values: Values): VineNativeEnum<Values>;
/**
* Allow the field value to be anything
*/
any(): VineAny;
/**
* Define a union of unique schema types.
*/
unionOfTypes<Schema extends SchemaTypes>(schemas: Schema[]): VineUnionOfTypes<Schema>;
}

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import Macroable from '@poppinss/macroable';

@@ -18,29 +26,71 @@ import { VineAny } from './any/main.js';

import { IS_OF_TYPE, UNIQUE_NAME } from '../symbols.js';
/**
* Schema builder exposes methods to construct a Vine schema. You may
* add custom methods to it using macros.
*/
export class SchemaBuilder extends Macroable {
/**
* Define a sub-object as a union
*/
group = group;
/**
* Define a union value
*/
union = union;
/**
* Define a string value
*/
string() {
return new VineString();
}
/**
* Define a boolean value
*/
boolean(options) {
return new VineBoolean(options);
}
/**
* Validate a checkbox to be checked
*/
accepted() {
return new VineAccepted();
}
/**
* Define a number value
*/
number(options) {
return new VineNumber(options);
}
/**
* Define a schema type in which the input value
* matches the pre-defined value
*/
literal(value) {
return new VineLiteral(value);
}
/**
* Define an object with known properties. You may call "allowUnknownProperties"
* to merge unknown properties.
*/
object(properties) {
return new VineObject(properties);
}
/**
* Define an array field and validate its children elements.
*/
array(schema) {
return new VineArray(schema);
}
/**
* Define an array field with known length and each children
* element may have its own schema.
*/
tuple(schemas) {
return new VineTuple(schemas);
}
/**
* Define an object field with key-value pair. The keys in
* a record are unknown and values can be of a specific
* schema type.
*/
record(schema) {

@@ -55,5 +105,11 @@ return new VineRecord(schema);

}
/**
* Allow the field value to be anything
*/
any() {
return new VineAny();
}
/**
* Define a union of unique schema types.
*/
unionOfTypes(schemas) {

@@ -60,0 +116,0 @@ const schemasInUse = new Set();

@@ -0,1 +1,8 @@

/**
* Copy-pasted from
* https://github.com/ts-essentials/ts-essentials/blob/3f5d46a203cad06728fbf2a089a5b39bd473bf4e/lib/camel-case/index.ts
*
* Since, we need just one helper, I decided to not pull in the entire package and just copy-paste
* the types
*/
type IsStringLiteral<Type> = Type extends string ? (string extends Type ? false : true) : false;

@@ -9,2 +16,3 @@ type WordInPascalCase<Type> = Capitalize<WordInCamelCase<Uncapitalize<Type & string>>>;

type IsPascalCase<Type> = Type extends Capitalize<Type & string> ? true : false;
/** snake_case, CONSTANT_CASE, kebab-case or COBOL-CASE */
type SeparatorCaseParser<Type, Tuple extends readonly any[] = []> = Type extends `${infer Word}${Separator}${infer Tail}` ? SeparatorCaseParser<Tail, [...Tuple, Lowercase<Word>]> : Type extends `${infer Word}` ? [...Tuple, Lowercase<Word>] : Tuple;

@@ -11,0 +19,0 @@ type CamelCaseParser<Type, Tuple extends readonly any[] = []> = Type extends '' ? Tuple : Type extends `${WordInCamelCase<Type & string>}${infer Tail}` ? Type extends `${infer Word}${Tail}` ? CamelCaseParser<Uncapitalize<Tail>, [...Tuple, Lowercase<Word>]> : never : never;

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export {};
import { BaseLiteralType } from '../base/literal.js';
import type { FieldContext, FieldOptions, Validation } from '../../types.js';
/**
* VineEnum represents a enum data type that performs validation
* against a pre-defined choices list.
*/
export declare class VineEnum<const Values extends readonly unknown[]> extends BaseLiteralType<Values[number], Values[number]> {
#private;
/**
* Default collection of enum rules
*/
static rules: {

@@ -13,3 +20,7 @@ enum: (options: {

constructor(values: Values | ((field: FieldContext) => Values), options?: FieldOptions, validations?: Validation<any>[]);
/**
* Clones the VineEnum schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,4 +1,19 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { enumRule } from './rules.js';
import { BaseLiteralType } from '../base/literal.js';
/**
* VineEnum represents a enum data type that performs validation
* against a pre-defined choices list.
*/
export class VineEnum extends BaseLiteralType {
/**
* Default collection of enum rules
*/
static rules = {

@@ -12,2 +27,6 @@ enum: enumRule,

}
/**
* Clones the VineEnum schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -14,0 +33,0 @@ return new VineEnum(this.#values, this.cloneOptions(), this.cloneValidations());

import { BaseLiteralType } from '../base/literal.js';
import type { EnumLike, FieldOptions, Validation } from '../../types.js';
/**
* VineNativeEnum represents a enum data type that performs validation
* against a pre-defined choices list.
*
* The choices list is derived from TypeScript enum data type or an
* object
*/
export declare class VineNativeEnum<Values extends EnumLike> extends BaseLiteralType<Values[keyof Values], Values[keyof Values]> {
#private;
/**
* Default collection of enum rules
*/
static rules: {

@@ -13,3 +23,7 @@ enum: (options: {

constructor(values: Values, options?: FieldOptions, validations?: Validation<any>[]);
/**
* Clones the VineNativeEnum schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,4 +1,22 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { enumRule } from './rules.js';
import { BaseLiteralType } from '../base/literal.js';
/**
* VineNativeEnum represents a enum data type that performs validation
* against a pre-defined choices list.
*
* The choices list is derived from TypeScript enum data type or an
* object
*/
export class VineNativeEnum extends BaseLiteralType {
/**
* Default collection of enum rules
*/
static rules = {

@@ -12,2 +30,6 @@ enum: enumRule,

}
/**
* Clones the VineNativeEnum schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -14,0 +36,0 @@ return new VineNativeEnum(this.#values, this.cloneOptions(), this.cloneValidations());

import { FieldContext } from '@vinejs/compiler/types';
/**
* Enum rule is used to validate the field's value to be one
* from the pre-defined choices.
*/
export declare const enumRule: (options: {

@@ -3,0 +7,0 @@ choices: readonly any[] | ((field: FieldContext) => readonly any[]);

@@ -0,5 +1,21 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { createRule } from '../../vine/create_rule.js';
import { messages } from '../../defaults.js';
/**
* Enum rule is used to validate the field's value to be one
* from the pre-defined choices.
*/
export const enumRule = createRule((value, options, field) => {
const choices = typeof options.choices === 'function' ? options.choices(field) : options.choices;
/**
* Report error when value is not part of the pre-defined
* options
*/
if (!choices.includes(value)) {

@@ -6,0 +22,0 @@ field.report(messages.enum, 'enum', field, { choices });

import { BaseLiteralType } from '../base/literal.js';
import type { FieldOptions, Validation } from '../../types.js';
/**
* VineLiteral represents a type that matches an exact value
*/
export declare class VineLiteral<Value> extends BaseLiteralType<Value, Value> {
#private;
/**
* Default collection of literal rules
*/
static rules: {

@@ -13,3 +19,7 @@ equals: (options: {

constructor(value: Value, options?: FieldOptions, validations?: Validation<any>[]);
/**
* Clones the VineLiteral schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,4 +1,18 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { equalsRule } from './rules.js';
import { BaseLiteralType } from '../base/literal.js';
/**
* VineLiteral represents a type that matches an exact value
*/
export class VineLiteral extends BaseLiteralType {
/**
* Default collection of literal rules
*/
static rules = {

@@ -12,2 +26,6 @@ equals: equalsRule,

}
/**
* Clones the VineLiteral schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -14,0 +32,0 @@ return new VineLiteral(this.#value, this.cloneOptions(), this.cloneValidations());

@@ -0,1 +1,5 @@

/**
* Verifies two equals are equal considering the HTML forms
* serialization behavior.
*/
export declare const equalsRule: (options: {

@@ -2,0 +6,0 @@ expectedValue: any;

@@ -0,6 +1,22 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { messages } from '../../defaults.js';
import { helpers } from '../../vine/helpers.js';
import { createRule } from '../../vine/create_rule.js';
/**
* Verifies two equals are equal considering the HTML forms
* serialization behavior.
*/
export const equalsRule = createRule((value, options, field) => {
let input = value;
/**
* Normalizing the field value as per the expected
* value.
*/
if (typeof options.expectedValue === 'boolean') {

@@ -12,2 +28,5 @@ input = helpers.asBoolean(value);

}
/**
* Performing validation and reporting error
*/
if (input !== options.expectedValue) {

@@ -17,3 +36,6 @@ field.report(messages.literal, 'literal', field, options);

}
/**
* Mutating input with normalized value
*/
field.mutate(input, field);
});
import { BaseLiteralType } from '../base/literal.js';
import { FieldOptions, Validation } from '../../types.js';
import { IS_OF_TYPE, UNIQUE_NAME } from '../../symbols.js';
/**
* VineNumber represents a numeric value in the validation schema.
*/
export declare class VineNumber extends BaseLiteralType<number, number> {

@@ -8,2 +11,5 @@ protected options: FieldOptions & {

};
/**
* Default collection of number rules
*/
static rules: {

@@ -41,3 +47,10 @@ max: (options: {

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of number type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;

@@ -47,10 +60,36 @@ constructor(options?: Partial<FieldOptions> & {

}, validations?: Validation<any>[]);
/**
* Enforce a minimum value for the number input
*/
min(value: number): this;
/**
* Enforce a maximum value for the number input
*/
max(value: number): this;
/**
* Enforce value to be within the range of minimum and maximum output.
*/
range(value: [min: number, max: number]): this;
/**
* Enforce the value be a positive number
*/
positive(): this;
/**
* Enforce the value be a negative number
*/
negative(): this;
/**
* Enforce the value to have fixed or range
* of decimal places
*/
decimal(range: number | [number, number]): this;
/**
* Enforce the value to be an integer (aka without decimals)
*/
withoutDecimals(): this;
/**
* Clones the VineNumber schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,1 +1,9 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from '../../vine/helpers.js';

@@ -5,3 +13,9 @@ import { BaseLiteralType } from '../base/literal.js';

import { maxRule, minRule, rangeRule, numberRule, decimalRule, negativeRule, positiveRule, withoutDecimalsRule, } from './rules.js';
/**
* VineNumber represents a numeric value in the validation schema.
*/
export class VineNumber extends BaseLiteralType {
/**
* Default collection of number rules
*/
static rules = {

@@ -17,3 +31,10 @@ max: maxRule,

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.number';
/**
* Checks if the value is of number type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -26,23 +47,49 @@ const valueAsNumber = helpers.asNumber(value);

}
/**
* Enforce a minimum value for the number input
*/
min(value) {
return this.use(minRule({ min: value }));
}
/**
* Enforce a maximum value for the number input
*/
max(value) {
return this.use(maxRule({ max: value }));
}
/**
* Enforce value to be within the range of minimum and maximum output.
*/
range(value) {
return this.use(rangeRule({ min: value[0], max: value[1] }));
}
/**
* Enforce the value be a positive number
*/
positive() {
return this.use(positiveRule());
}
/**
* Enforce the value be a negative number
*/
negative() {
return this.use(negativeRule());
}
/**
* Enforce the value to have fixed or range
* of decimal places
*/
decimal(range) {
return this.use(decimalRule({ range: Array.isArray(range) ? range : [range] }));
}
/**
* Enforce the value to be an integer (aka without decimals)
*/
withoutDecimals() {
return this.use(withoutDecimalsRule());
}
/**
* Clones the VineNumber schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -49,0 +96,0 @@ return new VineNumber(this.cloneOptions(), this.cloneValidations());

@@ -0,1 +1,5 @@

/**
* Enforce the value to be a number or a string representation
* of a number
*/
export declare const numberRule: (options: {

@@ -6,2 +10,5 @@ strict?: boolean | undefined;

}>;
/**
* Enforce a minimum value on a number field
*/
export declare const minRule: (options: {

@@ -12,2 +19,5 @@ min: number;

}>;
/**
* Enforce a maximum value on a number field
*/
export declare const maxRule: (options: {

@@ -18,2 +28,5 @@ max: number;

}>;
/**
* Enforce a range of values on a number field.
*/
export declare const rangeRule: (options: {

@@ -26,4 +39,13 @@ min: number;

}>;
/**
* Enforce the value is a positive number
*/
export declare const positiveRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Enforce the value is a negative number
*/
export declare const negativeRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Enforce the value to have a fixed or range of decimals
*/
export declare const decimalRule: (options: {

@@ -34,2 +56,5 @@ range: [number, number?];

}>;
/**
* Enforce the value to not have decimal places
*/
export declare const withoutDecimalsRule: (options?: undefined) => import("../../types.js").Validation<undefined>;

@@ -0,4 +1,16 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from '../../vine/helpers.js';
import { createRule } from '../../vine/create_rule.js';
import { messages } from '../../defaults.js';
/**
* Enforce the value to be a number or a string representation
* of a number
*/
export const numberRule = createRule((value, options, field) => {

@@ -15,3 +27,9 @@ const valueAsNumber = options.strict ? value : helpers.asNumber(value);

});
/**
* Enforce a minimum value on a number field
*/
export const minRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -24,3 +42,9 @@ return;

});
/**
* Enforce a maximum value on a number field
*/
export const maxRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -33,3 +57,9 @@ return;

});
/**
* Enforce a range of values on a number field.
*/
export const rangeRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -42,3 +72,9 @@ return;

});
/**
* Enforce the value is a positive number
*/
export const positiveRule = createRule((value, _, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -51,3 +87,9 @@ return;

});
/**
* Enforce the value is a negative number
*/
export const negativeRule = createRule((value, _, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -60,3 +102,9 @@ return;

});
/**
* Enforce the value to have a fixed or range of decimals
*/
export const decimalRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -72,3 +120,9 @@ return;

});
/**
* Enforce the value to not have decimal places
*/
export const withoutDecimalsRule = createRule((value, _, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -75,0 +129,0 @@ return;

import type { ConditionalFn, ObjectGroupNode, RefsStore } from '@vinejs/compiler/types';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
import type { ParserOptions, SchemaTypes } from '../../types.js';
/**
* Group conditional represents a sub-set of object wrapped
* inside a conditional
*/
export declare class GroupConditional<Properties extends Record<string, SchemaTypes>, Output, CamelCaseOutput> {

@@ -9,3 +13,6 @@ #private;

constructor(conditional: ConditionalFn<Record<string, unknown>>, properties: Properties);
/**
* Compiles to a union conditional
*/
[PARSE](refs: RefsStore, options: ParserOptions): ObjectGroupNode['conditions'][number];
}

@@ -0,4 +1,22 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
/**
* Group conditional represents a sub-set of object wrapped
* inside a conditional
*/
export class GroupConditional {
/**
* Properties to merge when conditonal is true
*/
#properties;
/**
* Conditional to evaluate
*/
#conditional;

@@ -9,2 +27,5 @@ constructor(conditional, properties) {

}
/**
* Compiles to a union conditional
*/
[PARSE](refs, options) {

@@ -17,3 +38,3 @@ return {

}),
groups: [],
groups: [], // Compiler allows nested groups, but we are not implementing it
},

@@ -20,0 +41,0 @@ conditionalFnRefId: refs.trackConditional(this.#conditional),

@@ -6,2 +6,6 @@ import { ObjectGroup } from './group.js';

import type { FieldContext, SchemaTypes } from '../../types.js';
/**
* Create an object group. Groups are used to conditionally merge properties
* to an existing object.
*/
export declare function group<Conditional extends GroupConditional<any, any, any>>(conditionals: Conditional[]): ObjectGroup<Conditional>;

@@ -8,0 +12,0 @@ export declare namespace group {

@@ -0,11 +1,29 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { ObjectGroup } from './group.js';
import { GroupConditional } from './conditional.js';
/**
* Create an object group. Groups are used to conditionally merge properties
* to an existing object.
*/
export function group(conditionals) {
return new ObjectGroup(conditionals);
}
/**
* Wrap object properties inside a conditonal
*/
group.if = function groupIf(conditon, properties) {
return new GroupConditional(conditon, properties);
};
/**
* Wrap object properties inside an else conditon
*/
group.else = function groupElse(properties) {
return new GroupConditional(() => true, properties);
};

@@ -5,2 +5,7 @@ import { ObjectGroupNode, RefsStore } from '@vinejs/compiler/types';

import type { ParserOptions, UnionNoMatchCallback } from '../../types.js';
/**
* Object group represents a group with multiple conditionals, where each
* condition returns a set of object properties to merge into the
* existing object.
*/
export declare class ObjectGroup<Conditional extends GroupConditional<any, any, any>> {

@@ -11,5 +16,15 @@ #private;

constructor(conditionals: Conditional[]);
/**
* Clones the ObjectGroup schema type.
*/
clone(): this;
/**
* Define a fallback method to invoke when all of the group conditions
* fail. You may use this method to report an error.
*/
otherwise(callback: UnionNoMatchCallback<Record<string, unknown>>): this;
/**
* Compiles the group
*/
[PARSE](refs: RefsStore, options: ParserOptions): ObjectGroupNode;
}

@@ -0,3 +1,16 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { messages } from '../../defaults.js';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
/**
* Object group represents a group with multiple conditionals, where each
* condition returns a set of object properties to merge into the
* existing object.
*/
export class ObjectGroup {

@@ -11,2 +24,5 @@ #conditionals;

}
/**
* Clones the ObjectGroup schema type.
*/
clone() {

@@ -17,2 +33,6 @@ const cloned = new ObjectGroup(this.#conditionals);

}
/**
* Define a fallback method to invoke when all of the group conditions
* fail. You may use this method to report an error.
*/
otherwise(callback) {

@@ -22,2 +42,5 @@ this.#otherwiseCallback = callback;

}
/**
* Compiles the group
*/
[PARSE](refs, options) {

@@ -24,0 +47,0 @@ return {

@@ -7,16 +7,51 @@ import type { ObjectNode, RefsStore } from '@vinejs/compiler/types';

import type { Validation, SchemaTypes, FieldOptions, ParserOptions } from '../../types.js';
/**
* Converts schema properties to camelCase
*/
export declare class VineCamelCaseObject<Schema extends VineObject<any, any, any>> extends BaseModifiersType<Schema[typeof COTYPE], Schema[typeof COTYPE]> {
#private;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(schema: Schema);
/**
* Clone object
*/
clone(): this;
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): ObjectNode;
}
/**
* VineObject represents an object value in the validation
* schema.
*/
export declare class VineObject<Properties extends Record<string, SchemaTypes>, Output, CamelCaseOutput> extends BaseType<Output, CamelCaseOutput> {
#private;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(properties: Properties, options?: FieldOptions, validations?: Validation<any>[]);
/**
* Returns a clone copy of the object properties. The object groups
* are not copied to keep the implementations simple and easy to
* reason about.
*/
getProperties(): Properties;
/**
* Copy unknown properties to the final output.
*/
allowUnknownProperties<Value>(): VineObject<Properties, Output & {

@@ -27,6 +62,19 @@ [K: string]: Value;

}>;
/**
* Merge a union to the object groups. The union can be a "vine.union"
* with objects, or a "vine.object.union" with properties.
*/
merge<Group extends ObjectGroup<GroupConditional<any, any, any>>>(group: Group): VineObject<Properties, Output & Group[typeof OTYPE], CamelCaseOutput & Group[typeof COTYPE]>;
/**
* Clone object
*/
clone(): this;
/**
* Applies camelcase transform
*/
toCamelCase(): VineCamelCaseObject<this>;
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): ObjectNode;
}

@@ -0,7 +1,25 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';
import { BaseModifiersType, BaseType } from '../base/main.js';
import { PARSE, UNIQUE_NAME, IS_OF_TYPE } from '../../symbols.js';
/**
* Converts schema properties to camelCase
*/
export class VineCamelCaseObject extends BaseModifiersType {
#schema;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'types.object';
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -14,5 +32,11 @@ return value !== null && typeof value === 'object' && !Array.isArray(value);

}
/**
* Clone object
*/
clone() {
return new VineCamelCaseObject(this.#schema.clone());
}
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -23,7 +47,27 @@ options.toCamelCase = true;

}
/**
* VineObject represents an object value in the validation
* schema.
*/
export class VineObject extends BaseType {
/**
* Object properties
*/
#properties;
/**
* Object groups to merge based on conditionals
*/
#groups = [];
/**
* Whether or not to allow unknown properties
*/
#allowUnknownProperties = false;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.object';
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -36,2 +80,7 @@ return value !== null && typeof value === 'object' && !Array.isArray(value);

}
/**
* Returns a clone copy of the object properties. The object groups
* are not copied to keep the implementations simple and easy to
* reason about.
*/
getProperties() {

@@ -43,2 +92,5 @@ return Object.keys(this.#properties).reduce((result, key) => {

}
/**
* Copy unknown properties to the final output.
*/
allowUnknownProperties() {

@@ -48,2 +100,6 @@ this.#allowUnknownProperties = true;

}
/**
* Merge a union to the object groups. The union can be a "vine.union"
* with objects, or a "vine.object.union" with properties.
*/
merge(group) {

@@ -53,2 +109,5 @@ this.#groups.push(group);

}
/**
* Clone object
*/
clone() {

@@ -62,5 +121,11 @@ const cloned = new VineObject(this.getProperties(), this.cloneOptions(), this.cloneValidations());

}
/**
* Applies camelcase transform
*/
toCamelCase() {
return new VineCamelCaseObject(this);
}
/**
* Compiles the schema type to a compiler node
*/
[PARSE](propertyName, refs, options) {

@@ -67,0 +132,0 @@ return {

@@ -6,2 +6,6 @@ import { RefsStore, RecordNode } from '@vinejs/compiler/types';

import { validateKeysRule } from './rules.js';
/**
* VineRecord represents an object of key-value pair in which
* keys are unknown
*/
export declare class VineRecord<Schema extends SchemaTypes> extends BaseType<{

@@ -13,2 +17,5 @@ [K: string]: Schema[typeof OTYPE];

#private;
/**
* Default collection of record rules
*/
static rules: {

@@ -32,11 +39,37 @@ maxLength: (options: {

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(schema: Schema, options?: FieldOptions, validations?: Validation<any>[]);
/**
* Enforce a minimum length on an object field
*/
minLength(expectedLength: number): this;
/**
* Enforce a maximum length on an object field
*/
maxLength(expectedLength: number): this;
/**
* Enforce a fixed length on an object field
*/
fixedLength(expectedLength: number): this;
/**
* Register a callback to validate the object keys
*/
validateKeys(...args: Parameters<typeof validateKeysRule>): this;
/**
* Clones the VineRecord schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
/**
* Compiles to record data type
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): RecordNode;
}

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';

@@ -5,3 +13,10 @@ import { BaseType } from '../base/main.js';

import { fixedLengthRule, maxLengthRule, minLengthRule, validateKeysRule } from './rules.js';
/**
* VineRecord represents an object of key-value pair in which
* keys are unknown
*/
export class VineRecord extends BaseType {
/**
* Default collection of record rules
*/
static rules = {

@@ -14,3 +29,10 @@ maxLength: maxLengthRule,

#schema;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.object';
/**
* Checks if the value is of object type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -23,17 +45,36 @@ return value !== null && typeof value === 'object' && !Array.isArray(value);

}
/**
* Enforce a minimum length on an object field
*/
minLength(expectedLength) {
return this.use(minLengthRule({ min: expectedLength }));
}
/**
* Enforce a maximum length on an object field
*/
maxLength(expectedLength) {
return this.use(maxLengthRule({ max: expectedLength }));
}
/**
* Enforce a fixed length on an object field
*/
fixedLength(expectedLength) {
return this.use(fixedLengthRule({ size: expectedLength }));
}
/**
* Register a callback to validate the object keys
*/
validateKeys(...args) {
return this.use(validateKeysRule(...args));
}
/**
* Clones the VineRecord schema type. The applied options
* and validations are copied to the new instance
*/
clone() {
return new VineRecord(this.#schema.clone(), this.cloneOptions(), this.cloneValidations());
}
/**
* Compiles to record data type
*/
[PARSE](propertyName, refs, options) {

@@ -40,0 +81,0 @@ return {

import { FieldContext } from '@vinejs/compiler/types';
/**
* Enforce a minimum length on an object field
*/
export declare const minLengthRule: (options: {

@@ -7,2 +10,5 @@ min: number;

}>;
/**
* Enforce a maximum length on an object field
*/
export declare const maxLengthRule: (options: {

@@ -13,2 +19,5 @@ max: number;

}>;
/**
* Enforce a fixed length on an object field
*/
export declare const fixedLengthRule: (options: {

@@ -19,2 +28,5 @@ size: number;

}>;
/**
* Register a callback to validate the object keys
*/
export declare const validateKeysRule: (options: (keys: string[], field: FieldContext) => void) => import("../../types.js").Validation<(keys: string[], field: FieldContext) => void>;

@@ -0,7 +1,24 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { messages } from '../../defaults.js';
import { createRule } from '../../vine/create_rule.js';
/**
* Enforce a minimum length on an object field
*/
export const minLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an object if the field is valid.
*/
if (Object.keys(value).length < options.min) {

@@ -11,6 +28,15 @@ field.report(messages['record.minLength'], 'record.minLength', field, options);

});
/**
* Enforce a maximum length on an object field
*/
export const maxLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an object if the field is valid.
*/
if (Object.keys(value).length > options.max) {

@@ -20,6 +46,15 @@ field.report(messages['record.maxLength'], 'record.maxLength', field, options);

});
/**
* Enforce a fixed length on an object field
*/
export const fixedLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {
return;
}
/**
* Value will always be an object if the field is valid.
*/
if (Object.keys(value).length !== options.size) {

@@ -29,3 +64,9 @@ field.report(messages['record.fixedLength'], 'record.fixedLength', field, options);

});
/**
* Register a callback to validate the object keys
*/
export const validateKeysRule = createRule((value, callback, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -32,0 +73,0 @@ return;

@@ -5,2 +5,5 @@ import { BaseLiteralType } from '../base/literal.js';

import { urlRule, uuidRule, emailRule, mobileRule, passportRule, creditCardRule, postalCodeRule, normalizeUrlRule } from './rules.js';
/**
* VineString represents a string value in the validation schema.
*/
export declare class VineString extends BaseLiteralType<string, string> {

@@ -92,42 +95,157 @@ static rules: {

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of string type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(options?: FieldOptions, validations?: Validation<any>[]);
/**
* Validates the value to be a valid URL
*/
url(...args: Parameters<typeof urlRule>): this;
/**
* Validates the value to be an active URL
*/
activeUrl(): this;
/**
* Validates the value to be a valid email address
*/
email(...args: Parameters<typeof emailRule>): this;
/**
* Validates the value to be a valid mobile number
*/
mobile(...args: Parameters<typeof mobileRule>): this;
/**
* Validates the value to be a valid IP address.
*/
ipAddress(version?: 4 | 6): this;
/**
* Validates the value to be a valid hex color code
*/
hexCode(): this;
/**
* Validates the value to be an active URL
*/
regex(expression: RegExp): this;
/**
* Validates the value to contain only letters
*/
alpha(options?: AlphaOptions): this;
/**
* Validates the value to contain only letters and
* numbers
*/
alphaNumeric(options?: AlphaNumericOptions): this;
/**
* Enforce a minimum length on a string field
*/
minLength(expectedLength: number): this;
/**
* Enforce a maximum length on a string field
*/
maxLength(expectedLength: number): this;
/**
* Enforce a fixed length on a string field
*/
fixedLength(expectedLength: number): this;
/**
* Ensure the field under validation is confirmed by
* having another field with the same name.
*/
confirmed(options?: {
confirmationField: string;
}): this;
/**
* Trims whitespaces around the string value
*/
trim(): this;
/**
* Normalizes the email address
*/
normalizeEmail(options?: NormalizeEmailOptions): this;
/**
* Converts the field value to UPPERCASE.
*/
toUpperCase(): this;
/**
* Converts the field value to lowercase.
*/
toLowerCase(): this;
/**
* Converts the field value to camelCase.
*/
toCamelCase(): this;
/**
* Escape string for HTML entities
*/
escape(): this;
/**
* Normalize a URL
*/
normalizeUrl(...args: Parameters<typeof normalizeUrlRule>): this;
/**
* Ensure the value starts with the pre-defined substring
*/
startsWith(substring: string): this;
/**
* Ensure the value ends with the pre-defined substring
*/
endsWith(substring: string): this;
/**
* Ensure the value ends with the pre-defined substring
*/
sameAs(otherField: string): this;
/**
* Ensure the value ends with the pre-defined substring
*/
notSameAs(otherField: string): this;
/**
* Ensure the field's value under validation is a subset of the pre-defined list.
*/
in(choices: string[] | ((field: FieldContext) => string[])): this;
/**
* Ensure the field's value under validation is not inside the pre-defined list.
*/
notIn(list: string[] | ((field: FieldContext) => string[])): this;
/**
* Validates the value to be a valid credit card number
*/
creditCard(...args: Parameters<typeof creditCardRule>): this;
/**
* Validates the value to be a valid passport number
*/
passport(...args: Parameters<typeof passportRule>): this;
/**
* Validates the value to be a valid postal code
*/
postalCode(...args: Parameters<typeof postalCodeRule>): this;
/**
* Validates the value to be a valid UUID
*/
uuid(...args: Parameters<typeof uuidRule>): this;
/**
* Validates the value contains ASCII characters only
*/
ascii(): this;
/**
* Validates the value to be a valid IBAN number
*/
iban(): this;
/**
* Validates the value to be a valid JWT token
*/
jwt(): this;
/**
* Ensure the value is a string with latitude and longitude coordinates
*/
coordinates(): this;
/**
* Clones the VineString schema type. The applied options
* and validations are copied to the new instance
*/
clone(): this;
}

@@ -0,4 +1,15 @@

/*
* vinejs
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { BaseLiteralType } from '../base/literal.js';
import { IS_OF_TYPE, UNIQUE_NAME } from '../../symbols.js';
import { inRule, urlRule, uuidRule, trimRule, alphaRule, emailRule, notInRule, regexRule, sameAsRule, mobileRule, escapeRule, stringRule, hexCodeRule, passportRule, endsWithRule, ipAddressRule, confirmedRule, notSameAsRule, activeUrlRule, minLengthRule, maxLengthRule, startsWithRule, creditCardRule, postalCodeRule, fixedLengthRule, alphaNumericRule, normalizeEmailRule, asciiRule, ibanRule, jwtRule, coordinatesRule, toUpperCaseRule, toLowerCaseRule, toCamelCaseRule, normalizeUrlRule, } from './rules.js';
/**
* VineString represents a string value in the validation schema.
*/
export class VineString extends BaseLiteralType {

@@ -42,3 +53,10 @@ static rules = {

};
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.string';
/**
* Checks if the value is of string type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -50,104 +68,212 @@ return typeof value === 'string';

}
/**
* Validates the value to be a valid URL
*/
url(...args) {
return this.use(urlRule(...args));
}
/**
* Validates the value to be an active URL
*/
activeUrl() {
return this.use(activeUrlRule());
}
/**
* Validates the value to be a valid email address
*/
email(...args) {
return this.use(emailRule(...args));
}
/**
* Validates the value to be a valid mobile number
*/
mobile(...args) {
return this.use(mobileRule(...args));
}
/**
* Validates the value to be a valid IP address.
*/
ipAddress(version) {
return this.use(ipAddressRule(version ? { version } : undefined));
}
/**
* Validates the value to be a valid hex color code
*/
hexCode() {
return this.use(hexCodeRule());
}
/**
* Validates the value to be an active URL
*/
regex(expression) {
return this.use(regexRule(expression));
}
/**
* Validates the value to contain only letters
*/
alpha(options) {
return this.use(alphaRule(options));
}
/**
* Validates the value to contain only letters and
* numbers
*/
alphaNumeric(options) {
return this.use(alphaNumericRule(options));
}
/**
* Enforce a minimum length on a string field
*/
minLength(expectedLength) {
return this.use(minLengthRule({ min: expectedLength }));
}
/**
* Enforce a maximum length on a string field
*/
maxLength(expectedLength) {
return this.use(maxLengthRule({ max: expectedLength }));
}
/**
* Enforce a fixed length on a string field
*/
fixedLength(expectedLength) {
return this.use(fixedLengthRule({ size: expectedLength }));
}
/**
* Ensure the field under validation is confirmed by
* having another field with the same name.
*/
confirmed(options) {
return this.use(confirmedRule(options));
}
/**
* Trims whitespaces around the string value
*/
trim() {
return this.use(trimRule());
}
/**
* Normalizes the email address
*/
normalizeEmail(options) {
return this.use(normalizeEmailRule(options));
}
/**
* Converts the field value to UPPERCASE.
*/
toUpperCase() {
return this.use(toUpperCaseRule());
}
/**
* Converts the field value to lowercase.
*/
toLowerCase() {
return this.use(toLowerCaseRule());
}
/**
* Converts the field value to camelCase.
*/
toCamelCase() {
return this.use(toCamelCaseRule());
}
/**
* Escape string for HTML entities
*/
escape() {
return this.use(escapeRule());
}
/**
* Normalize a URL
*/
normalizeUrl(...args) {
return this.use(normalizeUrlRule(...args));
}
/**
* Ensure the value starts with the pre-defined substring
*/
startsWith(substring) {
return this.use(startsWithRule({ substring }));
}
/**
* Ensure the value ends with the pre-defined substring
*/
endsWith(substring) {
return this.use(endsWithRule({ substring }));
}
/**
* Ensure the value ends with the pre-defined substring
*/
sameAs(otherField) {
return this.use(sameAsRule({ otherField }));
}
/**
* Ensure the value ends with the pre-defined substring
*/
notSameAs(otherField) {
return this.use(notSameAsRule({ otherField }));
}
/**
* Ensure the field's value under validation is a subset of the pre-defined list.
*/
in(choices) {
return this.use(inRule({ choices }));
}
/**
* Ensure the field's value under validation is not inside the pre-defined list.
*/
notIn(list) {
return this.use(notInRule({ list }));
}
/**
* Validates the value to be a valid credit card number
*/
creditCard(...args) {
return this.use(creditCardRule(...args));
}
/**
* Validates the value to be a valid passport number
*/
passport(...args) {
return this.use(passportRule(...args));
}
/**
* Validates the value to be a valid postal code
*/
postalCode(...args) {
return this.use(postalCodeRule(...args));
}
/**
* Validates the value to be a valid UUID
*/
uuid(...args) {
return this.use(uuidRule(...args));
}
/**
* Validates the value contains ASCII characters only
*/
ascii() {
return this.use(asciiRule());
}
/**
* Validates the value to be a valid IBAN number
*/
iban() {
return this.use(ibanRule());
}
/**
* Validates the value to be a valid JWT token
*/
jwt() {
return this.use(jwtRule());
}
/**
* Ensure the value is a string with latitude and longitude coordinates
*/
coordinates() {
return this.use(coordinatesRule());
}
/**
* Clones the VineString schema type. The applied options
* and validations are copied to the new instance
*/
clone() {

@@ -154,0 +280,0 @@ return new VineString(this.cloneOptions(), this.cloneValidations());

import validator from 'validator';
import type { FieldContext } from '@vinejs/compiler/types';
import type { AlphaOptions, MobileOptions, PassportOptions, CreditCardOptions, PostalCodeOptions } from '../../types.js';
/**
* Validates the value to be a string
*/
export declare const stringRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Validates the value to be a valid email address
*/
export declare const emailRule: (options?: import("validator/lib/isEmail.js").IsEmailOptions | undefined) => import("../../types.js").Validation<import("validator/lib/isEmail.js").IsEmailOptions | undefined>;
/**
* Validates the value to be a valid mobile number
*/
export declare const mobileRule: (options?: MobileOptions | ((field: FieldContext) => MobileOptions | undefined) | undefined) => import("../../types.js").Validation<MobileOptions | ((field: FieldContext) => MobileOptions | undefined) | undefined>;
/**
* Validates the value to be a valid IP address.
*/
export declare const ipAddressRule: (options?: {

@@ -12,8 +24,29 @@ version: 4 | 6;

} | undefined>;
/**
* Validates the value against a regular expression
*/
export declare const regexRule: (options: RegExp) => import("../../types.js").Validation<RegExp>;
/**
* Validates the value to be a valid hex color code
*/
export declare const hexCodeRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Validates the value to be a valid URL
*/
export declare const urlRule: (options?: import("validator/lib/isURL.js").IsURLOptions | undefined) => import("../../types.js").Validation<import("validator/lib/isURL.js").IsURLOptions | undefined>;
/**
* Validates the value to be an active URL
*/
export declare const activeUrlRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Validates the value to contain only letters
*/
export declare const alphaRule: (options?: AlphaOptions | undefined) => import("../../types.js").Validation<AlphaOptions | undefined>;
/**
* Validates the value to contain only letters and numbers
*/
export declare const alphaNumericRule: (options?: AlphaOptions | undefined) => import("../../types.js").Validation<AlphaOptions | undefined>;
/**
* Enforce a minimum length on a string field
*/
export declare const minLengthRule: (options: {

@@ -24,2 +57,5 @@ min: number;

}>;
/**
* Enforce a maximum length on a string field
*/
export declare const maxLengthRule: (options: {

@@ -30,2 +66,5 @@ max: number;

}>;
/**
* Enforce a fixed length on a string field
*/
export declare const fixedLengthRule: (options: {

@@ -36,2 +75,5 @@ size: number;

}>;
/**
* Ensure the value ends with the pre-defined substring
*/
export declare const endsWithRule: (options: {

@@ -42,2 +84,5 @@ substring: string;

}>;
/**
* Ensure the value starts with the pre-defined substring
*/
export declare const startsWithRule: (options: {

@@ -48,2 +93,5 @@ substring: string;

}>;
/**
* Ensure the field's value under validation is the same as the other field's value
*/
export declare const sameAsRule: (options: {

@@ -54,2 +102,5 @@ otherField: string;

}>;
/**
* Ensure the field's value under validation is different from another field's value
*/
export declare const notSameAsRule: (options: {

@@ -60,2 +111,6 @@ otherField: string;

}>;
/**
* Ensure the field under validation is confirmed by
* having another field with the same name
*/
export declare const confirmedRule: (options?: {

@@ -66,9 +121,33 @@ confirmationField: string;

} | undefined>;
/**
* Trims whitespaces around the string value
*/
export declare const trimRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Normalizes the email address
*/
export declare const normalizeEmailRule: (options?: validator.default.NormalizeEmailOptions | undefined) => import("../../types.js").Validation<validator.default.NormalizeEmailOptions | undefined>;
/**
* Converts the field value to UPPERCASE.
*/
export declare const toUpperCaseRule: (options?: string | string[] | undefined) => import("../../types.js").Validation<string | string[] | undefined>;
/**
* Converts the field value to lowercase.
*/
export declare const toLowerCaseRule: (options?: string | string[] | undefined) => import("../../types.js").Validation<string | string[] | undefined>;
/**
* Converts the field value to camelCase.
*/
export declare const toCamelCaseRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Escape string for HTML entities
*/
export declare const escapeRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Normalize a URL
*/
export declare const normalizeUrlRule: (options?: import("normalize-url").Options | undefined) => import("../../types.js").Validation<import("normalize-url").Options | undefined>;
/**
* Ensure the field's value under validation is a subset of the pre-defined list.
*/
export declare const inRule: (options: {

@@ -79,2 +158,5 @@ choices: string[] | ((field: FieldContext) => string[]);

}>;
/**
* Ensure the field's value under validation is not inside the pre-defined list.
*/
export declare const notInRule: (options: {

@@ -85,5 +167,17 @@ list: string[] | ((field: FieldContext) => string[]);

}>;
/**
* Validates the value to be a valid credit card number
*/
export declare const creditCardRule: (options?: CreditCardOptions | ((field: FieldContext) => CreditCardOptions | void | undefined) | undefined) => import("../../types.js").Validation<CreditCardOptions | ((field: FieldContext) => CreditCardOptions | void | undefined) | undefined>;
/**
* Validates the value to be a valid passport number
*/
export declare const passportRule: (options: PassportOptions | ((field: FieldContext) => PassportOptions)) => import("../../types.js").Validation<PassportOptions | ((field: FieldContext) => PassportOptions)>;
/**
* Validates the value to be a valid postal code
*/
export declare const postalCodeRule: (options?: PostalCodeOptions | ((field: FieldContext) => PostalCodeOptions | void | undefined) | undefined) => import("../../types.js").Validation<PostalCodeOptions | ((field: FieldContext) => PostalCodeOptions | void | undefined) | undefined>;
/**
* Validates the value to be a valid UUID
*/
export declare const uuidRule: (options?: {

@@ -94,5 +188,17 @@ version?: (1 | 2 | 4 | 3 | 5)[] | undefined;

} | undefined>;
/**
* Validates the value contains ASCII characters only
*/
export declare const asciiRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Validates the value to be a valid IBAN number
*/
export declare const ibanRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Validates the value to be a valid JWT token
*/
export declare const jwtRule: (options?: undefined) => import("../../types.js").Validation<undefined>;
/**
* Ensure the value is a string with latitude and longitude coordinates
*/
export declare const coordinatesRule: (options?: undefined) => import("../../types.js").Validation<undefined>;

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import validator from 'validator';

@@ -7,2 +15,5 @@ import { helpers } from '../../vine/helpers.js';

import normalizeUrl from 'normalize-url';
/**
* Validates the value to be a string
*/
export const stringRule = createRule((value, _, field) => {

@@ -13,2 +24,5 @@ if (typeof value !== 'string') {

});
/**
* Validates the value to be a valid email address
*/
export const emailRule = createRule((value, options, field) => {

@@ -22,2 +36,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid mobile number
*/
export const mobileRule = createRule((value, options, field) => {

@@ -33,2 +50,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid IP address.
*/
export const ipAddressRule = createRule((value, options, field) => {

@@ -42,2 +62,5 @@ if (!field.isValid) {

});
/**
* Validates the value against a regular expression
*/
export const regexRule = createRule((value, expression, field) => {

@@ -51,2 +74,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid hex color code
*/
export const hexCodeRule = createRule((value, _, field) => {

@@ -60,2 +86,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid URL
*/
export const urlRule = createRule((value, options, field) => {

@@ -69,2 +98,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be an active URL
*/
export const activeUrlRule = createRule(async (value, _, field) => {

@@ -78,2 +110,5 @@ if (!field.isValid) {

});
/**
* Validates the value to contain only letters
*/
export const alphaRule = createRule((value, options, field) => {

@@ -100,2 +135,5 @@ if (!field.isValid) {

});
/**
* Validates the value to contain only letters and numbers
*/
export const alphaNumericRule = createRule((value, options, field) => {

@@ -122,3 +160,9 @@ if (!field.isValid) {

});
/**
* Enforce a minimum length on a string field
*/
export const minLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -131,3 +175,9 @@ return;

});
/**
* Enforce a maximum length on a string field
*/
export const maxLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -140,3 +190,9 @@ return;

});
/**
* Enforce a fixed length on a string field
*/
export const fixedLengthRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -149,3 +205,9 @@ return;

});
/**
* Ensure the value ends with the pre-defined substring
*/
export const endsWithRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -158,3 +220,9 @@ return;

});
/**
* Ensure the value starts with the pre-defined substring
*/
export const startsWithRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -167,3 +235,9 @@ return;

});
/**
* Ensure the field's value under validation is the same as the other field's value
*/
export const sameAsRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -173,2 +247,5 @@ return;

const input = field.parent[options.otherField];
/**
* Performing validation and reporting error
*/
if (input !== value) {

@@ -179,3 +256,9 @@ field.report(messages.sameAs, 'sameAs', field, options);

});
/**
* Ensure the field's value under validation is different from another field's value
*/
export const notSameAsRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -185,2 +268,5 @@ return;

const input = field.parent[options.otherField];
/**
* Performing validation and reporting error
*/
if (input === value) {

@@ -191,3 +277,10 @@ field.report(messages.notSameAs, 'notSameAs', field, options);

});
/**
* Ensure the field under validation is confirmed by
* having another field with the same name
*/
export const confirmedRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -198,2 +291,5 @@ return;

const input = field.parent[otherField];
/**
* Performing validation and reporting error
*/
if (input !== value) {

@@ -204,2 +300,5 @@ field.report(messages.confirmed, 'confirmed', field, { otherField });

});
/**
* Trims whitespaces around the string value
*/
export const trimRule = createRule((value, _, field) => {

@@ -211,2 +310,5 @@ if (!field.isValid) {

});
/**
* Normalizes the email address
*/
export const normalizeEmailRule = createRule((value, options, field) => {

@@ -218,2 +320,5 @@ if (!field.isValid) {

});
/**
* Converts the field value to UPPERCASE.
*/
export const toUpperCaseRule = createRule((value, locales, field) => {

@@ -225,2 +330,5 @@ if (!field.isValid) {

});
/**
* Converts the field value to lowercase.
*/
export const toLowerCaseRule = createRule((value, locales, field) => {

@@ -232,2 +340,5 @@ if (!field.isValid) {

});
/**
* Converts the field value to camelCase.
*/
export const toCamelCaseRule = createRule((value, _, field) => {

@@ -239,2 +350,5 @@ if (!field.isValid) {

});
/**
* Escape string for HTML entities
*/
export const escapeRule = createRule((value, _, field) => {

@@ -246,2 +360,5 @@ if (!field.isValid) {

});
/**
* Normalize a URL
*/
export const normalizeUrlRule = createRule((value, options, field) => {

@@ -253,3 +370,9 @@ if (!field.isValid) {

});
/**
* Ensure the field's value under validation is a subset of the pre-defined list.
*/
export const inRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -259,2 +382,5 @@ return;

const choices = typeof options.choices === 'function' ? options.choices(field) : options.choices;
/**
* Performing validation and reporting error
*/
if (!choices.includes(value)) {

@@ -265,3 +391,9 @@ field.report(messages.in, 'in', field, options);

});
/**
* Ensure the field's value under validation is not inside the pre-defined list.
*/
export const notInRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -271,2 +403,5 @@ return;

const list = typeof options.list === 'function' ? options.list(field) : options.list;
/**
* Performing validation and reporting error
*/
if (list.includes(value)) {

@@ -277,3 +412,9 @@ field.report(messages.notIn, 'notIn', field, options);

});
/**
* Validates the value to be a valid credit card number
*/
export const creditCardRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -304,3 +445,9 @@ return;

});
/**
* Validates the value to be a valid passport number
*/
export const passportRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -315,3 +462,9 @@ return;

});
/**
* Validates the value to be a valid postal code
*/
export const postalCodeRule = createRule((value, options, field) => {
/**
* Skip if the field is not valid.
*/
if (!field.isValid) {

@@ -337,2 +490,5 @@ return;

});
/**
* Validates the value to be a valid UUID
*/
export const uuidRule = createRule((value, options, field) => {

@@ -354,2 +510,5 @@ if (!field.isValid) {

});
/**
* Validates the value contains ASCII characters only
*/
export const asciiRule = createRule((value, _, field) => {

@@ -363,2 +522,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid IBAN number
*/
export const ibanRule = createRule((value, _, field) => {

@@ -372,2 +534,5 @@ if (!field.isValid) {

});
/**
* Validates the value to be a valid JWT token
*/
export const jwtRule = createRule((value, _, field) => {

@@ -381,2 +546,5 @@ if (!field.isValid) {

});
/**
* Ensure the value is a string with latitude and longitude coordinates
*/
export const coordinatesRule = createRule((value, _, field) => {

@@ -383,0 +551,0 @@ if (!field.isValid) {

@@ -5,7 +5,21 @@ import { RefsStore, TupleNode } from '@vinejs/compiler/types';

import type { FieldOptions, ParserOptions, SchemaTypes, Validation } from '../../types.js';
/**
* VineTuple is an array with known length and may have different
* schema type for each array element.
*/
export declare class VineTuple<Schema extends SchemaTypes[], Output extends any[], CamelCaseOutput extends any[]> extends BaseType<Output, CamelCaseOutput> {
#private;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME]: string;
/**
* Checks if the value is of array type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE]: (value: unknown) => boolean;
constructor(schemas: [...Schema], options?: FieldOptions, validations?: Validation<any>[]);
/**
* Copy unknown properties to the final output.
*/
allowUnknownProperties<Value>(): VineTuple<Schema, [

@@ -18,4 +32,10 @@ ...Output,

]>;
/**
* Clone object
*/
clone(): this;
/**
* Compiles to array data type
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): TupleNode;
}

@@ -0,8 +1,30 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';
import { BaseType } from '../base/main.js';
import { IS_OF_TYPE, PARSE, UNIQUE_NAME } from '../../symbols.js';
/**
* VineTuple is an array with known length and may have different
* schema type for each array element.
*/
export class VineTuple extends BaseType {
#schemas;
/**
* Whether or not to allow unknown properties
*/
#allowUnknownProperties = false;
/**
* The property must be implemented for "unionOfTypes"
*/
[UNIQUE_NAME] = 'vine.array';
/**
* Checks if the value is of array type. The method must be
* implemented for "unionOfTypes"
*/
[IS_OF_TYPE] = (value) => {

@@ -15,2 +37,5 @@ return Array.isArray(value);

}
/**
* Copy unknown properties to the final output.
*/
allowUnknownProperties() {

@@ -20,2 +45,5 @@ this.#allowUnknownProperties = true;

}
/**
* Clone object
*/
clone() {

@@ -28,2 +56,5 @@ const cloned = new VineTuple(this.#schemas.map((schema) => schema.clone()), this.cloneOptions(), this.cloneValidations());

}
/**
* Compiles to array data type
*/
[PARSE](propertyName, refs, options) {

@@ -30,0 +61,0 @@ return {

import type { RefsStore, UnionNode } from '@vinejs/compiler/types';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
import type { SchemaTypes, ParserOptions, ConstructableSchema, UnionNoMatchCallback } from '../../types.js';
/**
* Vine union represents a union data type. A union is a collection
* of conditionals and each condition has an associated schema
*/
export declare class VineUnionOfTypes<Schema extends SchemaTypes> implements ConstructableSchema<Schema[typeof OTYPE], Schema[typeof COTYPE]> {

@@ -9,5 +13,15 @@ #private;

constructor(schemas: Schema[]);
/**
* Define a fallback method to invoke when all of the union conditions
* fail. You may use this method to report an error.
*/
otherwise(callback: UnionNoMatchCallback<Record<string, unknown>>): this;
/**
* Clones the VineUnionOfTypes schema type.
*/
clone(): this;
/**
* Compiles to a union
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): UnionNode;
}

@@ -0,4 +1,16 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';
import { messages } from '../../defaults.js';
import { OTYPE, COTYPE, PARSE, IS_OF_TYPE } from '../../symbols.js';
/**
* Vine union represents a union data type. A union is a collection
* of conditionals and each condition has an associated schema
*/
export class VineUnionOfTypes {

@@ -12,2 +24,6 @@ #schemas;

}
/**
* Define a fallback method to invoke when all of the union conditions
* fail. You may use this method to report an error.
*/
otherwise(callback) {

@@ -17,2 +33,5 @@ this.#otherwiseCallback = callback;

}
/**
* Clones the VineUnionOfTypes schema type.
*/
clone() {

@@ -23,2 +42,5 @@ const cloned = new VineUnionOfTypes(this.#schemas);

}
/**
* Compiles to a union
*/
[PARSE](propertyName, refs, options) {

@@ -25,0 +47,0 @@ return {

import { VineUnion } from './main.js';
import { UnionConditional } from './conditional.js';
import type { FieldContext, SchemaTypes } from '../../types.js';
/**
* Create a new union schema type. A union is a collection of conditionals
* and schema associated with it.
*/
export declare function union<Conditional extends UnionConditional<any>>(conditionals: Conditional[]): VineUnion<Conditional>;

@@ -5,0 +9,0 @@ export declare namespace union {

@@ -0,11 +1,29 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { VineUnion } from './main.js';
import { UnionConditional } from './conditional.js';
/**
* Create a new union schema type. A union is a collection of conditionals
* and schema associated with it.
*/
export function union(conditionals) {
return new VineUnion(conditionals);
}
/**
* Wrap object properties inside a conditonal
*/
union.if = function unionIf(conditon, schema) {
return new UnionConditional(conditon, schema);
};
/**
* Wrap object properties inside an else conditon
*/
union.else = function unionElse(schema) {
return new UnionConditional(() => true, schema);
};
import { ConditionalFn, RefsStore, UnionNode } from '@vinejs/compiler/types';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
import type { ParserOptions, SchemaTypes } from '../../types.js';
/**
* Represents a union conditional type. A conditional is a predicate
* with a schema
*/
export declare class UnionConditional<Schema extends SchemaTypes> {

@@ -9,3 +13,6 @@ #private;

constructor(conditional: ConditionalFn<Record<string, unknown>>, schema: Schema);
/**
* Compiles to a union conditional
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): UnionNode['conditions'][number];
}

@@ -0,4 +1,22 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
/**
* Represents a union conditional type. A conditional is a predicate
* with a schema
*/
export class UnionConditional {
/**
* Properties to merge when conditonal is true
*/
#schema;
/**
* Conditional to evaluate
*/
#conditional;

@@ -9,2 +27,5 @@ constructor(conditional, schema) {

}
/**
* Compiles to a union conditional
*/
[PARSE](propertyName, refs, options) {

@@ -11,0 +32,0 @@ return {

@@ -5,2 +5,6 @@ import { RefsStore, UnionNode } from '@vinejs/compiler/types';

import type { ConstructableSchema, ParserOptions, SchemaTypes, UnionNoMatchCallback } from '../../types.js';
/**
* Vine union represents a union data type. A union is a collection
* of conditionals and each condition has an associated schema
*/
export declare class VineUnion<Conditional extends UnionConditional<SchemaTypes>> implements ConstructableSchema<Conditional[typeof OTYPE], Conditional[typeof COTYPE]> {

@@ -11,5 +15,15 @@ #private;

constructor(conditionals: Conditional[]);
/**
* Define a fallback method to invoke when all of the union conditions
* fail. You may use this method to report an error.
*/
otherwise(callback: UnionNoMatchCallback<Record<string, unknown>>): this;
/**
* Clones the VineUnion schema type.
*/
clone(): this;
/**
* Compiles to a union
*/
[PARSE](propertyName: string, refs: RefsStore, options: ParserOptions): UnionNode;
}

@@ -0,4 +1,16 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import camelcase from 'camelcase';
import { messages } from '../../defaults.js';
import { OTYPE, COTYPE, PARSE } from '../../symbols.js';
/**
* Vine union represents a union data type. A union is a collection
* of conditionals and each condition has an associated schema
*/
export class VineUnion {

@@ -12,2 +24,6 @@ #conditionals;

}
/**
* Define a fallback method to invoke when all of the union conditions
* fail. You may use this method to report an error.
*/
otherwise(callback) {

@@ -17,2 +33,5 @@ this.#otherwiseCallback = callback;

}
/**
* Clones the VineUnion schema type.
*/
clone() {

@@ -23,2 +42,5 @@ const cloned = new VineUnion(this.#conditionals);

}
/**
* Compiles to a union
*/
[PARSE](propertyName, refs, options) {

@@ -25,0 +47,0 @@ return {

@@ -0,6 +1,25 @@

/**
* The symbol to define a unique name for the schema type
*/
export declare const UNIQUE_NAME: unique symbol;
/**
* The symbol to check if a value is of the given schema
* type
*/
export declare const IS_OF_TYPE: unique symbol;
/**
* The symbol for the compile method
*/
export declare const PARSE: unique symbol;
/**
* The symbol for the opaque type
*/
export declare const OTYPE: unique symbol;
/**
* The symbol for the camelcase opaque type
*/
export declare const COTYPE: unique symbol;
/**
* The symbol to generate a validation rule from rule builder
*/
export declare const VALIDATION: unique symbol;

@@ -0,6 +1,33 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* The symbol to define a unique name for the schema type
*/
export const UNIQUE_NAME = Symbol.for('schema_nme');
/**
* The symbol to check if a value is of the given schema
* type
*/
export const IS_OF_TYPE = Symbol.for('is_of_type');
/**
* The symbol for the compile method
*/
export const PARSE = Symbol.for('parse');
/**
* The symbol for the opaque type
*/
export const OTYPE = Symbol.for('opaque_type');
/**
* The symbol for the camelcase opaque type
*/
export const COTYPE = Symbol.for('camelcase_opaque_type');
/**
* The symbol to generate a validation rule from rule builder
*/
export const VALIDATION = Symbol.for('to_validation');

@@ -10,17 +10,41 @@ import type { ParseFn, RefsStore, TransformFn, FieldContext, CompilerNodes, MessagesProviderContact, ErrorReporterContract as BaseReporter } from '@vinejs/compiler/types';

import type { OTYPE, COTYPE, PARSE, VALIDATION, UNIQUE_NAME, IS_OF_TYPE } from './symbols.js';
/**
* Options accepted by the mobile number validation
*/
export type MobileOptions = {
locale?: MobilePhoneLocale[];
} & IsMobilePhoneOptions;
/**
* Options accepted by the email address validation
*/
export type EmailOptions = IsEmailOptions;
/**
* Options accepted by the normalize email
*/
export { NormalizeEmailOptions };
/**
* Options accepted by the URL validation
*/
export type URLOptions = IsURLOptions;
/**
* Options accepted by the credit card validation
*/
export type CreditCardOptions = {
provider: ('amex' | 'dinersclub' | 'discover' | 'jcb' | 'mastercard' | 'unionpay' | 'visa')[];
};
/**
* Options accepted by the passport validation
*/
export type PassportOptions = {
countryCode: (typeof helpers)['passportCountryCodes'][number][];
};
/**
* Options accepted by the postal code validation
*/
export type PostalCodeOptions = {
countryCode: (typeof helpers)['postalCountryCodes'][number][];
};
/**
* Options accepted by the alpha rule
*/
export type AlphaOptions = {

@@ -32,4 +56,13 @@ allowSpaces?: boolean;

export type NormalizeUrlOptions = UrlOptions;
/**
* Options accepted by the alpha numeric rule
*/
export type AlphaNumericOptions = AlphaOptions;
/**
* Re-exporting selected types from compiler
*/
export type { Refs, FieldContext, RefIdentifier, ConditionalFn, MessagesProviderContact, } from '@vinejs/compiler/types';
/**
* Representation of a native enum like type
*/
export type EnumLike = {

@@ -39,4 +72,12 @@ [K: string]: string | number;

};
/**
* Representation of fields and messages accepted by the messages
* provider
*/
export type ValidationMessages = Record<string, string>;
export type ValidationFields = Record<string, string>;
/**
* Constructable schema type refers to any type that can be
* constructed for type inference and compiler output
*/
export interface ConstructableSchema<Output, CamelCaseOutput> {

@@ -47,2 +88,5 @@ [OTYPE]: Output;

clone(): this;
/**
* Implement if you want schema type to be used with the unionOfTypes
*/
[UNIQUE_NAME]?: string;

@@ -52,3 +96,18 @@ [IS_OF_TYPE]?: (value: unknown, field: FieldContext) => boolean;

export type SchemaTypes = ConstructableSchema<any, any>;
/**
* Representation of a function that performs validation.
* The function receives the following arguments.
*
* - the current value of the input field
* - runtime options
* - field context
*/
export type Validator<Options extends any> = (value: unknown, options: Options, field: FieldContext) => any | Promise<any>;
/**
* A validation rule is a combination of a validator and
* some metadata required at the time of compiling the
* rule.
*
* Think of this type as "Validator" + "metaData"
*/
export type ValidationRule<Options extends any> = {

@@ -59,11 +118,36 @@ validator: Validator<Options>;

};
/**
* Validation is a combination of a validation rule and the options
* to supply to validator at the time of validating the field.
*
* Think of this type as "ValidationRule" + "options"
*/
export type Validation<Options extends any> = {
/**
* Options to pass to the validator function.
*/
options?: Options;
/**
* The rule to use
*/
rule: ValidationRule<Options>;
};
/**
* A rule builder is an object that implements the "VALIDATION"
* method and returns [[Validation]] type
*/
export interface RuleBuilder {
[VALIDATION](): Validation<any>;
}
/**
* The transform function to mutate the output value
*/
export type Transformer<Schema extends SchemaTypes, Output> = TransformFn<Exclude<Schema[typeof OTYPE], undefined>, Output>;
/**
* The parser function to mutate the input value
*/
export type Parser = ParseFn;
/**
* A set of options accepted by the field
*/
export type FieldOptions = {

@@ -75,16 +159,47 @@ allowNull: boolean;

};
/**
* Options accepted when compiling schema types.
*/
export type ParserOptions = {
toCamelCase: boolean;
};
/**
* Method to invoke when union has no match
*/
export type UnionNoMatchCallback<Input> = (value: Input, field: FieldContext) => any;
/**
* Error reporters must implement the reporter contract interface
*/
export interface ErrorReporterContract extends BaseReporter {
createError(): ValidationError;
}
export type ValidationOptions = {
meta?: Record<string, any>;
/**
* The validator function to validate metadata given to a validation
* pipeline
*/
export type MetaDataValidator = (meta: Record<string, any>) => void;
/**
* Options accepted during the validate call.
*/
export type ValidationOptions<MetaData extends Record<string, any> | undefined> = {
/**
* Messages provider is used to resolve error messages during
* the validation lifecycle
*/
messagesProvider?: MessagesProviderContact;
/**
* Validation errors are reported directly to an error reporter. The reporter
* can decide how to format and output errors.
*/
errorReporter?: () => ErrorReporterContract;
};
} & ([undefined] extends MetaData ? {
meta?: MetaData;
} : {
meta: MetaData;
});
/**
* Infers the schema type
*/
export type Infer<Schema extends {
[OTYPE]: any;
}> = Schema[typeof OTYPE];

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export {};
import type { Validation, Validator } from '../types.js';
/**
* Returns args for the validation function.
*/
type GetArgs<T> = undefined extends T ? [options?: T] : [options: T];
/**
* Convert a validator function to a rule that you can apply
* to any schema type using the `schema.use` method.
*/
export declare function createRule<Options = undefined>(validator: Validator<Options>, metaData?: {

@@ -4,0 +11,0 @@ implicit?: boolean;

@@ -0,1 +1,13 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Convert a validator function to a rule that you can apply
* to any schema type using the `schema.use` method.
*/
export function createRule(validator, metaData) {

@@ -2,0 +14,0 @@ const rule = {

import validator from 'validator';
/**
* Collection of helpers used across the codebase to coerce
* and type-check values from HTML forms.
*/
export declare const helpers: {
/**
* Returns true when value is not null and neither
* undefined
*/
exists(value: any): boolean;
/**
* Returns true when value is null or value is undefined
*/
isMissing(value: any): boolean;
/**
* Returns true when the value is one of the following.
*
* true
* 1
* "1"
* "true"
* "on"
*/
isTrue(value: any): boolean;
/**
* Returns true when the value is one of the following.
*
* false
* 0
* "0"
* "false"
*/
isFalse(value: any): boolean;
/**
* Check if the value is a valid string. This method narrows
* the type of value to string.
*/
isString(value: unknown): value is string;
/**
* Check if the value is a plain JavaScript object. This method
* filters out null and Arrays and does not consider them as Objects.
*/
isObject<Value>(value: unknown): value is Record<PropertyKey, Value>;
/**
* Check if an object has all the mentioned keys
*/
hasKeys(value: Record<string, any>, keys: string[]): boolean;
/**
* Check if the value is an Array.
*/
isArray<Value_1>(value: unknown): value is Value_1[];
/**
* Check if the value is a number or a string representation of a number.
*/
isNumeric(value: any): boolean;
/**
* Casts the value to a number using the Number method.
* Returns NaN when unable to cast.
*/
asNumber(value: any): number;
/**
* Casts the value to a boolean.
*
* - [true, 1, "1", "true", "on"] will be converted to true.
* - [false, 0, "0", "false"] will be converted to false.
* - Everything else will return null. So make sure to handle that case.
*/
asBoolean(value: any): boolean | null;

@@ -33,5 +89,48 @@ isEmail: typeof import("validator/lib/isEmail.js").default;

passportCountryCodes: readonly ["AM", "AR", "AT", "AU", "AZ", "BE", "BG", "BR", "BY", "CA", "CH", "CY", "CZ", "DE", "DK", "DZ", "ES", "FI", "FR", "GB", "GR", "HR", "HU", "IE", "IN", "ID", "IR", "IS", "IT", "JM", "JP", "KR", "KZ", "LI", "LT", "LU", "LV", "LY", "MT", "MZ", "MY", "MX", "NL", "NZ", "PH", "PK", "PL", "PT", "RO", "RU", "SE", "SL", "SK", "TH", "TR", "UA", "US"];
/**
* Check if the value is a valid color hexcode
*/
isHexColor: (value: string) => boolean;
/**
* Check if a URL has valid `A` or `AAAA` DNS records
*/
isActiveURL: (url: string) => Promise<boolean>;
/**
* Check if all the elements inside the dataset are unique.
*
* In case of an array of objects, you must provide one or more keys
* for the fields that must be unique across the objects.
*
* ```ts
* helpers.isDistinct([1, 2, 4, 5]) // true
*
* // Null and undefined values are ignored
* helpers.isDistinct([1, null, 2, null, 4, 5]) // true
*
* helpers.isDistinct([
* {
* email: 'foo@bar.com',
* name: 'foo'
* },
* {
* email: 'baz@bar.com',
* name: 'baz'
* }
* ], 'email') // true
*
* helpers.isDistinct([
* {
* email: 'foo@bar.com',
* tenant_id: 1,
* name: 'foo'
* },
* {
* email: 'foo@bar.com',
* tenant_id: 2,
* name: 'baz'
* }
* ], ['email', 'tenant_id']) // true
* ```
*/
isDistinct: (dataSet: any[], fields?: string | string[]) => boolean;
};

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import validator from 'validator';

@@ -5,21 +13,60 @@ import { resolve4, resolve6 } from 'node:dns/promises';

const BOOLEAN_NEGATIVES = ['0', 0, 'false', false];
/**
* Collection of helpers used across the codebase to coerce
* and type-check values from HTML forms.
*/
export const helpers = {
/**
* Returns true when value is not null and neither
* undefined
*/
exists(value) {
return value !== null && value !== undefined;
},
/**
* Returns true when value is null or value is undefined
*/
isMissing(value) {
return !this.exists(value);
},
/**
* Returns true when the value is one of the following.
*
* true
* 1
* "1"
* "true"
* "on"
*/
isTrue(value) {
return BOOLEAN_POSITIVES.includes(value);
},
/**
* Returns true when the value is one of the following.
*
* false
* 0
* "0"
* "false"
*/
isFalse(value) {
return BOOLEAN_NEGATIVES.includes(value);
},
/**
* Check if the value is a valid string. This method narrows
* the type of value to string.
*/
isString(value) {
return typeof value === 'string';
},
/**
* Check if the value is a plain JavaScript object. This method
* filters out null and Arrays and does not consider them as Objects.
*/
isObject(value) {
return !!(value && typeof value === 'object' && !Array.isArray(value));
},
/**
* Check if an object has all the mentioned keys
*/
hasKeys(value, keys) {

@@ -33,11 +80,28 @@ for (let key of keys) {

},
/**
* Check if the value is an Array.
*/
isArray(value) {
return Array.isArray(value);
},
/**
* Check if the value is a number or a string representation of a number.
*/
isNumeric(value) {
return !Number.isNaN(Number(value));
},
/**
* Casts the value to a number using the Number method.
* Returns NaN when unable to cast.
*/
asNumber(value) {
return value === null ? Number.NaN : Number(value);
},
/**
* Casts the value to a boolean.
*
* - [true, 1, "1", "true", "on"] will be converted to true.
* - [false, 0, "0", "false"] will be converted to false.
* - Everything else will return null. So make sure to handle that case.
*/
asBoolean(value) {

@@ -129,2 +193,5 @@ if (this.isTrue(value)) {

],
/**
* Check if the value is a valid color hexcode
*/
isHexColor: (value) => {

@@ -136,2 +203,5 @@ if (!value.startsWith('#')) {

},
/**
* Check if a URL has valid `A` or `AAAA` DNS records
*/
isActiveURL: async (url) => {

@@ -143,2 +213,3 @@ try {

return true;
/* c8 ignore next 4 */
}

@@ -154,4 +225,44 @@ else {

},
/**
* Check if all the elements inside the dataset are unique.
*
* In case of an array of objects, you must provide one or more keys
* for the fields that must be unique across the objects.
*
* ```ts
* helpers.isDistinct([1, 2, 4, 5]) // true
*
* // Null and undefined values are ignored
* helpers.isDistinct([1, null, 2, null, 4, 5]) // true
*
* helpers.isDistinct([
* {
* email: 'foo@bar.com',
* name: 'foo'
* },
* {
* email: 'baz@bar.com',
* name: 'baz'
* }
* ], 'email') // true
*
* helpers.isDistinct([
* {
* email: 'foo@bar.com',
* tenant_id: 1,
* name: 'foo'
* },
* {
* email: 'foo@bar.com',
* tenant_id: 2,
* name: 'baz'
* }
* ], ['email', 'tenant_id']) // true
* ```
*/
isDistinct: (dataSet, fields) => {
const uniqueItems = new Set();
/**
* Check for duplicates when no fields are provided
*/
if (!fields) {

@@ -170,4 +281,11 @@ for (let item of dataSet) {

}
/**
* Checking for duplicates when one or more fields are mentioned
*/
const fieldsList = Array.isArray(fields) ? fields : [fields];
for (let item of dataSet) {
/**
* Only process item, if it is an object and has all the fields
* required for uniqueness check
*/
if (helpers.isObject(item) && helpers.hasKeys(item, fieldsList)) {

@@ -174,0 +292,0 @@ const element = fieldsList.map((field) => item[field]).join('_');

import { createRule } from './create_rule.js';
import { SchemaBuilder } from '../schema/builder.js';
import { VineValidator } from './validator.js';
import type { Infer, SchemaTypes, ValidationOptions, ErrorReporterContract, MessagesProviderContact } from '../types.js';
import type { Infer, SchemaTypes, MetaDataValidator, ValidationOptions, ErrorReporterContract, MessagesProviderContact } from '../types.js';
/**
* Validate user input with type-safety using a pre-compiled schema.
*/
export declare class Vine extends SchemaBuilder {
/**
* Messages provider to use on the validator
*/
messagesProvider: MessagesProviderContact;
/**
* Error reporter to use on the validator
*/
errorReporter: () => ErrorReporterContract;
/**
* Control whether or not to convert empty strings to null
*/
convertEmptyStringsToNull: boolean;
/**
* Helpers to perform type-checking or cast types keeping
* HTML forms serialization behavior in mind.
*/
helpers: {

@@ -22,3 +38,5 @@ exists(value: any): boolean;

isEmail: typeof import("validator/lib/isEmail.js").default;
isURL: typeof import("validator/lib/isURL.js").default;
isURL: typeof import("validator/lib/isURL.js").default; /**
* Schema to use for validation
*/
isAlpha: typeof import("validator").default.isAlpha;

@@ -45,8 +63,46 @@ isAlphaNumeric: typeof import("validator").default.isAlphanumeric;

};
/**
* Convert a validation function to a Vine schema rule
*/
createRule: typeof createRule;
compile<Schema extends SchemaTypes>(schema: Schema): VineValidator<Schema>;
/**
* Pre-compiles a schema into a validation function.
*
* ```ts
* const validate = vine.compile(schema)
* await validate({ data })
* ```
*/
compile<Schema extends SchemaTypes>(schema: Schema): VineValidator<Schema, Record<string, any> | undefined>;
/**
* Define a callback to validate the metadata given to the validator
* at runtime
*/
withMetaData<MetaData extends Record<string, any>>(callback?: MetaDataValidator): {
compile: <Schema extends SchemaTypes>(schema: Schema) => VineValidator<Schema, MetaData>;
};
/**
* Validate data against a schema. Optionally, you can define
* error messages, fields, a custom messages provider,
* or an error reporter.
*
* ```ts
* await vine.validate({ schema, data })
* await vine.validate({ schema, data, messages, fields })
*
* await vine.validate({ schema, data, messages, fields }, {
* errorReporter
* })
* ```
*/
validate<Schema extends SchemaTypes>(options: {
/**
* Schema to use for validation
*/
schema: Schema;
/**
* Data to validate
*/
data: any;
} & ValidationOptions): Promise<Infer<Schema>>;
} & ValidationOptions<Record<string, any> | undefined>): Promise<Infer<Schema>>;
}

@@ -0,1 +1,9 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { helpers } from './helpers.js';

@@ -8,8 +16,35 @@ import { createRule } from './create_rule.js';

import { SimpleErrorReporter } from '../reporters/simple_error_reporter.js';
/**
* Validate user input with type-safety using a pre-compiled schema.
*/
export class Vine extends SchemaBuilder {
/**
* Messages provider to use on the validator
*/
messagesProvider = new SimpleMessagesProvider(messages, fields);
/**
* Error reporter to use on the validator
*/
errorReporter = () => new SimpleErrorReporter();
/**
* Control whether or not to convert empty strings to null
*/
convertEmptyStringsToNull = false;
/**
* Helpers to perform type-checking or cast types keeping
* HTML forms serialization behavior in mind.
*/
helpers = helpers;
/**
* Convert a validation function to a Vine schema rule
*/
createRule = createRule;
/**
* Pre-compiles a schema into a validation function.
*
* ```ts
* const validate = vine.compile(schema)
* await validate({ data })
* ```
*/
compile(schema) {

@@ -22,2 +57,32 @@ return new VineValidator(schema, {

}
/**
* Define a callback to validate the metadata given to the validator
* at runtime
*/
withMetaData(callback) {
return {
compile: (schema) => {
return new VineValidator(schema, {
convertEmptyStringsToNull: this.convertEmptyStringsToNull,
messagesProvider: this.messagesProvider,
errorReporter: this.errorReporter,
metaDataValidator: callback,
});
},
};
}
/**
* Validate data against a schema. Optionally, you can define
* error messages, fields, a custom messages provider,
* or an error reporter.
*
* ```ts
* await vine.validate({ schema, data })
* await vine.validate({ schema, data, messages, fields })
*
* await vine.validate({ schema, data, messages, fields }, {
* errorReporter
* })
* ```
*/
validate(options) {

@@ -24,0 +89,0 @@ const validator = this.compile(options.schema);

import type { MessagesProviderContact } from '@vinejs/compiler/types';
import { OTYPE } from '../symbols.js';
import type { ErrorReporterContract, Infer, SchemaTypes, ValidationOptions } from '../types.js';
export declare class VineValidator<Schema extends SchemaTypes> {
import type { Infer, SchemaTypes, MetaDataValidator, ValidationOptions, ErrorReporterContract } from '../types.js';
/**
* Vine Validator exposes the API to validate data using a pre-compiled
* schema.
*/
export declare class VineValidator<Schema extends SchemaTypes, MetaData extends undefined | Record<string, any>> {
#private;
/**
* Reference to static types
*/
[OTYPE]: Schema[typeof OTYPE];
/**
* Messages provider to use on the validator
*/
messagesProvider: MessagesProviderContact;
/**
* Error reporter to use on the validator
*/
errorReporter: () => ErrorReporterContract;
constructor(schema: Schema, options: {
convertEmptyStringsToNull: boolean;
metaDataValidator?: MetaDataValidator;
messagesProvider: MessagesProviderContact;
errorReporter: () => ErrorReporterContract;
});
validate(data: any, options?: ValidationOptions): Promise<Infer<Schema>>;
/**
* Validate data against a schema. Optionally, you can share metaData with
* the validator
*
* ```ts
* await validator.validate(data)
* await validator.validate(data, { meta: {} })
*
* await validator.validate(data, {
* meta: { userId: auth.user.id },
* errorReporter,
* messagesProvider
* })
* ```
*/
validate(data: any, ...[options]: [undefined] extends MetaData ? [options?: ValidationOptions<MetaData> | undefined] : [options: ValidationOptions<MetaData>]): Promise<Infer<Schema>>;
}

@@ -0,4 +1,15 @@

/*
* @vinejs/vine
*
* (c) VineJS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Compiler, refsBuilder } from '@vinejs/compiler';
import { messages } from '../defaults.js';
import { OTYPE, PARSE } from '../symbols.js';
/**
* Error messages to share with the compiler
*/
const COMPILER_ERROR_MESSAGES = {

@@ -9,5 +20,22 @@ required: messages.required,

};
/**
* Vine Validator exposes the API to validate data using a pre-compiled
* schema.
*/
export class VineValidator {
/**
* Validator to use to validate metadata
*/
#metaDataValidator;
/**
* Messages provider to use on the validator
*/
messagesProvider;
/**
* Error reporter to use on the validator
*/
errorReporter;
/**
* Parses schema to compiler nodes.
*/
#parse(schema) {

@@ -23,3 +51,9 @@ const refs = refsBuilder();

}
/**
* Refs computed from the compiled output
*/
#refs;
/**
* Compiled validator function
*/
#validateFn;

@@ -35,4 +69,23 @@ constructor(schema, options) {

this.messagesProvider = options.messagesProvider;
this.#metaDataValidator = options.metaDataValidator;
}
validate(data, options) {
/**
* Validate data against a schema. Optionally, you can share metaData with
* the validator
*
* ```ts
* await validator.validate(data)
* await validator.validate(data, { meta: {} })
*
* await validator.validate(data, {
* meta: { userId: auth.user.id },
* errorReporter,
* messagesProvider
* })
* ```
*/
validate(data, ...[options]) {
if (options?.meta && this.#metaDataValidator) {
this.#metaDataValidator(options.meta);
}
const errorReporter = options?.errorReporter || this.errorReporter;

@@ -39,0 +92,0 @@ const messagesProvider = options?.messagesProvider || this.messagesProvider;

59

package.json
{
"name": "@vinejs/vine",
"version": "1.4.1",
"version": "1.5.0",
"description": "Form data validation library for Node.js",

@@ -28,2 +28,3 @@ "type": "module",

"benchmark": "node build/benchmarks/flat_object.js && node build/benchmarks/nested_object.js && node build/benchmarks/array.js && node build/benchmarks/union.js",
"typecheck": "tsc --noEmit",
"compile": "npm run lint && npm run clean && tsc",

@@ -46,10 +47,10 @@ "build": "npm run compile",

"devDependencies": {
"@adonisjs/eslint-config": "^1.1.6",
"@adonisjs/prettier-config": "^1.1.6",
"@adonisjs/tsconfig": "^1.1.6",
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@japa/assert": "^1.4.1",
"@japa/expect-type": "^1.0.3",
"@japa/run-failed-tests": "^1.1.1",
"@japa/runner": "^2.5.1",
"@japa/snapshot": "^1.0.1-2",
"@japa/spec-reporter": "^1.3.3",
"@japa/assert": "^2.0.0-1",
"@japa/expect-type": "^2.0.0-0",
"@japa/runner": "^3.0.0-2",
"@swc/core": "^1.3.63",

@@ -61,5 +62,2 @@ "@types/node": "^20.3.1",

"eslint": "^8.42.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-adonis": "^3.0.3",
"eslint-plugin-prettier": "^4.2.1",
"github-label-sync": "^2.3.1",

@@ -74,35 +72,2 @@ "husky": "^8.0.3",

},
"eslintConfig": {
"extends": [
"plugin:adonis/typescriptPackage",
"prettier"
],
"plugins": [
"prettier"
],
"rules": {
"@typescript-eslint/no-floating-promises": [
"error"
],
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
}
},
"eslintIgnore": [
"build"
],
"prettier": {
"trailingComma": "es5",
"semi": false,
"singleQuote": true,
"useTabs": false,
"quoteProps": "consistent",
"bracketSpacing": true,
"arrowParens": "always",
"printWidth": 100
},
"commitlint": {

@@ -134,3 +99,3 @@ "extends": [

"@types/validator": "^13.7.17",
"@vinejs/compiler": "^2.0.1",
"@vinejs/compiler": "^2.1.0",
"camelcase": "^7.0.1",

@@ -151,3 +116,7 @@ "normalize-url": "^8.0.0",

},
"homepage": "https://github.com/vinejs/vine#readme"
"homepage": "https://github.com/vinejs/vine#readme",
"eslintConfig": {
"extends": "@adonisjs/eslint-config/package"
},
"prettier": "@adonisjs/prettier-config"
}

@@ -29,3 +29,3 @@ # @vinejs/vine

<span> | </span>
<a href=".github/CONTRIBUTING.md">
<a href="https://github.com/vinejs/.github/blob/main/docs/CONTRIBUTING.md">
Contributing

@@ -32,0 +32,0 @@ </a>

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc