koa-use-decorator-router 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +450 -0
- package/dist/index.cjs +511 -0
- package/dist/index.d.cts +175 -0
- package/dist/index.d.mts +175 -0
- package/dist/index.d.ts +175 -0
- package/dist/index.mjs +494 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yige Wang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
# 一个基于装饰器的 Koa 路由封装,提供控制器抽象、参数注入和单例管理
|
|
2
|
+
|
|
3
|
+
## A decorator-driven Koa routing framework with controller abstraction, parameter injection, and singleton support.
|
|
4
|
+
|
|
5
|
+
> 依赖 `koa`、`@koa/router`、`reflect-metadata`
|
|
6
|
+
|
|
7
|
+
> Requires `koa`, `@koa/router`, and `reflect-metadata`.
|
|
8
|
+
|
|
9
|
+
> 此插件使用的装饰器是 TypeScript 的功能,如果使用 JavaScript,需要确保能正确编译为 TypeScript 风格的装饰器产物(如 Babel),包括参数装饰器。
|
|
10
|
+
|
|
11
|
+
> This plugin relies on TypeScript decorators. If you are using JavaScript, you must ensure your build toolchain (e.g., Babel) supports legacy/TypeScript-style decorators, including parameter decorators.
|
|
12
|
+
|
|
13
|
+
### 提供基于 Koa 的装饰器路由,使路由定义更简洁以及更易读。
|
|
14
|
+
|
|
15
|
+
### Provides decorator-based routing for Koa, making route definitions cleaner and more readable.
|
|
16
|
+
|
|
17
|
+
## 安装 / Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install koa-use-decorator-router
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 依赖要求 / Requirements
|
|
24
|
+
|
|
25
|
+
- `koa` >=2.0.0
|
|
26
|
+
- `@koa/router` >=10.0.0
|
|
27
|
+
- `reflect-metadata` >=0.2.0
|
|
28
|
+
|
|
29
|
+
> tsconfig.json:
|
|
30
|
+
|
|
31
|
+
- `"experimentalDecorators": true`
|
|
32
|
+
- `"emitDecoratorMetadata": true`
|
|
33
|
+
|
|
34
|
+
## 使用 / Usage
|
|
35
|
+
|
|
36
|
+
> 目录下的控制器文件名必须以 `Controller` 结尾。可以通过 `acceptAnyControllerName` 允许任何控制器文件名
|
|
37
|
+
|
|
38
|
+
> The controller file name must end with `Controller`. You can allow any controller file name by setting `acceptAnyControllerName: true`
|
|
39
|
+
|
|
40
|
+
> 目录下的控制器文件必须导出一个被 `@Controller` 装饰器装饰的类
|
|
41
|
+
|
|
42
|
+
> The controller file must export a class decorated with `@Controller`.
|
|
43
|
+
|
|
44
|
+
- ### 声明 / Declaration
|
|
45
|
+
|
|
46
|
+
#### ESM Module
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import Koa from 'koa';
|
|
50
|
+
import { decorator } from 'koa-use-decorator-router';
|
|
51
|
+
import { dirname, resolve } from 'node:path';
|
|
52
|
+
import { fileURLToPath } from 'node:url';
|
|
53
|
+
|
|
54
|
+
const app = new Koa();
|
|
55
|
+
app.use(
|
|
56
|
+
decorator({
|
|
57
|
+
controllerDir: resolve(dirname(fileURLToPath(import.meta.url)), './controller'),
|
|
58
|
+
allowedMethods: true,
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### CommonJS Module
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const Koa = require('koa');
|
|
67
|
+
const decorator = require('koa-use-decorator-router');
|
|
68
|
+
const { dirname, resolve } = require('node:path');
|
|
69
|
+
const { fileURLToPath } = require('node:url');
|
|
70
|
+
|
|
71
|
+
const app = new Koa();
|
|
72
|
+
app.use(
|
|
73
|
+
decorator({
|
|
74
|
+
controllerDir: resolve(__dirname, './controller'),
|
|
75
|
+
allowedMethods: true,
|
|
76
|
+
}),
|
|
77
|
+
);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### 函数创建中间件 / Create Middleware via Function
|
|
81
|
+
|
|
82
|
+
> 扩展传参方式 / Extended parameter options
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import Koa from 'koa';
|
|
86
|
+
import Router from '@koa/router';
|
|
87
|
+
import { decorator } from 'koa-use-decorator-router';
|
|
88
|
+
import { dirname, resolve } from 'node:path';
|
|
89
|
+
import { fileURLToPath } from 'node:url';
|
|
90
|
+
|
|
91
|
+
const dir = resolve(dirname(fileURLToPath(import.meta.url)), './controller');
|
|
92
|
+
|
|
93
|
+
const app = new Koa();
|
|
94
|
+
const router = new Router();
|
|
95
|
+
// 可以传递 router 实例,来自定义插件内部的路由实例
|
|
96
|
+
// You can pass a router instance to customize the internal router instance.
|
|
97
|
+
app.use(decorator(dir, router)).use(router.allowedMethods());
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### 构造函数创建中间件 / Create Middleware via Constructor
|
|
101
|
+
|
|
102
|
+
> `Decorator` 实例可以直接调用 `Router` 实例的方法,内部通过代理模式实现。
|
|
103
|
+
|
|
104
|
+
> You can directly call methods of `Router` instance on `Decorator` instance. The methods are proxied internally.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import Koa from 'koa';
|
|
108
|
+
import Router from '@koa/router';
|
|
109
|
+
|
|
110
|
+
import { Decorator } from 'koa-use-decorator-router';
|
|
111
|
+
// ======= or =======
|
|
112
|
+
import Decorator from 'koa-use-decorator-router';
|
|
113
|
+
|
|
114
|
+
import { dirname, resolve } from 'node:path';
|
|
115
|
+
import { fileURLToPath } from 'node:url';
|
|
116
|
+
|
|
117
|
+
const dir = resolve(dirname(fileURLToPath(import.meta.url)), './controller');
|
|
118
|
+
|
|
119
|
+
const app = new Koa();
|
|
120
|
+
|
|
121
|
+
const decorator = new Decorator(dir);
|
|
122
|
+
// 可以直接使用 `Router` 实例中的 `prefix` 方法
|
|
123
|
+
// You can directly call `prefix` method of `Router` instance on `Decorator` instance.
|
|
124
|
+
decorator.prefix('/api');
|
|
125
|
+
app.use(decorator.middleware()).use(decorator.allowedMethods());
|
|
126
|
+
|
|
127
|
+
// 自定义路由实例 / Customize Router Instance
|
|
128
|
+
const router = new Router();
|
|
129
|
+
const decorator = new Decorator(dir, router);
|
|
130
|
+
app.use(decorator.middleware()).use(decorator.allowedMethods());
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- ### 基本声明示例 / Basic Declaration Example
|
|
134
|
+
|
|
135
|
+
#### 成员函数返回的数据会作为响应体返回
|
|
136
|
+
|
|
137
|
+
#### The return value of the member function will be used as the response body.
|
|
138
|
+
|
|
139
|
+
#### 成员函数可以使用 `@Context` 注入 `Koa.Context` 类型的参数
|
|
140
|
+
|
|
141
|
+
#### The member function can use `@Context` to inject a `Koa.Context` object.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import type Koa from 'koa';
|
|
145
|
+
import { Controller, HttpMethod, Context } from 'koa-use-decorator-router';
|
|
146
|
+
|
|
147
|
+
@Controller('/home')
|
|
148
|
+
export class HomeController {
|
|
149
|
+
@HttpMethod.Get('/')
|
|
150
|
+
async index(@Context() ctx: Koa.Context) {
|
|
151
|
+
console.log(ctx.query);
|
|
152
|
+
return 'Hello World!';
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- ### 单例 / Singleton
|
|
158
|
+
|
|
159
|
+
#### 单例装饰器不会修改或重写类的构造函数,而是在内部维护一个单例实例,插件生命周期内会复用该实例。
|
|
160
|
+
|
|
161
|
+
#### The `@Singleton` decorator does not modify or override the class constructor. Instead, it internally manages a single shared instance, which is reused whenever the class is instantiated within the plugin lifecycle.
|
|
162
|
+
|
|
163
|
+
#### 非控制器目录下的其它类也可以使用 `@Singleton` 装饰器
|
|
164
|
+
|
|
165
|
+
#### Classes outside the controller directory can also use the `@Singleton` decorator.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import { Singleton, Controller, HttpMethod } from 'koa-use-decorator-router';
|
|
169
|
+
|
|
170
|
+
@Singleton()
|
|
171
|
+
@Controller('/home')
|
|
172
|
+
export class HomeController {
|
|
173
|
+
@HttpMethod.Get('/')
|
|
174
|
+
async index() {
|
|
175
|
+
return 'Hello World!';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// HomeService.ts
|
|
180
|
+
import { Singleton } from 'koa-use-decorator-router';
|
|
181
|
+
|
|
182
|
+
@Singleton()
|
|
183
|
+
export class HomeService {
|
|
184
|
+
async index() {
|
|
185
|
+
return 'Hello World!';
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
- ### 参数注入示例 / Parameter Injection Example
|
|
191
|
+
|
|
192
|
+
#### `@Inject` 装饰器第二个参数可以是一个枚举值,也可以是一个函数
|
|
193
|
+
|
|
194
|
+
> - 预定义枚举值(如 `Types.Int`)用于内置类型转换
|
|
195
|
+
> - 自定义函数用于转换参数值
|
|
196
|
+
|
|
197
|
+
#### `@Inject` decorator second parameter can be an enum value or a function.
|
|
198
|
+
|
|
199
|
+
> - a predefined enum (e.g., `Types.Int`) for built-in type conversion
|
|
200
|
+
> - a custom function for transforming the value
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { Controller, HttpMethod, Inject, Types } from 'koa-use-decorator-router';
|
|
204
|
+
|
|
205
|
+
@Controller('/home')
|
|
206
|
+
export class HomeController {
|
|
207
|
+
@HttpMethod.Get('/:name')
|
|
208
|
+
async string(@Inject('name') name: string) {
|
|
209
|
+
return `Hello ${name}`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@HttpMethod.Get('/:id')
|
|
213
|
+
async int(@Inject('id', Types.Int) id: number) {
|
|
214
|
+
return `Hello ${id}`;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@HttpMethod.Get('/:path')
|
|
218
|
+
async custom(@Inject('path', decodeURIComponent) path: string) {
|
|
219
|
+
return `Hello ${path}`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
- ### 响应头示例 / Response Header Example
|
|
225
|
+
|
|
226
|
+
#### `@ResponseHeader` 装饰器用于设置响应头,第一个参数是响应头名称,第二个参数是响应头值
|
|
227
|
+
|
|
228
|
+
#### The `@ResponseHeader` decorator is used to set response headers. The first parameter specifies the header name, and the second parameter specifies the header value.
|
|
229
|
+
|
|
230
|
+
#### 提供一个 `@Cross` 装饰器,用于处理跨域请求,可作用于控制器或成员函数上
|
|
231
|
+
|
|
232
|
+
#### The `@Cross` decorator enables CORS (Cross-Origin Resource Sharing). It can be applied at the controller or method level.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
import { Controller, HttpMethod, ResponseHeader, Methods, Cross } from 'koa-use-decorator-router';
|
|
236
|
+
|
|
237
|
+
@Controller('/home')
|
|
238
|
+
@Cross()
|
|
239
|
+
export class HomeController {
|
|
240
|
+
@HttpMethod.Get('/')
|
|
241
|
+
@ResponseHeader('Content-Type', 'text/plain')
|
|
242
|
+
async index() {
|
|
243
|
+
return 'Hello World!';
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
@HttpMethod.Get('/cross')
|
|
247
|
+
@Cross('http://localhost:3000', ['Content-Type', 'Authorization'], [Methods.GET])
|
|
248
|
+
async cross() {
|
|
249
|
+
return 'Hello Cross!';
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- ### 条件装饰器 / Conditional Decorator
|
|
255
|
+
|
|
256
|
+
#### `@IF` 装饰器可以根据条件判断应用不同的装饰器,必须要链式调用 `ENDIF` 结束
|
|
257
|
+
|
|
258
|
+
#### The `@IF` decorator allows applying different decorators based on a condition, and must be concluded by chaining a call to `ENDIF`.
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
import { Controller, HttpMethod, IF } from 'koa-use-decorator-router';
|
|
262
|
+
|
|
263
|
+
@(IF(process.env.SOME_ENV, Controller('/if-not'))
|
|
264
|
+
.ELIF(process.env.SOME_ENV, Controller('/elif'))
|
|
265
|
+
.ELSE(Controller('/else'))
|
|
266
|
+
.ENDIF())
|
|
267
|
+
export class HomeController {
|
|
268
|
+
@HttpMethod.Get('/')
|
|
269
|
+
async index() {
|
|
270
|
+
return 'Hello World!';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
- ### 成员属性注入 / Property Injection
|
|
276
|
+
|
|
277
|
+
#### 可以通过传递构造函数给 `@Inject` 装饰器来注入成员属性,或者在 ts 中通过类型反射来注入
|
|
278
|
+
|
|
279
|
+
#### You can inject member properties by passing the class constructor to the `@Inject` decorator, or by using TypeScript's type reflection.
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
// HomeController.ts
|
|
283
|
+
import type { HomeService } from '@/service/HomeService';
|
|
284
|
+
import { Controller, HttpMethod, Inject } from 'koa-use-decorator-router';
|
|
285
|
+
import { HomeService2, HomeService3 } from '@/service/HomeService';
|
|
286
|
+
|
|
287
|
+
@Controller('/home')
|
|
288
|
+
export class HomeController {
|
|
289
|
+
// 如果不用非空断言 (!),则 `tsconfig.json` 中必须开启 `strictPropertyInitialization`
|
|
290
|
+
// If you do not use the non-null assertion operator (!), you must enable `strictPropertyInitialization` in `tsconfig.json`.
|
|
291
|
+
@Inject()
|
|
292
|
+
service!: HomeService;
|
|
293
|
+
|
|
294
|
+
@Inject(HomeService2)
|
|
295
|
+
service2!: HomeService2;
|
|
296
|
+
|
|
297
|
+
// 当将类的构造函数作为参数传入 `@Inject` 装饰器时,TypeScript 类型也可以使用 `any`
|
|
298
|
+
// This means that when passing a class constructor to the `@Inject` decorator, the TypeScript type can be specified as `any`.
|
|
299
|
+
@Inject(HomeService3)
|
|
300
|
+
service3: any;
|
|
301
|
+
|
|
302
|
+
@HttpMethod.Get('/')
|
|
303
|
+
async index() {
|
|
304
|
+
return this.service.show();
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@HttpMethod.Get('/service2')
|
|
308
|
+
async index2() {
|
|
309
|
+
return this.service2.show();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@HttpMethod.Get('/service3')
|
|
313
|
+
async index3() {
|
|
314
|
+
return this.service3.show();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// HomeService.ts
|
|
319
|
+
export class HomeService {
|
|
320
|
+
show() {
|
|
321
|
+
return 'Hello World!';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export class HomeService2 {
|
|
326
|
+
show() {
|
|
327
|
+
return 'Hello World 2!';
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export class HomeService3 {
|
|
332
|
+
show() {
|
|
333
|
+
return 'Hello World 3!';
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
- ### 控制器基础路径覆盖 / Controller Base Path Override
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
import { Controller, HttpMethod, ControllerBasePathOverride } from 'koa-use-decorator-router';
|
|
342
|
+
|
|
343
|
+
@Controller('/home')
|
|
344
|
+
export class HomeController {
|
|
345
|
+
@ControllerBasePathOverride()
|
|
346
|
+
@HttpMethod.Get('/home2/:name')
|
|
347
|
+
async string(@Inject('name') name: string) {
|
|
348
|
+
return `Hello ${name}`;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
- ### 路由实例方法代理 / Router Method Proxying
|
|
354
|
+
|
|
355
|
+
```ts
|
|
356
|
+
import Koa from 'koa';
|
|
357
|
+
import Decorator from 'koa-use-decorator-router';
|
|
358
|
+
import { dirname, resolve } from 'node:path';
|
|
359
|
+
import { fileURLToPath } from 'node:url';
|
|
360
|
+
|
|
361
|
+
const dir = resolve(dirname(fileURLToPath(import.meta.url)), './controller');
|
|
362
|
+
|
|
363
|
+
const app = new Koa();
|
|
364
|
+
|
|
365
|
+
const decorator = new Decorator(dir);
|
|
366
|
+
decorator.prefix('/api').param('user', (id, ctx, next) => {
|
|
367
|
+
ctx.user = users[id];
|
|
368
|
+
if (!ctx.user) return (ctx.status = 404);
|
|
369
|
+
return next();
|
|
370
|
+
});
|
|
371
|
+
app.use(decorator.middleware()).use(decorator.allowedMethods());
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
- ### 控制器文件过滤 / Controller File Filter
|
|
375
|
+
|
|
376
|
+
#### 通过函数创建 / Create a custom filter function
|
|
377
|
+
|
|
378
|
+
```ts
|
|
379
|
+
app.use(
|
|
380
|
+
decorator({
|
|
381
|
+
controllerDir: dir,
|
|
382
|
+
// 仅加载名为 IndexController 的文件(去除扩展名后比较)
|
|
383
|
+
// Only load files with the name IndexController (without extension)
|
|
384
|
+
matchFileName: 'IndexController',
|
|
385
|
+
}),
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
app.use(
|
|
389
|
+
decorator({
|
|
390
|
+
controllerDir: dir,
|
|
391
|
+
// 加载以 Admin 开头的控制器:AdminController、AdminUserController 等
|
|
392
|
+
// Load controllers that start with Admin, such as AdminController, AdminUserController, etc.
|
|
393
|
+
matchFileName: /^Admin/,
|
|
394
|
+
}),
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
app.use(
|
|
398
|
+
decorator({
|
|
399
|
+
controllerDir: dir,
|
|
400
|
+
matchFileName: ['IndexController', /^Admin/],
|
|
401
|
+
}),
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
app.use(
|
|
405
|
+
decorator({
|
|
406
|
+
controllerDir: dir,
|
|
407
|
+
// 自定义函数可以同时访问文件基名 (val) 和扩展名 (suffix)
|
|
408
|
+
// Custom function can access both the file base name (val) and extension (suffix)
|
|
409
|
+
matchFileName: (val, suffix) => {
|
|
410
|
+
return val.startsWith('Index') && suffix === '.ts';
|
|
411
|
+
},
|
|
412
|
+
}),
|
|
413
|
+
);
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
#### 通过构造函数创建 / Create a custom filter function
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
const decorator = new Decorator(dir);
|
|
420
|
+
|
|
421
|
+
// 链式添加规则(可以多次调用 matchFileName)
|
|
422
|
+
// Chainable rules (can be called multiple times)
|
|
423
|
+
decorator
|
|
424
|
+
.matchFileName('IndexController')
|
|
425
|
+
.matchFileName(/^Admin/)
|
|
426
|
+
.matchFileName(['IndexController', /^Admin/]);
|
|
427
|
+
|
|
428
|
+
// 传递函数时会覆盖之前的所有规则
|
|
429
|
+
// Passing a function will override all previous rules
|
|
430
|
+
decorator.matchFileName((val, suffix) => val !== 'SkipController');
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
- ### 控制器名称限制 / Controller Naming Convention
|
|
434
|
+
|
|
435
|
+
#### 默认情况下,控制器文件名需要以 `Controller` 结尾。从 `0.2.0` 版本开始,可以通过配置关闭该限制。
|
|
436
|
+
|
|
437
|
+
#### By default, controller file names are expected to end with `Controller`. Starting from version `0.2.0`, this restriction can be disabled via configuration.
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
app.use(
|
|
441
|
+
decorator({
|
|
442
|
+
controllerDir: dir,
|
|
443
|
+
acceptAnyControllerName: true,
|
|
444
|
+
}),
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
// or
|
|
448
|
+
|
|
449
|
+
app.use(decorator.acceptAnyControllerName().middleware());
|
|
450
|
+
```
|