UNPKG

n4s

Version:

typed schema validation version of enforce

100 lines (90 loc) 2.43 kB
import { hasOwnProperty } from 'vest-utils'; import { StandardSchemaV1 } from 'vest-utils/standardSchemaSpec'; import { RuleInstance } from '../../utils/RuleInstance'; import { CHAIN_PREPEND } from '../parsers/parserUtils'; import type { Predicate } from './chainExecutor'; import { getLazyRule } from './lazyRegistry'; export function createChainProxyHandlers<T extends RuleInstance<any, any>>( rules: Record<string, (...args: any[]) => any>, { add, test, validate, run, parse, message, prepend, '~standard': standard, }: { add: (p: Predicate) => T; test: T['test']; validate: T['validate']; run: T['run']; parse: T['parse']; message: (msg: any) => T; prepend: (p: Predicate) => T; '~standard': StandardSchemaV1.Props<any, any>; }, ) { const methods = { '~standard': standard, message, parse, run, test, validate, }; const methodKeys = new Set([ 'infer', 'test', 'validate', 'run', 'parse', 'message', '~standard', ]); return createProxyHandlersHelper(rules, methods, methodKeys, { add, prepend, }); } function createProxyHandlersHelper<T extends RuleInstance<any, any>>( rules: Record<string, any>, methods: Record<string, any>, methodKeys: Set<string>, inserters: { add: (p: Predicate) => T; prepend: (p: Predicate) => T }, ) { function getRuleHandler(prop: string | symbol) { if (hasOwnProperty(rules, prop)) { const insert = rules[prop][CHAIN_PREPEND] ? inserters.prepend : inserters.add; return (...args: any[]) => insert((value: any) => rules[prop](value, ...args)); } if (typeof prop === 'string') { const lazyRule = getLazyRule(prop); if (lazyRule) { return (...args: any[]) => inserters.add(lazyRule(...args)); } } return undefined; } return { get(_target: T, prop: string | symbol, receiver: any) { if (hasOwnProperty(methods, prop)) { return methods[prop]; } return ( getRuleHandler(prop) ?? Reflect.get(_target as object, prop, receiver) ); }, has(_target: T, prop: string | symbol) { if (typeof prop === 'string') { if (methodKeys.has(prop) || getLazyRule(prop)) return true; } if (hasOwnProperty(rules, prop)) return true; return Reflect.has(_target as object, prop); }, }; }