@dangao/bun-server 1.9.0 → 1.12.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 (209) hide show
  1. package/README.md +79 -6
  2. package/dist/cache/cache-module.d.ts +6 -0
  3. package/dist/cache/cache-module.d.ts.map +1 -1
  4. package/dist/client/generator.d.ts +16 -0
  5. package/dist/client/generator.d.ts.map +1 -0
  6. package/dist/client/index.d.ts +4 -0
  7. package/dist/client/index.d.ts.map +1 -0
  8. package/dist/client/runtime.d.ts +15 -0
  9. package/dist/client/runtime.d.ts.map +1 -0
  10. package/dist/client/types.d.ts +36 -0
  11. package/dist/client/types.d.ts.map +1 -0
  12. package/dist/config/config-module.d.ts +7 -0
  13. package/dist/config/config-module.d.ts.map +1 -1
  14. package/dist/config/index.d.ts +1 -1
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/service.d.ts +13 -0
  17. package/dist/config/service.d.ts.map +1 -1
  18. package/dist/config/types.d.ts +10 -0
  19. package/dist/config/types.d.ts.map +1 -1
  20. package/dist/core/application.d.ts +7 -0
  21. package/dist/core/application.d.ts.map +1 -1
  22. package/dist/core/apply-decorators.d.ts +6 -0
  23. package/dist/core/apply-decorators.d.ts.map +1 -0
  24. package/dist/core/cluster.d.ts +47 -0
  25. package/dist/core/cluster.d.ts.map +1 -0
  26. package/dist/core/index.d.ts +1 -0
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/server.d.ts +8 -0
  29. package/dist/core/server.d.ts.map +1 -1
  30. package/dist/dashboard/controller.d.ts +55 -0
  31. package/dist/dashboard/controller.d.ts.map +1 -0
  32. package/dist/dashboard/dashboard-extension.d.ts +20 -0
  33. package/dist/dashboard/dashboard-extension.d.ts.map +1 -0
  34. package/dist/dashboard/dashboard-module.d.ts +13 -0
  35. package/dist/dashboard/dashboard-module.d.ts.map +1 -0
  36. package/dist/dashboard/index.d.ts +4 -0
  37. package/dist/dashboard/index.d.ts.map +1 -0
  38. package/dist/dashboard/types.d.ts +16 -0
  39. package/dist/dashboard/types.d.ts.map +1 -0
  40. package/dist/dashboard/ui.d.ts +7 -0
  41. package/dist/dashboard/ui.d.ts.map +1 -0
  42. package/dist/database/database-module.d.ts +7 -0
  43. package/dist/database/database-module.d.ts.map +1 -1
  44. package/dist/debug/debug-module.d.ts +13 -0
  45. package/dist/debug/debug-module.d.ts.map +1 -0
  46. package/dist/debug/debug-ui-middleware.d.ts +8 -0
  47. package/dist/debug/debug-ui-middleware.d.ts.map +1 -0
  48. package/dist/debug/index.d.ts +5 -0
  49. package/dist/debug/index.d.ts.map +1 -0
  50. package/dist/debug/middleware.d.ts +12 -0
  51. package/dist/debug/middleware.d.ts.map +1 -0
  52. package/dist/debug/recorder.d.ts +61 -0
  53. package/dist/debug/recorder.d.ts.map +1 -0
  54. package/dist/debug/types.d.ts +48 -0
  55. package/dist/debug/types.d.ts.map +1 -0
  56. package/dist/debug/ui.d.ts +6 -0
  57. package/dist/debug/ui.d.ts.map +1 -0
  58. package/dist/di/async-module.d.ts +49 -0
  59. package/dist/di/async-module.d.ts.map +1 -0
  60. package/dist/di/lifecycle.d.ts +49 -0
  61. package/dist/di/lifecycle.d.ts.map +1 -0
  62. package/dist/di/module-registry.d.ts +24 -0
  63. package/dist/di/module-registry.d.ts.map +1 -1
  64. package/dist/index.d.ts +9 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +1887 -35
  67. package/dist/router/route.d.ts +5 -7
  68. package/dist/router/route.d.ts.map +1 -1
  69. package/dist/swagger/generator.d.ts +10 -0
  70. package/dist/swagger/generator.d.ts.map +1 -1
  71. package/dist/testing/test-client.d.ts +49 -0
  72. package/dist/testing/test-client.d.ts.map +1 -0
  73. package/dist/testing/testing-module.d.ts +90 -0
  74. package/dist/testing/testing-module.d.ts.map +1 -0
  75. package/dist/websocket/registry.d.ts +1 -6
  76. package/dist/websocket/registry.d.ts.map +1 -1
  77. package/docs/async-module.md +59 -0
  78. package/docs/client-generation.md +100 -0
  79. package/docs/cluster.md +81 -0
  80. package/docs/custom-decorators.md +1 -7
  81. package/docs/dashboard.md +54 -0
  82. package/docs/debug.md +58 -0
  83. package/docs/extensions.md +0 -2
  84. package/docs/guide.md +0 -1
  85. package/docs/lifecycle.md +72 -0
  86. package/docs/testing.md +110 -0
  87. package/docs/zh/async-module.md +98 -0
  88. package/docs/zh/client-generation.md +92 -0
  89. package/docs/zh/cluster.md +74 -0
  90. package/docs/zh/custom-decorators.md +1 -7
  91. package/docs/zh/dashboard.md +69 -0
  92. package/docs/zh/debug.md +81 -0
  93. package/docs/zh/extensions.md +0 -2
  94. package/docs/zh/guide.md +0 -1
  95. package/docs/zh/lifecycle.md +87 -0
  96. package/docs/zh/migration.md +0 -5
  97. package/docs/zh/testing.md +119 -0
  98. package/package.json +4 -4
  99. package/src/cache/cache-module.ts +25 -0
  100. package/src/client/generator.ts +36 -0
  101. package/src/client/index.ts +8 -0
  102. package/src/client/runtime.ts +101 -0
  103. package/src/client/types.ts +38 -0
  104. package/src/config/config-module.ts +44 -4
  105. package/src/config/index.ts +1 -0
  106. package/src/config/service.ts +50 -0
  107. package/src/config/types.ts +12 -0
  108. package/src/core/application.ts +37 -0
  109. package/src/core/apply-decorators.ts +31 -0
  110. package/src/core/cluster.ts +143 -0
  111. package/src/core/index.ts +1 -0
  112. package/src/core/server.ts +14 -1
  113. package/src/dashboard/controller.ts +227 -0
  114. package/src/dashboard/dashboard-extension.ts +26 -0
  115. package/src/dashboard/dashboard-module.ts +38 -0
  116. package/src/dashboard/index.ts +3 -0
  117. package/src/dashboard/types.ts +16 -0
  118. package/src/dashboard/ui.ts +219 -0
  119. package/src/database/database-module.ts +20 -0
  120. package/src/debug/debug-module.ts +70 -0
  121. package/src/debug/debug-ui-middleware.ts +110 -0
  122. package/src/debug/index.ts +9 -0
  123. package/src/debug/middleware.ts +126 -0
  124. package/src/debug/recorder.ts +141 -0
  125. package/src/debug/types.ts +49 -0
  126. package/src/debug/ui.ts +393 -0
  127. package/src/di/async-module.ts +141 -0
  128. package/src/di/lifecycle.ts +117 -0
  129. package/src/di/module-registry.ts +75 -0
  130. package/src/index.ts +35 -0
  131. package/src/router/route.ts +20 -20
  132. package/src/swagger/generator.ts +100 -0
  133. package/src/testing/test-client.ts +112 -0
  134. package/src/testing/testing-module.ts +238 -0
  135. package/src/websocket/registry.ts +3 -16
  136. package/tests/auth/auth-decorators.test.ts +0 -1
  137. package/tests/auth/oauth2-service.test.ts +0 -1
  138. package/tests/cache/cache-decorators-extended.test.ts +0 -1
  139. package/tests/cache/cache-decorators.test.ts +0 -1
  140. package/tests/cache/cache-interceptors.test.ts +0 -1
  141. package/tests/cache/cache-module.test.ts +0 -1
  142. package/tests/cache/cache-service-proxy.test.ts +0 -1
  143. package/tests/client/client-generator.test.ts +142 -0
  144. package/tests/config/config-center-integration.test.ts +0 -1
  145. package/tests/config/config-module-extended.test.ts +0 -1
  146. package/tests/config/config-module.test.ts +0 -1
  147. package/tests/controller/controller.test.ts +0 -1
  148. package/tests/controller/param-binder.test.ts +0 -1
  149. package/tests/controller/path-combination.test.ts +0 -1
  150. package/tests/core/application.test.ts +34 -0
  151. package/tests/core/apply-decorators.test.ts +109 -0
  152. package/tests/core/cluster.test.ts +32 -0
  153. package/tests/dashboard/dashboard-module.test.ts +85 -0
  154. package/tests/database/database-module.test.ts +0 -1
  155. package/tests/database/orm.test.ts +0 -1
  156. package/tests/database/postgres-mysql-integration.test.ts +0 -1
  157. package/tests/database/transaction.test.ts +0 -1
  158. package/tests/debug/debug-module.test.ts +141 -0
  159. package/tests/di/async-module.test.ts +125 -0
  160. package/tests/di/container.test.ts +0 -1
  161. package/tests/di/lifecycle.test.ts +140 -0
  162. package/tests/error/error-handler.test.ts +0 -1
  163. package/tests/events/event-decorators.test.ts +0 -1
  164. package/tests/events/event-listener-scanner.test.ts +0 -1
  165. package/tests/events/event-module.test.ts +0 -1
  166. package/tests/extensions/logger-module.test.ts +0 -1
  167. package/tests/health/health-module.test.ts +0 -1
  168. package/tests/integration/oauth2-e2e.test.ts +0 -1
  169. package/tests/integration/session-e2e.test.ts +0 -1
  170. package/tests/interceptor/base-interceptor.test.ts +0 -1
  171. package/tests/interceptor/builtin/cache-interceptor.test.ts +0 -1
  172. package/tests/interceptor/builtin/log-interceptor.test.ts +0 -1
  173. package/tests/interceptor/builtin/permission-interceptor.test.ts +0 -1
  174. package/tests/interceptor/interceptor-advanced-integration.test.ts +0 -1
  175. package/tests/interceptor/interceptor-chain.test.ts +0 -1
  176. package/tests/interceptor/interceptor-integration.test.ts +0 -1
  177. package/tests/interceptor/interceptor-metadata.test.ts +0 -1
  178. package/tests/interceptor/interceptor-registry.test.ts +0 -1
  179. package/tests/interceptor/perf/interceptor-performance.test.ts +0 -1
  180. package/tests/metrics/metrics-module.test.ts +0 -1
  181. package/tests/microservice/config-center.test.ts +0 -1
  182. package/tests/microservice/service-client-decorators.test.ts +0 -1
  183. package/tests/microservice/service-registry-decorators.test.ts +0 -1
  184. package/tests/microservice/service-registry.test.ts +0 -1
  185. package/tests/middleware/builtin/middleware-builtin-extended.test.ts +0 -1
  186. package/tests/middleware/builtin/rate-limit.test.ts +0 -1
  187. package/tests/middleware/middleware-decorators.test.ts +0 -1
  188. package/tests/middleware/middleware-pipeline.test.ts +0 -1
  189. package/tests/middleware/middleware.test.ts +0 -1
  190. package/tests/perf/optimization.test.ts +0 -1
  191. package/tests/queue/queue-decorators.test.ts +0 -1
  192. package/tests/queue/queue-module.test.ts +0 -1
  193. package/tests/queue/queue-service.test.ts +0 -1
  194. package/tests/router/router-decorators.test.ts +0 -1
  195. package/tests/router/router-extended.test.ts +0 -1
  196. package/tests/security/guards/guards-integration.test.ts +0 -1
  197. package/tests/security/guards/guards.test.ts +0 -1
  198. package/tests/security/guards/reflector.test.ts +0 -1
  199. package/tests/security/security-filter.test.ts +0 -1
  200. package/tests/security/security-module-extended.test.ts +0 -1
  201. package/tests/security/security-module.test.ts +0 -1
  202. package/tests/session/session-decorators.test.ts +0 -1
  203. package/tests/session/session-module.test.ts +0 -1
  204. package/tests/swagger/decorators.test.ts +0 -1
  205. package/tests/swagger/swagger-module.test.ts +0 -1
  206. package/tests/swagger/ui.test.ts +0 -1
  207. package/tests/testing/testing-module.test.ts +129 -0
  208. package/tests/validation/class-validator.test.ts +0 -1
  209. package/tests/validation/controller-validation.test.ts +0 -1
