import 'pob-babel'; import type { Middleware as ComposeMiddleware, ComposedMiddleware, } from 'koa-compose'; export type Composed = ComposedMiddleware; export type Middleware = ComposeMiddleware; // TODO create lib export default function compose( middlewares: Middleware[], ): Composed { return function (ctx: Context): Promise { let index = -1; return (function dispatch(i: number): Promise { if (i <= index) { return Promise.reject( new Error(!__DEV__ ? undefined : 'next() called multiple times'), ); } index = i; const fn = middlewares[i]; let called = false; try { return Promise.resolve( fn.call(ctx, ctx, (): Promise => { if (called) { throw new Error( !__DEV__ ? undefined : 'Cannot call next() more than once.', ); } called = true; return dispatch(i + 1); }), ); } catch (err) { return Promise.reject(err); } })(0); }; }