@dangao/bun-server 1.0.3 → 1.1.2

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.
Files changed (77) hide show
  1. package/dist/controller/controller.d.ts +1 -1
  2. package/dist/controller/controller.d.ts.map +1 -1
  3. package/dist/core/application.d.ts.map +1 -1
  4. package/dist/database/database-extension.d.ts.map +1 -1
  5. package/dist/database/database-module.d.ts.map +1 -1
  6. package/dist/database/orm/transaction-decorator.d.ts +1 -0
  7. package/dist/database/orm/transaction-decorator.d.ts.map +1 -1
  8. package/dist/database/orm/transaction-interceptor.d.ts +12 -3
  9. package/dist/database/orm/transaction-interceptor.d.ts.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +678 -310
  13. package/dist/interceptor/base-interceptor.d.ts +94 -0
  14. package/dist/interceptor/base-interceptor.d.ts.map +1 -0
  15. package/dist/interceptor/builtin/cache-interceptor.d.ts +69 -0
  16. package/dist/interceptor/builtin/cache-interceptor.d.ts.map +1 -0
  17. package/dist/interceptor/builtin/index.d.ts +4 -0
  18. package/dist/interceptor/builtin/index.d.ts.map +1 -0
  19. package/dist/interceptor/builtin/log-interceptor.d.ts +56 -0
  20. package/dist/interceptor/builtin/log-interceptor.d.ts.map +1 -0
  21. package/dist/interceptor/builtin/permission-interceptor.d.ts +70 -0
  22. package/dist/interceptor/builtin/permission-interceptor.d.ts.map +1 -0
  23. package/dist/interceptor/index.d.ts +7 -0
  24. package/dist/interceptor/index.d.ts.map +1 -0
  25. package/dist/interceptor/interceptor-chain.d.ts +22 -0
  26. package/dist/interceptor/interceptor-chain.d.ts.map +1 -0
  27. package/dist/interceptor/interceptor-registry.d.ts +59 -0
  28. package/dist/interceptor/interceptor-registry.d.ts.map +1 -0
  29. package/dist/interceptor/metadata.d.ts +12 -0
  30. package/dist/interceptor/metadata.d.ts.map +1 -0
  31. package/dist/interceptor/types.d.ts +42 -0
  32. package/dist/interceptor/types.d.ts.map +1 -0
  33. package/dist/middleware/decorators.d.ts +2 -1
  34. package/dist/middleware/decorators.d.ts.map +1 -1
  35. package/dist/router/decorators.d.ts.map +1 -1
  36. package/dist/router/registry.d.ts +2 -1
  37. package/dist/router/registry.d.ts.map +1 -1
  38. package/dist/router/route.d.ts +3 -2
  39. package/dist/router/route.d.ts.map +1 -1
  40. package/dist/router/router.d.ts +2 -1
  41. package/dist/router/router.d.ts.map +1 -1
  42. package/dist/websocket/decorators.d.ts +2 -1
  43. package/dist/websocket/decorators.d.ts.map +1 -1
  44. package/package.json +2 -2
  45. package/src/controller/controller.ts +41 -14
  46. package/src/core/application.ts +7 -1
  47. package/src/database/database-extension.ts +23 -2
  48. package/src/database/database-module.ts +6 -0
  49. package/src/database/orm/transaction-decorator.ts +33 -2
  50. package/src/database/orm/transaction-interceptor.ts +31 -11
  51. package/src/index.ts +22 -0
  52. package/src/interceptor/base-interceptor.ts +203 -0
  53. package/src/interceptor/builtin/cache-interceptor.ts +169 -0
  54. package/src/interceptor/builtin/index.ts +28 -0
  55. package/src/interceptor/builtin/log-interceptor.ts +178 -0
  56. package/src/interceptor/builtin/permission-interceptor.ts +173 -0
  57. package/src/interceptor/index.ts +26 -0
  58. package/src/interceptor/interceptor-chain.ts +79 -0
  59. package/src/interceptor/interceptor-registry.ts +132 -0
  60. package/src/interceptor/metadata.ts +40 -0
  61. package/src/interceptor/types.ts +52 -0
  62. package/src/middleware/decorators.ts +2 -1
  63. package/src/router/decorators.ts +44 -43
  64. package/src/router/registry.ts +2 -1
  65. package/src/router/route.ts +3 -2
  66. package/src/router/router.ts +2 -1
  67. package/src/websocket/decorators.ts +3 -1
  68. package/tests/controller/path-combination.test.ts +207 -0
  69. package/tests/interceptor/builtin/cache-interceptor.test.ts +137 -0
  70. package/tests/interceptor/builtin/permission-interceptor.test.ts +182 -0
  71. package/tests/interceptor/interceptor-advanced-integration.test.ts +592 -0
  72. package/tests/interceptor/interceptor-arg-modification.test.ts +76 -0
  73. package/tests/interceptor/interceptor-chain.test.ts +199 -0
  74. package/tests/interceptor/interceptor-integration.test.ts +230 -0
  75. package/tests/interceptor/interceptor-registry.test.ts +200 -0
  76. package/tests/interceptor/perf/interceptor-performance.test.ts +341 -0
  77. package/tests/router/decorators.test.ts +13 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dangao/bun-server",
