import { useCallback , MutableRefObject } from 'react' ; import { ValidateRule , Wrapped , FormContext , ActionEnums } from '../types' ; import isPromise from '@boty-design/utils/src/isPromise' ; import { FormActions } from '../types' ; function setValidating < V > ( field , status , context ) { return context . dispatch ( { type : ActionEnums . SET_VALIDATING_FIELD , payload : { [ field ] : status } , } as FormActions < V > ) ; } function useValidator < V > ( fieldName , schema , contextRef ) { return ( val ) => { const context = contextRef . current ; setValidating ( fieldName , true , context ) ; context . dispatch ( { type : ActionEnums . SET_ERRORS , payload : { [ fieldName ] : [ ] } , } as FormActions < V > ) ; if ( ! schema [ fieldName ] ) { return [ ] ; } const rules = [ ] . concat ( schema [ fieldName ] ) ; const results = rules . map ( ( rule ) => rule ( val , context ) ) ; const asyncResults = results . filter ( ( result ) => isPromise ( result ) ) as Promise < string > [ ] ; const syncResults = results . filter ( ( result ) => ! isPromise ( result ) ) as string [ ] ; if ( ! asyncResults . length ) { setValidating ( fieldName , false , context ) ; return syncResults . filter ( Boolean ) ; } else { return Promise . all ( asyncResults ) . then ( ( [ ... resolved ] ) => { context . dispatch ( { type : ActionEnums . SET_ERRORS , payload : { [ fieldName ] : syncResults . concat ( resolved ) . filter ( Boolean ) , } , } as FormActions < V > ) ; setValidating ( fieldName , false , context ) ; return syncResults . concat ( resolved ) . filter ( Boolean ) ; } ) ; } } ; } export default useValidator ;