35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
type Middleware<TContext, TReturn> = (
|
|
context: TContext,
|
|
next: () => Promise<TReturn>
|
|
) => Promise<TReturn>;
|
|
|
|
export type MiddlewareChain<TContext, TReturn> = {
|
|
use: (middleware: Middleware<TContext, TReturn>) => void;
|
|
execute: (context: TContext) => Promise<TReturn>;
|
|
};
|
|
|
|
export function createMiddlewareChain<TContext extends object, TReturn=TContext>(
|
|
fallback?: (context: TContext) => Promise<TReturn>
|
|
): MiddlewareChain<TContext, TReturn> {
|
|
const middlewares: Middleware<TContext, TReturn>[] = [];
|
|
|
|
return {
|
|
use(middleware: Middleware<TContext, TReturn>) {
|
|
middlewares.push(middleware);
|
|
},
|
|
async execute(context: TContext) {
|
|
let index = 0;
|
|
|
|
async function dispatch(ctx: TContext): Promise<TReturn> {
|
|
if (index >= middlewares.length) {
|
|
return fallback ? fallback(ctx) : ctx as unknown as TReturn;
|
|
}
|
|
const current = middlewares[index++];
|
|
return current(ctx, () => dispatch(ctx));
|
|
}
|
|
|
|
return dispatch(context);
|
|
},
|
|
};
|
|
}
|