@dangao/bun-server 1.8.0 → 1.8.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 (62) hide show
  1. package/docs/api.md +194 -81
  2. package/docs/extensions.md +53 -0
  3. package/docs/guide.md +243 -1
  4. package/docs/microservice-config-center.md +73 -74
  5. package/docs/microservice-nacos.md +89 -90
  6. package/docs/microservice-service-registry.md +85 -86
  7. package/docs/microservice.md +142 -137
  8. package/docs/request-lifecycle.md +45 -4
  9. package/docs/symbol-interface-pattern.md +106 -106
  10. package/docs/zh/api.md +458 -18
  11. package/docs/zh/extensions.md +53 -0
  12. package/docs/zh/guide.md +251 -4
  13. package/docs/zh/microservice-config-center.md +258 -0
  14. package/docs/zh/microservice-nacos.md +346 -0
  15. package/docs/zh/microservice-service-registry.md +306 -0
  16. package/docs/zh/microservice.md +680 -0
  17. package/docs/zh/request-lifecycle.md +43 -5
  18. package/package.json +1 -1
  19. package/tests/auth/auth-decorators.test.ts +241 -0
  20. package/tests/auth/oauth2-service.test.ts +318 -0
  21. package/tests/cache/cache-decorators-extended.test.ts +272 -0
  22. package/tests/cache/cache-interceptors.test.ts +534 -0
  23. package/tests/cache/cache-service-proxy.test.ts +246 -0
  24. package/tests/cache/memory-cache-store.test.ts +155 -0
  25. package/tests/cache/redis-cache-store.test.ts +199 -0
  26. package/tests/config/config-center-integration.test.ts +334 -0
  27. package/tests/config/config-module-extended.test.ts +165 -0
  28. package/tests/controller/param-binder.test.ts +333 -0
  29. package/tests/error/error-handler.test.ts +166 -57
  30. package/tests/error/i18n-extended.test.ts +105 -0
  31. package/tests/events/event-listener-scanner.test.ts +114 -0
  32. package/tests/events/event-module.test.ts +133 -302
  33. package/tests/extensions/logger-module.test.ts +158 -0
  34. package/tests/files/file-storage.test.ts +136 -0
  35. package/tests/interceptor/base-interceptor.test.ts +605 -0
  36. package/tests/interceptor/builtin/cache-interceptor.test.ts +233 -86
  37. package/tests/interceptor/builtin/log-interceptor.test.ts +469 -0
  38. package/tests/interceptor/builtin/permission-interceptor.test.ts +219 -120
  39. package/tests/interceptor/interceptor-chain.test.ts +241 -189
  40. package/tests/interceptor/interceptor-metadata.test.ts +221 -0
  41. package/tests/microservice/circuit-breaker.test.ts +221 -0
  42. package/tests/microservice/service-client-decorators.test.ts +86 -0
  43. package/tests/microservice/service-client-interceptors.test.ts +274 -0
  44. package/tests/microservice/service-registry-decorators.test.ts +147 -0
  45. package/tests/microservice/tracer.test.ts +213 -0
  46. package/tests/microservice/tracing-collectors.test.ts +168 -0
  47. package/tests/middleware/builtin/middleware-builtin-extended.test.ts +237 -0
  48. package/tests/middleware/builtin/rate-limit.test.ts +257 -0
  49. package/tests/middleware/middleware-decorators.test.ts +222 -0
  50. package/tests/middleware/middleware-pipeline.test.ts +160 -0
  51. package/tests/queue/queue-decorators.test.ts +139 -0
  52. package/tests/queue/queue-service.test.ts +191 -0
  53. package/tests/request/body-parser-extended.test.ts +291 -0
  54. package/tests/request/request-wrapper.test.ts +319 -0
  55. package/tests/router/router-decorators.test.ts +260 -0
  56. package/tests/router/router-extended.test.ts +298 -0
  57. package/tests/security/guards/reflector.test.ts +188 -0
  58. package/tests/security/security-filter.test.ts +182 -0
  59. package/tests/security/security-module-extended.test.ts +133 -0
  60. package/tests/session/memory-session-store.test.ts +172 -0
  61. package/tests/session/session-decorators.test.ts +163 -0
  62. package/tests/swagger/ui.test.ts +212 -0
