validlyjs
Version:
A high-performance Laravel-inspired validation library for TypeScript/JavaScript
423 lines (402 loc) • 14.1 kB
TypeScript
type RuleDefinition = FluentRule | StringRule | ArrayRule | UnionRule;
interface FluentRule {
_type: 'fluent';
_rules: CompiledRule[];
_dataType: DataType;
_modifiers: RuleModifier[];
required(): FluentRule;
nullable(): FluentRule;
optional(): FluentRule;
custom(name: string, parameters?: any[]): FluentRule;
requiredIf(field: string, value: any | ((value: any) => boolean)): FluentRule;
requiredWith(...fields: string[]): FluentRule;
requiredWithAll(fields: string[]): FluentRule;
requiredWithout(...fields: string[]): FluentRule;
requiredWithoutAll(fields: string[]): FluentRule;
requiredUnless(field: string, value: any): FluentRule;
when(field: string, conditions: WhenConditions): FluentRule;
}
interface WhenConditions {
[key: string]: {
[operator: string]: any;
} | any;
then?: RuleDefinition;
otherwise?: RuleDefinition;
}
type StringRule = string;
type ArrayRule = string[] | string[][];
interface UnionRule {
_type: 'union';
rules: RuleDefinition[];
stopOnFirstPass?: boolean;
}
type DataType = 'string' | 'number' | 'boolean' | 'date' | 'file' | 'array' | 'object' | 'union' | 'custom' | 'any';
interface RuleModifier {
type: 'required' | 'nullable' | 'optional' | 'conditional';
parameters?: any[];
}
interface StringFluentRule extends FluentRule {
min(length: number): StringFluentRule;
max(length: number): StringFluentRule;
length(length: number): StringFluentRule;
email(): StringFluentRule;
url(): StringFluentRule;
regex(pattern: RegExp): StringFluentRule;
alpha(): StringFluentRule;
alphaNum(): StringFluentRule;
alphaNumDash(): StringFluentRule;
uuid(): StringFluentRule;
json(): StringFluentRule;
startsWith(prefix: string): StringFluentRule;
endsWith(suffix: string): StringFluentRule;
contains(substring: string): StringFluentRule;
in(values: string[]): StringFluentRule;
notIn(values: string[]): StringFluentRule;
}
interface NumberFluentRule extends FluentRule {
min(value: number): NumberFluentRule;
max(value: number): NumberFluentRule;
between(min: number, max: number): NumberFluentRule;
positive(): NumberFluentRule;
negative(): NumberFluentRule;
integer(): NumberFluentRule;
decimal(places?: number): NumberFluentRule;
multipleOf(value: number): NumberFluentRule;
}
interface BooleanFluentRule extends FluentRule {
true(): BooleanFluentRule;
false(): BooleanFluentRule;
}
interface DateFluentRule extends FluentRule {
after(date: string | Date): DateFluentRule;
before(date: string | Date): DateFluentRule;
afterOrEqual(date: string | Date): DateFluentRule;
beforeOrEqual(date: string | Date): DateFluentRule;
format(format: string): DateFluentRule;
timezone(timezone: string): DateFluentRule;
weekday(): DateFluentRule;
weekend(): DateFluentRule;
}
interface FileFluentRule extends FluentRule {
mimeTypes(types: string[]): FileFluentRule;
extensions(extensions: string[]): FileFluentRule;
size(): FileSizeFluentRule;
image(): FileFluentRule;
dimensions(): FileDimensionsFluentRule;
}
interface FileSizeFluentRule extends FileFluentRule {
min(size: string | number): FileFluentRule;
max(size: string | number): FileFluentRule;
}
interface FileDimensionsFluentRule extends FileFluentRule {
width(width: number): FileFluentRule;
height(height: number): FileFluentRule;
minWidth(width: number): FileFluentRule;
maxWidth(width: number): FileFluentRule;
minHeight(height: number): FileFluentRule;
maxHeight(height: number): FileFluentRule;
}
interface ArrayFluentRule extends FluentRule {
min(length: number): ArrayFluentRule;
max(length: number): ArrayFluentRule;
length(length: number): ArrayFluentRule;
each(rule: RuleDefinition): ArrayFluentRule;
unique(): ArrayFluentRule;
contains(value: any): ArrayFluentRule;
}
interface ObjectFluentRule extends FluentRule {
shape(schema: Record<string, RuleDefinition>): ObjectFluentRule;
keys(keys: string[]): ObjectFluentRule;
strict(): ObjectFluentRule;
}
type ValidationSchema = Record<string, RuleDefinition>;
interface ValidatorOptions {
responseType?: ResponseType;
language?: string;
messages?: Record<string, string>;
fieldMessages?: Record<string, string>;
stopOnFirstError?: boolean;
coercion?: CoercionOptions;
performance?: PerformanceOptions;
debug?: boolean;
}
interface CoercionOptions {
enabled?: boolean;
strings?: boolean;
numbers?: boolean;
booleans?: boolean;
dates?: boolean;
}
interface PerformanceOptions {
cacheRules?: boolean;
optimizeUnions?: boolean;
parallelValidation?: boolean;
compileRules?: boolean;
}
type ResponseType = 'laravel' | 'flat' | 'grouped' | 'nested';
interface CustomRuleDefinition {
validate: (value: any, parameters: any[], field: string, data: Record<string, any>) => boolean | Promise<boolean>;
message: string;
async?: boolean;
priority?: number;
}
interface RuleResult {
passed: boolean;
message?: string;
skip?: boolean;
}
interface CompiledRule {
name: string;
validator: (value: any, context: ValidationContext) => RuleResult | Promise<RuleResult>;
async: boolean;
dependencies?: string[];
parameters?: any[];
}
interface LanguagePack {
[key: string]: string;
}
interface GlobalConfig$1 {
responseType: ResponseType;
stopOnFirstError?: boolean;
language: string;
messages: Record<string, string>;
fieldMessages: Record<string, string>;
customLanguages?: Record<string, LanguagePack>;
performance?: PerformanceOptions;
errorHandling?: ErrorHandlingOptions;
coercion?: CoercionOptions;
debug?: boolean;
}
interface ErrorHandlingOptions {
stopOnFirstError: boolean;
includeFieldPath: boolean;
includeRuleName: boolean;
verboseErrors: boolean;
includeStackTrace: boolean;
}
type ValidationContext = {
field: string;
data: Record<string, any>;
parentPath?: string;
path?: string;
index?: number;
parameters?: any[];
};
interface ValidationResult {
isValid: boolean;
errors: ValidationError[];
data?: any;
}
interface ValidationError {
field: string;
rule: string;
message: string;
value: any;
parameters: any[];
}
declare class Validator {
private schema;
private options;
private ruleEngine;
private fieldResolver;
private unionValidator;
private asyncValidator;
private messageResolver;
private responseFormatter;
private cache;
private compiler;
private compiledRules;
private readonly defaultOptions;
private readonly coercionEnabled;
private readonly coercionConfig;
private readonly stopOnFirstError;
private readonly debugMode;
private readonly schemaKeys;
private readonly wildcardPatterns;
private readonly ruleNameToCoercionMap;
private readonly fieldPathToWildcardCache;
constructor(schema: ValidationSchema, options?: ValidatorOptions);
private validateSchema;
private coerceValue;
validateSync(data: Record<string, any>): ValidationResult;
validate(data: Record<string, any>): Promise<ValidationResult>;
private validateField;
private validateFieldWithAsync;
private getCompiledRules;
private createWildcardRegex;
private findWildcardPattern;
private compileSchema;
private getDefaultOptions;
extend(name: string, rule: CustomRuleDefinition): void;
refresh(): void;
private clearCompiledRulesCaches;
setLanguage(language: string): void;
createLanguage(code: string, messages: any): void;
setMessages(messages: Record<string, string>): void;
setFieldMessages(fieldMessages: Record<string, string>): void;
static extend(name: string, rule: CustomRuleDefinition): void;
static configure(config: Partial<GlobalConfig$1>): void;
static usePreset(preset: string): void;
static createPreset(name: string, config: Partial<GlobalConfig$1>): void;
}
declare class GlobalConfig {
private static config;
static configure(config: Partial<GlobalConfig$1>): void;
static usePreset(preset: string): void;
static createPreset(name: string, config: Partial<GlobalConfig>): void;
static getConfig(): GlobalConfig$1;
}
declare abstract class BaseFluentBuilder implements FluentRule {
_type: 'fluent';
_rules: CompiledRule[];
_modifiers: RuleModifier[];
_dataType: DataType;
constructor(dataType: DataType);
protected addRegistryRule(ruleName: string, parameters?: any[]): this;
required(): this;
nullable(): this;
optional(): this;
custom(name: string, parameters?: any[]): this;
requiredIf(field: string, value: any | ((value: any) => boolean)): this;
requiredWith(...fields: string[]): this;
requiredWithAll(fields: string[]): this;
requiredWithout(...fields: string[]): this;
requiredWithoutAll(fields: string[]): this;
requiredUnless(field: string, value: any): this;
prohibited(): this;
prohibitedIf(field: string, value: any): this;
prohibitedUnless(field: string, value: any): this;
same(field: string): this;
present(field: string): this;
confirmed(field: string): this;
different(field: string): this;
when(field: string, conditions: any): this;
}
declare class StringBuilder extends BaseFluentBuilder implements StringFluentRule {
constructor();
min(length: number): this;
max(length: number): this;
length(length: number): this;
email(): this;
url(): this;
regex(pattern: RegExp | string): this;
alpha(): this;
alphaNum(): this;
alphaNumDash(): this;
uuid(): this;
json(): this;
startsWith(prefix: string): this;
endsWith(suffix: string): this;
contains(substring: string): this;
in(values: string[]): this;
notIn(values: string[]): this;
}
declare class NumberBuilder extends BaseFluentBuilder implements NumberFluentRule {
constructor();
min(minValue: number): this;
max(maxValue: number): this;
between(min: number, max: number): this;
positive(): this;
negative(): this;
integer(): this;
decimal(places?: number): this;
multipleOf(divisor: number): this;
}
declare class BooleanBuilder extends BaseFluentBuilder implements BooleanFluentRule {
constructor();
true(): this;
accepted(): this;
false(): this;
}
declare class DateBuilder extends BaseFluentBuilder implements DateFluentRule {
constructor();
after(date: string | Date): this;
before(date: string | Date): this;
afterOrEqual(date: string | Date): this;
beforeOrEqual(date: string | Date): this;
format(format: string): this;
timezone(timezone: string): this;
weekday(): this;
weekend(): this;
}
declare class FileBuilder extends BaseFluentBuilder implements FileFluentRule {
constructor();
mimeTypes(types: string[]): this;
extensions(extensions: string[]): this;
size(): FileSizeBuilder;
image(): this;
dimensions(): FileDimensionsBuilder;
min(size: string | number): this;
max(size: string | number): this;
between(min: string | number, max: string | number): this;
}
declare class FileSizeBuilder extends FileBuilder implements FileSizeFluentRule {
constructor(parentBuilder: FileBuilder);
min(size: string | number): this;
max(size: string | number): this;
}
declare class FileDimensionsBuilder extends FileBuilder implements FileDimensionsFluentRule {
constructor(parentBuilder: FileBuilder);
width(width: number): this;
height(height: number): this;
minWidth(width: number): this;
maxWidth(width: number): this;
minHeight(height: number): this;
maxHeight(height: number): this;
}
declare class ArrayBuilder extends BaseFluentBuilder implements ArrayFluentRule {
constructor();
min(length: number): this;
max(length: number): this;
length(length: number): this;
each(rule: RuleDefinition): this;
unique(): this;
contains(value: any): this;
}
declare class ObjectBuilder extends BaseFluentBuilder implements ObjectFluentRule {
constructor();
shape(schema: Record<string, RuleDefinition>): this;
keys(keys: string[]): this;
strict(): this;
}
declare class UnionBuilder extends BaseFluentBuilder {
private rules;
constructor();
add(rule: RuleDefinition): this;
stopOnFirstPass(enabled?: boolean): this;
}
interface NetworkFluentRule {
port(): this;
domain(): this;
}
declare class NetworkBuilder extends BaseFluentBuilder implements NetworkFluentRule {
constructor();
port(): this;
domain(): this;
}
declare class CoreBuilder {
static string(): StringBuilder;
static number(): NumberBuilder;
static boolean(): BooleanBuilder;
static date(): DateBuilder;
static file(): FileBuilder;
static array(): ArrayBuilder;
static object(): ObjectBuilder;
static union(): UnionBuilder;
static network(): NetworkBuilder;
}
declare const string: typeof CoreBuilder.string;
declare const number: typeof CoreBuilder.number;
declare const boolean: typeof CoreBuilder.boolean;
declare const date: typeof CoreBuilder.date;
declare const file: typeof CoreBuilder.file;
declare const array: typeof CoreBuilder.array;
declare const object: typeof CoreBuilder.object;
declare const union: typeof CoreBuilder.union;
declare function configure(config: Partial<GlobalConfig$1>): void;
declare function extend(name: string, rule: CustomRuleDefinition): void;
declare function usePreset(preset: string): void;
declare function createPreset(name: string, config: Partial<GlobalConfig$1>): void;
declare const version = "2.0.0";
export { GlobalConfig, Validator, array, boolean, configure, createPreset, date, extend, file, number, object, string, union, usePreset, version };
export type { CustomRuleDefinition, GlobalConfig$1 as GlobalConfigType, RuleDefinition, ValidationError, ValidationResult, ValidatorOptions };