3
- "version": "1.0.3",
3
+ "version": "1.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -56,6 +56,6 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "reflect-metadata": "^0.2.2",
59
- "@dangao/logsmith": "0.1.0"
59
+ "@dangao/logsmith": "0.1.1"
60
60
  }
61
61
  }
@@ -8,7 +8,13 @@ import { getClassMiddlewares, getMethodMiddlewares } from '../middleware';
8
8
  import type { Middleware } from '../middleware';
9
9
  import { getValidationMetadata, validateParameters, ValidationError } from '../validation';
10
10
  import { HttpException } from '../error';
11
- import type { Constructor } from '@/core/types'
11
+ import type { Constructor } from '@/core/types';
12
+ import {
13
+ type InterceptorRegistry,
14
+ INTERCEPTOR_REGISTRY_TOKEN,
15
+ InterceptorChain,
16
+ scanInterceptorMetadata,
17
+ } from '../interceptor';
12
18
 
13
19
  /**
14
20
  * 控制器元数据键
@@ -27,7 +33,7 @@ export interface ControllerMetadata {
27
33
  /**
28
34
  * 控制器类
29
35
  */
30
- target: new (...args: unknown[]) => unknown;
36
+ target: Constructor<unknown>;
31
37
  }
32
38
 
33
39
  /**
@@ -49,7 +55,7 @@ export function Controller(path: string = '') {
49
55
  export class ControllerRegistry {
50
56
  private static instance: ControllerRegistry;
51
57
  private readonly container: Container;
52
- private readonly controllers = new Map<new (...args: unknown[]) => unknown, unknown>();
58
+ private readonly controllers = new Map<Constructor<unknown>, unknown>();
53
59
  private readonly controllerContainers = new Map<Constructor<unknown>, Container>();
54
60
 
55
61
  private constructor() {
@@ -142,35 +148,56 @@ export class ControllerRegistry {
142
148
 
143
149
  // 调用控制器方法
144
150
  // 优先从实例获取,如果不存在则从原型获取
151
+ // 注意:prototype 已在上面声明(第 140 行),因为后续扫描拦截器元数据时需要用到
145
152
  let method = (controllerInstance as Record<string, (...args: unknown[]) => unknown>)[propertyKey!];
146
153
  if (!method || typeof method !== 'function') {
147
154
  // 从构造函数原型获取方法
148
- const prototype = controllerClass.prototype;
149
155
  method = prototype[propertyKey!];
150
156
  }
151
157
  if (!method || typeof method !== 'function') {
152
158
  throw new Error(`Method ${propertyKey} not found on controller ${controllerClass.name}`);
153
159
  }
154
160
 
155
- // 检查是否有事务装饰器
156
- let result: unknown;
161
+ // 获取拦截器注册表
162
+ let interceptorRegistry: InterceptorRegistry | undefined;
157
163
  try {
158
- const { TransactionInterceptor } = await import('../database/orm/transaction-interceptor');
159
- const { getTransactionMetadata } = await import('../database/orm/transaction-decorator');
160
- const hasTransaction = getTransactionMetadata(prototype, propertyKey!);
161
- if (hasTransaction) {
162
- result = TransactionInterceptor.executeWithTransaction(
163
- prototype,
164
+ interceptorRegistry = controllerContainer.resolve<InterceptorRegistry>(
165
+ INTERCEPTOR_REGISTRY_TOKEN,
166
+ );
167
+ } catch (error) {
168
+ // 如果拦截器注册表未注册,继续执行(向后兼容)
169
+ interceptorRegistry = undefined;
170
+ }
171
+
172
+ // 执行拦截器链或直接调用方法
173
+ let result: unknown;
174
+ if (interceptorRegistry) {
175
+ // 扫描方法上的所有拦截器元数据
176
+ const interceptors = scanInterceptorMetadata(
177
+ prototype,
178
+ propertyKey!,
179
+ interceptorRegistry,
180
+ );
181
+
182
+ if (interceptors.length > 0) {
183
+ // 执行拦截器链
184
+ // 注意:传递 controllerInstance 以确保 originalMethod.apply 的 this 绑定正确
185
+ // getMetadata 方法已经修复以支持从原型链查找元数据
186
+ result = await InterceptorChain.execute(
187
+ interceptors,
188
+ controllerInstance,
164
189
  propertyKey!,
165
190
  method,
166
191
  params,
167
192
  controllerContainer,
193
+ context,
168
194
  );
169
195
  } else {
196
+ // 没有拦截器,直接执行方法
170
197
  result = method.apply(controllerInstance, params);
171
198
  }
172
- } catch (error) {
173
- // 如果导入失败或执行失败,回退到直接调用
199
+ } else {
200
+ // 拦截器注册表未注册,直接执行方法(向后兼容)
174
201
  result = method.apply(controllerInstance, params);
175
202
  }
176
203
 
@@ -10,7 +10,8 @@ import type { ApplicationExtension } from '../extensions/types';
10
10
  import { LoggerExtension } from '../extensions/logger-extension';
11
11
  import { ModuleRegistry } from '../di/module-registry';
12
12
  import type { ModuleClass } from '../di/module';
13
- import type { Constructor } from './types'
13
+ import type { Constructor } from './types';
14
+ import { InterceptorRegistry, INTERCEPTOR_REGISTRY_TOKEN } from '../interceptor';
14
15
 
15
16
  /**
16
17
  * 应用配置选项
@@ -48,6 +49,11 @@ export class Application {
48
49
  ControllerRegistry.getInstance().clear();
49
50
  ModuleRegistry.getInstance().clear();
50
51
 
52
+ // 注册 InterceptorRegistry 到 DI 容器
53
+ const container = ControllerRegistry.getInstance().getContainer();
54
+ const interceptorRegistry = new InterceptorRegistry();
55
+ container.registerInstance(INTERCEPTOR_REGISTRY_TOKEN, interceptorRegistry);
56
+
51
57
  // 默认注册 Logger(如果通过模块注册,会被覆盖)
52
58
  this.registerExtension(new LoggerExtension());
53
59
  }
@@ -1,6 +1,12 @@
1
1
  import type { Container } from '../di/container';
2
2
  import type { ApplicationExtension } from '../extensions/types';
3
+ import {
4
+ InterceptorRegistry,
5
+ INTERCEPTOR_REGISTRY_TOKEN,
6
+ } from '../interceptor';
3
7
 
8
+ import { TransactionInterceptor } from './orm/transaction-interceptor';
9
+ import { TRANSACTION_METADATA_KEY } from './orm/transaction-decorator';
4
10
  import { DATABASE_SERVICE_TOKEN } from './types';
5
11
  import type { DatabaseService } from './service';
6
12
 
@@ -10,8 +16,23 @@ import type { DatabaseService } from './service';
10
16
  */
