import { registerMock , onRun } from './eventEmitter' ; import type { AsyncFnAfterEvent , AsyncFnBeforeEvent , AsyncFnRegister , } from './types' ; type PartialKeys < T , K extends keyof T > = Omit < T , K > & { [ P in K ] ? : T [ P ] ; } ; export const mockAsyncFn = ( mock = { } ) => < T extends ( ... args : unknown [ ] ) => Promise < unknown > > ( targetFn ) : T => { const rule = { scenarios : [ ] , ... mock , type : 'Register/asyncFn' , target : targetFn , timeStamp : new Date ( ) . getTime ( ) , } ; registerMock ( rule ) ; return ( ( ... args ) => new Promise ( ( resolve , reject ) => { const beforeEvent = { type : 'Run/asyncFn/before' , target : targetFn , timeStamp : new Date ( ) . getTime ( ) , rule , resolve , reject , pass : async ( interceptReturn = false ) => { let originResult ; let error = undefined ; try { originResult = await targetFn ( ... args ) ; } catch ( e ) { if ( e instanceof Error ) { error = e ; } else { error = new Error ( `Unknown error: ${ e }` ) ; } } const passReturn = ( ) => { if ( error ) { reject ( error ) ; return ; } resolve ( originResult ) ; } ; if ( ! interceptReturn ) { passReturn ( ) ; return ; } const afterEvent = { type : 'Run/asyncFn/after' , target : targetFn , timeStamp : new Date ( ) . getTime ( ) , rule , result : originResult , error , resolve , reject , pass : passReturn , } ; onRun ( afterEvent ) ; } , } ; onRun ( beforeEvent ) ; } ) ) as T ; } ;