import callsites from 'callsites'; import {inferLabel} from './lib/utils/infer-label'; import {Predicate} from './lib/predicates/predicate'; import {BasePredicate, isPredicate} from './lib/predicates/base-predicate'; import modifiers, {Modifiers} from './modifiers'; import predicates, {Predicates} from './predicates'; import test from './lib/test'; /** * @hidden */ export type Main = (value: T, label: string | Function, predicate: BasePredicate) => void; // Extends is only necessary for the generated documentation to be cleaner. The loaders below infer the correct type. export interface Ow extends Modifiers, Predicates { /** * Test if the value matches the predicate. Throws an `ArgumentError` if the test fails. * * @param value Value to test. * @param predicate Predicate to test against. */ (value: T, predicate: BasePredicate): void; /** * Test if `value` matches the provided `predicate`. Throws an `ArgumentError` with the specified `label` if the test fails. * * @param value Value to test. * @param label Label which should be used in error messages. * @param predicate Predicate to test against. */ (value: T, label: string, predicate: BasePredicate): void; /** * Returns `true` if the value matches the predicate, otherwise returns `false`. * * @param value Value to test. * @param predicate Predicate to test against. */ isValid(value: T, predicate: BasePredicate): value is T; /** * Create a reusable validator. * * @param predicate Predicate used in the validator function. */ create(predicate: BasePredicate): (value: T) => void; /** * Create a reusable validator. * * @param label Label which should be used in error messages. * @param predicate Predicate used in the validator function. */ create(label: string, predicate: BasePredicate): (value: T) => void; } const ow = (value: T, labelOrPredicate: any, predicate?: BasePredicate) => { if (!isPredicate(labelOrPredicate) && typeof labelOrPredicate !== 'string') { throw new TypeError(`Expected second argument to be a predicate or a string, got \`${typeof labelOrPredicate}\``); } if (isPredicate(labelOrPredicate)) { // If the second argument is a predicate, infer the label const stackFrames = callsites(); test(value, () => inferLabel(stackFrames), labelOrPredicate); return; } test(value, labelOrPredicate, predicate as BasePredicate); }; Object.defineProperties(ow, { isValid: { value: (value: T, predicate: BasePredicate) => { try { ow(value, predicate); return true; } catch { return false; } } }, create: { value: (labelOrPredicate: BasePredicate | string | undefined, predicate?: BasePredicate) => (value: T) => { if (isPredicate(labelOrPredicate)) { const stackFrames = callsites(); test(value, () => inferLabel(stackFrames), labelOrPredicate); return; } test(value, labelOrPredicate as string, predicate as BasePredicate); } } }); export default predicates(modifiers(ow)) as Ow; export {BasePredicate, Predicate}; export { StringPredicate, NumberPredicate, BooleanPredicate, ArrayPredicate, ObjectPredicate, DatePredicate, ErrorPredicate, MapPredicate, WeakMapPredicate, SetPredicate, WeakSetPredicate, AnyPredicate, Shape } from './predicates';