@@ -20,6 +20,10 @@ HTTP Request
20
20
  └─────────────────────────────────────┘
21
21
 
22
22
  ┌─────────────────────────────────────┐
23
+ │ Guards │
24
+ └─────────────────────────────────────┘
25
+
26
+ ┌─────────────────────────────────────┐
23
27
  │ Interceptors (Pre) │
24
28
  └─────────────────────────────────────┘
25
29
 
@@ -79,6 +83,7 @@ class ApiController {
79
83
  | `createCorsMiddleware` | CORS headers |
80
84
  | `createErrorHandlingMiddleware` | Global error handling |
81
85
  | `createRateLimitMiddleware` | Rate limiting |
86
+ | `createHttpMetricsMiddleware` | HTTP metrics collection |
82
87
  | `createStaticFileMiddleware` | Static file serving |
83
88
  | `createFileUploadMiddleware` | File upload handling |
84
89
  | `createSessionMiddleware` | Session management |
@@ -140,6 +145,40 @@ class UserController {
140
145
 
141
146
  The router matches the request path and method to a registered route.
142
147
 
148
+ ## 4. Guards
149
+
150
+ Guards execute after routing and before interceptors, providing fine-grained access control. They have access to the `ExecutionContext` which provides rich information about the current request.
151
+
152
+ ### Execution Order
153
+
154
+ 1. **Global Guards** - Registered via `SecurityModule.forRoot({ globalGuards: [...] })`
155
+ 2. **Controller Guards** - Applied via `@UseGuards()` on controller class
156
+ 3. **Method Guards** - Applied via `@UseGuards()` on method
157
+
158
+ ### Built-in Guards
159
+
160
+ - `AuthGuard`: Requires authentication
161
+ - `OptionalAuthGuard`: Optional authentication
162
+ - `RolesGuard`: Role-based authorization (used with `@Roles()` decorator)
163
+
164
+ ### Example
165
+
166
+ ```typescript
167
+ @Controller('/api/admin')
168
+ @UseGuards(AuthGuard, RolesGuard)
169
+ class AdminController {
170
+ @GET('/dashboard')
171
+ @Roles('admin')
172
+ public dashboard() {
173
+ return { message: 'Admin Dashboard' };
174
+ }
175
+ }
176
+ ```
177
+
178
+ For detailed documentation, see [Guards](./guards.md).
179
+
180
+ ## 5. Interceptors (Pre-processing)
181
+
143
182
  ### Matching Priority
144
183
 
145
184
  1. **Static Routes** - Exact path match (`/api/users`)
@@ -200,7 +239,7 @@ class ApiController {}
200
239
  - Response transformation
201
240
  - Performance monitoring
202
241
 
203
- ## 5. Parameter Binding and Validation
242
+ ## 6. Parameter Binding and Validation
204
243
 
205
244
  ### Parameter Decorators
206
245
 
@@ -208,9 +247,11 @@ class ApiController {}
208
247
  |-----------|--------|---------|
209
248
  | `@Param(name)` | URL path parameter | `/users/:id` → `@Param('id')` |
210
249
  | `@Query(name)` | Query string | `?page=1` → `@Query('page')` |
250
+ | `@QueryMap()` | All query parameters | `?page=1&limit=10` → `@QueryMap()` returns `{ page: '1', limit: '10' }` |
211
251
  | `@Body()` | Request body | JSON body |
212
252
  | `@Body(name)` | Body property | `body.name` → `@Body('name')` |
213
253
  | `@Header(name)` | Request header | `@Header('Authorization')` |
254
+ | `@HeaderMap()` | All headers | `@HeaderMap()` returns all headers as object |
214
255
  | `@Context()` | Full context | Request context object |
215
256
  | `@Session()` | Session data | Session object |
216
257
 
@@ -262,7 +303,7 @@ When validation fails, a `ValidationError` is thrown with detailed information:
262
303
  }
263
304
  ```
264
305
 
265
- ## 6. Controller Method Execution
306
+ ## 7. Controller Method Execution
266
307
 
267
308
  After validation, the controller method is invoked with resolved dependencies and bound parameters.
268
309
 
@@ -294,7 +335,7 @@ Controller methods can return:
294
335
  - **void** - Empty response (204)
295
336
  - **Promise** - Async operations
296
337
 
297
- ## 7. Interceptors (Post-processing)
338
+ ## 8. Interceptors (Post-processing)
298
339
 
299
340
  After the handler executes, post-interceptors run in reverse order:
300
341
 
@@ -318,7 +359,7 @@ class TransformInterceptor implements Interceptor {
318
359
  }
319
360
  ```
320
361
 
321
- ## 8. Exception Filter
362
+ ## 9. Exception Filter
322
363
 
323
364
  If any exception is thrown during the request lifecycle, it's caught by the exception filter.
324
365
 
@@ -1,19 +1,19 @@
1
- # Symbol + Interface 同名模式详解
1
+ # Symbol + Interface Same-Name Pattern Explained
2
2
 
3
- ## 📖 背景
3
+ ## 📖 Background
4
4
 
5
- TypeScript 在编译为 JavaScript 后,所有类型信息都会丢失。这给依赖注入框架带来了挑战:如何在运行时识别注入的依赖类型?
5
+ After TypeScript is compiled to JavaScript, all type information is lost. This poses a challenge for dependency injection frameworks: how to identify the type of injected dependencies at runtime?
6
6
 
7
- ## 🎯 解决方案
7
+ ## 🎯 Solution
8
8
 
9
- Bun Server Framework 采用 **Symbol + Interface 同名模式**,优雅地解决了这个问题。
9
+ Bun Server Framework adopts the **Symbol + Interface Same-Name Pattern** to elegantly solve this problem.
10
10
 
11
- ## 💡 核心概念
11
+ ## 💡 Core Concepts
12
12
 
13
- ### 传统方式的问题
13
+ ### Problems with Traditional Approach
14
14
 
15
15
  ```typescript
16
- // ❌ 传统方式:只能注入具体类
16
+ // ❌ Traditional approach: can only inject concrete classes
17
17
  interface UserService {
18
18
  find(id: string): Promise<User>;
19
19
  }
@@ -23,102 +23,102 @@ class UserServiceImpl implements UserService {
23
23
  async find(id: string) { ... }
24
24
  }
25
25
 
26
- // 问题:TypeScript 编译后 interface 消失
27
- // 无法在运行时通过 interface 类型进行注入
26
+ // Problem: TypeScript interfaces disappear after compilation
27
+ // Cannot inject using interface type at runtime
28
28
  public constructor(
29
- private readonly userService: UserService // 编译后类型信息丢失
29
+ private readonly userService: UserService // Type information lost after compilation
30
30
  ) {}
31
31
  ```
32
32
 
33
- ### Symbol + Interface 同名模式
33
+ ### Symbol + Interface Same-Name Pattern
34
34
 
35
35
  ```typescript
36
- // ✅ Bun Server 方式:Symbol + Interface 同名
36
+ // ✅ Bun Server approach: Symbol + Interface same name
37
37
 
38
- // 1. 定义接口(编译时类型检查)
38
+ // 1. Define interface (compile-time type checking)
39
39
  interface UserService {
40
40
  find(id: string): Promise<User>;
41
41
  create(user: User): Promise<User>;
42
42
  }
43
43
 
44
- // 2. 定义同名 Symbol(运行时 Token
45
- // 注意:声明为 const,与 interface 同名
44
+ // 2. Define same-name Symbol (runtime Token)
45
+ // Note: declared as const, same name as interface
46
46
  const UserService = Symbol('UserService');
47
47
 
48
- // 3. 实现接口
48
+ // 3. Implement interface
49
49
  @Injectable()
50
50
  class UserServiceImpl implements UserService {
51
51
  public async find(id: string): Promise<User> {
52
- // 实现...
52
+ // Implementation...
53
53
  }
54
54
 
55
55
  public async create(user: User): Promise<User> {
56
- // 实现...
56
+ // Implementation...
57
57
  }
58
58
  }
59
59
 
60
- // 4. Module 中配置
60
+ // 4. Configure in Module
61
61
  @Module({
62
62
  providers: [{
63
- provide: UserService, // Symbol Token(运行时)
64
- useClass: UserServiceImpl, // 实现类
63
+ provide: UserService, // Symbol Token (runtime)
64
+ useClass: UserServiceImpl, // Implementation class
65
65
  }],
66
- exports: [UserServiceImpl], // 导出实现类(可选)
66
+ exports: [UserServiceImpl], // Export implementation class (optional)
67
67
  })
68
68
  class UserModule {}
69
69
 
70
- // 5. 注入使用
70
+ // 5. Inject and use
71
71
  @Controller('/users')
72
72
  class UserController {
73
73
  public constructor(
74
- // 类型是 interface UserService(编译时检查)
75
- // 实际注入的是 Symbol('UserService') 对应的实例(运行时)
74
+ // Type is interface UserService (compile-time check)
75
+ // Actually injected is instance corresponding to Symbol('UserService') (runtime)
76
76
  private readonly userService: UserService,
77
77
  ) {}
78
78
 
79
79
  @GET('/:id')
80
80
  public async getUser(@Param('id') id: string) {
81
- // TypeScript 知道 userService find 方法
81
+ // TypeScript knows userService has find method
82
82
  return await this.userService.find(id);
83
83
  }
84
84
  }
85
85
  ```
86
86
 
87
- ## 🔑 关键要点
87
+ ## 🔑 Key Points
88
88
 
89
- ### 1. 导入时不能使用 `import type`
89
+ ### 1. Cannot Use `import type` When Importing
90
90
 
91
91
  ```typescript
92
- // ✅ 正确:同时导入 Symbol interface
92
+ // ✅ Correct: Import both Symbol and interface
93
93
  import { UserService } from './user-service';
94
94
 
95
- // ❌ 错误:只导入类型,Symbol 丢失
95
+ // ❌ Wrong: Only import type, Symbol is lost
96
96
  import type { UserService } from './user-service';
97
97
 
98
- // ❌ 错误:混合导入会导致混淆
98
+ // ❌ Wrong: Mixed import causes confusion
99
99
  import { type UserService } from './user-service';
100
100
  ```
101
101
 
102
- **原因**:`import type` 只导入类型信息,编译后会被完全移除,导致 Symbol 丢失。
102
+ **Reason**: `import type` only imports type information, which is completely removed after compilation, causing the Symbol to be lost.
103
103
 
104
- ### 2. 导出顺序
104
+ ### 2. Export Order
105
105
 
106
106
  ```typescript
107
- // 推荐的文件组织方式
107
+ // Recommended file organization
108
108
 
109
109
  // user-service.ts
110
- // 1. 导入依赖
110
+ // 1. Import dependencies
111
111
  import { Injectable } from '@dangao/bun-server';
112
112
 
113
- // 2. 定义接口
113
+ // 2. Define interface
114
114
  export interface UserService {
115
115
  find(id: string): Promise<User>;
116
116
  }
117
117
 
118
- // 3. 定义 Symbol(与接口同名)
118
+ // 3. Define Symbol (same name as interface)
119
119
  export const UserService = Symbol('UserService');
120
120
 
121
- // 4. 实现类
121
+ // 4. Implementation class
122
122
  @Injectable()
123
123
  export class UserServiceImpl implements UserService {
124
124
  public async find(id: string): Promise<User> {
@@ -127,66 +127,66 @@ export class UserServiceImpl implements UserService {
127
127
  }
128
128
  ```
129
129
 
130
- ### 3. Module 配置
130
+ ### 3. Module Configuration
131
131
 
132
132
  ```typescript
133
133
  @Module({
134
134
  providers: [
135
135
  {
136
- provide: UserService, // 使用 Symbol 作为 Token
137
- useClass: UserServiceImpl, // 指定实现类
136
+ provide: UserService, // Use Symbol as Token
137
+ useClass: UserServiceImpl, // Specify implementation class
138
138
  }
139
139
  ],
140
- exports: [UserServiceImpl], // 导出实现类(供其他模块使用)
140
+ exports: [UserServiceImpl], // Export implementation class (for other modules to use)
141
141
  })
142
142
  class UserModule {}
143
143
  ```
144
144
 
145
- **注意**:
146
- - `provide` 使用 Symbol Token
147
- - `exports` 导出实现类(不是 Symbol
145
+ **Note**:
146
+ - `provide` uses Symbol Token
147
+ - `exports` exports implementation class (not Symbol)
148
148
 
149
- ### 4. 构造函数注入
149
+ ### 4. Constructor Injection
150
150
 
151
151
  ```typescript
152
- // ✅ 推荐:默认注入(无需装饰器)
152
+ // ✅ Recommended: Default injection (no decorator needed)
153
153
  public constructor(
154
- private readonly userService: UserService, // 框架自动识别类型
154
+ private readonly userService: UserService, // Framework automatically recognizes type
155
155
  ) {}
156
156
 
157
- // ⚠️ 仅在以下情况使用 @Inject
157
+ // ⚠️ Only use @Inject in the following cases
158
158
  public constructor(
159
159
  @Inject(UserService) private readonly userService: UserService,
160
160
  ) {}
161
161
  ```
162
162
 
163
- ## 📋 完整示例
163
+ ## 📋 Complete Example
164
164
 
165
- ### 步骤 1:定义服务接口和实现
165
+ ### Step 1: Define Service Interface and Implementation
166
166
 
167
167
  ```typescript
168
168
  // src/user/user-service.ts
169
169
 
170
170
  import { Injectable } from '@dangao/bun-server';
171
171
 
172
- // 1. 定义用户实体
172
+ // 1. Define user entity
173
173
  export interface User {
174
174
  id: string;
175
175
  name: string;
176
176
  email: string;
177
177
  }
178
178
 
179
- // 2. 定义服务接口
179
+ // 2. Define service interface
180
180
  export interface UserService {
181
181
  find(id: string): Promise<User | undefined>;
182
182
  create(name: string, email: string): Promise<User>;
183
183
  findAll(): Promise<User[]>;
184
184
  }
185
185
 
186
- // 3. 定义同名 Symbol
186
+ // 3. Define same-name Symbol
187
187
  export const UserService = Symbol('UserService');
188
188
 
189
- // 4. 实现服务
189
+ // 4. Implement service
190
190
  @Injectable()
191
191
  export class UserServiceImpl implements UserService {
192
192
  private readonly users = new Map<string, User>();
@@ -208,18 +208,18 @@ export class UserServiceImpl implements UserService {
208
208
  }
209
209
  ```
210
210
 
211
- ### 步骤 2:创建控制器
211
+ ### Step 2: Create Controller
212
212
 
213
213
  ```typescript
214
214
  // src/user/user-controller.ts
215
215
 
216
216
  import { Controller, GET, POST, Body, Param } from '@dangao/bun-server';
217
- // ✅ 注意:不要用 import type
217
+ // ✅ Note: Don't use import type
218
218
  import { UserService } from './user-service';
219
219
 
220
220
  @Controller('/api/users')
221
221
  export class UserController {
222
- // 构造函数注入,框架自动识别类型
222
+ // Constructor injection, framework automatically recognizes type
223
223
  public constructor(
224
224
  private readonly userService: UserService,
225
225
  ) {}
@@ -245,7 +245,7 @@ export class UserController {
245
245
  }
246
246
  ```
247
247
 
248
- ### 步骤 3:配置模块
248
+ ### Step 3: Configure Module
249
249
 
250
250
  ```typescript
251
251
  // src/user/user-module.ts
@@ -259,15 +259,15 @@ import { UserService, UserServiceImpl } from './user-service';
259
259
  providers: [
260
260
  {
261
261
  provide: UserService, // Symbol Token
262
- useClass: UserServiceImpl, // 实现类
262
+ useClass: UserServiceImpl, // Implementation class
263
263
  }
264
264
  ],
265
- exports: [UserServiceImpl], // 导出供其他模块使用
265
+ exports: [UserServiceImpl], // Export for other modules to use
266
266
  })
267
267
  export class UserModule {}
268
268
  ```
269
269
 
270
- ### 步骤 4:启动应用
270
+ ### Step 4: Start Application
271
271
 
272
272
  ```typescript
273
273
  // src/main.ts
@@ -282,19 +282,19 @@ app.listen();
282
282
  console.log('Server running on http://localhost:3000');
283
283
  ```
284
284
 
285
- ## 🎨 高级用法
285
+ ## 🎨 Advanced Usage
286
286
 
287
- ### 多实现切换
287
+ ### Multiple Implementation Switching
288
288
 
289
289
  ```typescript
290
- // 定义接口和 Symbol
290
+ // Define interface and Symbol
291
291
  export interface CacheService {
292
292
  get(key: string): Promise<string | null>;
293
293
  set(key: string, value: string): Promise<void>;
294
294
  }
295
295
  export const CacheService = Symbol('CacheService');
296
296
 
297
- // 内存实现
297
+ // Memory implementation
298
298
  @Injectable()
299
299
  export class MemoryCacheService implements CacheService {
300
300
  private cache = new Map<string, string>();
@@ -308,19 +308,19 @@ export class MemoryCacheService implements CacheService {
308
308
  }
309
309
  }
310
310
 
311
- // Redis 实现
311
+ // Redis implementation
312
312
  @Injectable()
313
313
  export class RedisCacheService implements CacheService {
314
314
  async get(key: string) {
315
- // Redis 实现...
315
+ // Redis implementation...
316
316
  }
317
317
 
318
318
  async set(key: string, value: string) {
319
- // Redis 实现...
319
+ // Redis implementation...
320
320
  }
321
321
  }
322
322
 
323
- // 根据环境切换实现
323
+ // Switch implementation based on environment
324
324
  const isProduction = process.env.NODE_ENV === 'production';
325
325
 
326
326
  @Module({
@@ -334,10 +334,10 @@ const isProduction = process.env.NODE_ENV === 'production';
334
334
  export class CacheModule {}
335
335
  ```
336
336
 
337
- ### 工厂函数
337
+ ### Factory Function
338
338
 
339
339
  ```typescript
340
- // 使用工厂函数创建实例
340
+ // Use factory function to create instances
341
341
  @Module({
342
342
  providers: [
343
343
  {
@@ -355,54 +355,54 @@ export class CacheModule {}
355
355
  export class UserModule {}
356
356
  ```
357
357
 
358
- ## ❓ 常见问题
358
+ ## ❓ Common Questions
359
359
 
360
- ### Q1: 为什么不直接使用类作为 Token?
360
+ ### Q1: Why Not Use Classes Directly as Tokens?
361
361
 
362
- **A**: 使用类作为 Token 有以下问题:
363
- 1. 无法实现面向接口编程
364
- 2. 紧耦合实现类,不利于测试
365
- 3. 无法在运行时动态切换实现
362
+ **A**: Using classes as tokens has the following problems:
363
+ 1. Cannot implement interface-oriented programming
364
+ 2. Tight coupling to implementation classes, not conducive to testing
365
+ 3. Cannot dynamically switch implementations at runtime
366
366
 
367
- Symbol + Interface 模式提供了更好的灵活性。
367
+ The Symbol + Interface pattern provides better flexibility.
368
368
 
369
- ### Q2: Symbol String Token 有什么区别?
369
+ ### Q2: What's the Difference Between Symbol and String Tokens?
370
370
 
371
371
  ```typescript
372
- // Symbol Token(推荐)
372
+ // Symbol Token (recommended)
373
373
  const UserService = Symbol('UserService');
374
374
 
375
- // String Token(不推荐)
375
+ // String Token (not recommended)
376
376
  const USER_SERVICE_TOKEN = 'UserService';
377
377
  ```
378
378
 
379
- **区别**:
380
- - Symbol 是唯一的,避免命名冲突
381
- - String 可能在大型项目中重复,导致注入错误
382
- - Symbol 配合 interface 同名,语义更清晰
379
+ **Differences**:
380
+ - Symbol is unique, avoiding naming conflicts
381
+ - String may be duplicated in large projects, causing injection errors
382
+ - Symbol combined with same-name interface provides clearer semantics
383
383
 
384
- ### Q3: 什么时候必须用 @Inject 装饰器?
384
+ ### Q3: When Must @Inject Decorator Be Used?
385
385
 
386
- 只有以下情况需要:
387
- 1. 使用 Symbol Token(虽然默认注入也支持,但显式使用更清晰)
388
- 2. 参数类型无法推断(如 interface
389
- 3. 需要注入特定的实现
386
+ Only needed in the following cases:
387
+ 1. Using Symbol Token (although default injection also supports it, explicit use is clearer)
388
+ 2. Parameter type cannot be inferred (e.g., interface)
389
+ 3. Need to inject specific implementation
390
390
 
391
391
  ```typescript
392
- // 需要 @Inject 的情况
392
+ // Cases requiring @Inject
393
393
  public constructor(
394
394
  @Inject(CONFIG_SERVICE_TOKEN) private config: ConfigService,
395
395
  @Inject(LOGGER_TOKEN) private logger: Logger,
396
396
  ) {}
397
397
 
398
- // 不需要 @Inject(推荐)
398
+ // No @Inject needed (recommended)
399
399
  public constructor(
400
400
  private readonly userService: UserService,
401
401
  private readonly productService: ProductService,
402
402
  ) {}
403
403
  ```
404
404
 
405
- ### Q4: exports 为什么导出实现类而不是 Symbol?
405
+ ### Q4: Why Does exports Export Implementation Classes Instead of Symbols?
406
406
 
407
407
  ```typescript
408
408
  @Module({
@@ -410,22 +410,22 @@ public constructor(
410
410
  provide: UserService, // Symbol Token
411
411
  useClass: UserServiceImpl,
412
412
  }],
413
- exports: [UserServiceImpl], // 导出实现类
413
+ exports: [UserServiceImpl], // Export implementation class
414
414
  })
415
415
  ```
416
416
 
417
- **原因**:
418
- - `exports` 的作用是让其他模块可以导入该模块的 providers
419
- - 导出的是 providers 数组中的元素(实现类)
420
- - 其他模块通过 `imports` 导入后,可以使用 Symbol Token 注入
417
+ **Reason**:
418
+ - The purpose of `exports` is to allow other modules to import this module's providers
419
+ - What's exported are elements from the providers array (implementation classes)
420
+ - After other modules import through `imports`, they can use Symbol Token for injection
421
421
 
422
- ## 📚 相关资源
422
+ ## 📚 Related Resources
423
423
 
424
- - [依赖注入指南](./guide.md#dependency-injection)
425
- - [模块系统详解](./guide.md#module-system)
426
- - [最佳实践](./best-practices.md)
427
- - [示例代码](../examples/basic-app.ts)
424
+ - [Dependency Injection Guide](./guide.md#dependency-injection)
425
+ - [Module System Explained](./guide.md#module-system)
426
+ - [Best Practices](./best-practices.md)
427
+ - [Example Code](../examples/basic-app.ts)
428
428
 
429
429
  ---
430
430
 
431
- **提示**:这个模式是 Bun Server Framework 的核心特性之一,理解它能帮助你更好地设计可维护的应用架构。
431
+ **Tip**: This pattern is one of the core features of Bun Server Framework. Understanding it will help you design more maintainable application architectures.