diff --git a/src/domain-functions.ts b/src/domain-functions.ts index ce180e42..b1cced6e 100644 --- a/src/domain-functions.ts +++ b/src/domain-functions.ts @@ -233,7 +233,7 @@ function sequence( */ function map( dfn: DomainFunction, - mapper: (element: O) => R, + mapper: (element: O) => R | Promise, ): DomainFunction { return ((input, environment) => dfResultFromcomposable( @@ -327,16 +327,16 @@ function fromSuccess( */ function mapError( dfn: DomainFunction, - mapper: (element: ErrorData) => ErrorData, + mapper: (element: ErrorData) => ErrorData | Promise, ): DomainFunction { - return async (input, environment) => { + return (async (input, environment) => { const result = await dfn(input, environment) if (result.success) return result - return safeResult(() => { - throw new ResultError({ ...mapper(result) }) + return safeResult(async () => { + throw new ResultError({ ...(await mapper(result)) }) }) - } + }) as DomainFunction } type TraceData = { @@ -394,4 +394,3 @@ export { sequence, trace, } - diff --git a/src/map-error.test.ts b/src/map-error.test.ts index dc37dcb5..7f50948f 100644 --- a/src/map-error.test.ts +++ b/src/map-error.test.ts @@ -13,7 +13,7 @@ describe('mapError', () => { ({ errors: [{ message: 'New Error Message' }], inputErrors: [{ message: 'New Input Error Message' }], - } as ErrorData) + }) as ErrorData const c = mapError(a, b) type _R = Expect>> @@ -39,7 +39,32 @@ describe('mapError', () => { path: [], }, ], - } as ErrorData) + }) as ErrorData + + const c = mapError(a, b) + type _R = Expect>> + + assertEquals(await c({ invalidInput: '1' }), { + success: false, + errors: [{ message: 'Number of errors: 0' }], + environmentErrors: [], + inputErrors: [{ message: 'Number of input errors: 1', path: [] }], + }) + }) + + it('returns a domain function function that will apply an async function over the error of the first one', async () => { + const a = mdf(z.object({ id: z.number() }))(({ id }) => id + 1) + const b = (result: ErrorData) => + Promise.resolve({ + errors: [{ message: 'Number of errors: ' + result.errors.length }], + environmentErrors: [], + inputErrors: [ + { + message: 'Number of input errors: ' + result.inputErrors.length, + path: [], + }, + ], + }) as Promise const c = mapError(a, b) type _R = Expect>> diff --git a/src/map.test.ts b/src/map.test.ts index a2eb09e5..9e64986f 100644 --- a/src/map.test.ts +++ b/src/map.test.ts @@ -23,6 +23,22 @@ describe('map', () => { }) }) + it('returns a domain function function that will apply an async function over the results of the first one', async () => { + const a = mdf(z.object({ id: z.number() }))(({ id }) => id + 1) + const b = (id: number) => Promise.resolve(id + 1) + + const c = map(a, b) + type _R = Expect>> + + assertEquals(await c({ id: 1 }), { + success: true, + data: 3, + errors: [], + inputErrors: [], + environmentErrors: [], + }) + }) + it('returns the error when the domain function fails', async () => { const firstInputParser = z.object({ id: z.number() }) const a = mdf(firstInputParser)(({ id }) => id + 1)