UNPKG

veffect

Version:

powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha

213 lines (212 loc) 8.18 kB
/** * Core types for the validation library */ import type { Effect } from './internal/effect'; /** * Represents the result of a validation operation */ export type ValidationResult<T> = Effect<T, ValidationError>; /** * Base interface for validation errors */ export interface ValidationError { readonly _tag: string; readonly message: string; readonly path?: string[]; } /** * Configuration options for validators */ export interface ValidatorOptions { readonly path?: string[]; readonly stopOnFirstError?: boolean; } /** * Core validator interface */ export interface Validator<T, I = unknown> { /** * Validates input and returns an Effect (internal implementation) */ readonly validate: (input: I, options?: ValidatorOptions) => ValidationResult<T>; /** * Synchronously parses and validates input * Throws an error if validation fails */ readonly parse: (input: I) => T | never; /** * Synchronously parses and validates input * Returns a result object indicating success or failure */ readonly safeParse: (input: I) => { success: true; data: T; } | { success: false; error: ValidationError; }; /** * Asynchronously validates input * Returns a Promise that resolves with the validated data or rejects with a validation error */ readonly validateAsync: (input: I, options?: ValidatorOptions) => Promise<T>; } /** * Schema definition interface */ export interface Schema<T, I = unknown> { readonly _tag: string; readonly toValidator: () => Validator<T, I>; } /** * Generic interface for schemas supporting refinement */ export interface RefinableSchema<T, S extends Schema<T>> { /** * Add a refinement to validate the output further */ readonly refine: (refinement: (value: T) => boolean | Promise<boolean>, message?: string | ((value: T) => string)) => S; } /** * Generic interface for schemas that can be transformed */ export interface TransformableSchema<T, S> { /** * Transform the output of this schema */ readonly transform: <U>(transformer: (value: T) => U) => Schema<U, unknown>; } /** * Generic interface for schemas that can have default values */ export interface DefaultableSchema<T, S extends Schema<T>> { /** * Define a default value if the input is undefined */ readonly default: (defaultValue: T | (() => T)) => S; } /** * Generic interface for schemas that can be optional or nullable */ export interface NullableSchema<T, S extends Schema<T>> { /** * Make this schema accept null values */ readonly nullable: () => Schema<T | null>; /** * Make this schema accept undefined values */ readonly optional: () => Schema<T | undefined>; /** * Make this schema accept null or undefined values */ readonly nullish: () => Schema<T | null | undefined>; } /** * Generic interface for schemas with specific string or number validations */ export interface PredicateSchema<T, S extends Schema<T>> { /** * Validate with a custom predicate function */ readonly predicate: (predicate: (value: T) => boolean, message?: string | ((value: T) => string)) => S; } /** * Generic interface for schemas that can have custom error messages */ export interface CustomErrorsSchema<T, S extends Schema<T>> { /** * Override error message for this schema */ readonly error: (message: string) => S; } /** * Catch-all union schema interface */ export interface CatchAllSchema<T> extends Schema<T> { readonly catchAll: <U>(fallback: U | ((error: ValidationError) => U)) => Schema<T | U>; } /** * Boolean schema interface */ export interface BooleanSchema extends Schema<boolean>, RefinableSchema<boolean, BooleanSchema>, TransformableSchema<boolean, BooleanSchema>, DefaultableSchema<boolean, BooleanSchema>, NullableSchema<boolean, BooleanSchema> { readonly _tag: 'BooleanSchema'; } /** * String schema interface */ export interface StringSchema extends Schema<string>, RefinableSchema<string, StringSchema>, TransformableSchema<string, StringSchema>, DefaultableSchema<string, StringSchema>, NullableSchema<string, StringSchema>, PredicateSchema<string, StringSchema>, CustomErrorsSchema<string, StringSchema> { readonly _tag: 'StringSchema'; readonly minLength: (min: number, message?: string) => StringSchema; readonly maxLength: (max: number, message?: string) => StringSchema; readonly length: (length: number, message?: string) => StringSchema; readonly regex: (pattern: RegExp, message?: string) => StringSchema; readonly email: (message?: string) => StringSchema; readonly url: (message?: string) => StringSchema; readonly uuid: (message?: string) => StringSchema; readonly cuid: (message?: string) => StringSchema; readonly cuid2: (message?: string) => StringSchema; readonly ulid: (message?: string) => StringSchema; readonly startsWith: (substring: string, message?: string) => StringSchema; readonly endsWith: (substring: string, message?: string) => StringSchema; readonly includes: (substring: string, message?: string) => StringSchema; readonly datetime: (options?: { offset?: boolean; precision?: number; local?: boolean; }, message?: string) => StringSchema; readonly ip: (version?: 'v4' | 'v6', message?: string) => StringSchema; readonly nonempty: (message?: string) => StringSchema; readonly trim: (message?: string) => StringSchema; readonly toLowerCase: () => StringSchema; readonly toUpperCase: () => StringSchema; readonly emoji: (message?: string) => StringSchema; readonly nanoid: (message?: string) => StringSchema; readonly cidr: (options?: { version?: 'v4' | 'v6'; }, message?: string) => StringSchema; readonly base64: (message?: string) => StringSchema; readonly date: (message?: string) => StringSchema; readonly time: (options?: { precision?: number; }, message?: string) => StringSchema; readonly duration: (message?: string) => StringSchema; } /** * Number schema interface */ export interface NumberSchema extends Schema<number>, RefinableSchema<number, NumberSchema>, TransformableSchema<number, NumberSchema>, DefaultableSchema<number, NumberSchema>, NullableSchema<number, NumberSchema> { readonly _tag: 'NumberSchema'; readonly min: (min: number, message?: string) => NumberSchema; readonly max: (max: number, message?: string) => NumberSchema; readonly integer: (message?: string) => NumberSchema; readonly positive: (message?: string) => NumberSchema; readonly negative: (message?: string) => NumberSchema; readonly nonnegative: (message?: string) => NumberSchema; readonly nonpositive: (message?: string) => NumberSchema; readonly multipleOf: (value: number, message?: string) => NumberSchema; readonly finite: (message?: string) => NumberSchema; readonly safe: (message?: string) => NumberSchema; readonly step: (step: number, message?: string) => NumberSchema; readonly port: (message?: string) => NumberSchema; } /** * Array schema interface */ export interface ArraySchema<T> extends Schema<T[]>, RefinableSchema<T[], ArraySchema<T>>, TransformableSchema<T[], ArraySchema<T>>, DefaultableSchema<T[], ArraySchema<T>>, NullableSchema<T[], ArraySchema<T>> { readonly _tag: 'ArraySchema'; readonly elementSchema: Schema<T>; readonly minLength: (min: number, message?: string) => ArraySchema<T>; readonly maxLength: (max: number, message?: string) => ArraySchema<T>; readonly length: (length: number, message?: string) => ArraySchema<T>; readonly nonEmpty: (message?: string) => ArraySchema<T>; } /** * Object schema interface */ export interface ObjectSchema<T extends Record<string, any>> extends Schema<T>, RefinableSchema<T, ObjectSchema<T>>, TransformableSchema<T, ObjectSchema<T>>, DefaultableSchema<T, ObjectSchema<T>>, NullableSchema<T, ObjectSchema<T>> { readonly _tag: 'ObjectSchema'; readonly properties: { [K in keyof T]: Schema<T[K]>; }; }