1
|
|
|
import { |
2
|
|
|
NextFunction, Request, RequestHandler, Response, |
3
|
|
|
} from 'express'; |
4
|
|
|
import { ExpressRouterBean, HTTPMethod } from '@/ExpressBeansTypes'; |
5
|
|
|
import { logger, registeredMethods } from '@/core'; |
6
|
|
|
import { RouterMethods } from '@/core/RouterMethods'; |
7
|
|
|
|
8
|
|
|
// Return type here should be "void | Promise<void>" but it is not possible to do it. |
9
|
|
|
// Using "any" instead |
10
|
|
|
// https://github.com/microsoft/TypeScript/issues/43921 |
11
|
|
|
declare type RouterBeanHandler = (req: Request, res: Response, next?: NextFunction) => any; |
12
|
|
|
declare type RouteOptions = { middlewares: Array<RequestHandler> } |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Registers a RequestHandler |
16
|
|
|
* @param httpMethod |
17
|
|
|
* @param path {string} |
18
|
|
|
* @param options {RouteOptions} |
19
|
|
|
* @decorator |
20
|
|
|
*/ |
21
|
|
|
export function Route<This>( |
22
|
|
|
httpMethod: HTTPMethod, |
23
|
|
|
path: string, |
24
|
|
|
options: RouteOptions = { middlewares: [] }, |
25
|
|
|
) { |
26
|
24 |
|
return ( |
27
|
|
|
method: RouterBeanHandler, |
28
|
|
|
context: ClassMethodDecoratorContext<This, RouterBeanHandler>, |
29
|
|
|
) => { |
30
|
24 |
|
setImmediate(() => { |
31
|
24 |
|
const bean = registeredMethods.get(method) as ExpressRouterBean; |
32
|
24 |
|
if (bean?.routerConfig) { |
33
|
23 |
|
const { routerConfig } = bean; |
34
|
23 |
|
const { router } = routerConfig; |
35
|
23 |
|
logger.debug(`Mapping ${bean.className}.${String(context.name)} with ${httpMethod} ${routerConfig.path}${path}`); |
36
|
23 |
|
router[RouterMethods[httpMethod]](path, ...options.middlewares, (req, res, next) => { |
37
|
23 |
|
const result = method.bind(bean)(req, res); |
38
|
22 |
|
Promise.resolve(result).catch(next); |
39
|
|
|
}); |
40
|
|
|
} |
41
|
|
|
}); |
42
|
24 |
|
return method; |
43
|
|
|
}; |
44
|
|
|
} |
45
|
|
|
|