@dangao/bun-server 1.7.1 → 1.8.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.
Files changed (116) hide show
  1. package/README.md +129 -21
  2. package/dist/di/decorators.d.ts +37 -0
  3. package/dist/di/decorators.d.ts.map +1 -1
  4. package/dist/di/index.d.ts +1 -1
  5. package/dist/di/index.d.ts.map +1 -1
  6. package/dist/di/module-registry.d.ts +17 -0
  7. package/dist/di/module-registry.d.ts.map +1 -1
  8. package/dist/events/decorators.d.ts +52 -0
  9. package/dist/events/decorators.d.ts.map +1 -0
  10. package/dist/events/event-module.d.ts +97 -0
  11. package/dist/events/event-module.d.ts.map +1 -0
  12. package/dist/events/index.d.ts +5 -0
  13. package/dist/events/index.d.ts.map +1 -0
  14. package/dist/events/service.d.ts +76 -0
  15. package/dist/events/service.d.ts.map +1 -0
  16. package/dist/events/types.d.ts +184 -0
  17. package/dist/events/types.d.ts.map +1 -0
  18. package/dist/index.d.ts +5 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1511 -11
  21. package/dist/security/filter.d.ts +23 -0
  22. package/dist/security/filter.d.ts.map +1 -1
  23. package/dist/security/guards/builtin/auth-guard.d.ts +44 -0
  24. package/dist/security/guards/builtin/auth-guard.d.ts.map +1 -0
  25. package/dist/security/guards/builtin/index.d.ts +3 -0
  26. package/dist/security/guards/builtin/index.d.ts.map +1 -0
  27. package/dist/security/guards/builtin/roles-guard.d.ts +66 -0
  28. package/dist/security/guards/builtin/roles-guard.d.ts.map +1 -0
  29. package/dist/security/guards/decorators.d.ts +50 -0
  30. package/dist/security/guards/decorators.d.ts.map +1 -0
  31. package/dist/security/guards/execution-context.d.ts +56 -0
  32. package/dist/security/guards/execution-context.d.ts.map +1 -0
  33. package/dist/security/guards/guard-registry.d.ts +67 -0
  34. package/dist/security/guards/guard-registry.d.ts.map +1 -0
  35. package/dist/security/guards/index.d.ts +7 -0
  36. package/dist/security/guards/index.d.ts.map +1 -0
  37. package/dist/security/guards/reflector.d.ts +57 -0
  38. package/dist/security/guards/reflector.d.ts.map +1 -0
  39. package/dist/security/guards/types.d.ts +126 -0
  40. package/dist/security/guards/types.d.ts.map +1 -0
  41. package/dist/security/index.d.ts +1 -0
  42. package/dist/security/index.d.ts.map +1 -1
  43. package/dist/security/security-module.d.ts +20 -0
  44. package/dist/security/security-module.d.ts.map +1 -1
  45. package/dist/validation/class-validator.d.ts +108 -0
  46. package/dist/validation/class-validator.d.ts.map +1 -0
  47. package/dist/validation/custom-validator.d.ts +130 -0
  48. package/dist/validation/custom-validator.d.ts.map +1 -0
  49. package/dist/validation/errors.d.ts +22 -2
  50. package/dist/validation/errors.d.ts.map +1 -1
  51. package/dist/validation/index.d.ts +7 -1
  52. package/dist/validation/index.d.ts.map +1 -1
  53. package/dist/validation/rules/array.d.ts +33 -0
  54. package/dist/validation/rules/array.d.ts.map +1 -0
  55. package/dist/validation/rules/common.d.ts +90 -0
  56. package/dist/validation/rules/common.d.ts.map +1 -0
  57. package/dist/validation/rules/conditional.d.ts +30 -0
  58. package/dist/validation/rules/conditional.d.ts.map +1 -0
  59. package/dist/validation/rules/index.d.ts +5 -0
  60. package/dist/validation/rules/index.d.ts.map +1 -0
  61. package/dist/validation/rules/object.d.ts +30 -0
  62. package/dist/validation/rules/object.d.ts.map +1 -0
  63. package/dist/validation/types.d.ts +52 -1
  64. package/dist/validation/types.d.ts.map +1 -1
  65. package/docs/events.md +494 -0
  66. package/docs/guards.md +376 -0
  67. package/docs/guide.md +309 -1
  68. package/docs/request-lifecycle.md +444 -0
  69. package/docs/validation.md +407 -0
  70. package/docs/zh/events.md +494 -0
  71. package/docs/zh/guards.md +376 -0
  72. package/docs/zh/guide.md +309 -1
  73. package/docs/zh/request-lifecycle.md +444 -0
  74. package/docs/zh/validation.md +407 -0
  75. package/package.json +1 -1
  76. package/src/di/decorators.ts +46 -0
  77. package/src/di/index.ts +10 -1
  78. package/src/di/module-registry.ts +39 -0
  79. package/src/events/decorators.ts +103 -0
  80. package/src/events/event-module.ts +272 -0
  81. package/src/events/index.ts +32 -0
  82. package/src/events/service.ts +352 -0
  83. package/src/events/types.ts +223 -0
  84. package/src/index.ts +133 -1
  85. package/src/security/filter.ts +88 -8
  86. package/src/security/guards/builtin/auth-guard.ts +68 -0
  87. package/src/security/guards/builtin/index.ts +3 -0
  88. package/src/security/guards/builtin/roles-guard.ts +165 -0
  89. package/src/security/guards/decorators.ts +124 -0
  90. package/src/security/guards/execution-context.ts +152 -0
  91. package/src/security/guards/guard-registry.ts +164 -0
  92. package/src/security/guards/index.ts +7 -0
  93. package/src/security/guards/reflector.ts +99 -0
  94. package/src/security/guards/types.ts +144 -0
  95. package/src/security/index.ts +1 -0
  96. package/src/security/security-module.ts +72 -2
  97. package/src/validation/class-validator.ts +322 -0
  98. package/src/validation/custom-validator.ts +289 -0
  99. package/src/validation/errors.ts +50 -2
  100. package/src/validation/index.ts +103 -1
  101. package/src/validation/rules/array.ts +118 -0
  102. package/src/validation/rules/common.ts +286 -0
  103. package/src/validation/rules/conditional.ts +52 -0
  104. package/src/validation/rules/index.ts +51 -0
  105. package/src/validation/rules/object.ts +86 -0
  106. package/src/validation/types.ts +61 -1
  107. package/tests/di/global-module.test.ts +487 -0
  108. package/tests/events/event-decorators.test.ts +173 -0
  109. package/tests/events/event-emitter.test.ts +373 -0
  110. package/tests/events/event-module.test.ts +373 -0
  111. package/tests/security/guards/guards-integration.test.ts +371 -0
  112. package/tests/security/guards/guards.test.ts +775 -0
  113. package/tests/security/security-module.test.ts +2 -2
  114. package/tests/validation/class-validator.test.ts +349 -0
  115. package/tests/validation/custom-validator.test.ts +335 -0
  116. package/tests/validation/rules.test.ts +543 -0