11
17
  export class DatabaseExtension implements ApplicationExtension {
12
18
  public register(container: Container): void {
13
- // 扩展注册时不初始化,等待应用启动时初始化
14
- // 这里只是标记需要初始化
19
+ // 注册事务拦截器到拦截器注册表
20
+ try {
21
+ const interceptorRegistry = container.resolve<InterceptorRegistry>(
22
+ INTERCEPTOR_REGISTRY_TOKEN,
23
+ );
24
+ const transactionInterceptor = new TransactionInterceptor();
25
+ // 使用 TRANSACTION_METADATA_KEY 作为元数据键
26
+ // 优先级设置为 50,确保事务拦截器在其他业务拦截器之前执行
27
+ interceptorRegistry.register(
28
+ TRANSACTION_METADATA_KEY,
29
+ transactionInterceptor,
30
+ 50,
31
+ );
32
+ } catch (error) {
33
+ // 如果拦截器注册表未注册,忽略错误(向后兼容)
34
+ // 这意味着拦截器机制可能未启用
35
+ }
15
36
  }
16
37
 
17
38
  /**
@@ -1,10 +1,16 @@
1
1
  import { Module, MODULE_METADATA_KEY, type ModuleProvider } from '../di/module';
2
2
  import type { ApplicationExtension } from '../extensions/types';
3
+ import {
4
+ InterceptorRegistry,
5
+ INTERCEPTOR_REGISTRY_TOKEN,
6
+ } from '../interceptor';
3
7
 
4
8
  import { DatabaseExtension } from './database-extension';
5
9
  import { DatabaseHealthIndicator } from './health-indicator';
6
10
  import { OrmService } from './orm/service';
7
11
  import { TransactionManager } from './orm/transaction-manager';
12
+ import { TransactionInterceptor } from './orm/transaction-interceptor';
13
+ import { TRANSACTION_METADATA_KEY } from './orm/transaction-decorator';
8
14
  import { DatabaseService } from './service';
9
15
  import {
10
16
  DATABASE_OPTIONS_TOKEN,
@@ -33,13 +33,44 @@ export function Transactional(options?: TransactionOptions): MethodDecorator {
33
33
 
34
34
  /**
35
35
  * 获取 Transaction 元数据
36
+ * 支持从实例或原型上获取元数据(元数据通常存储在原型上)
36
37
  */
37
38
  export function getTransactionMetadata(
38
39
  target: unknown,
39
40
  propertyKey: string | symbol,
40
41
  ): TransactionOptions | undefined {
41
- if (typeof target === 'object' && target !== null) {
42
- return Reflect.getMetadata(TRANSACTION_METADATA_KEY, target, propertyKey);
42
+ if (typeof target !== 'object' || target === null) {
43
+ return undefined;
43
44
  }
45
+
46
+ // 首先尝试直接从 target 获取(如果 target 是原型)
47
+ let metadata = Reflect.getMetadata(TRANSACTION_METADATA_KEY, target, propertyKey) as TransactionOptions | undefined;
48
+ if (metadata !== undefined) {
49
+ return metadata;
50
+ }
51
+
52
+ // 如果 target 是实例,尝试从原型获取
53
+ // 装饰器元数据通常存储在原型上,而不是实例上
54
+ const prototype = Object.getPrototypeOf(target);
55
+ if (prototype && prototype !== Object.prototype) {
56
+ metadata = Reflect.getMetadata(TRANSACTION_METADATA_KEY, prototype, propertyKey) as TransactionOptions | undefined;
57
+ if (metadata !== undefined) {
58
+ return metadata;
59
+ }
60
+ }
61
+
62
+ // 如果仍然找不到,尝试从构造函数原型获取
63
+ // 这处理了 target 是实例但原型链查找失败的情况
64
+ const constructor = (target as any).constructor;
65
+ if (constructor && typeof constructor === 'function') {
66
+ // 如果 target 本身不是构造函数原型,尝试从构造函数原型获取
67
+ if (target !== constructor.prototype) {
68
+ metadata = Reflect.getMetadata(TRANSACTION_METADATA_KEY, constructor.prototype, propertyKey) as TransactionOptions | undefined;
69
+ if (metadata !== undefined) {
70
+ return metadata;
71
+ }
72
+ }
73
+ }
74
+
44
75
  return undefined;
45
76
  }
@@ -1,23 +1,28 @@
1
- import { Container } from '../../di/container';
1
+ import type { Container } from '../../di/container';
2
+ import type { Context } from '../../core/context';
3
+ import type { Interceptor } from '../../interceptor';
2
4
  import { TRANSACTION_SERVICE_TOKEN } from './transaction-types';
3
5
  import { TransactionManager } from './transaction-manager';
4
- import { getTransactionMetadata } from './transaction-decorator';
6
+ import { getTransactionMetadata, TRANSACTION_METADATA_KEY } from './transaction-decorator';
5
7
  import { Propagation, TransactionStatus } from './transaction-types';
6
8
 
7
9
  /**
8
10
  * 事务拦截器
9
11
  * 在方法调用时检查 @Transactional() 装饰器并执行事务逻辑
12
+ * 实现 Interceptor 接口,通过拦截器机制注册和执行
10
13
  */
11
- export class TransactionInterceptor {
14
+ export class TransactionInterceptor implements Interceptor {
12
15
  /**
13
- * 执行带事务的方法
16
+ * 执行拦截器逻辑
17
+ * 实现 Interceptor 接口
14
18
  */
15
- public static async executeWithTransaction<T>(
19
+ public async execute<T>(
16
20
  target: unknown,
17
21
  propertyKey: string | symbol,
18
22
  originalMethod: (...args: unknown[]) => T | Promise<T>,
19
23
  args: unknown[],
20
24
  container: Container,
25
+ context?: Context,
21
26
  ): Promise<T> {
22
27
  const transactionMetadata = getTransactionMetadata(target, propertyKey);
23
28
 
@@ -46,7 +51,7 @@ export class TransactionInterceptor {
46
51
  case Propagation.REQUIRED:
47
52
  if (currentTransaction) {
48
53
  // 加入现有事务
49
- return await this.executeInExistingTransaction(
54
+ return await TransactionInterceptor.executeInExistingTransaction(
50
55
  originalMethod,
51
56
  target,
52
57
  args,
@@ -55,7 +60,7 @@ export class TransactionInterceptor {
55
60
  );
56
61
  } else {
57
62
  // 创建新事务
58
- return await this.executeInNewTransaction(
63
+ return await TransactionInterceptor.executeInNewTransaction(
59
64
  originalMethod,
60
65
  target,
61
66
  args,
@@ -66,7 +71,7 @@ export class TransactionInterceptor {
66
71
 
67
72
  case Propagation.REQUIRES_NEW:
68
73
  // 总是创建新事务
69
- return await this.executeInNewTransaction(
74
+ return await TransactionInterceptor.executeInNewTransaction(
70
75
  originalMethod,
71
76
  target,
72
77
  args,
@@ -77,7 +82,7 @@ export class TransactionInterceptor {
77
82
  case Propagation.SUPPORTS:
78
83
  if (currentTransaction) {
79
84
  // 加入现有事务
80
- return await this.executeInExistingTransaction(
85
+ return await TransactionInterceptor.executeInExistingTransaction(
81
86
  originalMethod,
82
87
  target,
83
88
  args,
@@ -104,7 +109,7 @@ export class TransactionInterceptor {
104
109
  case Propagation.NESTED:
105
110
  if (currentTransaction) {
106
111
  // 创建嵌套事务(保存点)
107
- return await this.executeInNestedTransaction(
112
+ return await TransactionInterceptor.executeInNestedTransaction(
108
113
  originalMethod,
109
114
  target,
110
115
  args,
@@ -114,7 +119,7 @@ export class TransactionInterceptor {
114
119
  );
115
120
  } else {
116
121
  // 创建新事务
117
- return await this.executeInNewTransaction(
122
+ return await TransactionInterceptor.executeInNewTransaction(
118
123
  originalMethod,
119
124
  target,
120
125
  args,
@@ -128,6 +133,21 @@ export class TransactionInterceptor {
128
133
  }
129
134
  }
130
135
 
136
+ /**
137
+ * 执行带事务的方法(静态方法,保持向后兼容)
138
+ * @deprecated 使用拦截器机制,此方法保留用于向后兼容
139
+ */
140
+ public static async executeWithTransaction<T>(
141
+ target: unknown,
142
+ propertyKey: string | symbol,
143
+ originalMethod: (...args: unknown[]) => T | Promise<T>,
144
+ args: unknown[],
145
+ container: Container,
146
+ ): Promise<T> {
147
+ const interceptor = new TransactionInterceptor();
148
+ return await interceptor.execute(target, propertyKey, originalMethod, args, container);
149
+ }
150
+
131
151
  /**
132
152
  * 在新事务中执行方法
133
153
  */
package/src/index.ts CHANGED
@@ -17,6 +17,28 @@ export {
17
17
  type ModuleClass,
18
18
  } from './di/module';
19
19
  export { ModuleRegistry } from './di/module-registry';
20
+ export {
21
+ InterceptorRegistry,
22
+ InterceptorChain,
23
+ scanInterceptorMetadata,
24
+ BaseInterceptor,
25
+ Cache,
26
+ CacheInterceptor,
27
+ Permission,
28
+ PermissionInterceptor,
29
+ Log,
30
+ LogInterceptor,
31
+ INTERCEPTOR_REGISTRY_TOKEN,
32
+ CACHE_METADATA_KEY,
33
+ PERMISSION_METADATA_KEY,
34
+ LOG_METADATA_KEY,
35
+ type Interceptor,
36
+ type InterceptorMetadata,
37
+ type CacheOptions,
38
+ type PermissionOptions,
39
+ type PermissionService,
40
+ type LogOptions,
41
+ } from './interceptor';
20
42
  export { UseMiddleware, RateLimit, MiddlewarePipeline } from './middleware';
21
43
  export type { Middleware, NextFunction } from './middleware';
22
44
  export {
@@ -0,0 +1,203 @@
1
+ import type { Interceptor } from './types';
2
+ import type { Container } from '../di/container';
3
+ import type { Context } from '../core/context';
4
+ import 'reflect-metadata';
5
+
6
+ /**
7
+ * 拦截器基类
8
+ * 提供便捷的前置处理、后置处理和错误处理方法
9
+ */
10
+ export abstract class BaseInterceptor implements Interceptor {
11
+ /**
12
+ * 执行拦截器逻辑
13
+ * 子类必须实现此方法
14
+ */
15
+ public abstract execute<T>(
16
+ target: unknown,
17
+ propertyKey: string | symbol,
18
+ originalMethod: (...args: unknown[]) => T | Promise<T>,
19
+ args: unknown[],
20
+ container: Container,
21
+ context?: Context,
22
+ ): Promise<T>;
23
+
24
+ /**
25
+ * 前置处理(可选)
26
+ * 在方法执行前调用,子类可以覆盖此方法
27
+ * @param target - 目标对象
28
+ * @param propertyKey - 方法名
29
+ * @param args - 方法参数
30
+ * @param container - DI 容器
31
+ * @param context - 请求上下文(可选)
32
+ */
33
+ protected async before(
34
+ target: unknown,
35
+ propertyKey: string | symbol,
36
+ args: unknown[],
37
+ container: Container,
38
+ context?: Context,
39
+ ): Promise<void> {
40
+ // 默认空实现,子类可覆盖
41
+ }
42
+
43
+ /**
44
+ * 后置处理(可选)
45
+ * 在方法执行后调用,子类可以覆盖此方法
46
+ * @param target - 目标对象
47
+ * @param propertyKey - 方法名
48
+ * @param result - 方法执行结果
49
+ * @param container - DI 容器
50
+ * @param context - 请求上下文(可选)
51
+ * @returns 处理后的结果(默认返回原结果)
52
+ */
53
+ protected async after<T>(
54
+ target: unknown,
55
+ propertyKey: string | symbol,
56
+ result: T,
57
+ container: Container,
58
+ context?: Context,
59
+ ): Promise<T> {
60
+ // 默认返回原结果,子类可覆盖
61
+ return result;
62
+ }
63
+
64
+ /**
65
+ * 错误处理(可选)
66
+ * 在方法执行出错时调用,子类可以覆盖此方法
67
+ * @param target - 目标对象
68
+ * @param propertyKey - 方法名
69
+ * @param error - 错误对象
70
+ * @param container - DI 容器
71
+ * @param context - 请求上下文(可选)
72
+ * @returns 永远不会返回(总是抛出错误)
73
+ * @throws 重新抛出错误或抛出新的错误
74
+ */
75
+ protected async onError(
76
+ target: unknown,
77
+ propertyKey: string | symbol,
78
+ error: unknown,
79
+ container: Container,
80
+ context?: Context,
81
+ ): Promise<never> {
82
+ // 默认重新抛出错误,子类可覆盖
83
+ throw error;
84
+ }
85
+
86
+ /**
87
+ * 获取元数据
88
+ * 从目标对象的方法上获取指定元数据键的元数据
89
+ * 支持从实例或原型上获取元数据(元数据通常存储在原型上)
90
+ * @param target - 目标对象(可能是实例或原型)
91
+ * @param propertyKey - 方法名
92
+ * @param metadataKey - 元数据键
93
+ * @returns 元数据值,如果不存在则返回 undefined
94
+ */
95
+ protected getMetadata<T = unknown>(
96
+ target: unknown,
97
+ propertyKey: string | symbol,
98
+ metadataKey: symbol,
99
+ ): T | undefined {
100
+ if (typeof target !== 'object' || target === null) {
101
+ return undefined;
102
+ }
103
+
104
+ // 首先尝试直接从 target 获取(如果 target 是原型)
105
+ let metadata = Reflect.getMetadata(metadataKey, target, propertyKey) as T | undefined;
106
+ if (metadata !== undefined) {
107
+ return metadata;
108
+ }
109
+
110
+ // 如果 target 是实例,尝试从原型获取
111
+ // 装饰器元数据通常存储在原型上,而不是实例上
112
+ const prototype = Object.getPrototypeOf(target);
113
+ if (prototype && prototype !== Object.prototype) {
114
+ metadata = Reflect.getMetadata(metadataKey, prototype, propertyKey) as T | undefined;
115
+ if (metadata !== undefined) {
116
+ return metadata;
117
+ }
118
+ }
119
+
120
+ // 如果仍然找不到,尝试从构造函数原型获取
121
+ // 这处理了 target 是实例但原型链查找失败的情况
122
+ const constructor = (target as any).constructor;
123
+ if (constructor && typeof constructor === 'function') {
124
+ // 如果 target 本身不是构造函数原型,尝试从构造函数原型获取
125
+ if (target !== constructor.prototype) {
126
+ metadata = Reflect.getMetadata(metadataKey, constructor.prototype, propertyKey) as T | undefined;
127
+ if (metadata !== undefined) {
128
+ return metadata;
129
+ }
130
+ }
131
+ }
132
+
133
+ return undefined;
134
+ }
135
+
136
+ /**
137
+ * 从容器解析服务
138
+ * @param container - DI 容器
139
+ * @param token - 服务标识符
140
+ * @returns 服务实例
141
+ */
142
+ protected resolveService<T>(
143
+ container: Container,
144
+ token: (new (...args: unknown[]) => T) | string | symbol,
145
+ ): T {
146
+ return container.resolve<T>(token);
147
+ }
148
+
149
+ /**
150
+ * 从上下文获取值
151
+ * @param context - 请求上下文
152
+ * @param key - 键名
153
+ * @returns 值,如果不存在则返回 undefined
154
+ */
155
+ protected getContextValue<T = unknown>(context: Context | undefined, key: string): T | undefined {
156
+ if (!context) {
157
+ return undefined;
158
+ }
159
+ // Context 没有直接的存储机制,可以通过 headers 或其他方式获取
160
+ // 这里提供一个基础实现,子类可以根据需要扩展
161
+ return undefined;
162
+ }
163
+
164
+ /**
165
+ * 从上下文获取请求头
166
+ * @param context - 请求上下文
167
+ * @param headerName - 请求头名称
168
+ * @returns 请求头值,如果不存在则返回 null
169
+ */
170
+ protected getHeader(context: Context | undefined, headerName: string): string | null {
171
+ if (!context) {
172
+ return null;
173
+ }
174
+ return context.getHeader(headerName);
175
+ }
176
+
177
+ /**
178
+ * 从上下文获取查询参数
179
+ * @param context - 请求上下文
180
+ * @param paramName - 参数名称
181
+ * @returns 参数值,如果不存在则返回 null
182
+ */
183
+ protected getQuery(context: Context | undefined, paramName: string): string | null {
184
+ if (!context) {
185
+ return null;
186
+ }
187
+ return context.getQuery(paramName);
188
+ }
189
+
190
+ /**
191
+ * 从上下文获取路径参数
192
+ * @param context - 请求上下文
193
+ * @param paramName - 参数名称
194
+ * @returns 参数值,如果不存在则返回 undefined
195
+ */
196
+ protected getParam(context: Context | undefined, paramName: string): string | undefined {
197
+ if (!context) {
198
+ return undefined;
199
+ }
200
+ return context.getParam(paramName);
201
+ }
202
+ }
203
+