@hestjs/core 0.1.9 → 0.2.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/README.md +93 -37
- package/dist/application/application-factory.d.ts +6 -1
- package/dist/application/application-factory.d.ts.map +1 -1
- package/dist/application/application-factory.js +33 -9
- package/dist/application/application-factory.js.map +1 -1
- package/dist/application/hest-application.d.ts +3 -22
- package/dist/application/hest-application.d.ts.map +1 -1
- package/dist/application/hest-application.js +4 -29
- package/dist/application/hest-application.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/application.d.ts +2 -2
- package/dist/interfaces/application.d.ts.map +1 -1
- package/dist/router/router-explorer.d.ts +0 -20
- package/dist/router/router-explorer.d.ts.map +1 -1
- package/dist/router/router-explorer.js +11 -69
- package/dist/router/router-explorer.js.map +1 -1
- package/package.json +1 -1
- package/dist/exceptions/base-exception.d.ts +0 -20
- package/dist/exceptions/base-exception.d.ts.map +0 -1
- package/dist/exceptions/base-exception.js +0 -42
- package/dist/exceptions/base-exception.js.map +0 -1
- package/dist/exceptions/exception-filter.d.ts +0 -39
- package/dist/exceptions/exception-filter.d.ts.map +0 -1
- package/dist/exceptions/exception-filter.js +0 -69
- package/dist/exceptions/exception-filter.js.map +0 -1
- package/dist/exceptions/http-exception.d.ts +0 -40
- package/dist/exceptions/http-exception.d.ts.map +0 -1
- package/dist/exceptions/http-exception.js +0 -88
- package/dist/exceptions/http-exception.js.map +0 -1
- package/dist/exceptions/index.d.ts +0 -4
- package/dist/exceptions/index.d.ts.map +0 -1
- package/dist/exceptions/index.js +0 -20
- package/dist/exceptions/index.js.map +0 -1
- package/dist/interceptors/index.d.ts +0 -2
- package/dist/interceptors/index.d.ts.map +0 -1
- package/dist/interceptors/index.js +0 -18
- package/dist/interceptors/index.js.map +0 -1
- package/dist/interceptors/interceptor.d.ts +0 -82
- package/dist/interceptors/interceptor.d.ts.map +0 -1
- package/dist/interceptors/interceptor.js +0 -120
- package/dist/interceptors/interceptor.js.map +0 -1
package/README.md
CHANGED
@@ -13,11 +13,12 @@ HestJS 核心包 - 基于 Hono 构建的现代化 TypeScript 后端库,提供
|
|
13
13
|
|
14
14
|
## 🎯 核心理念
|
15
15
|
|
16
|
-
- **🔓
|
16
|
+
- **🔓 拒绝过度封装**:用户直接控制 Hono 实例,保留所有底层功能和灵活性
|
17
17
|
- **✈️ 零配置**:你看不到类似 `hestjs.config.ts`这样的配置文件,无需任何配置
|
18
18
|
- **🎯 装饰器驱动**:提供熟悉的 NestJS 风格开发体验
|
19
19
|
- **💉 轻量依赖注入**:基于 TSyringe 的简洁 DI 容器
|
20
20
|
- **⚡ 极致性能**:基于 Hono 和 Bun 的高性能运行时
|
21
|
+
- **🌊 原生中间件**:直接使用 Hono 中间件,无需额外抽象层
|
21
22
|
|
22
23
|
## 📦 安装
|
23
24
|
|
@@ -48,6 +49,8 @@ bun add @hestjs/core
|
|
48
49
|
|
49
50
|
```typescript
|
50
51
|
import { Controller, Get, HestFactory, Module } from "@hestjs/core";
|
52
|
+
import { Hono } from "hono";
|
53
|
+
import { cors } from "hono/cors";
|
51
54
|
|
52
55
|
@Controller("/")
|
53
56
|
export class WelcomeController {
|
@@ -66,9 +69,13 @@ export class WelcomeController {
|
|
66
69
|
export class AppModule {}
|
67
70
|
|
68
71
|
async function bootstrap() {
|
69
|
-
const
|
70
|
-
|
72
|
+
const hono = new Hono();
|
73
|
+
hono.use(cors());
|
74
|
+
|
75
|
+
// 将 Hono 实例传递给 HestJS
|
76
|
+
const app = await HestFactory.create(hono, AppModule);
|
71
77
|
|
78
|
+
// 直接使用原生 Hono 实例
|
72
79
|
Bun.serve({
|
73
80
|
port: 3000,
|
74
81
|
fetch: hono.fetch,
|
@@ -78,7 +85,36 @@ async function bootstrap() {
|
|
78
85
|
bootstrap();
|
79
86
|
```
|
80
87
|
|
81
|
-
### 2.
|
88
|
+
### 2. 异常处理中间件
|
89
|
+
|
90
|
+
替代全局异常过滤器,直接使用 Hono 中间件处理异常:
|
91
|
+
|
92
|
+
```typescript
|
93
|
+
import type { Context, Next } from 'hono';
|
94
|
+
|
95
|
+
const exceptionMiddleware = async (c: Context, next: Next) => {
|
96
|
+
try {
|
97
|
+
await next();
|
98
|
+
} catch (error: any) {
|
99
|
+
const status = error.status || 500;
|
100
|
+
return c.json({
|
101
|
+
statusCode: status,
|
102
|
+
timestamp: new Date().toISOString(),
|
103
|
+
path: c.req.url,
|
104
|
+
message: error.message || 'Internal Server Error',
|
105
|
+
}, status);
|
106
|
+
}
|
107
|
+
};
|
108
|
+
|
109
|
+
// 在 bootstrap 中使用
|
110
|
+
const hono = new Hono();
|
111
|
+
hono.use('*', exceptionMiddleware); // 全局异常处理
|
112
|
+
hono.use(cors());
|
113
|
+
|
114
|
+
const app = await HestFactory.create(hono, AppModule);
|
115
|
+
```
|
116
|
+
|
117
|
+
### 3. 定义控制器
|
82
118
|
|
83
119
|
```typescript
|
84
120
|
import { Controller, Get, Post, Context, Body, Param } from "@hestjs/core";
|
@@ -103,7 +139,7 @@ export class UsersController {
|
|
103
139
|
}
|
104
140
|
```
|
105
141
|
|
106
|
-
###
|
142
|
+
### 4. 创建模块
|
107
143
|
|
108
144
|
```typescript
|
109
145
|
import { Module } from "@hestjs/core";
|
@@ -118,7 +154,7 @@ import { UsersService } from "./users.service";
|
|
118
154
|
export class UsersModule {}
|
119
155
|
```
|
120
156
|
|
121
|
-
###
|
157
|
+
### 5. 创建服务
|
122
158
|
|
123
159
|
```typescript
|
124
160
|
import { injectable } from "@hestjs/core";
|
@@ -307,27 +343,6 @@ export class UsersService {
|
|
307
343
|
}
|
308
344
|
```
|
309
345
|
|
310
|
-
### 🔄 拦截器和过滤器
|
311
|
-
|
312
|
-
#### 全局拦截器
|
313
|
-
|
314
|
-
```typescript
|
315
|
-
const app = await HestFactory.create(AppModule);
|
316
|
-
|
317
|
-
// 添加全局拦截器
|
318
|
-
app.useGlobalInterceptors(new ValidationInterceptor());
|
319
|
-
app.useGlobalInterceptors(new ResponseInterceptor());
|
320
|
-
```
|
321
|
-
|
322
|
-
#### 全局异常过滤器
|
323
|
-
|
324
|
-
```typescript
|
325
|
-
const app = await HestFactory.create(AppModule);
|
326
|
-
|
327
|
-
// 添加全局异常过滤器
|
328
|
-
app.useGlobalFilters(new HttpExceptionFilter());
|
329
|
-
```
|
330
|
-
|
331
346
|
### 🌐 直接访问 Hono
|
332
347
|
|
333
348
|
HestJS 不会封装 Hono,你可以直接使用所有 Hono 功能:
|
@@ -408,16 +423,57 @@ async handler(@Context() c: HestContext) {
|
|
408
423
|
|
409
424
|
### ✅ 已实现功能
|
410
425
|
|
411
|
-
- [
|
412
|
-
- [
|
413
|
-
- [
|
414
|
-
- [
|
415
|
-
- [
|
416
|
-
- [
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
426
|
+
- [X] **应用工厂** - `HestFactory.create(honoInstance, moduleClass)`
|
427
|
+
- [X] **控制器系统** - `@Controller()` 装饰器
|
428
|
+
- [X] **路由装饰器** - `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`
|
429
|
+
- [X] **参数装饰器** - `@Context()`, `@Body()`, `@Param()`, `@Query()`, `@Header()`
|
430
|
+
- [X] **模块系统** - `@Module()` 装饰器
|
431
|
+
- [X] **依赖注入** - 基于 TSyringe 的 DI 容器
|
432
|
+
|
433
|
+
## 🔄 重构说明
|
434
|
+
|
435
|
+
### v0.2.0 重大更新 - 移除过度封装
|
436
|
+
|
437
|
+
为了提供更大的灵活性和更好的性能,我们进行了一次重要的架构重构:
|
438
|
+
|
439
|
+
#### 🗑️ 移除的功能
|
440
|
+
|
441
|
+
- **全局异常过滤器** - 使用 Hono 中间件替代
|
442
|
+
- **拦截器系统** - 使用 Hono 中间件替代
|
443
|
+
- **`app.hono()` 方法** - 用户直接控制 Hono 实例
|
444
|
+
- **`app.useGlobalFilters()` 方法** - 使用中间件实现
|
445
|
+
|
446
|
+
#### ✨ 新的设计理念
|
447
|
+
|
448
|
+
- **用户控制** - 用户手动创建 `new Hono()` 实例
|
449
|
+
- **原生中间件** - 直接使用 Hono 的中间件生态
|
450
|
+
- **零抽象层** - 减少性能开销和学习成本
|
451
|
+
- **最大灵活性** - 保留 Hono 的所有原生功能
|
452
|
+
|
453
|
+
#### 🚀 迁移指南
|
454
|
+
|
455
|
+
**旧的方式:**
|
456
|
+
|
457
|
+
```typescript
|
458
|
+
const app = await HestFactory.create(AppModule);
|
459
|
+
app.useGlobalFilters(new ExceptionFilter());
|
460
|
+
const hono = app.hono();
|
461
|
+
```
|
462
|
+
|
463
|
+
**新的方式:**
|
464
|
+
|
465
|
+
```typescript
|
466
|
+
const hono = new Hono();
|
467
|
+
hono.use('*', exceptionMiddleware); // 直接使用中间件
|
468
|
+
const app = await HestFactory.create(hono, AppModule);
|
469
|
+
```
|
470
|
+
|
471
|
+
这种设计让 HestJS 真正成为"基于 Hono 的 OOP 框架",而不是"包装 Hono 的框架"。
|
472
|
+
|
473
|
+
- [X] **异常处理** - 基础异常过滤器
|
474
|
+
- [X] **拦截器** - 全局拦截器支持
|
475
|
+
- [X] **类型安全** - 完整的 TypeScript 支持
|
476
|
+
- [X] **Hono 集成** - 直接访问 Hono 实例
|
421
477
|
|
422
478
|
### 🚧 开发中功能
|
423
479
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { Hono } from "hono";
|
1
2
|
import { HestApplicationInstance } from "./hest-application";
|
2
3
|
/**
|
3
4
|
* HestJS 应用工厂
|
@@ -6,10 +7,14 @@ export declare class HestFactory {
|
|
6
7
|
/**
|
7
8
|
* 创建应用实例
|
8
9
|
*/
|
9
|
-
static create(moduleClass: any): Promise<HestApplicationInstance>;
|
10
|
+
static create(honoApp: Hono, moduleClass: any): Promise<HestApplicationInstance>;
|
10
11
|
/**
|
11
12
|
* 初始化模块
|
12
13
|
*/
|
13
14
|
private static initializeModule;
|
15
|
+
/**
|
16
|
+
* 递归收集所有模块的控制器
|
17
|
+
*/
|
18
|
+
private static collectAllControllers;
|
14
19
|
}
|
15
20
|
//# sourceMappingURL=application-factory.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"application-factory.d.ts","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"application-factory.d.ts","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAI7D;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;WACU,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA4BtF;;OAEG;mBACkB,gBAAgB;IAiDrC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;CA4BrC"}
|
@@ -1,7 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.HestFactory = void 0;
|
4
|
-
const hono_1 = require("hono");
|
5
4
|
const container_1 = require("../container/container");
|
6
5
|
const metadata_scanner_1 = require("../metadata/metadata-scanner");
|
7
6
|
const router_explorer_1 = require("../router/router-explorer");
|
@@ -15,9 +14,9 @@ class HestFactory {
|
|
15
14
|
/**
|
16
15
|
* 创建应用实例
|
17
16
|
*/
|
18
|
-
static async create(moduleClass) {
|
19
|
-
//
|
20
|
-
const app =
|
17
|
+
static async create(honoApp, moduleClass) {
|
18
|
+
// 使用用户传入的 Hono 实例
|
19
|
+
const app = honoApp;
|
21
20
|
// 创建 DI 容器
|
22
21
|
const container = container_1.Container.getInstance();
|
23
22
|
// 初始化模块
|
@@ -26,11 +25,10 @@ class HestFactory {
|
|
26
25
|
const appInstance = new hest_application_1.HestApplicationInstance(app, container);
|
27
26
|
// 设置路由
|
28
27
|
const routerExplorer = new router_explorer_1.RouterExplorer(app, container);
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
routerExplorer.explore(moduleMetadata.controllers);
|
28
|
+
// 收集所有模块的控制器
|
29
|
+
const allControllers = HestFactory.collectAllControllers(moduleClass);
|
30
|
+
if (allControllers.length > 0) {
|
31
|
+
routerExplorer.explore(allControllers);
|
34
32
|
}
|
35
33
|
// 执行所有注册的应用启动钩子
|
36
34
|
await application_hooks_1.ApplicationHooks.getInstance().executeHooks(container);
|
@@ -79,6 +77,32 @@ class HestFactory {
|
|
79
77
|
}
|
80
78
|
logger_1.logger.info(`✅ Module ${moduleClass.name} initialized`);
|
81
79
|
}
|
80
|
+
/**
|
81
|
+
* 递归收集所有模块的控制器
|
82
|
+
*/
|
83
|
+
static collectAllControllers(moduleClass, visited = new Set()) {
|
84
|
+
// 防止循环依赖
|
85
|
+
if (visited.has(moduleClass)) {
|
86
|
+
return [];
|
87
|
+
}
|
88
|
+
visited.add(moduleClass);
|
89
|
+
const controllers = [];
|
90
|
+
const moduleMetadata = metadata_scanner_1.MetadataScanner.scanModule(moduleClass);
|
91
|
+
if (!moduleMetadata) {
|
92
|
+
return controllers;
|
93
|
+
}
|
94
|
+
// 收集当前模块的控制器
|
95
|
+
if (moduleMetadata.controllers) {
|
96
|
+
controllers.push(...moduleMetadata.controllers);
|
97
|
+
}
|
98
|
+
// 递归收集导入模块的控制器
|
99
|
+
if (moduleMetadata.imports) {
|
100
|
+
for (const importedModule of moduleMetadata.imports) {
|
101
|
+
controllers.push(...HestFactory.collectAllControllers(importedModule, visited));
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return controllers;
|
105
|
+
}
|
82
106
|
}
|
83
107
|
exports.HestFactory = HestFactory;
|
84
108
|
//# sourceMappingURL=application-factory.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"application-factory.js","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":";;;
|
1
|
+
{"version":3,"file":"application-factory.js","sourceRoot":"","sources":["../../src/application/application-factory.ts"],"names":[],"mappings":"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"}
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import { Hono } from "hono";
|
2
2
|
import { Container } from "../container/container";
|
3
|
-
import type { ExceptionFilter } from "../exceptions/exception-filter";
|
4
|
-
import type { Interceptor } from "../interceptors/interceptor";
|
5
3
|
import type { HestApplication } from "../interfaces/application";
|
6
4
|
/**
|
7
5
|
* HestJS 应用实例
|
@@ -9,32 +7,15 @@ import type { HestApplication } from "../interfaces/application";
|
|
9
7
|
export declare class HestApplicationInstance implements HestApplication {
|
10
8
|
private readonly app;
|
11
9
|
private readonly container;
|
12
|
-
private globalFilters;
|
13
|
-
private globalInterceptors;
|
14
10
|
constructor(app: Hono, container: Container);
|
15
|
-
/**
|
16
|
-
* 获取底层 Hono 实例
|
17
|
-
*/
|
18
|
-
hono(): Hono;
|
19
11
|
/**
|
20
12
|
* 获取 DI 容器
|
21
13
|
*/
|
22
14
|
getContainer(): Container;
|
23
15
|
/**
|
24
|
-
*
|
25
|
-
|
26
|
-
useGlobalFilters(...filters: ExceptionFilter[]): void;
|
27
|
-
/**
|
28
|
-
* 使用全局拦截器
|
29
|
-
*/
|
30
|
-
useGlobalInterceptors(...interceptors: Interceptor[]): void;
|
31
|
-
/**
|
32
|
-
* 获取全局异常过滤器
|
33
|
-
*/
|
34
|
-
getGlobalFilters(): ExceptionFilter[];
|
35
|
-
/**
|
36
|
-
* 获取全局拦截器
|
16
|
+
* 获取底层 Hono 实例 (内部使用)
|
17
|
+
* @internal
|
37
18
|
*/
|
38
|
-
|
19
|
+
getHonoInstance(): Hono;
|
39
20
|
}
|
40
21
|
//# sourceMappingURL=hest-application.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"hest-application.d.ts","sourceRoot":"","sources":["../../src/application/hest-application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,
|
1
|
+
{"version":3,"file":"hest-application.d.ts","sourceRoot":"","sources":["../../src/application/hest-application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE;;GAEG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;IAK3C;;OAEG;IACH,YAAY,IAAI,SAAS;IAIzB;;;OAGG;IACH,eAAe,IAAI,IAAI;CAGxB"}
|
@@ -7,18 +7,10 @@ exports.HestApplicationInstance = void 0;
|
|
7
7
|
class HestApplicationInstance {
|
8
8
|
app;
|
9
9
|
container;
|
10
|
-
globalFilters = [];
|
11
|
-
globalInterceptors = [];
|
12
10
|
constructor(app, container) {
|
13
11
|
this.app = app;
|
14
12
|
this.container = container;
|
15
13
|
}
|
16
|
-
/**
|
17
|
-
* 获取底层 Hono 实例
|
18
|
-
*/
|
19
|
-
hono() {
|
20
|
-
return this.app;
|
21
|
-
}
|
22
14
|
/**
|
23
15
|
* 获取 DI 容器
|
24
16
|
*/
|
@@ -26,28 +18,11 @@ class HestApplicationInstance {
|
|
26
18
|
return this.container;
|
27
19
|
}
|
28
20
|
/**
|
29
|
-
*
|
30
|
-
|
31
|
-
useGlobalFilters(...filters) {
|
32
|
-
this.globalFilters.push(...filters);
|
33
|
-
}
|
34
|
-
/**
|
35
|
-
* 使用全局拦截器
|
21
|
+
* 获取底层 Hono 实例 (内部使用)
|
22
|
+
* @internal
|
36
23
|
*/
|
37
|
-
|
38
|
-
this.
|
39
|
-
}
|
40
|
-
/**
|
41
|
-
* 获取全局异常过滤器
|
42
|
-
*/
|
43
|
-
getGlobalFilters() {
|
44
|
-
return this.globalFilters;
|
45
|
-
}
|
46
|
-
/**
|
47
|
-
* 获取全局拦截器
|
48
|
-
*/
|
49
|
-
getGlobalInterceptors() {
|
50
|
-
return this.globalInterceptors;
|
24
|
+
getHonoInstance() {
|
25
|
+
return this.app;
|
51
26
|
}
|
52
27
|
}
|
53
28
|
exports.HestApplicationInstance = HestApplicationInstance;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"hest-application.js","sourceRoot":"","sources":["../../src/application/hest-application.ts"],"names":[],"mappings":";;;
|
1
|
+
{"version":3,"file":"hest-application.js","sourceRoot":"","sources":["../../src/application/hest-application.ts"],"names":[],"mappings":";;;AAIA;;GAEG;AACH,MAAa,uBAAuB;IACjB,GAAG,CAAO;IACV,SAAS,CAAY;IAEtC,YAAY,GAAS,EAAE,SAAoB;QACzC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;CACF;AAvBD,0DAuBC"}
|
package/dist/index.d.ts
CHANGED
@@ -2,8 +2,6 @@ import "reflect-metadata";
|
|
2
2
|
export * from "./application";
|
3
3
|
export * from "./container";
|
4
4
|
export * from "./decorators";
|
5
|
-
export * from "./exceptions";
|
6
|
-
export * from "./interceptors";
|
7
5
|
export * from "./interfaces";
|
8
6
|
export * from "./metadata";
|
9
7
|
export * from "./middlewares";
|
package/dist/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAGhE,OAAO,EACL,qBAAqB,EACrB,YAAY,EACZ,eAAe,EACf,MAAM,EACN,QAAQ,EACR,eAAe,EACf,KAAK,MAAM,EACX,KAAK,YAAY,GAClB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
@@ -20,8 +20,6 @@ require("reflect-metadata");
|
|
20
20
|
__exportStar(require("./application"), exports);
|
21
21
|
__exportStar(require("./container"), exports);
|
22
22
|
__exportStar(require("./decorators"), exports);
|
23
|
-
__exportStar(require("./exceptions"), exports);
|
24
|
-
__exportStar(require("./interceptors"), exports);
|
25
23
|
__exportStar(require("./interfaces"), exports);
|
26
24
|
__exportStar(require("./metadata"), exports);
|
27
25
|
__exportStar(require("./middlewares"), exports);
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4BAA0B;AAE1B,aAAa;AACb,gDAA8B;AAC9B,8CAA4B;AAC5B,+CAA6B;AAC7B,+CAA6B;AAC7B,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,4BAA0B;AAE1B,aAAa;AACb,gDAA8B;AAC9B,8CAA4B;AAC5B,+CAA6B;AAC7B,+CAA6B;AAC7B,6CAA2B;AAC3B,gDAA8B;AAC9B,0CAAwB;AAExB,kBAAkB;AAClB,0DAAkF;AAAzE,wHAAA,aAAa,OAA0B;AAChD,4DAA0D;AAAjD,iHAAA,cAAc,OAAA;AAEvB,WAAW;AACX,yEAAgE;AAAvD,kHAAA,WAAW,OAAA;AAEpB,YAAY;AACZ,yCASwB;AARtB,+GAAA,qBAAqB,OAAA;AACrB,sGAAA,YAAY,OAAA;AACZ,yGAAA,eAAe,OAAA;AACf,gGAAA,MAAM,OAAA;AACN,kGAAA,QAAQ,OAAA;AACR,yGAAA,eAAe,OAAA"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/interfaces/application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,
|
1
|
+
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/interfaces/application.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,YAAY,IAAI,GAAG,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAClD,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,IAAI,MAAM,CAAC;IAClB,WAAW,IAAI,GAAG,CAAC;CACpB"}
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import { Hono } from "hono";
|
2
2
|
import { Container } from "../container/container";
|
3
|
-
import { type ExceptionFilter } from "../exceptions/exception-filter";
|
4
|
-
import { type Interceptor } from "../interceptors/interceptor";
|
5
3
|
import type { ControllerConstructor } from "../interfaces/router";
|
6
4
|
/**
|
7
5
|
* 路由资源管理器
|
@@ -9,17 +7,7 @@ import type { ControllerConstructor } from "../interfaces/router";
|
|
9
7
|
export declare class RouterExplorer {
|
10
8
|
private readonly app;
|
11
9
|
private readonly container;
|
12
|
-
private globalFilters;
|
13
|
-
private globalInterceptors;
|
14
10
|
constructor(app: Hono, container: Container);
|
15
|
-
/**
|
16
|
-
* 设置全局异常过滤器
|
17
|
-
*/
|
18
|
-
setGlobalFilters(filters: ExceptionFilter[]): void;
|
19
|
-
/**
|
20
|
-
* 设置全局拦截器
|
21
|
-
*/
|
22
|
-
setGlobalInterceptors(interceptors: Interceptor[]): void;
|
23
11
|
/**
|
24
12
|
* 探索并注册控制器路由
|
25
13
|
*/
|
@@ -36,14 +24,6 @@ export declare class RouterExplorer {
|
|
36
24
|
* 解析方法参数
|
37
25
|
*/
|
38
26
|
private resolveParameters;
|
39
|
-
/**
|
40
|
-
* 应用拦截器
|
41
|
-
*/
|
42
|
-
private applyInterceptors;
|
43
|
-
/**
|
44
|
-
* 处理异常
|
45
|
-
*/
|
46
|
-
private handleException;
|
47
27
|
/**
|
48
28
|
* 合并路径
|
49
29
|
*/
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"router-explorer.d.ts","sourceRoot":"","sources":["../../src/router/router-explorer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
1
|
+
{"version":3,"file":"router-explorer.d.ts","sourceRoot":"","sources":["../../src/router/router-explorer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAOnD,OAAO,KAAK,EACV,qBAAqB,EAKtB,MAAM,sBAAsB,CAAC;AAM9B;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAO;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;IAK3C;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAMnD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAgFrB;;OAEG;YACW,iBAAiB;IAiE/B;;OAEG;IACH,OAAO,CAAC,YAAY;CAUrB"}
|
@@ -2,8 +2,6 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.RouterExplorer = void 0;
|
4
4
|
const logger_1 = require("@hestjs/logger");
|
5
|
-
const exception_filter_1 = require("../exceptions/exception-filter");
|
6
|
-
const interceptor_1 = require("../interceptors/interceptor");
|
7
5
|
const metadata_scanner_1 = require("../metadata/metadata-scanner");
|
8
6
|
const constants_1 = require("../utils/constants");
|
9
7
|
const logger = (0, logger_1.createLogger)("Router");
|
@@ -13,24 +11,10 @@ const logger = (0, logger_1.createLogger)("Router");
|
|
13
11
|
class RouterExplorer {
|
14
12
|
app;
|
15
13
|
container;
|
16
|
-
globalFilters = [];
|
17
|
-
globalInterceptors = [];
|
18
14
|
constructor(app, container) {
|
19
15
|
this.app = app;
|
20
16
|
this.container = container;
|
21
17
|
}
|
22
|
-
/**
|
23
|
-
* 设置全局异常过滤器
|
24
|
-
*/
|
25
|
-
setGlobalFilters(filters) {
|
26
|
-
this.globalFilters = filters;
|
27
|
-
}
|
28
|
-
/**
|
29
|
-
* 设置全局拦截器
|
30
|
-
*/
|
31
|
-
setGlobalInterceptors(interceptors) {
|
32
|
-
this.globalInterceptors = interceptors;
|
33
|
-
}
|
34
18
|
/**
|
35
19
|
* 探索并注册控制器路由
|
36
20
|
*/
|
@@ -61,22 +45,17 @@ class RouterExplorer {
|
|
61
45
|
const method = route.method.toLowerCase();
|
62
46
|
// 获取参数元数据
|
63
47
|
const paramMetadata = metadata_scanner_1.MetadataScanner.scanParameters(controllerInstance.constructor, route.methodName);
|
64
|
-
//
|
48
|
+
// 创建路由处理器
|
65
49
|
const handler = async (c) => {
|
66
50
|
try {
|
67
|
-
//
|
68
|
-
const
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
}
|
76
|
-
return await controllerInstance[route.methodName](...resolutionResult.args);
|
77
|
-
};
|
78
|
-
// 应用拦截器
|
79
|
-
let result = await this.applyInterceptors(executionContext, executeMethod);
|
51
|
+
// 解析参数
|
52
|
+
const resolutionResult = await this.resolveParameters(c, paramMetadata);
|
53
|
+
if (resolutionResult.errors && resolutionResult.errors.length > 0) {
|
54
|
+
// 处理参数解析错误
|
55
|
+
throw new Error(`Parameter resolution failed: ${resolutionResult.errors.map((e) => e.error).join(", ")}`);
|
56
|
+
}
|
57
|
+
// 执行控制器方法
|
58
|
+
const result = await controllerInstance[route.methodName](...resolutionResult.args);
|
80
59
|
// 返回结果
|
81
60
|
if (typeof result === "object" && result !== null) {
|
82
61
|
return c.json(result);
|
@@ -89,8 +68,8 @@ class RouterExplorer {
|
|
89
68
|
}
|
90
69
|
}
|
91
70
|
catch (error) {
|
92
|
-
//
|
93
|
-
|
71
|
+
// 直接抛出异常,由用户的Hono中间件处理
|
72
|
+
throw error;
|
94
73
|
}
|
95
74
|
};
|
96
75
|
// 注册到 Hono
|
@@ -177,43 +156,6 @@ class RouterExplorer {
|
|
177
156
|
}
|
178
157
|
return { args, errors: errors.length > 0 ? errors : undefined };
|
179
158
|
}
|
180
|
-
/**
|
181
|
-
* 应用拦截器
|
182
|
-
*/
|
183
|
-
async applyInterceptors(context, handler) {
|
184
|
-
if (this.globalInterceptors.length === 0) {
|
185
|
-
return await handler();
|
186
|
-
}
|
187
|
-
// 构建拦截器链
|
188
|
-
let index = 0;
|
189
|
-
const callNext = async () => {
|
190
|
-
if (index >= this.globalInterceptors.length) {
|
191
|
-
return await handler();
|
192
|
-
}
|
193
|
-
const interceptor = this.globalInterceptors[index++];
|
194
|
-
const callHandler = new interceptor_1.DefaultCallHandler(callNext);
|
195
|
-
return await interceptor.intercept(context, callHandler);
|
196
|
-
};
|
197
|
-
return await callNext();
|
198
|
-
}
|
199
|
-
/**
|
200
|
-
* 处理异常
|
201
|
-
*/
|
202
|
-
handleException(error, context) {
|
203
|
-
const argumentsHost = new exception_filter_1.DefaultArgumentsHost(context);
|
204
|
-
// 优先使用全局异常过滤器
|
205
|
-
for (const filter of this.globalFilters) {
|
206
|
-
try {
|
207
|
-
return filter.catch(error, argumentsHost);
|
208
|
-
}
|
209
|
-
catch (filterError) {
|
210
|
-
console.error("Exception filter error:", filterError);
|
211
|
-
}
|
212
|
-
}
|
213
|
-
// 默认异常处理
|
214
|
-
const defaultFilter = new exception_filter_1.DefaultExceptionFilter();
|
215
|
-
return defaultFilter.catch(error, argumentsHost);
|
216
|
-
}
|
217
159
|
/**
|
218
160
|
* 合并路径
|
219
161
|
*/
|