UNPKG

n4s

Version:

typed schema validation version of enforce

1 lines 149 kB
{"version":3,"file":"n4s-BxrvnvKp.mjs","names":["ctx","isBoolean","isBooleanValue","equals","booleanRules.isBoolean","greaterThan","greaterThanOrEquals","lessThan","lessThanOrEquals","lengthEquals","longerThan","notEquals","isEmpty","isEmptyValue","isNotEmpty","isNotEmptyValue","isNumericValue","isNotNull","isNotNullValue","isNotUndefined","isNotUndefinedValue","isNotNullish","isNotNullishValue","isNotBlank","isNull","isNullValue","isUndefined","isUndefinedValue","isNullish","isNullishValue","gte","lt","lte","gte","min","lte","max","isNotBetween","min","max","toNumber","toNumberValue","numberNotEquals","numberNotEqualsValue","greaterThan","equals","numberNotEquals","isNumeric","isNumericValue","parsedArray: any[]","lastRes: RuleRunReturn<any> | undefined","passingTransformedType: any","output: Record<string, any>","filtered: Record<string, any>","parsedValue: Record<string, any>","parsedEntries: Record<string, any>","parsedValue: Record<string, any>","parsedTuple: any[]","arrayRules","booleanRules","commonComparison","commonContainer","commonLength","generalRules","nullishRules","numberRules","objectRules","stringRules","compoundRules","schemaRules","customRules: Record<string, (...args: any[]) => any>","customMessage: Maybe<string>","proxy: EagerReturn<T>","CHAIN_PREPEND: unique symbol","lazyRegistry: Record<string, (...args: any[]) => Predicate>","chain: Predicate[]","target: Partial<T>","lazyMessage: Maybe<LazyMessage>","prepend","validate: T['validate']","test: T['test']","parse: T['parse']","run: T['run']","proxy: T","max","min","arrayRules","numberRules","stringRules","booleanRules","isBoolean","isNull","isNullish","isNumeric","isUndefined","cached: RuleInstance<T, any> | null","schemaRules.omit","schemaRules.optional","schemaRules.partial","schemaRules.pick","schemaRules.shape","schemaRules.loose","schemaRules.record","arrayRules","schemaRules.isArrayOf","lazyRule","schemaRules.tuple","compoundRules","generalRules","objectRules","result: RuleRunReturn<T>"],"sources":["../src/enforceContext.ts","../src/rules/boolean/isBoolean.ts","../src/rules/boolean/isFalse.ts","../src/rules/boolean/isTrue.ts","../src/rules/general/equals.ts","../src/rules/general/isFalsy.ts","../src/rules/general/isTruthy.ts","../src/rules/booleanRules.ts","../src/ruleResult.ts","../src/eager/ruleCallGenerator.ts","../src/rules/array/includes.ts","../src/rules/array/isArrayRule.ts","../src/rules/commonComparison.ts","../src/rules/commonContainer.ts","../src/rules/commonLength.ts","../src/rules/general/isNotArray.ts","../src/rules/arrayRules.ts","../src/utils/RuleRunReturn.ts","../src/rules/compoundRules/allOf.ts","../src/rules/compoundRules/anyOf.ts","../src/rules/compoundRules/noneOf.ts","../src/rules/compoundRules/oneOf.ts","../src/rules/compoundRules/compoundRules.ts","../src/rules/general/condition.ts","../src/rules/general/notEquals.ts","../src/rules/general/isEmpty.ts","../src/rules/general/isNaN.ts","../src/rules/general/isNotBoolean.ts","../src/rules/general/isNotEmpty.ts","../src/rules/general/isNotNaN.ts","../src/rules/general/isNotNumber.ts","../src/rules/general/isNotNumeric.ts","../src/rules/general/isNotString.ts","../src/rules/general/isNotNull.ts","../src/rules/general/isNotUndefined.ts","../src/rules/general/isNotNullish.ts","../src/rules/general/isBlank.ts","../src/rules/generalRules.ts","../src/rules/nullish/isNull.ts","../src/rules/nullish/isUndefined.ts","../src/rules/nullish/isNullish.ts","../src/rules/nullishRules.ts","../src/rules/number/greaterThanOrEquals.ts","../src/rules/number/lessThan.ts","../src/rules/number/lessThanOrEquals.ts","../src/rules/number/isBetween.ts","../src/rules/number/isEven.ts","../src/rules/number/isNegative.ts","../src/rules/number/isNotBetween.ts","../src/rules/number/isNumber.ts","../src/rules/number/isOdd.ts","../src/rules/number/isPositive.ts","../src/rules/numeric/toNumber.ts","../src/rules/number/numberNotEquals.ts","../src/rules/numberRules.ts","../src/rules/numeric/isNumeric.ts","../src/rules/object/isKeyOf.ts","../src/rules/object/isValueOf.ts","../src/rules/objectRules.ts","../src/rules/schemaRules/isArrayOf.ts","../src/rules/schemaRules/schemaObjectUtils.ts","../src/rules/schemaRules/loose.ts","../src/rules/schemaRules/optional.ts","../src/rules/schemaRules/partial.ts","../src/rules/schemaRules/pick.ts","../src/rules/schemaRules/omit.ts","../src/rules/schemaRules/shape.ts","../src/rules/schemaRules/record.ts","../src/rules/schemaRules/tuple.ts","../src/rules/schemaRules/schemaRules.ts","../src/rules/string/endsWith.ts","../src/rules/string/doesNotEndWith.ts","../src/rules/string/startsWith.ts","../src/rules/string/doesNotStartWith.ts","../src/rules/string/isBlankString.ts","../src/rules/string/isNotBlank.ts","../src/rules/string/isString.ts","../src/utils/regex.ts","../src/rules/string/matches.ts","../src/rules/string/notMatches.ts","../src/rules/stringRules.ts","../src/eager/allRules.ts","../src/eager/ruleRegistry.ts","../src/eager.ts","../src/rules/chainBuilder/chainExecutor.ts","../src/rules/parsers/parserUtils.ts","../src/rules/chainBuilder/lazyRegistry.ts","../src/rules/chainBuilder/proxyHandlers.ts","../src/rules/chainBuilder/chainBuilder.ts","../src/rules/genRuleChain.ts","../src/extendLogic.ts","../src/lazy/ruleAdapter.ts","../src/rules/parsers/arrayParsers.ts","../src/rules/parsers/toBoolean.ts","../src/rules/parsers/generalParsers.ts","../src/rules/parsers/numberParsers.ts","../src/rules/parsers/stringParsers.ts","../src/lazy/typeRules.ts","../src/rules/schemaRules/lazy.ts","../src/lazy.ts","../src/compose.ts","../src/n4s.ts"],"sourcesContent":["import { createCascade } from 'context';\nimport { assign, Nullable } from 'vest-utils';\n\n/**\n * Context API for accessing validation state during rule execution.\n * Provides access to the current value being validated, metadata, and parent context.\n * Used internally by rules to track nested validation (e.g., in shape, isArrayOf).\n *\n * @example\n * ```typescript\n * // Access context in custom rules\n * enforce.extend({\n * customRule: (value: any) => {\n * const context = enforce.context();\n * console.log('Current value:', context?.value);\n * console.log('Metadata:', context?.meta);\n * return true;\n * }\n * });\n *\n * // Context is automatically set in nested validations\n * enforce({ user: { name: 'John' } }).shape({\n * user: enforce.shape({\n * name: enforce.isString()\n * })\n * });\n * // When validating 'name', context.parent() gives access to 'user' object\n * ```\n */\nexport const ctx = createCascade<CTXType>((ctxRef, parentContext): CTXType => {\n const base = {\n value: ctxRef.value,\n meta: ctxRef.meta || {},\n };\n\n if (!parentContext) {\n return assign(base, {\n parent: emptyParent,\n });\n } else if (ctxRef.set) {\n return assign(base, {\n parent: (): EnforceContext => stripContext(parentContext),\n });\n }\n\n return parentContext;\n});\n\nfunction stripContext(ctx: CTXType): EnforceContext {\n return {\n value: ctx.value,\n meta: ctx.meta,\n parent: ctx.parent,\n };\n}\n\ntype CTXType = {\n meta: Record<string, any>;\n value: any;\n set?: boolean;\n parent: () => Nullable<CTXType>;\n};\n\nexport type EnforceContext = Nullable<{\n meta: Record<string, any>;\n value: any;\n parent: () => EnforceContext;\n}>;\n\nfunction emptyParent(): null {\n return null;\n}\n","import { isBoolean as isBooleanValue } from 'vest-utils';\n\n/**\n * Validates that a value is a boolean.\n * Type guard that narrows the type to boolean.\n *\n * @param value - Value to validate\n * @returns True if value is a boolean\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(true).isBoolean(); // passes\n * enforce(false).isBoolean(); // passes\n * enforce(1).isBoolean(); // fails\n * enforce('true').isBoolean(); // fails\n *\n * // Lazy API\n * const boolRule = enforce.isBoolean();\n * boolRule.test(true); // true\n * boolRule.test(0); // false\n *\n * // Chains with boolean-specific rules\n * enforce(true).isBoolean().isTrue();\n * ```\n */\nexport function isBoolean(value: any): value is boolean {\n return isBooleanValue(value);\n}\n","// Checks if value is strictly equal to false\nexport function isFalse(value: boolean): boolean {\n return value === false;\n}\n","// Checks if value is strictly equal to true\nexport function isTrue(value: boolean): boolean {\n return value === true;\n}\n","// Validates that two values are strictly equal (===)\nexport function equals<T>(value: T, v: T): boolean {\n return value === v;\n}\n","// Validates that a value is falsy (false, 0, '', null, undefined, or NaN)\nexport function isFalsy(value: any): boolean {\n return !value;\n}\n","// Validates that a value is truthy (not false, 0, '', null, undefined, or NaN)\nexport function isTruthy(value: any): boolean {\n return !!value;\n}\n","import { type DropFirst } from 'vest-utils';\n\nimport { RuleInstance } from '../utils/RuleInstance';\n\nimport { isBoolean } from './boolean/isBoolean';\nimport { isFalse } from './boolean/isFalse';\nimport { isTrue } from './boolean/isTrue';\nimport { equals } from './general/equals';\nimport { isFalsy } from './general/isFalsy';\nimport { isTruthy } from './general/isTruthy';\n\nexport { equals, isFalsy, isFalse, isTrue, isTruthy, isBoolean };\n\nexport interface BooleanRuleInstance extends RuleInstance<boolean, [boolean]> {\n isTrue(...args: DropFirst<Parameters<typeof isTrue>>): BooleanRuleInstance;\n isFalse(...args: DropFirst<Parameters<typeof isFalse>>): BooleanRuleInstance;\n isTruthy(\n ...args: DropFirst<Parameters<typeof isTruthy>>\n ): BooleanRuleInstance;\n isFalsy(...args: DropFirst<Parameters<typeof isFalsy>>): BooleanRuleInstance;\n equals(...args: DropFirst<Parameters<typeof equals>>): BooleanRuleInstance;\n isBoolean(\n ...args: DropFirst<Parameters<typeof isBoolean>>\n ): BooleanRuleInstance;\n}\n","import { dynamicValue, invariant, isNullish, StringObject } from 'vest-utils';\nimport type { Stringable } from 'vest-utils';\n\nimport * as booleanRules from './rules/booleanRules';\n\nexport type RuleValue = unknown;\nexport type Args = any[];\nexport type RuleDetailedResult = {\n pass: boolean;\n message?: Stringable;\n path?: string[];\n};\n\nexport function enforceMessage(\n ruleName: string,\n transformedResult: RuleDetailedResult,\n value: RuleValue,\n customMessage?: string,\n) {\n if (!isNullish(customMessage)) return StringObject(customMessage);\n if (isNullish(transformedResult.message)) {\n return `enforce/${ruleName} failed with ${JSON.stringify(value)}`;\n }\n return StringObject(transformedResult.message);\n}\n\nexport function transformResult(\n result: any,\n ruleName: string,\n value: RuleValue,\n ...args: Args\n): RuleDetailedResult {\n validateResult(result);\n\n if (booleanRules.isBoolean(result)) {\n return { pass: result };\n }\n\n return {\n pass: !!result.pass,\n message: dynamicValue(result.message, ruleName, value, ...args),\n path: result.path,\n };\n}\n\nexport function validateResult(result: any): void {\n invariant(\n booleanRules.isBoolean(result) ||\n (result && booleanRules.isBoolean(result.pass)),\n 'Incorrect return value for rule: ' + JSON.stringify(result),\n );\n}\n","import { invariant } from 'vest-utils';\n\nimport { ctx } from '../enforceContext';\nimport { enforceMessage, transformResult } from '../ruleResult';\n\nimport type { UnmodifiedRules, SchemaRules } from './ruleRegistry';\n\ntype RuleCallConfig = {\n target: any;\n rule: UnmodifiedRules | SchemaRules;\n ruleName: string;\n value: any;\n customMessage: string | undefined;\n clearMessage: () => void;\n};\n\nexport function createRuleCall(config: RuleCallConfig) {\n const { target, rule, ruleName, value, customMessage, clearMessage } = config;\n\n return function ruleCall(...args: any[]): any {\n const transformedResult = ctx.run({ value }, () =>\n transformResult(\n (rule as (...args: any[]) => any)(value, ...args),\n ruleName,\n value,\n ...args,\n ),\n );\n\n invariant(\n transformedResult.pass,\n enforceMessage(ruleName, transformedResult, value, customMessage),\n );\n\n // Clear message after each rule - it only applies to the next rule\n clearMessage();\n target.pass = transformedResult.pass;\n\n return target;\n };\n}\n","// Checks if array contains the given item\nexport function includes<T>(arr: T[], item: T): boolean {\n return Array.isArray(arr) && arr.includes(item);\n}\n","/**\n * Validates that a value is an array.\n * Type guard that narrows the type to any[].\n *\n * @param value - Value to validate\n * @returns True if value is an array\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce([1, 2, 3]).isArray(); // passes\n * enforce('hello').isArray(); // fails\n *\n * // Lazy API\n * const arrayRule = enforce.isArray();\n * arrayRule.test([1, 2]); // true\n * arrayRule.test({}); // false\n * ```\n */\nexport function isArray(value: any): value is any[] {\n return Array.isArray(value);\n}\n","/**\n * Common comparison predicates that work across multiple types\n */\n\nexport function equals<T>(a: T, b: T): boolean {\n return a === b;\n}\n\nexport function notEquals<T>(a: T, b: T): boolean {\n return a !== b;\n}\n\nexport function greaterThan<T extends number | string>(a: T, b: T): boolean {\n return a > b;\n}\n\nexport function greaterThanOrEquals<T extends number | string>(\n a: T,\n b: T,\n): boolean {\n return a >= b;\n}\n\nexport function lessThan<T extends number | string>(a: T, b: T): boolean {\n return a < b;\n}\n\nexport function lessThanOrEquals<T extends number | string>(\n a: T,\n b: T,\n): boolean {\n return a <= b;\n}\n","/**\n * Common container predicates for arrays and strings\n */\n\nfunction isStringContainment(value: unknown, container: unknown): boolean {\n return typeof container === 'string' && typeof value === 'string';\n}\n\nfunction checkAllItemsInSet<T>(items: T[], set: Set<T>): boolean {\n for (const item of items) {\n if (!set.has(item)) return false;\n }\n return true;\n}\n\nfunction checkAnyItemNotInSet<T>(items: T[], set: Set<T>): boolean {\n for (const item of items) {\n if (!set.has(item)) return true;\n }\n return false;\n}\n\nexport function inside<T>(value: T, container: T[] | string): boolean {\n if (isStringContainment(value, container)) {\n return (container as string).includes(value as string);\n }\n\n if (Array.isArray(container)) {\n const set = new Set(container as T[]);\n return Array.isArray(value)\n ? checkAllItemsInSet(value, set)\n : set.has(value as T);\n }\n\n return false;\n}\n\nexport function notInside<T>(value: T, container: any): boolean {\n if (isStringContainment(value, container)) {\n return !(container as string).includes(value as string);\n }\n\n if (Array.isArray(container)) {\n const set = new Set(container as T[]);\n return Array.isArray(value)\n ? checkAnyItemNotInSet(value, set)\n : !set.has(value as T);\n }\n\n return true;\n}\n","// Shared length-based predicates for strings and arrays.\n// Works on any value with a .length property.\n\ntype Lengthable = { length: number };\n\nexport function minLength(value: Lengthable, n: number): boolean {\n return value.length >= n;\n}\n\nexport function maxLength(value: Lengthable, n: number): boolean {\n return value.length <= n;\n}\n\nexport const min = minLength;\nexport const max = maxLength;\n\nexport function lengthEquals(value: Lengthable, n: number): boolean {\n return value.length === n;\n}\n\nexport function lengthNotEquals(value: Lengthable, n: number): boolean {\n return value.length !== n;\n}\n\nexport function longerThan(value: Lengthable, n: number): boolean {\n return value.length > n;\n}\n\nexport function longerThanOrEquals(value: Lengthable, n: number): boolean {\n return value.length >= n;\n}\n\nexport function shorterThan(value: Lengthable, n: number): boolean {\n return value.length < n;\n}\n\nexport function shorterThanOrEquals(value: Lengthable, n: number): boolean {\n return value.length <= n;\n}\n","/**\n * Validates that a value is not an array.\n * Inverse of isArray.\n *\n * @param value - Value to validate\n * @returns True if value is not an array\n *\n * @example\n * ```typescript\n * enforce({}).isNotArray(); // passes\n * enforce('hello').isNotArray(); // passes\n * enforce([1, 2, 3]).isNotArray(); // fails\n * ```\n */\nexport function isNotArray(value: any): boolean {\n return !Array.isArray(value);\n}\n","import { isEmpty, isNotEmpty } from 'vest-utils';\n\nimport { BuildRuleInstance, ExtractRuleFunctions } from './RuleInstanceBuilder';\nimport { includes } from './array/includes';\nimport { isArray } from './array/isArrayRule';\nimport { equals, notEquals } from './commonComparison';\nimport { inside, notInside } from './commonContainer';\nimport {\n lengthEquals,\n lengthNotEquals,\n longerThan,\n longerThanOrEquals,\n maxLength,\n minLength,\n shorterThan,\n shorterThanOrEquals,\n} from './commonLength';\nimport { isNotArray } from './general/isNotArray';\n\nexport {\n equals,\n includes,\n inside,\n isArray,\n isEmpty,\n isNotArray,\n isNotEmpty,\n lengthEquals,\n lengthNotEquals,\n longerThan,\n longerThanOrEquals,\n maxLength,\n minLength,\n notEquals,\n notInside,\n shorterThan,\n shorterThanOrEquals,\n};\n\nconst arrayRules = {\n equals,\n includes,\n inside,\n isEmpty,\n isNotEmpty,\n lengthEquals,\n lengthNotEquals,\n longerThan,\n longerThanOrEquals,\n maxLength,\n minLength,\n notEquals,\n notInside,\n shorterThan,\n shorterThanOrEquals,\n} as const;\n\nexport type ArrayRuleInstance<T = any, TInput = T> = BuildRuleInstance<\n T[],\n [TInput[]],\n ExtractRuleFunctions<typeof arrayRules>\n>;\n","import { isBoolean, Stringable, dynamicValue } from 'vest-utils';\n\n/**\n * Represents the result of a validation rule execution.\n * Contains the pass/fail status, the validated type, and an optional error message.\n *\n * @template T - The type of value that was validated\n *\n * @example\n * ```typescript\n * const result = RuleRunReturn.Passing('hello');\n * console.log(result.pass); // true\n * console.log(result.type); // 'hello'\n *\n * const failed = RuleRunReturn.Failing(123, 'Must be positive');\n * console.log(failed.pass); // false\n * console.log(failed.message); // 'Must be positive'\n * ```\n */\nexport class RuleRunReturn<T> {\n /** Whether the validation passed */\n pass: boolean;\n /** The validated value's type */\n type: T;\n /** Optional error message if validation failed */\n message?: string;\n path?: string[];\n\n constructor(pass: boolean, type: T, message?: string) {\n this.pass = pass;\n this.type = type;\n this.message = message;\n }\n\n /**\n * Creates a RuleRunReturn from a boolean or existing RuleRunReturn.\n * Handles message resolution and type coercion.\n *\n * @param pass - Boolean indicating success, or existing RuleRunReturn\n * @param type - The type of the validated value\n * @param message - Optional error message (can be string or function)\n * @returns A new RuleRunReturn instance\n */\n static create<T>(\n pass: boolean | RuleRunReturn<T>,\n type: T,\n message?: Stringable,\n ): RuleRunReturn<T> {\n if (isBoolean(pass)) {\n return new RuleRunReturn(!!pass, type, dynamicValue(message, type));\n }\n return RuleRunReturn.fromObject(pass, type, message);\n }\n\n // eslint-disable-next-line complexity\n private static fromObject<T>(\n pass: any,\n type: T,\n message?: Stringable,\n ): RuleRunReturn<T> {\n const hasValidObject = pass && isBoolean(pass.pass);\n\n if (!hasValidObject) {\n return new RuleRunReturn(false, type, dynamicValue(message, type));\n }\n\n const resolvedPass = !!pass.pass;\n\n const successType = pass.type === undefined ? type : pass.type;\n const failureType = type === undefined ? pass.type : type;\n const resolvedType = (resolvedPass ? successType : failureType) as T;\n\n const res = new RuleRunReturn(\n resolvedPass,\n resolvedType as T,\n dynamicValue(message ?? pass.message, type),\n );\n\n res.path = pass.path;\n\n return res;\n }\n\n /**\n * Creates a passing RuleRunReturn.\n *\n * @param type - The validated value's type\n * @param message - Optional success message\n * @returns A RuleRunReturn with pass=true\n *\n * @example\n * ```typescript\n * const result = RuleRunReturn.Passing('valid');\n * console.log(result.pass); // true\n * ```\n */\n static Passing<T>(type: T, message?: Stringable): RuleRunReturn<T> {\n return RuleRunReturn.create(true, type, message);\n }\n\n /**\n * Creates a failing RuleRunReturn.\n *\n * @param type - The validated value's type\n * @param message - Optional error message\n * @returns A RuleRunReturn with pass=false\n *\n * @example\n * ```typescript\n * const result = RuleRunReturn.Failing(123, 'Number must be positive');\n * console.log(result.pass); // false\n * console.log(result.message); // 'Number must be positive'\n * ```\n */\n static Failing<T>(type: T, message?: Stringable): RuleRunReturn<T> {\n return RuleRunReturn.create(false, type, message);\n }\n}\n","import { mapFirst } from 'vest-utils';\n\nimport { RuleInstance } from '../../utils/RuleInstance';\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\n/**\n * Validates that a value passes all of the provided rules.\n * All rules must pass for the validation to succeed.\n * Evaluation stops at the first failing rule.\n *\n * @template T - The value type to validate\n * @param value - The value to validate\n * @param rules - One or more RuleInstances that must all pass\n * @returns RuleRunReturn indicating success or failure\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(25)\n * .allOf(\n * enforce.isNumber().greaterThan(18).lessThan(100)\n * ); // passes (all rules pass)\n *\n * // Lazy API\n * const adultAgeRule = enforce.allOf(\n * enforce.isNumber().greaterThanOrEquals(18).lessThan(150)\n * );\n *\n * adultAgeRule.test(25); // true\n * adultAgeRule.test(16); // false\n * adultAgeRule.test('25'); // false (not a number)\n * ```\n */\nexport function allOf<T>(value: T, ...rules: any[]): RuleRunReturn<T> {\n return (\n mapFirst(rules, (rule, breakout) => {\n const res = rule.run(value);\n breakout(!res.pass, res);\n }) || RuleRunReturn.Passing(value)\n );\n}\n\n// Type for allOf rule instance\nexport type AllOfRuleInstance<T> = RuleInstance<T, [T]>;\n","import { mapFirst } from 'vest-utils';\n\nimport { RuleInstance } from '../../utils/RuleInstance';\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\n/**\n * Validates that a value passes at least one of the provided rules.\n * At least one rule must pass for the validation to succeed.\n * Evaluation stops at the first passing rule.\n *\n * @template T - The value type to validate\n * @param value - The value to validate\n * @param rules - One or more RuleInstances where at least one must pass\n * @returns RuleRunReturn indicating success or failure\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce('hello')\n * .anyOf(\n * enforce.isNumber(),\n * enforce.isString()\n * ); // passes (string matches)\n *\n * // Lazy API - accept either format\n * const phoneOrEmailRule = enforce.anyOf(\n * enforce.isString().matches(/^\\d{10}$/), // phone\n * enforce.isString().matches(/@/) // email\n * );\n *\n * phoneOrEmailRule.test('1234567890'); // true\n * phoneOrEmailRule.test('user@example.com'); // true\n * phoneOrEmailRule.test('invalid'); // false\n * ```\n */\nexport function anyOf<T>(value: T, ...rules: any[]): RuleRunReturn<T> {\n return (\n mapFirst(rules, (rule, breakout) => {\n const res = rule.run(value);\n breakout(res.pass, res);\n }) || RuleRunReturn.Failing(value)\n );\n}\n\n// Type for anyOf rule instance\nexport type AnyOfRuleInstance<T> = RuleInstance<T, [T]>;\n","import { mapFirst } from 'vest-utils';\n\nimport { RuleInstance } from '../../utils/RuleInstance';\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\n/**\n * Validates that a value passes none of the provided rules.\n * All rules must fail for the validation to succeed.\n * Evaluation stops at the first passing rule.\n *\n * @template T - The value type to validate\n * @param value - The value to validate\n * @param rules - One or more RuleInstances that must all fail\n * @returns RuleRunReturn indicating success or failure\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(0)\n * .noneOf(\n * enforce.greaterThan(0),\n * enforce.lessThan(0)\n * ); // passes (neither rule passes)\n *\n * // Lazy API - exclude reserved usernames\n * const notReservedRule = enforce.noneOf(\n * enforce.equals('admin'),\n * enforce.equals('root'),\n * enforce.equals('system')\n * );\n *\n * notReservedRule.test('john'); // true\n * notReservedRule.test('admin'); // false\n * notReservedRule.test('root'); // false\n * ```\n */\nexport function noneOf<T>(value: T, ...rules: any[]): RuleRunReturn<T> {\n return (\n mapFirst(rules, (rule, breakout) => {\n const res = rule.run(value);\n breakout(res.pass, RuleRunReturn.Failing(value));\n }) || RuleRunReturn.Passing(value)\n );\n}\n\n// Type for noneOf rule instance\nexport type NoneOfRuleInstance<T> = RuleInstance<T, [T]>;\n","import { greaterThan } from 'vest-utils';\n\nimport { RuleInstance } from '../../utils/RuleInstance';\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\nconst REQUIRED_COUNT = 1;\n\n/**\n * Validates that a value passes exactly one of the provided rules.\n * Exactly one rule must pass - not zero, not two or more.\n * All rules are evaluated to count passing rules.\n *\n * @template T - The value type to validate\n * @param value - The value to validate\n * @param rules - One or more RuleInstances where exactly one must pass\n * @returns RuleRunReturn indicating success or failure\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(5)\n * .oneOf(\n * enforce.lessThan(10),\n * enforce.greaterThan(100)\n * ); // passes (only first rule passes)\n *\n * // Lazy API - accept either type but not both\n * const stringOrNumberRule = enforce.oneOf(\n * enforce.isString(),\n * enforce.isNumber()\n * );\n *\n * stringOrNumberRule.test('hello'); // true\n * stringOrNumberRule.test(42); // true\n * stringOrNumberRule.test(true); // false (no rules pass)\n *\n * // More complex example - exclusive validation\n * const exclusiveRule = enforce.oneOf(\n * enforce.equals(null),\n * enforce.isString().longerThan(0)\n * );\n *\n * exclusiveRule.test(null); // true (exactly one passes)\n * exclusiveRule.test('hello'); // true (exactly one passes)\n * exclusiveRule.test(''); // false (neither passes)\n * ```\n */\nexport function oneOf<T>(value: T, ...rules: any[]): RuleRunReturn<T> {\n let passingCount = 0;\n rules.some(rule => {\n const res = rule.run(value);\n\n if (res.pass) {\n passingCount++;\n }\n\n if (greaterThan(passingCount, REQUIRED_COUNT)) {\n return RuleRunReturn.Failing(value);\n }\n });\n\n return RuleRunReturn.create(passingCount === REQUIRED_COUNT, value);\n}\n\n// Type for oneOf rule instance\nexport type OneOfRuleInstance<T> = RuleInstance<T, [T]>;\n","import './compoundRulesTypes';\n\nexport { allOf, type AllOfRuleInstance } from './allOf';\nexport { anyOf, type AnyOfRuleInstance } from './anyOf';\nexport { noneOf, type NoneOfRuleInstance } from './noneOf';\nexport { oneOf, type OneOfRuleInstance } from './oneOf';\nexport type { CompoundRuleLazyTypes } from './compoundRulesTypes';\n","// Runs custom validation function, returns false if callback throws\nexport function condition(\n value: any,\n callback: (value: any) => boolean,\n): boolean {\n try {\n return callback(value);\n } catch {\n return false;\n }\n}\n","// Validates that two values are not strictly equal (!==)\nexport function notEquals<T>(value: T, v: T): boolean {\n return value !== v;\n}\n","import { isEmpty as isEmptyValue } from 'vest-utils';\n\n// Validates that a value is empty (empty string, array, object, null, or undefined)\nexport function isEmpty(value: any): boolean {\n return isEmptyValue(value);\n}\n","import { toNumber } from 'vest-utils';\n\nimport { RuleInstance } from '../../utils/RuleInstance';\n\nexport interface NaNRuleInstance extends RuleInstance<number | string, [any]> {}\n\n// Validates that a value is NaN (Not a Number)\nexport function isNaN(value: number | string): boolean {\n return Number.isNaN(toNumber(value).unwrapOr(NaN));\n}\n","/**\n * Validates that a value is not a boolean.\n * Inverse of isBoolean.\n *\n * @param value - Value to validate\n * @returns True if value is not a boolean\n *\n * @example\n * ```typescript\n * enforce(1).isNotBoolean(); // passes\n * enforce('true').isNotBoolean(); // passes\n * enforce(true).isNotBoolean(); // fails\n * enforce(false).isNotBoolean(); // fails\n * ```\n */\nexport function isNotBoolean(value: any): boolean {\n return typeof value !== 'boolean';\n}\n","import { isNotEmpty as isNotEmptyValue } from 'vest-utils';\n\n// Checks if value is not empty (not null, undefined, empty string, empty array, or empty object)\nexport function isNotEmpty(value: any): boolean {\n return isNotEmptyValue(value);\n}\n","import { toNumber } from 'vest-utils';\n\n// Validates that a value is not NaN\nexport function isNotNaN(value: any): boolean {\n return !Number.isNaN(toNumber(value).unwrapOr(value));\n}\n","/**\n * Validates that a value is not a number (or is NaN).\n * Inverse of isNumber. Considers NaN as not a number.\n *\n * @param value - Value to validate\n * @returns True if value is not a number or is NaN\n *\n * @example\n * ```typescript\n * enforce('123').isNotNumber(); // passes\n * enforce(NaN).isNotNumber(); // passes\n * enforce(true).isNotNumber(); // passes\n * enforce(42).isNotNumber(); // fails\n * ```\n */\nexport function isNotNumber(value: any): boolean {\n return typeof value !== 'number' || Number.isNaN(value);\n}\n","import { isNumeric as isNumericValue } from 'vest-utils';\n\n/**\n * Validates that a value is not numeric (not a number or numeric string).\n * Inverse of isNumeric.\n *\n * @param value - Value to validate\n * @returns True if value is not numeric\n *\n * @example\n * ```typescript\n * enforce('hello').isNotNumeric(); // passes\n * enforce(true).isNotNumeric(); // passes\n * enforce(NaN).isNotNumeric(); // passes\n * enforce(42).isNotNumeric(); // fails\n * enforce('42').isNotNumeric(); // fails\n * ```\n */\nexport function isNotNumeric(value: any): boolean {\n // Accept numbers (including Infinity) and numeric strings as numeric\n if (typeof value === 'number') {\n // Only NaN is not numeric among numbers\n return Number.isNaN(value);\n }\n // For strings, use the vest-utils isNumeric which excludes Infinity strings\n return !isNumericValue(value);\n}\n","/**\n * Validates that a value is not a string.\n * Inverse of isString.\n *\n * @param value - Value to validate\n * @returns True if value is not a string\n *\n * @example\n * ```typescript\n * enforce(123).isNotString(); // passes\n * enforce([]).isNotString(); // passes\n * enforce('hello').isNotString(); // fails\n * ```\n */\nexport function isNotString(value: any): boolean {\n return typeof value !== 'string';\n}\n","import { isNotNull as isNotNullValue } from 'vest-utils';\n\n/**\n * Validates that a value is not null.\n * Inverse of isNull. Note: undefined passes this check.\n *\n * @param value - Value to validate\n * @returns True if value is not null\n *\n * @example\n * ```typescript\n * enforce(undefined).isNotNull(); // passes\n * enforce(0).isNotNull(); // passes\n * enforce('').isNotNull(); // passes\n * enforce(null).isNotNull(); // fails\n * ```\n */\nexport function isNotNull(value: any): boolean {\n return isNotNullValue(value);\n}\n","import { isNotUndefined as isNotUndefinedValue } from 'vest-utils';\n\n/**\n * Validates that a value is not undefined.\n * Inverse of isUndefined. Note: null passes this check.\n *\n * @param value - Value to validate\n * @returns True if value is not undefined\n *\n * @example\n * ```typescript\n * enforce(null).isNotUndefined(); // passes\n * enforce(0).isNotUndefined(); // passes\n * enforce('').isNotUndefined(); // passes\n * enforce(undefined).isNotUndefined(); // fails\n * ```\n */\nexport function isNotUndefined(value: any): boolean {\n return isNotUndefinedValue(value);\n}\n","import { isNotNullish as isNotNullishValue } from 'vest-utils';\n\n/**\n * Validates that a value is not nullish (not null and not undefined).\n * Inverse of isNullish.\n *\n * @param value - Value to validate\n * @returns True if value is neither null nor undefined\n *\n * @example\n * ```typescript\n * enforce(0).isNotNullish(); // passes\n * enforce('').isNotNullish(); // passes\n * enforce(false).isNotNullish(); // passes\n * enforce(null).isNotNullish(); // fails\n * enforce(undefined).isNotNullish(); // fails\n * ```\n */\nexport function isNotNullish(value: any): boolean {\n return isNotNullishValue(value);\n}\n","import { BlankValue, isNullish, isStringValue } from 'vest-utils';\n\nexport function isBlank(value: unknown): value is BlankValue {\n return isNullish(value) || (isStringValue(value) && !value.trim());\n}\n\nexport function isNotBlank(value: unknown): boolean {\n return !isBlank(value);\n}\n","import { RuleInstance } from '../utils/RuleInstance';\n\n// Common type for rules that accept any value\nexport interface AnyRuleInstance extends RuleInstance<any, [any]> {}\n\nexport { condition } from './general/condition';\nexport { equals } from './general/equals';\nexport { notEquals } from './general/notEquals';\nexport { isEmpty } from './general/isEmpty';\nexport { isFalsy } from './general/isFalsy';\nexport { isNaN } from './general/isNaN';\nexport type { NaNRuleInstance } from './general/isNaN';\nexport { isNotArray } from './general/isNotArray';\nexport { isNotBoolean } from './general/isNotBoolean';\nexport { isNotEmpty } from './general/isNotEmpty';\nexport { isNotNaN } from './general/isNotNaN';\nexport { isNotNumber } from './general/isNotNumber';\nexport { isNotNumeric } from './general/isNotNumeric';\nexport { isNotString } from './general/isNotString';\nexport { isTruthy } from './general/isTruthy';\nexport { isNotNull } from './general/isNotNull';\nexport { isNotUndefined } from './general/isNotUndefined';\nexport { isNotNullish } from './general/isNotNullish';\nexport { isBlank } from './general/isBlank';\nexport { isNotBlank } from './general/isBlank';\n","import { isNull as isNullValue } from 'vest-utils';\n\n/**\n * Validates that a value is null.\n * Type guard that narrows the type to null.\n *\n * @param value - Value to validate\n * @returns True if value is null\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(null).isNull(); // passes\n * enforce(undefined).isNull(); // fails\n * enforce(0).isNull(); // fails\n *\n * // Lazy API\n * const nullRule = enforce.isNull();\n * nullRule.test(null); // true\n * nullRule.test(undefined); // false\n * ```\n */\nexport function isNull(value: any): value is null {\n return isNullValue(value);\n}\n","import { isUndefined as isUndefinedValue } from 'vest-utils';\n\n/**\n * Validates that a value is undefined.\n * Type guard that narrows the type to undefined.\n *\n * @param value - Value to validate\n * @returns True if value is undefined\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(undefined).isUndefined(); // passes\n * enforce(null).isUndefined(); // fails\n * enforce('').isUndefined(); // fails\n *\n * // Lazy API\n * const undefRule = enforce.isUndefined();\n * undefRule.test(undefined); // true\n * undefRule.test(null); // false\n *\n * // Useful for optional properties\n * const schema = enforce.shape({\n * optional: enforce.optional(enforce.isString())\n * });\n * ```\n */\nexport function isUndefined(value: any): value is undefined {\n return isUndefinedValue(value);\n}\n","import { isNullish as isNullishValue } from 'vest-utils';\n\n/**\n * Validates that a value is null or undefined (nullish).\n * Type guard that narrows the type to null | undefined.\n *\n * @param value - Value to validate\n * @returns True if value is null or undefined\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(null).isNullish(); // passes\n * enforce(undefined).isNullish(); // passes\n * enforce(0).isNullish(); // fails\n * enforce('').isNullish(); // fails\n * enforce(false).isNullish(); // fails\n *\n * // Lazy API\n * const nullishRule = enforce.isNullish();\n * nullishRule.test(null); // true\n * nullishRule.test(undefined); // true\n * nullishRule.test(0); // false\n * ```\n */\nexport function isNullish(value: any): value is null | undefined {\n return isNullishValue(value);\n}\n","import { RuleInstance } from '../utils/RuleInstance';\n\n// Backward-compatible re-exports to avoid breaking existing imports\nexport { isNull } from './nullish/isNull';\n\nexport { isUndefined } from './nullish/isUndefined';\n\nexport { isNullish } from './nullish/isNullish';\n\nexport interface NullRuleInstance extends RuleInstance<null, [null]> {}\n\nexport interface UndefinedRuleInstance extends RuleInstance<\n undefined,\n [undefined]\n> {}\n\nexport interface NullishRuleInstance extends RuleInstance<\n null | undefined,\n [null | undefined]\n> {}\n","import { greaterThan, numberEquals } from 'vest-utils';\n\n// Checks if numeric value is greater than or equal to the given threshold\nexport function greaterThanOrEquals(\n value: string | number,\n gte: string | number,\n): boolean {\n return numberEquals(value, gte) || greaterThan(value, gte);\n}\n","import { isNumeric } from 'vest-utils';\n\n// Checks if numeric value is less than the given threshold\nexport function lessThan(value: string | number, lt: string | number): boolean {\n return isNumeric(value) && isNumeric(lt) && Number(value) < Number(lt);\n}\n","import { numberEquals } from 'vest-utils';\n\nimport { lessThan } from './lessThan';\n\n// Checks if numeric value is less than or equal to the given threshold\nexport function lessThanOrEquals(\n value: string | number,\n lte: string | number,\n): boolean {\n return numberEquals(value, lte) || lessThan(value, lte);\n}\n","import { bindNot } from 'vest-utils';\n\nimport { greaterThanOrEquals as gte } from './greaterThanOrEquals';\nimport { lessThanOrEquals as lte } from './lessThanOrEquals';\n\n// Checks if numeric value is within the given range (inclusive)\nexport function isBetween(\n value: number | string,\n min: number | string,\n max: number | string,\n): boolean {\n return gte(value, min) && lte(value, max);\n}\n\nexport const isNotBetween = bindNot(isBetween);\n","import { isNumeric, toNumber } from 'vest-utils';\n\n/**\n * Validates that a given value is an even number\n */\nexport const isEven = (value: string | number): boolean => {\n if (isNumeric(value)) {\n const asNumber = toNumber(value).unwrap();\n\n if (asNumber !== null) {\n return asNumber % 2 === 0;\n }\n }\n\n return false;\n};\n","// Checks if number is less than zero\nexport function isNegative(value: number): boolean {\n return value < 0;\n}\n","export function isNotBetween(value: number, min: number, max: number): boolean {\n return value < min || value > max;\n}\n","/**\n * Validates that a value is a number (excluding NaN).\n * Type guard that narrows the type to number.\n *\n * @param value - Value to validate\n * @returns True if value is a number and not NaN\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(42).isNumber(); // passes\n * enforce('42').isNumber(); // fails (string)\n * enforce(NaN).isNumber(); // fails (NaN is excluded)\n *\n * // Lazy API\n * const numberRule = enforce.isNumber();\n * numberRule.test(42); // true\n * numberRule.test(Infinity); // true\n * numberRule.test(NaN); // false\n *\n * // Chains with number-specific rules\n * enforce(25).isNumber().greaterThan(18);\n * ```\n */\nexport function isNumber(value: any): value is number {\n return typeof value === 'number' && !Number.isNaN(value);\n}\n","import { isNumeric, toNumber } from 'vest-utils';\n\n/**\n * Validates that a given value is an odd number\n */\nexport const isOdd = (value: string | number): boolean => {\n if (isNumeric(value)) {\n const asNumber = toNumber(value).unwrap();\n if (asNumber !== null) {\n return asNumber % 2 !== 0;\n }\n }\n\n return false;\n};\n","// Checks if number is greater than zero\nexport function isPositive(value: number): boolean {\n return value > 0;\n}\n","import { isFailure, toNumber as toNumberValue } from 'vest-utils';\n\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\nexport function toNumber(value: unknown): RuleRunReturn<number> {\n const result = toNumberValue(value);\n\n if (isFailure(result)) {\n return RuleRunReturn.Failing(NaN, result.error);\n }\n\n return RuleRunReturn.Passing(result.value);\n}\n","import { numberNotEquals as numberNotEqualsValue } from 'vest-utils';\n\n// Checks if numeric value is not equal to the given number (with tolerance for floating-point)\nexport function numberNotEquals(value: number, n: number | string): boolean {\n return numberNotEqualsValue(value, n);\n}\n","import { greaterThan, numberEquals } from 'vest-utils';\n\nimport { BuildRuleInstance, ExtractRuleFunctions } from './RuleInstanceBuilder';\nimport { equals } from './general/equals';\nimport { isNaN } from './general/isNaN';\nimport { isNotNaN } from './general/isNotNaN';\nimport { greaterThanOrEquals } from './number/greaterThanOrEquals';\nimport { isBetween } from './number/isBetween';\nimport { isEven } from './number/isEven';\nimport { isNegative } from './number/isNegative';\nimport { isNotBetween } from './number/isNotBetween';\nimport { isNumber } from './number/isNumber';\nimport { isOdd } from './number/isOdd';\nimport { isPositive } from './number/isPositive';\nimport { lessThan } from './number/lessThan';\nimport { lessThanOrEquals } from './number/lessThanOrEquals';\nimport { toNumber } from './numeric/toNumber';\nimport { numberNotEquals } from './number/numberNotEquals';\n\nconst gt = greaterThan;\nconst gte = greaterThanOrEquals;\nconst lt = lessThan;\nconst lte = lessThanOrEquals;\nconst eq = equals;\nconst neq = numberNotEquals;\n\nconst aliases = {\n eq,\n gt,\n gte,\n lt,\n lte,\n neq,\n};\n\nexport {\n gt,\n gte,\n lt,\n lte,\n eq,\n neq,\n equals,\n greaterThan,\n greaterThanOrEquals,\n isBetween,\n isEven,\n isNaN,\n isNegative,\n isNotBetween,\n isNotNaN,\n isNumber,\n isOdd,\n isPositive,\n lessThan,\n lessThanOrEquals,\n numberEquals,\n numberNotEquals,\n toNumber,\n};\n\nconst numberRules = {\n ...aliases,\n equals,\n greaterThan,\n greaterThanOrEquals,\n isBetween,\n isEven,\n isNaN,\n isNegative,\n isNotBetween,\n isNotNaN,\n isNumber,\n isOdd,\n isPositive,\n lessThan,\n lessThanOrEquals,\n numberEquals,\n numberNotEquals,\n toNumber,\n} as const;\n\nexport type NumberRuleInstance = BuildRuleInstance<\n number,\n [number],\n ExtractRuleFunctions<typeof numberRules>\n>;\n\nexport type NumericRuleInstance = BuildRuleInstance<\n string | number,\n [string | number],\n ExtractRuleFunctions<typeof numberRules>\n>;\n","import { isNumeric as isNumericValue } from 'vest-utils';\n\n/**\n * Validates that a value is numeric (a number or a numeric string).\n * Type guard that narrows the type to number | string.\n * Excludes NaN but includes Infinity and numeric strings.\n *\n * @param value - Value to validate\n * @returns True if value is a number or numeric string\n *\n * @example\n * ```typescript\n * // Eager API\n * enforce(42).isNumeric(); // passes\n * enforce('42').isNumeric(); // passes (numeric string)\n * enforce('42.5').isNumeric(); // passes\n * enforce(Infinity).isNumeric(); // passes\n * enforce('hello').isNumeric(); // fails\n * enforce(NaN).isNumeric(); // fails\n *\n * // Lazy API\n * const numericRule = enforce.isNumeric();\n * numericRule.test(100); // true\n * numericRule.test('100'); // true\n * numericRule.test('abc'); // false\n *\n * // Chains with numeric comparison rules\n * enforce('25').isNumeric().greaterThan(18);\n * ```\n */\nexport function isNumeric(value: any): value is number | string {\n // Accept numbers (including Infinity) and numeric strings\n if (typeof value === 'number') {\n return !Number.isNaN(value);\n }\n // For strings, use the vest-utils isNumeric which excludes Infinity strings\n return isNumericValue(value);\n}\n","import { isObject, hasOwnProperty } from 'vest-utils';\n\n// Checks if value is a key that exists in the given object\nexport function isKeyOf(key: string | number | symbol, obj: object): boolean {\n return isObject(obj) && hasOwnProperty(obj, key);\n}\n\n// Checks if value is not a key in the given object\nexport function isNotKeyOf(\n key: string | number | symbol,\n obj: object,\n): boolean {\n return !isObject(obj) || !hasOwnProperty(obj, key);\n}\n","import { isObject } from 'vest-utils';\n\n// Checks if value exists in the given object's values\nexport function isValueOf<T = any>(value: T, obj: Record<string, T>): boolean {\n return isObject(obj) && Object.values(obj).includes(value);\n}\n\n// Checks if value does not exist in the given object's values\nexport function isNotValueOf<T = any>(\n value: T,\n obj: Record<string, T>,\n): boolean {\n return isObject(obj) && !Object.values(obj).includes(value);\n}\n","import { RuleInstance } from '../utils/RuleInstance';\n\nexport interface ObjectRuleInstance extends RuleInstance<object, [object]> {}\n\nexport interface KeyOfRuleInstance extends RuleInstance<\n string | number | symbol,\n [string | number | symbol]\n> {}\n\nexport interface ValueOfRuleInstance<T> extends RuleInstance<T, [T]> {}\n\nexport type ObjectRulesUnion =\n | ObjectRuleInstance\n | KeyOfRuleInstance\n | ValueOfRuleInstance<any>;\n\nexport { isKeyOf, isNotKeyOf } from './object/isKeyOf';\n\nexport { isValueOf, isNotValueOf } from './object/isValueOf';\n","/* eslint-disable max-nested-callbacks */\nimport { lengthEquals, mapFirst } from 'vest-utils';\n\nimport { ctx } from '../../enforceContext';\nimport { transformResult } from '../../ruleResult';\nimport { RuleRunReturn } from '../../utils/RuleRunReturn';\n\n/**\n * Validates that a value is an array and all elements match at least one of the provided rules.\n * Each array element must pass at least one of the validation rules.\n *\n * @template T - The element type of the array\n * @param value - The array to validate\n * @param rules - One or more RuleInstances that elements should match\n * @returns RuleRunReturn indicating success or failure\n *\n * @example\n * ```typescript\n * // Eager API - array of strings\n * enforce(['a', 'b', 'c'])\n * .isArrayOf(enforce.isString()); // passes\n *\n * enforce([1, 2, 'three'])\n * .isArrayOf(enforce.isString()); // fails\n *\n * // Lazy API - array of numbers or strings\n * const mixedArrayRule = enforce.isArrayOf(\n * enforce.isNumber(),\n * enforce.isString()\n * );\n *\n * mixedArrayRule.test([1, 'two', 3, 'four']); // true\n * mixedArrayRule.test([1, 2, true]); // false (boolean not allowed)\n *\n * // Complex schema validation\n * const usersRule = enforce.isArrayOf(\n * enforce.shape({\n * name: enforce.isString(),\n * age: enforce.isNumber()\n * })\n * );\n *\n * usersRule.test([\n * { name: 'John', age: 30 },\n * { name: 'Jane', age: 25 }\n * ]); // true\n * ```\n */\n\nexport function isArrayOf<T>(value: T[], ...rules: any[]): RuleRunReturn<T[]> {\n if (!Array.isArray(value)) {\n return RuleRunReturn.Failing(value);\n }\n\n const parsedArray: any[] = [];\n\n const failingResult = mapFirst(value, (item, breakout, index) => {\n const res = ctx.run({ value: item, set: true, meta: { index } }, () => {\n let lastRes: RuleRunReturn<any> | undefined;\n let passingTransformedType: any = item;\n\n // Try each rule with the item - any rule passing is OK\n const anyPass = rules.some(rule => {\n const rawResult = rule.run(item);\n lastRes = rawResult;\n const transformed = transformResult(rawResult, 'isArrayOf', item);\n if (transformed.pass) {\n passingTransformedType = rawResult.type ?? item;\n }\n return transformed.pass;\n });\n\n if (anyPass) {\n parsedArray.push(passingTransformedType);\n return RuleRunReturn.Passing(passingTransformedType);\n }\n\n // If failed and we have a single rule, return its failure (might contain nested path)\n if (lengthEquals(rules, 1) && lastRes) {\n return lastRes;\n }\n\n return RuleRunReturn.Failing(item);\n });\n\n if (!res.pass) {\n const currentPath = res.path || [];\n const newRes = { ...res, path: [index.toString(), ...currentPath] };\n breakout(true, newRes);\n }\n });\n\n return failingResult || RuleRunReturn.Passing(parsedArray as T[]);\n}\n\n// Type for isArrayOf rule instance - should chain array rules like isArray does\nexport type IsArrayOfRuleInstance<\n T,\n TInput = T,\n> = import('../arrayRules').ArrayRuleInstance<T, TInput>;\n","import { isObject, isUnsafeKey } from 'vest-utils';\n\n/**\n * Returns only own enumerable keys for object-like values.\n *\n * Prototype keys are never traversed which prevents inherited-key surprises.\n */\nexport function ownKeys(value: unknown): string[] {\n if (!isObject(value)) {\n return [];\n }\n\n return Object.keys(v