@@ -0,0 +1,444 @@
1
+ # 请求生命周期
2
+
3
+ 本文档详细说明 Bun Server 如何处理 HTTP 请求,从接收请求到发送响应的完整流程。
4
+
5
+ ## 概览
6
+
7
+ ```
8
+ HTTP Request
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
+ HTTP Response
43
+ ```
44
+
45
+ ## 1. 中间件管道
46
+
47
+ 请求到达时首先执行中间件。中间件可以在多个级别注册:
48
+
49
+ ### 执行顺序
50
+
51
+ 1. **全局中间件** - 通过 `app.use()` 注册
52
+ 2. **模块中间件** - 在模块配置中定义
53
+ 3. **控制器中间件** - 在类上使用 `@UseMiddleware()` 装饰
54
+ 4. **方法中间件** - 在方法上使用 `@UseMiddleware()` 装饰
55
+
56
+ ### 示例
57
+
58
+ ```typescript
59
+ // 全局中间件
60
+ app.use(createLoggerMiddleware({ prefix: '[App]' }));
61
+ app.use(createCorsMiddleware({ origin: '*' }));
62
+
63
+ // 控制器级中间件
64
+ @Controller('/api')
65
+ @UseMiddleware(authMiddleware)
66
+ class ApiController {
67
+ // 方法级中间件
68
+ @GET('/admin')
69
+ @UseMiddleware(adminOnlyMiddleware)
70
+ public admin() {}
71
+ }
72
+ ```
73
+
74
+ ### 内置中间件
75
+
76
+ | 中间件 | 用途 |
77
+ |--------|------|
78
+ | `createLoggerMiddleware` | 请求/响应日志 |
79
+ | `createCorsMiddleware` | CORS 头部 |
80
+ | `createErrorHandlingMiddleware` | 全局错误处理 |
81
+ | `createRateLimitMiddleware` | 速率限制 |
82
+ | `createStaticFileMiddleware` | 静态文件服务 |
83
+ | `createFileUploadMiddleware` | 文件上传处理 |
84
+ | `createSessionMiddleware` | 会话管理 |
85
+ | `createHttpMetricsMiddleware` | HTTP 指标收集 |
86
+
87
+ ### 何时使用中间件
88
+
89
+ - 横切关注点(日志、指标)
90
+ - 请求/响应转换
91
+ - 认证令牌提取
92
+ - CORS 处理
93
+ - 速率限制
94
+ - 静态文件服务
95
+
96
+ ## 2. 安全过滤器
97
+
98
+ 中间件之后,安全过滤器检查认证和授权。
99
+
100
+ ### 流程
101
+
102
+ 1. 检查路径是否在 `excludePaths` 中
103
+ 2. 提取凭证(JWT、OAuth2 令牌)
104
+ 3. 使用 `AuthenticationManager` 进行认证
105
+ 4. 为请求设置 `SecurityContext`
106
+ 5. 如果指定了 `@Auth({ roles: [...] })`,检查角色
107
+
108
+ ### 配置
109
+
110
+ ```typescript
111
+ SecurityModule.forRoot({
112
+ jwt: {
113
+ secret: 'your-secret-key',
114
+ accessTokenExpiresIn: 3600,
115
+ },
116
+ oauth2Clients: [/* ... */],
117
+ excludePaths: ['/public', '/health'],
118
+ });
119
+ ```
120
+
121
+ ### 使用方法
122
+
123
+ ```typescript
124
+ @Controller('/api/users')
125
+ class UserController {
126
+ @GET('/profile')
127
+ @Auth() // 需要认证
128
+ public getProfile() {
129
+ const context = SecurityContextHolder.getContext();
130
+ return context.getPrincipal();
131
+ }
132
+
133
+ @GET('/admin')
134
+ @Auth({ roles: ['admin'] }) // 需要 admin 角色
135
+ public adminOnly() {}
136
+ }
137
+ ```
138
+
139
+ ## 3. 路由匹配
140
+
141
+ 路由器将请求路径和方法匹配到已注册的路由。
142
+
143
+ ### 匹配优先级
144
+
145
+ 1. **静态路由** - 精确路径匹配(`/api/users`)
146
+ 2. **动态路由** - 带参数的路径(`/api/users/:id`)
147
+ 3. **通配符路由** - 全匹配模式(`/api/*`)
148
+
149
+ ### 路由注册
150
+
151
+ 使用装饰器时自动注册路由:
152
+
153
+ ```typescript
154
+ @Controller('/api/users')
155
+ class UserController {
156
+ @GET('/:id') // GET /api/users/:id
157
+ public getUser() {}
158
+
159
+ @POST('/') // POST /api/users
160
+ public createUser() {}
161
+
162
+ @PUT('/:id') // PUT /api/users/:id
163
+ public updateUser() {}
164
+
165
+ @DELETE('/:id') // DELETE /api/users/:id
166
+ public deleteUser() {}
167
+ }
168
+ ```
169
+
170
+ ## 4. 拦截器(前置处理)
171
+
172
+ 拦截器在控制器方法之前和之后运行。前置拦截器按顺序执行:
173
+
174
+ 1. **全局拦截器**
175
+ 2. **控制器拦截器**
176
+ 3. **方法拦截器**
177
+
178
+ ### 示例
179
+
180
+ ```typescript
181
+ @Injectable()
182
+ class LoggingInterceptor implements Interceptor {
183
+ public async intercept(context: ExecutionContext, next: () => Promise<Response>): Promise<Response> {
184
+ console.log('处理器之前...');
185
+ const response = await next();
186
+ console.log('处理器之后...');
187
+ return response;
188
+ }
189
+ }
190
+
191
+ @Controller('/api')
192
+ @UseInterceptors(LoggingInterceptor)
193
+ class ApiController {}
194
+ ```
195
+
196
+ ### 使用场景
197
+
198
+ - 日志记录
199
+ - 缓存
200
+ - 响应转换
201
+ - 性能监控
202
+
203
+ ## 5. 参数绑定和验证
204
+
205
+ ### 参数装饰器
206
+
207
+ | 装饰器 | 来源 | 示例 |
208
+ |--------|------|------|
209
+ | `@Param(name)` | URL 路径参数 | `/users/:id` → `@Param('id')` |
210
+ | `@Query(name)` | 查询字符串 | `?page=1` → `@Query('page')` |
211
+ | `@Body()` | 请求体 | JSON 请求体 |
212
+ | `@Body(name)` | 请求体属性 | `body.name` → `@Body('name')` |
213
+ | `@Header(name)` | 请求头 | `@Header('Authorization')` |
214
+ | `@Context()` | 完整上下文 | 请求上下文对象 |
215
+ | `@Session()` | 会话数据 | 会话对象 |
216
+
217
+ ### 验证
218
+
219
+ 使用 `@Validate()` 装饰器进行验证:
220
+
221
+ ```typescript
222
+ @POST('/users')
223
+ public createUser(
224
+ @Body('name') @Validate(IsString(), MinLength(3)) name: string,
225
+ @Body('email') @Validate(IsEmail()) email: string,
226
+ @Body('age') @Validate(IsNumber(), Min(0), Max(150)) age: number,
227
+ ) {
228
+ return { name, email, age };
229
+ }
230
+ ```
231
+
232
+ ### 内置验证器
233
+
234
+ | 验证器 | 描述 |
235
+ |--------|------|
236
+ | `IsString()` | 必须是字符串 |
237
+ | `IsNumber()` | 必须是数字 |
238
+ | `IsEmail()` | 必须是有效邮箱 |
239
+ | `MinLength(n)` | 最小字符串长度 |
240
+ | `MaxLength(n)` | 最大字符串长度 |
241
+ | `Min(n)` | 最小数值 |
242
+ | `Max(n)` | 最大数值 |
243
+ | `IsOptional()` | 字段可选 |
244
+ | `IsEnum(enum)` | 必须是枚举值 |
245
+ | `Matches(regex)` | 必须匹配模式 |
246
+
247
+ ### 验证错误处理
248
+
249
+ 验证失败时,抛出 `ValidationError` 并包含详细信息:
250
+
251
+ ```json
252
+ {
253
+ "status": 400,
254
+ "message": "Validation failed",
255
+ "issues": [
256
+ {
257
+ "field": "email",
258
+ "message": "Must be a valid email address",
259
+ "value": "invalid"
260
+ }
261
+ ]
262
+ }
263
+ ```
264
+
265
+ ## 6. 控制器方法执行
266
+
267
+ 验证通过后,使用已解析的依赖和绑定的参数调用控制器方法。
268
+
269
+ ### 依赖注入
270
+
271
+ 通过构造函数注入服务:
272
+
273
+ ```typescript
274
+ @Controller('/api/users')
275
+ class UserController {
276
+ public constructor(
277
+ private readonly userService: UserService,
278
+ @Inject(CONFIG_SERVICE_TOKEN) private readonly config: ConfigService,
279
+ ) {}
280
+
281
+ @GET('/:id')
282
+ public async getUser(@Param('id') id: string) {
283
+ return await this.userService.findById(id);
284
+ }
285
+ }
286
+ ```
287
+
288
+ ### 返回值
289
+
290
+ 控制器方法可以返回:
291
+
292
+ - **普通对象** - 序列化为 JSON
293
+ - **Response** - 原生 Response 对象
294
+ - **void** - 空响应(204)
295
+ - **Promise** - 异步操作
296
+
297
+ ## 7. 拦截器(后置处理)
298
+
299
+ 处理器执行后,后置拦截器按相反顺序运行:
300
+
301
+ 1. **方法拦截器**
302
+ 2. **控制器拦截器**
303
+ 3. **全局拦截器**
304
+
305
+ 这允许拦截器转换响应:
306
+
307
+ ```typescript
308
+ @Injectable()
309
+ class TransformInterceptor implements Interceptor {
310
+ public async intercept(context: ExecutionContext, next: () => Promise<Response>): Promise<Response> {
311
+ const response = await next();
312
+ // 在此转换响应
313
+ return new Response(JSON.stringify({
314
+ data: await response.json(),
315
+ timestamp: Date.now(),
316
+ }));
317
+ }
318
+ }
319
+ ```
320
+
321
+ ## 8. 异常过滤器
322
+
323
+ 如果在请求生命周期中抛出任何异常,它会被异常过滤器捕获。
324
+
325
+ ### 内置异常
326
+
327
+ | 异常 | 状态码 | 用途 |
328
+ |------|--------|------|
329
+ | `HttpException` | 自定义 | 基础异常类 |
330
+ | `BadRequestException` | 400 | 无效请求 |
331
+ | `UnauthorizedException` | 401 | 需要认证 |
332
+ | `ForbiddenException` | 403 | 拒绝访问 |
333
+ | `NotFoundException` | 404 | 资源未找到 |
334
+ | `ValidationError` | 400 | 验证失败 |
335
+
336
+ ### 自定义异常过滤器
337
+
338
+ ```typescript
339
+ ExceptionFilterRegistry.getInstance().register({
340
+ catch(error: Error, context: Context): Response | undefined {
341
+ if (error instanceof CustomException) {
342
+ return context.createResponse(
343
+ { error: error.message, code: error.code },
344
+ { status: error.status }
345
+ );
346
+ }
347
+ return undefined; // 传递给下一个过滤器
348
+ }
349
+ });
350
+ ```
351
+
352
+ ### 错误响应格式
353
+
354
+ 默认错误响应遵循以下格式:
355
+
356
+ ```json
357
+ {
358
+ "status": 400,
359
+ "message": "Error message",
360
+ "code": "ERROR_CODE",
361
+ "timestamp": "2024-01-01T00:00:00.000Z"
362
+ }
363
+ ```
364
+
365
+ ## 组件对比
366
+
367
+ | 组件 | 执行时机 | 使用场景 |
368
+ |------|----------|----------|
369
+ | **中间件** | 路由之前 | 横切关注点、请求转换 |
370
+ | **守卫** | 路由之后、处理器之前 | 认证、授权 |
371
+ | **拦截器** | 处理器之前/之后 | 日志、缓存、响应转换 |
372
+ | **管道** | 参数绑定 | 验证、转换 |
373
+ | **异常过滤器** | 异常发生时 | 错误处理 |
374
+
375
+ ## 最佳实践
376
+
377
+ ### 1. 中间件用于横切关注点
378
+
379
+ 对适用于所有或大多数请求的关注点使用中间件:
380
+
381
+ ```typescript
382
+ // 好:全局日志
383
+ app.use(createLoggerMiddleware({ prefix: '[App]' }));
384
+
385
+ // 好:所有 API 路由的 CORS
386
+ app.use(createCorsMiddleware({ origin: '*' }));
387
+ ```
388
+
389
+ ### 2. 守卫用于授权
390
+
391
+ 对特定路由的授权使用安全装饰器:
392
+
393
+ ```typescript
394
+ // 好:基于角色的访问控制
395
+ @Auth({ roles: ['admin'] })
396
+ @GET('/admin/dashboard')
397
+ public dashboard() {}
398
+ ```
399
+
400
+ ### 3. 拦截器用于响应转换
401
+
402
+ 当需要修改响应时使用拦截器:
403
+
404
+ ```typescript
405
+ // 好:为所有响应添加元数据
406
+ @UseInterceptors(ResponseMetadataInterceptor)
407
+ @Controller('/api')
408
+ class ApiController {}
409
+ ```
410
+
411
+ ### 4. 在参数级别验证
412
+
413
+ 尽早验证,快速失败:
414
+
415
+ ```typescript
416
+ // 好:在参数绑定时验证
417
+ @POST('/users')
418
+ public createUser(
419
+ @Body('email') @Validate(IsEmail()) email: string,
420
+ ) {}
421
+ ```
422
+
423
+ ### 5. 使用特定异常类型
424
+
425
+ 抛出特定异常以便清晰地处理错误:
426
+
427
+ ```typescript
428
+ // 好:特定异常
429
+ if (!user) {
430
+ throw new NotFoundException('User not found');
431
+ }
432
+
433
+ // 避免:通用错误
434
+ if (!user) {
435
+ throw new Error('Not found');
436
+ }
437
+ ```
438
+
439
+ ## 另请参阅
440
+
441
+ - [API 参考](./api.md)
442
+ - [使用指南](./guide.md)
443
+ - [错误处理](./error-handling.md)
444
+ - [安全认证](./guide.md#15-security-and-authentication)