@vinejs/vine
Advanced tools
Comparing version 1.4.1 to 1.5.0
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; |
{ | ||
"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> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
202541
22
6232
Updated@vinejs/compiler@^2.1.0