UNPKG

n4s

Version:

typed schema validation version of enforce

1,284 lines (1,282 loc) 53.4 kB
import { CB, DropFirst, Stringable, greaterThan as greaterThan$1, isEmpty as isEmpty$2, numberEquals as numberEquals$1 } from "vest-utils"; import { StandardSchemaV1 } from "vest-utils/standardSchemaSpec"; //#region src/utils/RuleRunReturn.d.ts /** * Represents the result of a validation rule execution. * Contains the pass/fail status, the validated type, and an optional error message. * * @template T - The type of value that was validated * * @example * ```typescript * const result = RuleRunReturn.Passing('hello'); * console.log(result.pass); // true * console.log(result.type); // 'hello' * * const failed = RuleRunReturn.Failing(123, 'Must be positive'); * console.log(failed.pass); // false * console.log(failed.message); // 'Must be positive' * ``` */ declare class RuleRunReturn<T> { /** Whether the validation passed */ pass: boolean; /** The validated value's type */ type: T; /** Optional error message if validation failed */ message?: string; path?: string[]; constructor(pass: boolean, type: T, message?: string); /** * Creates a RuleRunReturn from a boolean or existing RuleRunReturn. * Handles message resolution and type coercion. * * @param pass - Boolean indicating success, or existing RuleRunReturn * @param type - The type of the validated value * @param message - Optional error message (can be string or function) * @returns A new RuleRunReturn instance */ static create<T>(pass: boolean | RuleRunReturn<T>, type: T, message?: Stringable): RuleRunReturn<T>; private static fromObject; /** * Creates a passing RuleRunReturn. * * @param type - The validated value's type * @param message - Optional success message * @returns A RuleRunReturn with pass=true * * @example * ```typescript * const result = RuleRunReturn.Passing('valid'); * console.log(result.pass); // true * ``` */ static Passing<T>(type: T, message?: Stringable): RuleRunReturn<T>; /** * Creates a failing RuleRunReturn. * * @param type - The validated value's type * @param message - Optional error message * @returns A RuleRunReturn with pass=false * * @example * ```typescript * const result = RuleRunReturn.Failing(123, 'Number must be positive'); * console.log(result.pass); // false * console.log(result.message); // 'Number must be positive' * ``` */ static Failing<T>(type: T, message?: Stringable): RuleRunReturn<T>; } //#endregion //#region src/utils/RuleInstance.d.ts /** * Represents a lazy validation rule that can be executed with a value. * RuleInstances support chaining and can be reused across multiple validations. * Implements StandardSchemaV1 for interoperability with other schema libraries. * * @template T - The output type this rule produces (may differ from input when parsers are used) * @template Args - The argument types for this rule (Args[0] is the input type) * * @example * ```typescript * const stringRule = enforce.isString(); * * // Test returns boolean * stringRule.test('hello'); // true * stringRule.test(123); // false * * // StandardSchema validate method * const schemaResult = stringRule.validate('hello'); * console.log(schemaResult.value); // 'hello' * ``` */ declare class RuleInstance<T, Args$1 extends any[] = any[]> { [key: string]: any; infer: T; test: (...args: Args$1) => boolean; run: (...args: Args$1) => RuleRunReturn<T>; validate: (...args: Args$1) => StandardSchemaV1.Result<T>; parse: (...args: Args$1) => T; '~standard': StandardSchemaV1.Props<Args$1[0], T> & { readonly types: StandardSchemaV1.Types<Args$1[0], T>; }; private constructor(); /** * Creates a new RuleInstance from a validation function. * The created instance provides `test()`, `validate()` methods * and the `~standard` property for StandardSchema compliance. * * @param rule - Validation function that returns a RuleRunReturn * @returns A new RuleInstance that can be executed with values */ static create<R$1 extends RuleInstance<T, Args$1>, T, Args$1 extends any[]>(rule: (...args: Args$1) => RuleRunReturn<T>): R$1; } //#endregion //#region src/rules/RuleInstanceBuilder.d.ts type InferRuleReturn<TValue, TFunc> = TFunc extends ((...args: any[]) => { type: infer U; }) ? U : TValue; /** * Generic type utility to build RuleInstance interfaces with chaining methods. * Eliminates repetitive interface definitions across rule type files. * * @template TValue - The value type being validated * @template TArgs - Tuple of arguments for the RuleInstance * @template TRules - Record of rule functions available for this type */ type BuildRuleInstance<TValue, TArgs extends [any, ...any[]], TRules$1 extends Record<string, (...args: any[]) => any>> = RuleInstance<TValue, TArgs> & { [K in keyof TRules$1]: (...args: DropFirst<Parameters<TRules$1[K]>>) => BuildRuleInstance<InferRuleReturn<TValue, TRules$1[K]>, TArgs, TRules$1> }; /** * Helper type to extract rule functions from a module exports object. * Filters out non-function exports and type-only exports. */ type ExtractRuleFunctions<T> = { [K in keyof T as T[K] extends ((...args: any[]) => any) ? K : never]: T[K] }; //#endregion //#region src/rules/array/includes.d.ts declare function includes<T>(arr: T[], item: T): boolean; //#endregion //#region src/rules/array/isArrayRule.d.ts /** * Validates that a value is an array. * Type guard that narrows the type to any[]. * * @param value - Value to validate * @returns True if value is an array * * @example * ```typescript * // Eager API * enforce([1, 2, 3]).isArray(); // passes * enforce('hello').isArray(); // fails * * // Lazy API * const arrayRule = enforce.isArray(); * arrayRule.test([1, 2]); // true * arrayRule.test({}); // false * ``` */ declare function isArray(value: any): value is any[]; //#endregion //#region src/rules/commonComparison.d.ts /** * Common comparison predicates that work across multiple types */ declare function equals$1<T>(a: T, b: T): boolean; declare function notEquals<T>(a: T, b: T): boolean; //#endregion //#region src/rules/commonContainer.d.ts /** * Common container predicates for arrays and strings */ declare function inside<T>(value: T, container: T[] | string): boolean; declare function notInside<T>(value: T, container: any): boolean; //#endregion //#region src/rules/commonLength.d.ts type Lengthable = { length: number; }; declare function minLength(value: Lengthable, n: number): boolean; declare function maxLength(value: Lengthable, n: number): boolean; declare function lengthEquals$1(value: Lengthable, n: number): boolean; declare function lengthNotEquals(value: Lengthable, n: number): boolean; declare function longerThan$1(value: Lengthable, n: number): boolean; declare function longerThanOrEquals(value: Lengthable, n: number): boolean; declare function shorterThan(value: Lengthable, n: number): boolean; declare function shorterThanOrEquals(value: Lengthable, n: number): boolean; //#endregion //#region src/rules/general/isNotArray.d.ts /** * Validates that a value is not an array. * Inverse of isArray. * * @param value - Value to validate * @returns True if value is not an array * * @example * ```typescript * enforce({}).isNotArray(); // passes * enforce('hello').isNotArray(); // passes * enforce([1, 2, 3]).isNotArray(); // fails * ``` */ declare function isNotArray(value: any): boolean; //#endregion //#region src/rules/arrayRules.d.ts declare const arrayRules: { readonly equals: typeof equals$1; readonly includes: typeof includes; readonly inside: typeof inside; readonly isEmpty: typeof isEmpty$2; readonly isNotEmpty: (value: unknown) => boolean; readonly lengthEquals: typeof lengthEquals$1; readonly lengthNotEquals: typeof lengthNotEquals; readonly longerThan: typeof longerThan$1; readonly longerThanOrEquals: typeof longerThanOrEquals; readonly maxLength: typeof maxLength; readonly minLength: typeof minLength; readonly notEquals: typeof notEquals; readonly notInside: typeof notInside; readonly shorterThan: typeof shorterThan; readonly shorterThanOrEquals: typeof shorterThanOrEquals; }; type ArrayRuleInstance<T = any, TInput = T> = BuildRuleInstance<T[], [TInput[]], ExtractRuleFunctions<typeof arrayRules>>; //#endregion //#region src/rules/boolean/isBoolean.d.ts /** * Validates that a value is a boolean. * Type guard that narrows the type to boolean. * * @param value - Value to validate * @returns True if value is a boolean * * @example * ```typescript * // Eager API * enforce(true).isBoolean(); // passes * enforce(false).isBoolean(); // passes * enforce(1).isBoolean(); // fails * enforce('true').isBoolean(); // fails * * // Lazy API * const boolRule = enforce.isBoolean(); * boolRule.test(true); // true * boolRule.test(0); // false * * // Chains with boolean-specific rules * enforce(true).isBoolean().isTrue(); * ``` */ declare function isBoolean$1(value: any): value is boolean; //#endregion //#region src/rules/boolean/isFalse.d.ts declare function isFalse(value: boolean): boolean; //#endregion //#region src/rules/boolean/isTrue.d.ts declare function isTrue(value: boolean): boolean; //#endregion //#region src/rules/general/equals.d.ts declare function equals<T>(value: T, v: T): boolean; //#endregion //#region src/rules/general/isFalsy.d.ts declare function isFalsy(value: any): boolean; //#endregion //#region src/rules/general/isTruthy.d.ts declare function isTruthy(value: any): boolean; //#endregion //#region src/rules/booleanRules.d.ts interface BooleanRuleInstance extends RuleInstance<boolean, [boolean]> { isTrue(...args: DropFirst<Parameters<typeof isTrue>>): BooleanRuleInstance; isFalse(...args: DropFirst<Parameters<typeof isFalse>>): BooleanRuleInstance; isTruthy(...args: DropFirst<Parameters<typeof isTruthy>>): BooleanRuleInstance; isFalsy(...args: DropFirst<Parameters<typeof isFalsy>>): BooleanRuleInstance; equals(...args: DropFirst<Parameters<typeof equals>>): BooleanRuleInstance; isBoolean(...args: DropFirst<Parameters<typeof isBoolean$1>>): BooleanRuleInstance; } //#endregion //#region src/rules/compoundRules/allOf.d.ts /** * Validates that a value passes all of the provided rules. * All rules must pass for the validation to succeed. * Evaluation stops at the first failing rule. * * @template T - The value type to validate * @param value - The value to validate * @param rules - One or more RuleInstances that must all pass * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce(25) * .allOf( * enforce.isNumber().greaterThan(18).lessThan(100) * ); // passes (all rules pass) * * // Lazy API * const adultAgeRule = enforce.allOf( * enforce.isNumber().greaterThanOrEquals(18).lessThan(150) * ); * * adultAgeRule.test(25); // true * adultAgeRule.test(16); // false * adultAgeRule.test('25'); // false (not a number) * ``` */ declare function allOf<T>(value: T, ...rules: any[]): RuleRunReturn<T>; type AllOfRuleInstance<T> = RuleInstance<T, [T]>; //#endregion //#region src/rules/compoundRules/anyOf.d.ts /** * Validates that a value passes at least one of the provided rules. * At least one rule must pass for the validation to succeed. * Evaluation stops at the first passing rule. * * @template T - The value type to validate * @param value - The value to validate * @param rules - One or more RuleInstances where at least one must pass * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce('hello') * .anyOf( * enforce.isNumber(), * enforce.isString() * ); // passes (string matches) * * // Lazy API - accept either format * const phoneOrEmailRule = enforce.anyOf( * enforce.isString().matches(/^\d{10}$/), // phone * enforce.isString().matches(/@/) // email * ); * * phoneOrEmailRule.test('1234567890'); // true * phoneOrEmailRule.test('user@example.com'); // true * phoneOrEmailRule.test('invalid'); // false * ``` */ declare function anyOf<T>(value: T, ...rules: any[]): RuleRunReturn<T>; type AnyOfRuleInstance<T> = RuleInstance<T, [T]>; //#endregion //#region src/rules/compoundRules/noneOf.d.ts /** * Validates that a value passes none of the provided rules. * All rules must fail for the validation to succeed. * Evaluation stops at the first passing rule. * * @template T - The value type to validate * @param value - The value to validate * @param rules - One or more RuleInstances that must all fail * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce(0) * .noneOf( * enforce.greaterThan(0), * enforce.lessThan(0) * ); // passes (neither rule passes) * * // Lazy API - exclude reserved usernames * const notReservedRule = enforce.noneOf( * enforce.equals('admin'), * enforce.equals('root'), * enforce.equals('system') * ); * * notReservedRule.test('john'); // true * notReservedRule.test('admin'); // false * notReservedRule.test('root'); // false * ``` */ declare function noneOf<T>(value: T, ...rules: any[]): RuleRunReturn<T>; type NoneOfRuleInstance<T> = RuleInstance<T, [T]>; //#endregion //#region src/rules/compoundRules/oneOf.d.ts /** * Validates that a value passes exactly one of the provided rules. * Exactly one rule must pass - not zero, not two or more. * All rules are evaluated to count passing rules. * * @template T - The value type to validate * @param value - The value to validate * @param rules - One or more RuleInstances where exactly one must pass * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce(5) * .oneOf( * enforce.lessThan(10), * enforce.greaterThan(100) * ); // passes (only first rule passes) * * // Lazy API - accept either type but not both * const stringOrNumberRule = enforce.oneOf( * enforce.isString(), * enforce.isNumber() * ); * * stringOrNumberRule.test('hello'); // true * stringOrNumberRule.test(42); // true * stringOrNumberRule.test(true); // false (no rules pass) * * // More complex example - exclusive validation * const exclusiveRule = enforce.oneOf( * enforce.equals(null), * enforce.isString().longerThan(0) * ); * * exclusiveRule.test(null); // true (exactly one passes) * exclusiveRule.test('hello'); // true (exactly one passes) * exclusiveRule.test(''); // false (neither passes) * ``` */ declare function oneOf<T>(value: T, ...rules: any[]): RuleRunReturn<T>; type OneOfRuleInstance<T> = RuleInstance<T, [T]>; //#endregion //#region src/rules/compoundRules/compoundRulesTypes.d.ts /** * Type mappings for compound rule lazy API return types */ type CompoundRuleLazyTypes = { allOf: <T>(...rules: any[]) => AllOfRuleInstance<T>; anyOf: <Rules extends RuleInstance<any>[]>(...rules: Rules) => AnyOfRuleInstance<Rules[number]['infer']>; noneOf: <T>(...rules: any[]) => NoneOfRuleInstance<T>; oneOf: <Rules extends RuleInstance<any>[]>(...rules: Rules) => OneOfRuleInstance<Rules[number]['infer']>; }; //#endregion //#region src/rules/general/condition.d.ts declare function condition(value: any, callback: (value: any) => boolean): boolean; //#endregion //#region src/rules/general/isEmpty.d.ts declare function isEmpty$1(value: any): boolean; //#endregion //#region src/rules/general/isNaN.d.ts declare function isNaN(value: number | string): boolean; //#endregion //#region src/rules/general/isNotBoolean.d.ts /** * Validates that a value is not a boolean. * Inverse of isBoolean. * * @param value - Value to validate * @returns True if value is not a boolean * * @example * ```typescript * enforce(1).isNotBoolean(); // passes * enforce('true').isNotBoolean(); // passes * enforce(true).isNotBoolean(); // fails * enforce(false).isNotBoolean(); // fails * ``` */ declare function isNotBoolean(value: any): boolean; //#endregion //#region src/rules/general/isNotEmpty.d.ts declare function isNotEmpty$1(value: any): boolean; //#endregion //#region src/rules/general/isNotNaN.d.ts declare function isNotNaN(value: any): boolean; //#endregion //#region src/rules/general/isNotNumber.d.ts /** * Validates that a value is not a number (or is NaN). * Inverse of isNumber. Considers NaN as not a number. * * @param value - Value to validate * @returns True if value is not a number or is NaN * * @example * ```typescript * enforce('123').isNotNumber(); // passes * enforce(NaN).isNotNumber(); // passes * enforce(true).isNotNumber(); // passes * enforce(42).isNotNumber(); // fails * ``` */ declare function isNotNumber(value: any): boolean; //#endregion //#region src/rules/general/isNotNumeric.d.ts /** * Validates that a value is not numeric (not a number or numeric string). * Inverse of isNumeric. * * @param value - Value to validate * @returns True if value is not numeric * * @example * ```typescript * enforce('hello').isNotNumeric(); // passes * enforce(true).isNotNumeric(); // passes * enforce(NaN).isNotNumeric(); // passes * enforce(42).isNotNumeric(); // fails * enforce('42').isNotNumeric(); // fails * ``` */ declare function isNotNumeric(value: any): boolean; //#endregion //#region src/rules/general/isNotString.d.ts /** * Validates that a value is not a string. * Inverse of isString. * * @param value - Value to validate * @returns True if value is not a string * * @example * ```typescript * enforce(123).isNotString(); // passes * enforce([]).isNotString(); // passes * enforce('hello').isNotString(); // fails * ``` */ declare function isNotString(value: any): boolean; //#endregion //#region src/rules/general/isNotNull.d.ts /** * Validates that a value is not null. * Inverse of isNull. Note: undefined passes this check. * * @param value - Value to validate * @returns True if value is not null * * @example * ```typescript * enforce(undefined).isNotNull(); // passes * enforce(0).isNotNull(); // passes * enforce('').isNotNull(); // passes * enforce(null).isNotNull(); // fails * ``` */ declare function isNotNull$1(value: any): boolean; //#endregion //#region src/rules/general/isNotUndefined.d.ts /** * Validates that a value is not undefined. * Inverse of isUndefined. Note: null passes this check. * * @param value - Value to validate * @returns True if value is not undefined * * @example * ```typescript * enforce(null).isNotUndefined(); // passes * enforce(0).isNotUndefined(); // passes * enforce('').isNotUndefined(); // passes * enforce(undefined).isNotUndefined(); // fails * ``` */ declare function isNotUndefined$1(value: any): boolean; //#endregion //#region src/rules/general/isNotNullish.d.ts /** * Validates that a value is not nullish (not null and not undefined). * Inverse of isNullish. * * @param value - Value to validate * @returns True if value is neither null nor undefined * * @example * ```typescript * enforce(0).isNotNullish(); // passes * enforce('').isNotNullish(); // passes * enforce(false).isNotNullish(); // passes * enforce(null).isNotNullish(); // fails * enforce(undefined).isNotNullish(); // fails * ``` */ declare function isNotNullish$1(value: any): boolean; //#endregion //#region src/rules/generalRules.d.ts interface AnyRuleInstance extends RuleInstance<any, [any]> {} //#endregion //#region src/rules/nullish/isNull.d.ts /** * Validates that a value is null. * Type guard that narrows the type to null. * * @param value - Value to validate * @returns True if value is null * * @example * ```typescript * // Eager API * enforce(null).isNull(); // passes * enforce(undefined).isNull(); // fails * enforce(0).isNull(); // fails * * // Lazy API * const nullRule = enforce.isNull(); * nullRule.test(null); // true * nullRule.test(undefined); // false * ``` */ declare function isNull$1(value: any): value is null; //#endregion //#region src/rules/nullish/isUndefined.d.ts /** * Validates that a value is undefined. * Type guard that narrows the type to undefined. * * @param value - Value to validate * @returns True if value is undefined * * @example * ```typescript * // Eager API * enforce(undefined).isUndefined(); // passes * enforce(null).isUndefined(); // fails * enforce('').isUndefined(); // fails * * // Lazy API * const undefRule = enforce.isUndefined(); * undefRule.test(undefined); // true * undefRule.test(null); // false * * // Useful for optional properties * const schema = enforce.shape({ * optional: enforce.optional(enforce.isString()) * }); * ``` */ declare function isUndefined$1(value: any): value is undefined; //#endregion //#region src/rules/nullish/isNullish.d.ts /** * Validates that a value is null or undefined (nullish). * Type guard that narrows the type to null | undefined. * * @param value - Value to validate * @returns True if value is null or undefined * * @example * ```typescript * // Eager API * enforce(null).isNullish(); // passes * enforce(undefined).isNullish(); // passes * enforce(0).isNullish(); // fails * enforce('').isNullish(); // fails * enforce(false).isNullish(); // fails * * // Lazy API * const nullishRule = enforce.isNullish(); * nullishRule.test(null); // true * nullishRule.test(undefined); // true * nullishRule.test(0); // false * ``` */ declare function isNullish$1(value: any): value is null | undefined; //#endregion //#region src/rules/nullishRules.d.ts interface NullRuleInstance extends RuleInstance<null, [null]> {} interface UndefinedRuleInstance extends RuleInstance<undefined, [undefined]> {} interface NullishRuleInstance extends RuleInstance<null | undefined, [null | undefined]> {} //#endregion //#region src/rules/number/greaterThanOrEquals.d.ts declare function greaterThanOrEquals(value: string | number, gte: string | number): boolean; //#endregion //#region src/rules/number/isBetween.d.ts declare function isBetween(value: number | string, min: number | string, max: number | string): boolean; //#endregion //#region src/rules/number/isNegative.d.ts declare function isNegative(value: number): boolean; //#endregion //#region src/rules/number/isNotBetween.d.ts declare function isNotBetween(value: number, min: number, max: number): boolean; //#endregion //#region src/rules/number/isNumber.d.ts /** * Validates that a value is a number (excluding NaN). * Type guard that narrows the type to number. * * @param value - Value to validate * @returns True if value is a number and not NaN * * @example * ```typescript * // Eager API * enforce(42).isNumber(); // passes * enforce('42').isNumber(); // fails (string) * enforce(NaN).isNumber(); // fails (NaN is excluded) * * // Lazy API * const numberRule = enforce.isNumber(); * numberRule.test(42); // true * numberRule.test(Infinity); // true * numberRule.test(NaN); // false * * // Chains with number-specific rules * enforce(25).isNumber().greaterThan(18); * ``` */ declare function isNumber(value: any): value is number; //#endregion //#region src/rules/number/isPositive.d.ts declare function isPositive(value: number): boolean; //#endregion //#region src/rules/number/lessThan.d.ts declare function lessThan(value: string | number, lt: string | number): boolean; //#endregion //#region src/rules/number/lessThanOrEquals.d.ts declare function lessThanOrEquals(value: string | number, lte: string | number): boolean; //#endregion //#region src/rules/numeric/toNumber.d.ts declare function toNumber$1(value: unknown): RuleRunReturn<number>; //#endregion //#region src/rules/number/numberNotEquals.d.ts declare function numberNotEquals$1(value: number, n: number | string): boolean; //#endregion //#region src/rules/numeric/isNumeric.d.ts /** * Validates that a value is numeric (a number or a numeric string). * Type guard that narrows the type to number | string. * Excludes NaN but includes Infinity and numeric strings. * * @param value - Value to validate * @returns True if value is a number or numeric string * * @example * ```typescript * // Eager API * enforce(42).isNumeric(); // passes * enforce('42').isNumeric(); // passes (numeric string) * enforce('42.5').isNumeric(); // passes * enforce(Infinity).isNumeric(); // passes * enforce('hello').isNumeric(); // fails * enforce(NaN).isNumeric(); // fails * * // Lazy API * const numericRule = enforce.isNumeric(); * numericRule.test(100); // true * numericRule.test('100'); // true * numericRule.test('abc'); // false * * // Chains with numeric comparison rules * enforce('25').isNumeric().greaterThan(18); * ``` */ declare function isNumeric$1(value: any): value is number | string; //#endregion //#region src/rules/object/isKeyOf.d.ts declare function isKeyOf(key: string | number | symbol, obj: object): boolean; declare function isNotKeyOf(key: string | number | symbol, obj: object): boolean; //#endregion //#region src/rules/object/isValueOf.d.ts declare function isValueOf<T = any>(value: T, obj: Record<string, T>): boolean; declare function isNotValueOf<T = any>(value: T, obj: Record<string, T>): boolean; //#endregion //#region src/rules/objectRules.d.ts interface ObjectRuleInstance extends RuleInstance<object, [object]> {} interface KeyOfRuleInstance extends RuleInstance<string | number | symbol, [string | number | symbol]> {} interface ValueOfRuleInstance<T> extends RuleInstance<T, [T]> {} type ObjectRulesUnion = ObjectRuleInstance | KeyOfRuleInstance | ValueOfRuleInstance<any>; //#endregion //#region src/rules/schemaRules/isArrayOf.d.ts /** * Validates that a value is an array and all elements match at least one of the provided rules. * Each array element must pass at least one of the validation rules. * * @template T - The element type of the array * @param value - The array to validate * @param rules - One or more RuleInstances that elements should match * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API - array of strings * enforce(['a', 'b', 'c']) * .isArrayOf(enforce.isString()); // passes * * enforce([1, 2, 'three']) * .isArrayOf(enforce.isString()); // fails * * // Lazy API - array of numbers or strings * const mixedArrayRule = enforce.isArrayOf( * enforce.isNumber(), * enforce.isString() * ); * * mixedArrayRule.test([1, 'two', 3, 'four']); // true * mixedArrayRule.test([1, 2, true]); // false (boolean not allowed) * * // Complex schema validation * const usersRule = enforce.isArrayOf( * enforce.shape({ * name: enforce.isString(), * age: enforce.isNumber() * }) * ); * * usersRule.test([ * { name: 'John', age: 30 }, * { name: 'Jane', age: 25 } * ]); // true * ``` */ declare function isArrayOf<T>(value: T[], ...rules: any[]): RuleRunReturn<T[]>; type IsArrayOfRuleInstance<T, TInput = T> = ArrayRuleInstance<T, TInput>; //#endregion //#region src/rules/schemaRules/schemaRulesTypes.d.ts /** * Forces TypeScript to eagerly expand object type aliases in hover hints. */ type Prettify<T> = { [K in keyof T]: T[K] } & {}; /** Extracts the OUTPUT type from a RuleInstance (what parse() returns). */ type InferShape<T> = T extends RuleInstance<infer R, any> ? R : never; /** Extracts the INPUT type from a RuleInstance (what parse() accepts). */ type InferShapeInput<T> = T extends RuleInstance<any, [infer A, ...any[]]> ? A : never; /** * True only when T is exactly `unknown` (not a union that includes unknown). * Used to prevent `unknown` fields from being wrongly classified as optional. */ type IsUnknown<T> = unknown extends T ? T extends unknown ? [T] extends [undefined] ? false : true : false : false; /** * True when a field should be modelled as optional: its type explicitly includes * undefined (e.g. via `optional()`) but is NOT just the bare `unknown` type. */ type ShouldBeOptional<T> = IsUnknown<T> extends true ? false : undefined extends T ? true : false; /** Maps a schema record to its OUTPUT type (post-coercion). */ type SchemaInfer<T extends Record<string, RuleInstance<any>>> = Prettify<{ [K in keyof T as ShouldBeOptional<InferShape<T[K]>> extends true ? never : K]: InferShape<T[K]> } & { [K in keyof T as ShouldBeOptional<InferShape<T[K]>> extends true ? K : never]?: InferShape<T[K]> }>; /** Maps a schema record to its INPUT type (pre-coercion). */ type SchemaInput<T extends Record<string, RuleInstance<any>>> = Prettify<{ [K in keyof T as ShouldBeOptional<InferShapeInput<T[K]>> extends true ? never : K]: InferShapeInput<T[K]> } & { [K in keyof T as ShouldBeOptional<InferShapeInput<T[K]>> extends true ? K : never]?: InferShapeInput<T[K]> }>; type MultiTypeInput<T extends RuleInstance<any, any>[]> = InferShape<T[number]> extends never ? unknown : InferShape<T[number]>; /** Extracts the input element type from rule instances (what the array accepts). */ type MultiTypeInputArgs<T extends RuleInstance<any, any>[]> = InferShapeInput<T[number]> extends never ? unknown : InferShapeInput<T[number]>; //#endregion //#region src/rules/schemaRules/shape.d.ts /** * Validates that an object matches a schema exactly - all keys required, no extra keys allowed. * Each field value is validated against its corresponding RuleInstance in the schema. * * @template T - The object type to validate * @param value - The object to validate * @param schema - Schema mapping keys to validation rules * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce({ name: 'John', age: 30 }) * .shape({ * name: enforce.isString(), * age: enforce.isNumber().greaterThan(0) * }); // passes * * // Lazy API * const userSchema = enforce.shape({ * name: enforce.isString(), * email: enforce.isString().matches(/@/), * age: enforce.isNumber().greaterThanOrEquals(18) * }); * * userSchema.test({ name: 'Jane', email: 'jane@example.com', age: 25 }); // true * userSchema.test({ name: 'Jane', age: 25 }); // false (missing email) * userSchema.test({ name: 'Jane', email: 'jane@example.com', age: 25, extra: 'x' }); // false (extra key) * ``` */ declare function shape<T extends Record<string, any>>(value: T, schema: Record<string, any>): RuleRunReturn<T>; type ShapeType<T extends Record<string, RuleInstance<any>>> = SchemaInfer<T>; type ShapeInputType<T extends Record<string, RuleInstance<any>>> = SchemaInput<T>; type ShapeRuleInstance<S extends Record<string, RuleInstance<any>>> = RuleInstance<ShapeType<S>, [ShapeInputType<S>]>; //#endregion //#region src/rules/schemaRules/loose.d.ts /** * Validates that an object matches a schema loosely - all schema keys required, extra keys allowed. * Like shape() but permits additional properties not defined in the schema. * * @template T - The object type to validate * @param value - The object to validate * @param schema - Schema mapping keys to validation rules * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce({ name: 'John', age: 30, extra: 'allowed' }) * .loose({ * name: enforce.isString(), * age: enforce.isNumber() * }); // passes (extra key is ok) * * // Lazy API * const partialUserSchema = enforce.loose({ * name: enforce.isString(), * email: enforce.isString() * }); * * // All schema keys must be present and valid * partialUserSchema.test({ name: 'Jane', email: 'jane@example.com' }); // true * partialUserSchema.test({ name: 'Jane', email: 'jane@example.com', age: 30 }); // true (extra ok) * partialUserSchema.test({ name: 'Jane' }); // false (missing email) * ``` */ declare function loose<T extends Record<string, any>>(value: T, schema: Record<string, any>): RuleRunReturn<T>; type LooseRuleInstance<S extends Record<string, RuleInstance<any>>> = RuleInstance<Prettify<ShapeType<S> & Record<string, unknown>>, [Prettify<ShapeInputType<S> & Record<string, unknown>>]>; //#endregion //#region src/rules/schemaRules/optional.d.ts /** * Makes a validation rule optional by allowing null or undefined values to pass. * If the value is null or undefined, validation passes without running the inner rule. * Otherwise, the inner rule is executed. * * @template T - The value type to validate * @param value - The value to validate (may be null/undefined) * @param rule - The RuleInstance to apply if value is not nullish * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce(undefined).optional(enforce.isString()); // passes * enforce(null).optional(enforce.isString()); // passes * enforce('hello').optional(enforce.isString()); // passes * enforce(123).optional(enforce.isString()); // fails * * // Lazy API - useful in schemas * const userSchema = enforce.shape({ * name: enforce.isString(), * middleName: enforce.optional(enforce.isString()), * age: enforce.isNumber() * }); * * userSchema.test({ name: 'John', age: 30 }); // true (middleName optional) * userSchema.test({ name: 'John', middleName: null, age: 30 }); // true * userSchema.test({ name: 'John', middleName: 'Q', age: 30 }); // true * userSchema.test({ name: 'John', middleName: 123, age: 30 }); // false * ``` */ declare function optional<T>(value: T | undefined | null, rule: any): RuleRunReturn<T | undefined | null>; type OptionalRuleInstance<T> = RuleInstance<T | undefined | null, [T | undefined | null]>; //#endregion //#region src/rules/schemaRules/partial.d.ts /** * partial(value, schema) validates that: * 1. value's keys are a subset of schema's keys (no extras) * 2. Zero or more keys may be present (empty object is allowed) * 3. For each provided key, the corresponding rule passes */ /** * Validates that an object partially matches a schema - schema keys are optional, no extra keys allowed. * All provided keys must exist in schema and pass their validation rules. * Missing keys are allowed (making all fields optional). * * @template T - The object type to validate * @param value - The object to validate * @param schema - Schema mapping keys to validation rules * @returns RuleRunReturn indicating success or failure * * @example * ```typescript * // Eager API * enforce({ name: 'John' }) * .partial({ * name: enforce.isString(), * age: enforce.isNumber(), * email: enforce.isString() * }); // passes (age and email are optional) * * // Lazy API * const updateSchema = enforce.partial({ * name: enforce.isString(), * email: enforce.isString().matches(/@/), * age: enforce.isNumber() * }); * * updateSchema.test({}); // true (all fields optional) * updateSchema.test({ name: 'Jane' }); // true (partial update) * updateSchema.test({ name: 'Jane', email: 'jane@example.com' }); // true * updateSchema.test({ name: 'Jane', extra: 'x' }); // false (extra key not in schema) * ``` */ declare function partial<T extends Record<string, any>>(value: T, schema: Record<string, any>): RuleRunReturn<T>; type PartialRuleInstance<S extends Record<string, RuleInstance<any>>> = RuleInstance<Partial<ShapeType<S>>, [Partial<ShapeInputType<S>>]>; //#endregion //#region src/rules/schemaRules/pick.d.ts /** * Validates that an object loosely matches a schema but only validates the specified keys. * Other keys in the object are ignored and no validation is applied to them. * * @template T - The object type to validate * @param value - The object to validate * @param schema - Schema mapping keys to validation rules * @param keysToPick - Array of keys that should be validated from the schema * @returns RuleRunReturn indicating success or failure */ declare function pick<T extends Record<string, any>>(value: T, schema: Record<string, any>, keysToPick: string[] | string): RuleRunReturn<T>; type PickRuleInstance<S extends Record<string, RuleInstance<any>>> = RuleInstance<ShapeType<S>, [ShapeInputType<S>]>; //#endregion //#region src/rules/schemaRules/omit.d.ts /** * Validates that an object loosely matches a schema but omits specified keys from validation. * The omitted keys in the object are ignored and no validation is applied to them. * * @template T - The object type to validate * @param value - The object to validate * @param schema - Schema mapping keys to validation rules * @param keysToOmit - Array of keys that should be omitted from schema validation * @returns RuleRunReturn indicating success or failure */ declare function omit<T extends Record<string, any>>(value: T, schema: Record<string, any>, keysToOmit: string[] | string): RuleRunReturn<T>; type OmitRuleInstance<S extends Record<string, RuleInstance<any>>> = RuleInstance<ShapeType<S>, [ShapeInputType<S>]>; //#endregion //#region src/rules/schemaRules/record.d.ts /** * Validates that an object's dynamic keys and/or values match provided rules. * Like TypeScript's Record<K, V>, it checks elements against shape rules. * * @param value - The object to validate * @param arg1 - Either the key rule (if arg2 is present) or the value rule * @param arg2 - The value rule (if arg1 is the key rule) * @returns RuleRunReturn indicating success or failure */ declare function record<T extends Record<string, any>>(value: T, arg1: any, arg2?: any): RuleRunReturn<T>; type RecordKey<K$1> = [K$1] extends [never] ? string : K$1 extends RuleInstance<any, any> ? K$1['infer'] extends PropertyKey ? K$1['infer'] : string : string; type RecordInputKey<K$1> = [K$1] extends [never] ? string : K$1 extends RuleInstance<any, any> ? InferShapeInput<K$1> extends PropertyKey ? InferShapeInput<K$1> : string : string; type RecordRuleInstance<K$1 extends RuleInstance<any, any> | never, V$1 extends RuleInstance<any, any>> = RuleInstance<Record<RecordKey<K$1>, V$1['infer']>, [Record<RecordInputKey<K$1>, InferShapeInput<V$1>>]>; //#endregion //#region src/rules/schemaRules/tuple.d.ts /** * Validates that a value is a fixed-length array (tuple) where each position * matches the corresponding rule. Enforces exact length unless trailing * elements use enforce.optional(). * * Parsed values are propagated: if a rule transforms its input (e.g. toNumber), * the parsed tuple returned via `.parse()` carries the transformed values. * * @param value - The array to validate * @param rules - One RuleInstance per tuple position * @returns RuleRunReturn indicating success or failure, with `.type` holding * the parsed tuple on success * * @example * ```typescript * // Eager API * enforce(['hello', 42]).tuple(enforce.isString(), enforce.isNumber()); * * // Lazy API * const coordSchema = enforce.tuple(enforce.isNumber(), enforce.isNumber()); * coordSchema.test([40.7, -74.0]); // true * coordSchema.test([40.7]); // false — too few * coordSchema.test([40.7, -74, 0]);// false — too many * ``` */ declare function tuple(value: unknown, ...rules: any[]): RuleRunReturn<any>; /** * Maps a tuple of RuleInstances to their inferred output types. * [RuleInstance<string>, RuleInstance<number>] → [string, number] */ type InferTuple<T extends RuleInstance<any, any>[]> = { [K in keyof T]: T[K] extends RuleInstance<infer R, any> ? R : never }; /** * Maps a tuple of RuleInstances to their inferred input types. * Used for the Args parameter of the returned RuleInstance so that * .test() and .parse() accept correctly typed tuple input. */ type InferTupleInput<T extends RuleInstance<any, any>[]> = { [K in keyof T]: T[K] extends RuleInstance<any, [infer A, ...any[]]> ? A : never }; /** * The RuleInstance type returned by enforce.tuple(). * Infers both output and input types from the provided rule tuple. */ type TupleRuleInstance<T extends RuleInstance<any, any>[]> = RuleInstance<InferTuple<T>, [InferTupleInput<T>]>; //#endregion //#region src/rules/schemaRules/schemaRulesLazyTypes.d.ts /** * Type mappings for schema rule lazy API return types */ type SchemaRuleLazyTypes = { isArrayOf: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => IsArrayOfRuleInstance<MultiTypeInput<Rules>, MultiTypeInputArgs<Rules>>; list: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => IsArrayOfRuleInstance<MultiTypeInput<Rules>, MultiTypeInputArgs<Rules>>; lazy: <T>(factory: () => RuleInstance<T, any>) => LazyRuleInstance<T>; loose: <S extends Record<string, RuleInstance<any>>>(schema: S) => LooseRuleInstance<S>; optional: <R$1 extends RuleInstance<any>>(rule: R$1) => OptionalRuleInstance<R$1['infer']>; partial: <S extends Record<string, RuleInstance<any>>>(schema: S) => PartialRuleInstance<S>; pick: <S extends Record<string, RuleInstance<any>>>(schema: S, keys: string[] | string) => PickRuleInstance<S>; omit: <S extends Record<string, RuleInstance<any>>>(schema: S, keys: string[] | string) => OmitRuleInstance<S>; shape: <S extends Record<string, RuleInstance<any>>>(schema: S) => ShapeRuleInstance<S>; record: { <V$1 extends RuleInstance<any, any>>(valueRule: V$1): RecordRuleInstance<never, V$1>; <K$1 extends RuleInstance<string, any>, V$1 extends RuleInstance<any, any>>(keyRule: K$1, valueRule: V$1): RecordRuleInstance<K$1, V$1>; }; tuple: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => TupleRuleInstance<Rules>; }; //#endregion //#region src/rules/schemaRules/lazy.d.ts type LazyRuleInstance<T> = RuleInstance<T, [T]>; //#endregion //#region src/rules/string/doesNotEndWith.d.ts declare function doesNotEndWith(str: string, ending: string): boolean; //#endregion //#region src/rules/string/doesNotStartWith.d.ts declare function doesNotStartWith(str: string, start: string): boolean; //#endregion //#region src/rules/string/endsWith.d.ts declare function endsWith(str: string, ending: string): boolean; //#endregion //#region src/rules/string/isBlankString.d.ts declare function isBlankString(str: string): boolean; //#endregion //#region src/rules/string/isNotBlank.d.ts declare function isNotBlank(str: string): boolean; //#endregion //#region src/rules/string/isString.d.ts /** * Validates that a value is a string. * Type guard that narrows the type to string. * * @param value - Value to validate * @returns True if value is a string * * @example * ```typescript * // Eager API * enforce('hello').isString(); // passes * enforce(123).isString(); // fails * * // Lazy API * const stringRule = enforce.isString(); * stringRule.test('hello'); // true * * // Chains with string-specific rules * enforce('hello').isString().longerThan(3); * ``` */ declare function isString(value: any): value is string; //#endregion //#region src/rules/string/matches.d.ts declare function matches(str: string, regex: RegExp | string): boolean; //#endregion //#region src/rules/string/notMatches.d.ts declare function notMatches(str: string, regex: RegExp | string): boolean; //#endregion //#region src/rules/string/startsWith.d.ts declare function startsWith(str: string, start: string): boolean; //#endregion //#region src/eager/allRules.d.ts declare const allRules: { readonly doesNotEndWith: typeof doesNotEndWith; readonly doesNotStartWith: typeof doesNotStartWith; readonly endsWith: typeof endsWith; readonly equals: typeof equals$1; readonly inside: typeof inside; readonly isBlank: typeof isBlankString; readonly isNotBlank: typeof isNotBlank; readonly isString: typeof isString; readonly lengthEquals: typeof lengthEquals$1; readonly lengthNotEquals: typeof lengthNotEquals; readonly longerThan: typeof longerThan$1; readonly longerThanOrEquals: typeof longerThanOrEquals; readonly matches: typeof matches; readonly maxLength: typeof maxLength; readonly minLength: typeof minLength; readonly notEquals: typeof notEquals; readonly notInside: typeof notInside; readonly notMatches: typeof notMatches; readonly shorterThan: typeof shorterThan; readonly shorterThanOrEquals: typeof shorterThanOrEquals; readonly startsWith: typeof startsWith; readonly isKeyOf: typeof isKeyOf; readonly isNotKeyOf: typeof isNotKeyOf; readonly isValueOf: typeof isValueOf; readonly isNotValueOf: typeof isNotValueOf; readonly isNumeric: typeof isNumeric$1; readonly gt: typeof greaterThan$1; readonly gte: typeof greaterThanOrEquals; readonly lt: typeof lessThan; readonly lte: typeof lessThanOrEquals; readonly eq: typeof equals; readonly neq: typeof numberNotEquals$1; readonly greaterThan: typeof greaterThan$1; readonly greaterThanOrEquals: typeof greaterThanOrEquals; readonly isBetween: typeof isBetween; readonly isEven: (value: string | number) => boolean; readonly isNaN: typeof isNaN; readonly isNegative: typeof isNegative; readonly isNotBetween: typeof isNotBetween; readonly isNotNaN: typeof isNotNaN; readonly isNumber: typeof isNumber; readonly isOdd: (value: string | number) => boolean; readonly isPositive: typeof isPositive; readonly lessThan: typeof lessThan; readonly lessThanOrEquals: typeof lessThanOrEquals; readonly numberEquals: typeof numberEquals$1; readonly numberNotEquals: typeof numberNotEquals$1; readonly toNumber: typeof toNumber$1; readonly isNull: typeof isNull$1; readonly isUndefined: typeof isUndefined$1; readonly isNullish: typeof isNullish$1; readonly condition: typeof condition; readonly isEmpty: typeof isEmpty$1; readonly isFalsy: typeof isFalsy; readonly isNotArray: typeof isNotArray; readonly isNotBoolean: typeof isNotBoolean; readonly isNotEmpty: typeof isNotEmpty$1; readonly isNotNumber: typeof isNotNumber; readonly isNotNumeric: typeof isNotNumeric; readonly isNotString: typeof isNotString; readonly isTruthy: typeof isTruthy; readonly isNotNull: typeof isNotNull$1; readonly isNotUndefined: typeof isNotUndefined$1; readonly isNotNullish: typeof isNotNullish$1; readonly min: typeof minLength; readonly max: typeof maxLength; readonly isFalse: typeof isFalse; readonly isTrue: typeof isTrue; readonly isBoolean: typeof isBoolean$1; readonly includes: typeof includes; readonly isArray: typeof isArray; }; declare const schemaRulesMap: { readonly isArrayOf: typeof isArrayOf; readonly list: typeof isArrayOf; readonly loose: typeof loose; readonly optional: typeof optional; readonly partial: typeof partial; readonly pick: typeof pick; readonly omit: typeof omit; readonly shape: typeof shape; readonly record: typeof record; readonly tuple: typeof tuple; readonly allOf: typeof allOf; readonly anyOf: typeof anyOf; readonly noneOf: typeof noneOf; readonly oneOf: typeof oneOf; }; //#endregion //#region src/eager/typeUtils.d.ts type AnyFn = (...args: any[]) => any; type FirstParam<F extends AnyFn> = F extends ((arg: infer A, ...rest: any) => any) ? A : never; type TailParams<F extends AnyFn> = F extends ((arg: any, ...rest: infer R) => any) ? R : never; type InferNextValue<T, F extends AnyFn> = F extends ((arg: any, ...rest: any) => arg is infer Narrowed) ? Narrowed : ReturnType<F> extends RuleInstance<infer Inner> ? Inner : ReturnType<F> extends boolean | void ? T : ReturnType<F> extends T ? T : ReturnType<F>; type DropFirstFn<F> = F extends ((arg: any, ...rest: infer R) => infer Ret) ? (...args: R) => Ret : never; type UnwrapRuleInstance<R$1> = R$1 extends RuleInstance<infer V> ? V : R$1; //#endregion //#region src/eager/eagerTypes.d.ts type Msg<T, A$1, S> = { message: (input: string) => EnforceEagerReturn<T, A$1, S>; }; type TRules<T, A$1, S> = { [K in keyof A$1 as A$1[K] extends ((...args: any) => any) ? T extends FirstParam<Extract<A$1[K], AnyFn>> ? K : never : never]: (...args: TailParams<Extract<A$1[K], AnyFn>>) => EnforceEagerReturn<InferNextValue<T, Extract<A$1[K], AnyFn>>, A$1, S> }; type TSchemaRules<T, S, A$1> = T extends any[] ? Record<string, never> : T extends Record<string, any> ? { [K in keyof S]: DropFirstFn<S[K]> extends ((...args: infer Args) => infer R) ? (...args: Args) => EnforceEagerReturn<UnwrapRuleInstance<R>, A$1, S> : never } : Record<string, never>; type TArraySchemaRules<T, A$1, S> = T extends any[] ? { isArrayOf: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => EnforceEagerReturn<MultiTypeInput<Rules>[], A$1, S>; list: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => EnforceEagerReturn<MultiTypeInput<Rules>[], A$1, S>; tuple: <Rules extends RuleInstance<any, any>[]>(...rules: Rules) => EnforceEagerReturn<{ [K in keyof Rules]: Rules[K] extends RuleInstance<infer R, any> ? R : never }, A$1, S>; } : Record<string, never>; type TCompoundRules<T, A$1, S> = { [K in keyof S as K extends 'allOf' | 'anyOf' | 'noneOf' | 'oneOf' ? K : never]: DropFirstFn<S[K]> extends ((...args: infer Args) => infer _R) ? (...args: Args) => EnforceEagerReturn<T, A$1, S> : never }; type TOptionalRule<T, A$1, S> = { [K in keyof S as K extends 'optional' ? K : never]: (...args: TailParams<Extract<S[K], AnyFn>>) => EnforceEagerReturn<T, A$1, S> }; type Base<T, A$1, S> = Msg<T, A$1, S> & TRules<T, A$1, S> & TCustomRules<T, A$1, S> & TSchemaRules<T, S, A$1> & TArraySchemaRules<T, A$1, S> & TCompoundRules<T, A$1, S> & TOptionalRule<T, A$1, S>; type EnforceEagerReturn<T = any, A$1 = any, S = any> = Base<T, A$1, S> & { pass: boolean; }; //#endregion //#region src/eager.d.ts type EagerReturn<T> = EnforceEagerReturn<T, typeof allRules, typeof schemaRulesMap>; /** * Eager (imperative) validation API - validates a value immediately with chainable assertions. * Each chained rule executes synchronously and the chain breaks on the first failure. * * @template T - The type of value being validated * @param value - The value to validate * @returns A proxy object with chainable validation methods and a `pass` property * * @example * ```typescript * // Simple validation * enforce('hello').isString(); // passes * * // Chained validation * enforce(25) * .isNumber() * .greaterThan(18) * .lessThan(100); * * // Custom error messages * enforce('') * .message('Field is required') * .isNotEmpty(); * * // Type narrowing * enforce(value) *