@@ -0,0 +1,72 @@
1
+ # Lifecycle Hooks
2
+
3
+ Bun Server supports lifecycle hooks that let providers participate in application startup and shutdown. Implement the appropriate interface on your injectable services.
4
+
5
+ ## Interfaces
6
+
7
+ | Interface | Method | When Called |
8
+ |-----------|--------|-------------|
9
+ | `OnModuleInit` | `onModuleInit()` | After all module providers are registered |
10
+ | `OnModuleDestroy` | `onModuleDestroy()` | During shutdown (reverse order) |
11
+ | `OnApplicationBootstrap` | `onApplicationBootstrap()` | After all modules init, before server listens |
12
+ | `OnApplicationShutdown` | `onApplicationShutdown(signal?)` | When graceful shutdown begins |
13
+
14
+ ## Execution Order
15
+
16
+ **Startup**: `onModuleInit` (all modules) -> `onApplicationBootstrap` (all modules) -> server starts
17
+
18
+ **Shutdown**: `onApplicationShutdown` (reverse order) -> `onModuleDestroy` (reverse order)
19
+
20
+ ## Example: DatabaseService with init/destroy
21
+
22
+ ```ts
23
+ import {
24
+ Injectable,
25
+ OnModuleInit,
26
+ OnModuleDestroy,
27
+ } from '@dangao/bun-server';
28
+
29
+ @Injectable()
30
+ class DatabaseService implements OnModuleInit, OnModuleDestroy {
31
+ private connected = false;
32
+
33
+ public async onModuleInit(): Promise<void> {
34
+ console.log('[DatabaseService] Connecting...');
35
+ await this.connect();
36
+ this.connected = true;
37
+ }
38
+
39
+ public async onModuleDestroy(): Promise<void> {
40
+ console.log('[DatabaseService] Closing connection...');
41
+ await this.disconnect();
42
+ this.connected = false;
43
+ }
44
+
45
+ public isConnected(): boolean {
46
+ return this.connected;
47
+ }
48
+
49
+ private async connect(): Promise<void> {
50
+ // Open DB connection
51
+ }
52
+
53
+ private async disconnect(): Promise<void> {
54
+ // Close DB connection
55
+ }
56
+ }
57
+ ```
58
+
59
+ ## Example: Application-level hooks
60
+
61
+ ```ts
62
+ @Injectable()
63
+ class AppService implements OnApplicationBootstrap, OnApplicationShutdown {
64
+ public onApplicationBootstrap(): void {
65
+ console.log('Application bootstrapped');
66
+ }
67
+
68
+ public onApplicationShutdown(signal?: string): void {
69
+ console.log(`Shutting down (signal: ${signal ?? 'none'})`);
70
+ }
71
+ }
72
+ ```
@@ -0,0 +1,110 @@
1
+ # Testing Module
2
+
3
+ The Testing Module provides utilities for unit and integration testing of Bun Server applications. Use `Test.createTestingModule()` to build an isolated test environment with provider overrides.
4
+
5
+ ## API Overview
6
+
7
+ ### Test.createTestingModule()
8
+
9
+ Creates a test module builder with the given module metadata (controllers, providers, imports).
10
+
11
+ ```ts
12
+ const builder = Test.createTestingModule({
13
+ controllers: [UserController],
14
+ providers: [UserService],
15
+ });
16
+ ```
17
+
18
+ ### overrideProvider().useValue() / .useClass() / .useFactory()
19
+
20
+ Override a provider with a mock or alternative implementation:
21
+
22
+ ```ts
23
+ const module = await Test.createTestingModule({
24
+ controllers: [GreetController],
25
+ providers: [{ provide: GREETER_TOKEN, useClass: RealGreeter }],
26
+ })
27
+ .overrideProvider(GREETER_TOKEN)
28
+ .useValue(mockGreeter) // or .useClass(MockGreeter) or .useFactory(() => mock)
29
+ .compile();
30
+ ```
31
+
32
+ - **useValue**: Replace with a fixed value (e.g. mock object)
33
+ - **useClass**: Replace with an alternative class
34
+ - **useFactory**: Replace with a factory function
35
+
36
+ ### TestingModule.get()
37
+
38
+ Resolve a provider from the DI container:
39
+
40
+ ```ts
41
+ const service = module.get(UserService);
42
+ ```
43
+
44
+ ### TestingModule.createApplication()
45
+
46
+ Create an `Application` instance with all providers and controllers registered. Does not start the server.
47
+
48
+ ```ts
49
+ const app = module.createApplication({ port: 0 });
50
+ ```
51
+
52
+ ### TestingModule.createHttpClient()
53
+
54
+ Creates an `Application`, starts it on a random port, and returns a `TestHttpClient` for HTTP requests.
55
+
56
+ ```ts
57
+ const client = await module.createHttpClient();
58
+ const res = await client.get('/api/users');
59
+ await client.close();
60
+ ```
61
+
62
+ ### TestHttpClient Methods
63
+
64
+ | Method | Description |
65
+ |--------|-------------|
66
+ | `get(path, options?)` | GET request |
67
+ | `post(path, options?)` | POST request |
68
+ | `put(path, options?)` | PUT request |
69
+ | `delete(path, options?)` | DELETE request |
70
+ | `patch(path, options?)` | PATCH request |
71
+ | `close()` | Stop the test server |
72
+
73
+ Options support `headers`, `body`, and `query`.
74
+
75
+ ## Example with bun:test
76
+
77
+ ```ts
78
+ import { describe, expect, test } from 'bun:test';
79
+ import { Test, Controller, GET, Inject } from '@dangao/bun-server';
80
+
81
+ const GREETER_TOKEN = Symbol('Greeter');
82
+
83
+ @Controller('/api')
84
+ class GreetController {
85
+ public constructor(@Inject(GREETER_TOKEN) private greeter: { greet: (s: string) => string }) {}
86
+
87
+ @GET('/greet')
88
+ public greet(): object {
89
+ return { message: this.greeter.greet('World') };
90
+ }
91
+ }
92
+
93
+ describe('GreetController', () => {
94
+ test('should return mock greeting', async () => {
95
+ const mockGreeter = { greet: (name: string) => `Mock: ${name}` };
96
+
97
+ const module = await Test.createTestingModule({
98
+ controllers: [GreetController],
99
+ providers: [{ provide: GREETER_TOKEN, useValue: mockGreeter }],
100
+ }).compile();
101
+
102
+ const client = await module.createHttpClient();
103
+ const res = await client.get('/api/greet');
104
+ await client.close();
105
+
106
+ expect(res.status).toBe(200);
107
+ expect(res.body).toEqual({ message: 'Mock: World' });
108
+ });
109
+ });
110
+ ```
@@ -0,0 +1,98 @@
1
+ # 异步模块配置
2
+
3
+ 当模块配置需要异步加载(如远程配置中心、密钥库、数据库连接等)时,可使用 `forRootAsync()` 模式。
4
+
5
+ ## AsyncModuleOptions 接口
6
+
7
+ ```ts
8
+ interface AsyncModuleOptions<T> {
9
+ imports?: ModuleClass[]; // 需要导入的模块(提供 inject 依赖)
10
+ inject?: ProviderToken[]; // 注入到 useFactory 的 provider tokens
11
+ useFactory: (...deps: unknown[]) => T | Promise<T>; // 异步工厂函数
12
+ }
13
+ ```
14
+
15
+ ## 支持的模块
16
+
17
+ - **ConfigModule**:异步加载配置
18
+ - **DatabaseModule**:异步配置数据库连接
19
+ - **CacheModule**:异步配置缓存(如 Redis 连接)
20
+
21
+ ## 示例:ConfigModule.forRootAsync
22
+
23
+ ```ts
24
+ import {
25
+ Application,
26
+ ConfigModule,
27
+ ConfigService,
28
+ CONFIG_SERVICE_TOKEN,
29
+ Controller,
30
+ GET,
31
+ Inject,
32
+ Module,
33
+ } from '@dangao/bun-server';
34
+
35
+ async function loadRemoteConfig(): Promise<{ app: { name: string; port: number } }> {
36
+ console.log('[Config] 正在加载远程配置...');
37
+ await new Promise((resolve) => setTimeout(resolve, 200));
38
+ return {
39
+ app: { name: 'AsyncConfigApp', port: 3000 },
40
+ };
41
+ }
42
+
43
+ @Controller('/api')
44
+ class AppController {
45
+ public constructor(
46
+ @Inject(CONFIG_SERVICE_TOKEN) private readonly config: ConfigService,
47
+ ) {}
48
+
49
+ @GET('/config')
50
+ public getConfig(): object {
51
+ return {
52
+ name: this.config.get('app.name'),
53
+ port: this.config.get('app.port'),
54
+ };
55
+ }
56
+ }
57
+
58
+ @Module({
59
+ imports: [
60
+ ConfigModule.forRootAsync({
61
+ useFactory: async () => {
62
+ const remoteConfig = await loadRemoteConfig();
63
+ return { defaultConfig: remoteConfig };
64
+ },
65
+ }),
66
+ ],
67
+ controllers: [AppController],
68
+ })
69
+ class AppModule {}
70
+
71
+ const app = new Application({ port: 3000 });
72
+ app.registerModule(AppModule);
73
+ await app.listen();
74
+ ```
75
+
76
+ ## 示例:DatabaseModule.forRootAsync 配合 ConfigService
77
+
78
+ ```ts
79
+ import { ConfigModule, CONFIG_SERVICE_TOKEN } from '@dangao/bun-server';
80
+ import type { ConfigService } from '@dangao/bun-server';
81
+
82
+ @Module({
83
+ imports: [
84
+ ConfigModule.forRoot({ defaultConfig: { db: { url: '...' } } }),
85
+ DatabaseModule.forRootAsync({
86
+ imports: [ConfigModule],
87
+ inject: [CONFIG_SERVICE_TOKEN],
88
+ useFactory: (config: ConfigService) => ({
89
+ url: config.get<string>('db.url'),
90
+ // 其他数据库配置
91
+ }),
92
+ }),
93
+ ],
94
+ })
95
+ class AppModule {}
96
+ ```
97
+
98
+ 异步 provider 在 `Application.listen()` 期间顺序初始化,确保在应用开始处理请求前配置已就绪。
@@ -0,0 +1,92 @@
1
+ # 类型安全客户端生成
2
+
3
+ Bun Server 支持从服务端路由自动生成类型安全的 API 客户端,便于前端或微服务调用。
4
+
5
+ ## ClientGenerator.generate()
6
+
7
+ 从当前已注册的 `RouteRegistry` 提取路由清单:
8
+
9
+ ```ts
10
+ import { ClientGenerator } from '@dangao/bun-server';
11
+
12
+ const manifest = ClientGenerator.generate();
13
+ // { routes: [{ method, path, controllerName, methodName }, ...] }
14
+ ```
15
+
16
+ ## createClient(manifest, config)
17
+
18
+ 根据清单和配置创建 API 客户端:
19
+
20
+ ```ts
21
+ import { createClient } from '@dangao/bun-server';
22
+
23
+ const client = createClient(manifest, {
24
+ baseUrl: 'http://localhost:3001',
25
+ headers: { 'X-API-Key': 'xxx' },
26
+ });
27
+ ```
28
+
29
+ ## 客户端结构
30
+
31
+ 客户端按控制器名称分组(去除 `Controller` 后缀并首字母小写),每个方法名对应一个函数:
32
+
33
+ - `UserController` → `client.user`
34
+ - `getUser` → `client.user.getUser({ params: { id: '1' } })`
35
+
36
+ ## 完整示例
37
+
38
+ ```ts
39
+ import {
40
+ Application,
41
+ Controller,
42
+ GET,
43
+ POST,
44
+ Param,
45
+ Body,
46
+ Module,
47
+ ClientGenerator,
48
+ createClient,
49
+ } from '@dangao/bun-server';
50
+
51
+ @Controller('/api/users')
52
+ class UserController {
53
+ @GET('/')
54
+ public listUsers(): object {
55
+ return [{ id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }];
56
+ }
57
+
58
+ @GET('/:id')
59
+ public getUser(@Param('id') id: string): object {
60
+ return { id, name: 'Alice' };
61
+ }
62
+
63
+ @POST('/')
64
+ public createUser(@Body() body: unknown): object {
65
+ return { ...(body as object), id: '3' };
66
+ }
67
+ }
68
+
69
+ @Module({ controllers: [UserController] })
70
+ class AppModule {}
71
+
72
+ const app = new Application({ port: 3001, enableSignalHandlers: false });
73
+ app.registerModule(AppModule);
74
+ await app.listen();
75
+
76
+ // 从已注册控制器生成路由清单
77
+ const manifest = ClientGenerator.generate();
78
+
79
+ // 创建类型安全客户端
80
+ const client = createClient(manifest, {
81
+ baseUrl: 'http://localhost:3001',
82
+ });
83
+
84
+ // 调用 API
85
+ const users = await client.user.listUsers();
86
+ const user = await client.user.getUser({ params: { id: '42' } });
87
+ const newUser = await client.user.createUser({ body: { name: 'Charlie' } });
88
+
89
+ await app.stop();
90
+ ```
91
+
92
+ `ClientRequestOptions` 支持 `params`、`query`、`body`、`headers`,路径中的 `:id` 等占位符会通过 `params` 自动替换。
@@ -0,0 +1,74 @@
1
+ # 零配置集群
2
+
3
+ `ClusterManager` 提供零配置集群模式,自动派生多个 worker 进程,利用多核 CPU 提升吞吐量。
4
+
5
+ ## ClusterManager 类
6
+
7
+ ```ts
8
+ import { ClusterManager } from '@dangao/bun-server';
9
+
10
+ const manager = new ClusterManager({
11
+ workers: 'auto', // 或具体数字,'auto' 表示 CPU 核心数
12
+ scriptPath: import.meta.path,
13
+ port: 3300,
14
+ hostname: '0.0.0.0', // 可选
15
+ });
16
+
17
+ manager.start();
18
+ ```
19
+
20
+ ## 主进程 / 工作进程
21
+
22
+ - **ClusterManager.isWorker()**:判断当前进程是否为 worker
23
+ - **ClusterManager.getWorkerId()**:获取当前 worker ID(仅 worker 进程有效,主进程返回 -1)
24
+
25
+ 主进程负责派生 worker,worker 进程运行应用逻辑。每个 worker 使用 `reusePort` 绑定同一端口。
26
+
27
+ ## Linux reusePort 限制
28
+
29
+ `reusePort`(SO_REUSEPORT)仅在 **Linux** 上有效。macOS 和 Windows 会忽略该选项,多 worker 将无法共享同一端口,需在对应系统上单独验证行为。
30
+
31
+ ## 使用示例
32
+
33
+ ```ts
34
+ import { ClusterManager, Application, Controller, GET, Module } from '@dangao/bun-server';
35
+
36
+ const PORT = Number(process.env.PORT ?? 3300);
37
+
38
+ if (!ClusterManager.isWorker()) {
39
+ // 主进程:派生 worker
40
+ const manager = new ClusterManager({
41
+ workers: process.env.WORKERS ? Number(process.env.WORKERS) : 'auto',
42
+ scriptPath: import.meta.path,
43
+ port: PORT,
44
+ });
45
+ manager.start();
46
+
47
+ process.on('SIGINT', async () => {
48
+ await manager.stop();
49
+ process.exit(0);
50
+ });
51
+ } else {
52
+ // Worker 进程:运行应用
53
+ @Controller('/api')
54
+ class PerfController {
55
+ @GET('/ping')
56
+ public ping(): object {
57
+ return { pong: true, worker: ClusterManager.getWorkerId() };
58
+ }
59
+ }
60
+
61
+ @Module({ controllers: [PerfController] })
62
+ class WorkerModule {}
63
+
64
+ const app = new Application({
65
+ port: PORT,
66
+ reusePort: true,
67
+ enableSignalHandlers: true,
68
+ });
69
+ app.registerModule(WorkerModule);
70
+ await app.listen();
71
+ }
72
+ ```
73
+
74
+ Worker 异常退出时,主进程会自动重启对应 worker。
@@ -29,12 +29,10 @@ AOP(面向切面编程)。这使您能够添加横切关注点,如缓存
29
29
 
