-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
68 lines (59 loc) · 1.72 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { ErrorRequestHandler, RequestHandler } from "express";
import { Request, Response, NextFunction } from "express";
import { ParamsDictionary, Query } from "express-serve-static-core";
import { ParsedQs } from "qs";
export type ErrorConstructor<T extends unknown[]> = new (
...args: T
) => ErrorRequestHandler;
export type Callback<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = Query
> = (
...args: Parameters<RequestHandler<P, ResBody, ReqBody, ReqQuery>>
) => void;
export interface Maestro {
(middleware: Callback): Callback;
from(constructor: ErrorConstructor<[]>, middleware: Callback): Callback;
all(callbacks: Callback[]): Callback[];
}
const maestro = function opera(middleware: Callback) {
return async function orchestra(...args: any[]): Promise<void> {
const fnReturn = middleware(...(args as Parameters<RequestHandler>));
const next = args[args.length - 1];
if (typeof next !== "function") {
throw new TypeError("Next is not a function");
}
return Promise.resolve(fnReturn).catch(next);
};
};
maestro.from = function from(
constructor: any,
middleware: (
arg0: Error,
arg1: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>,
arg2: Response<any, Record<string, any>>,
arg3: NextFunction
) => void
) {
return function errorHandler(
err: Error,
req: Request,
res: Response,
next: NextFunction
) {
if (!(err instanceof constructor)) {
next(err);
return;
}
middleware(err, req, res, next);
};
};
maestro.all = function all(callbacks: Callback[]) {
return callbacks.map(maestro);
};
Object.freeze(maestro);
Object.freeze(maestro.from);
Object.freeze(maestro.all);
export { maestro };