forked from gwuhaolin/koa-router-decorator
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.ts
executable file
·113 lines (105 loc) · 3.16 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import {Context, Middleware} from 'koa';
import * as Router from 'koa-router';
import * as fs from 'fs';
export enum HttpMethod {
HEAD,
OPTIONS,
GET,
PUT,
PATCH,
POST,
DELETE,
ALL,
}
/**
* 找出目录下所有的文件
*/
function getFiles(dir: string, files_?: string[]): string[] {
files_ = files_ || [];
const files = fs.readdirSync(dir);
for (let i in files) {
const name = dir + '/' + files[i];
if (fs.statSync(name).isDirectory()) {
getFiles(name, files_);
} else {
files_.push(name);
}
}
return files_;
}
/**
* 格式化返回数据的格式
*/
async function formatResponse(descriptor: any, ctx: Context) {
const data = await descriptor.value(ctx);
if (data === null) {
ctx.status = 404;
} else {
ctx.status = 200;
ctx.body = data;
}
}
const router = new Router();
// @router 装饰器
export function route(path: string, method?: HttpMethod, ...middleware: Array<Middleware>) {
return (target: any, key?: string | symbol, descriptor?: any): void => {
// Decorator applied to Class (for Constructor injection).
if (typeof target === 'function' && key === undefined && descriptor === undefined) {
if (!target.prototype.router) {
target.prototype.router = new Router();
}
if (middleware.length > 0) {
target.prototype.router.use(...middleware);
}
router.use(path, target.prototype.router.routes(), target.prototype.router.allowedMethods());
return;
} else if (typeof target === 'object') {
if (!target.router) {
target.router = new Router();
}
const handleReturnMiddleware = async function (ctx: Context) {
await formatResponse(descriptor, ctx);
};
// Decorator applied to member (method or property).
switch (method) {
case HttpMethod.HEAD:
target.router.head(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.OPTIONS:
target.router.options(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.GET:
target.router.get(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.PUT:
target.router.put(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.PATCH:
target.router.patch(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.POST:
target.router.post(path, ...middleware, handleReturnMiddleware);
break;
case HttpMethod.DELETE:
target.router.del(path, ...middleware, handleReturnMiddleware);
break;
default:
target.router.all(path, ...middleware, handleReturnMiddleware);
break;
}
}
};
}
/**
* 加载所有controller文件
* @param controllersDir 陈放所有route的文件夹路径
* @param extension 只导入对应后缀的文件作为route,默认导入所有的.js文件
*/
export function load(controllersDir: string, extension: string = '.js'): Router {
getFiles(controllersDir).forEach((file) => {
if (file.endsWith(extension)) {
require(file);
}
});
return router;
}