30
30
  ### 基本装饰器模式
31
31
 
32
- 自定义装饰器是一个返回 `MethodDecorator` 的函数。它使用 `reflect-metadata`
32
+ 自定义装饰器是一个返回 `MethodDecorator` 的函数。它使用 Reflect 元数据 API
33
33
  在方法上存储元数据。
34
34
 
35
35
  ```typescript
36
- import "reflect-metadata";
37
-
38
36
  // 1. 定义元数据键(使用 Symbol 确保唯一性)
39
37
  export const MY_METADATA_KEY = Symbol("@my-app:my-decorator");
40
38
 
@@ -280,8 +278,6 @@ class MyInterceptor extends BaseInterceptor {
280
278
  ### 存储元数据
281
279
 
282
280
  ```typescript
283
- import "reflect-metadata";
284
-
285
281
  const METADATA_KEY = Symbol("my-metadata");
286
282
 
287
283
  // 存储元数据
@@ -364,7 +360,6 @@ class MyInterceptor extends BaseInterceptor {
364
360
  ### 示例 1:简单日志拦截器
365
361
 
366
362
  ```typescript
367
- import 'reflect-metadata';
368
363
  import { BaseInterceptor } from '@dangao/bun-server';
369
364
  import type { Container } from '@dangao/bun-server';
370
365
  import type { Context } from '@dangao/bun-server';
@@ -402,7 +397,6 @@ export class LogInterceptor extends BaseInterceptor {
402
397
  ### 示例 2:限流拦截器
403
398
 
404
399
  ```typescript
405
- import 'reflect-metadata';
406
400
  import { BaseInterceptor, HttpException } from '@dangao/bun-server';
407
401
  import type { Container } from '@dangao/bun-server';
408
402
  import type { Context } from '@dangao/bun-server';
@@ -0,0 +1,69 @@
1
+ # 监控仪表盘模块
2
+
3
+ `DashboardModule` 提供 Web UI 和 API,用于监控应用状态、路由和健康检查。
4
+
5
+ ## 配置
6
+
7
+ ```ts
8
+ import { DashboardModule } from '@dangao/bun-server';
9
+
10
+ DashboardModule.forRoot({
11
+ path: '/_dashboard', // UI 路径,默认 /_dashboard
12
+ auth: { // 可选,Basic Auth
13
+ username: 'admin',
14
+ password: 'admin',
15
+ },
16
+ });
17
+ ```
18
+
19
+ ## 可用端点
20
+
21
+ - **UI**:`GET /_dashboard`,监控仪表盘主页面
22
+ - **系统信息**:`GET /_dashboard/api/system`,运行时间、内存、平台、Bun 版本
23
+ - **路由列表**:`GET /_dashboard/api/routes`,已注册路由及控制器、方法名
24
+ - **健康检查**:`GET /_dashboard/api/health`,若已注册 HealthModule 则执行健康指示器
25
+
26
+ ## Basic Auth
27
+
28
+ 配置 `auth` 后,访问上述端点需提供 Basic 认证。未配置时无需认证。
29
+
30
+ ## 使用示例
31
+
32
+ ```ts
33
+ import {
34
+ Application,
35
+ Controller,
36
+ GET,
37
+ Module,
38
+ DashboardModule,
39
+ } from '@dangao/bun-server';
40
+
41
+ @Controller('/api')
42
+ class AppController {
43
+ @GET('/hello')
44
+ public hello(): object {
45
+ return { message: 'Hello from Dashboard!' };
46
+ }
47
+ }
48
+
49
+ @Module({
50
+ imports: [
51
+ DashboardModule.forRoot({
52
+ path: '/_dashboard',
53
+ auth: { username: 'admin', password: 'admin' },
54
+ }),
55
+ ],
56
+ controllers: [AppController],
57
+ })
58
+ class AppModule {}
59
+
60
+ const app = new Application({ port: 3000 });
61
+ app.registerModule(AppModule);
62
+ await app.listen();
63
+ // Dashboard UI: http://localhost:3000/_dashboard
64
+ // 认证:admin / admin
65
+ ```
66
+
67
+ ## UI 界面
68
+
69
+ 仪表盘 UI 展示系统信息、路由列表和健康状态,便于运维和调试。
@@ -0,0 +1,81 @@
1
+ # 调试与请求重放模块
2
+
3
+ `DebugModule` 在开发模式下录制 HTTP 请求,支持查看和重放,便于调试和问题复现。
4
+
5
+ ## 配置
6
+
7
+ ```ts
8
+ import { DebugModule } from '@dangao/bun-server';
9
+
10
+ DebugModule.forRoot({
11
+ enabled: true, // 是否启用,默认 true
12
+ maxRecords: 500, // 最大录制数(环形缓冲区),默认 500
13
+ recordBody: true, // 是否录制请求体,默认 true
14
+ path: '/_debug', // Debug UI 路径,默认 /_debug
15
+ });
16
+ ```
17
+
18
+ ## 录制内容
19
+
20
+ 每条记录包含:
21
+
22
+ - **request**:方法、路径、头部、请求体(可选)
23
+ - **response**:状态码、响应头、响应体大小
24
+ - **timing**:总耗时
25
+ - **metadata**:匹配路由、控制器、方法名
26
+
27
+ ## Debug UI 端点
28
+
29
+ - **UI**:`GET /_debug`,调试界面
30
+ - **记录列表**:`GET /_debug/api/records`,获取所有录制
31
+ - **清空记录**:`DELETE /_debug/api/records`
32
+ - **单条记录**:`GET /_debug/api/records/:id`
33
+ - **请求重放**:`POST /_debug/api/replay/:id`,按原请求重放并返回结果
34
+
35
+ ## 使用示例
36
+
37
+ ```ts
38
+ import {
39
+ Application,
40
+ Controller,
41
+ GET,
42
+ POST,
43
+ Body,
44
+ Module,
45
+ DebugModule,
46
+ } from '@dangao/bun-server';
47
+
48
+ @Controller('/api')
49
+ class AppController {
50
+ @GET('/hello')
51
+ public hello(): object {
52
+ return { message: 'Hello!' };
53
+ }
54
+
55
+ @POST('/echo')
56
+ public echo(@Body() body: unknown): unknown {
57
+ return body;
58
+ }
59
+ }
60
+
61
+ @Module({
62
+ imports: [
63
+ DebugModule.forRoot({
64
+ enabled: true,
65
+ maxRecords: 100,
66
+ recordBody: true,
67
+ path: '/_debug',
68
+ }),
69
+ ],
70
+ controllers: [AppController],
71
+ })
72
+ class AppModule {}
73
+
74
+ const app = new Application({ port: 3000 });
75
+ app.registerModule(AppModule);
76
+ await app.listen();
77
+ // Debug UI: http://localhost:3000/_debug
78
+ // 发送请求后可在 UI 中查看录制并重放
79
+ ```
80
+
81
+ 建议仅在开发环境启用,生产环境可通过 `enabled: false` 关闭。
@@ -511,8 +511,6 @@ app.listen();
511
511
  ### 创建装饰器
512
512
 
513
513
  ```typescript
514
- import "reflect-metadata";
515
-
516
514
  // 缓存装饰器
517
515
  export function Cache(ttl: number) {
518
516
  return function (
package/docs/zh/guide.md CHANGED
@@ -15,7 +15,6 @@ HTTP 请求 → 中间件 → 安全 → 路由 → 拦截器(前置) → 验证
15
15
  ## 1. 初始化应用
16
16
 
17
17
  ```ts
18
- import "reflect-metadata";
19
18
  import { Application } from "@dangao/bun-server";
20
19
 
21
20
  const app = new Application({ port: 3000 });