@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
@@ -28,23 +28,21 @@ export declare class Route {
28
28
  */
29
29
  readonly methodName?: string;
30
30
  /**
31
- * 路径模式(用于匹配)
31
+ * 动态路由匹配用正则(比 URLPattern.exec() 快约 10 倍)
32
32
  */
33
- private readonly pattern;
33
+ private readonly pattern?;
34
34
  /**
35
- * 路径参数名列表
35
+ * 动态路由参数名列表
36
36
  */
37
- private readonly paramNames;
37
+ private readonly paramNames?;
38
38
  private readonly middlewarePipeline;
39
39
  private readonly staticKey?;
40
40
  readonly isStatic: boolean;
41
41
  constructor(method: HttpMethod, path: string, handler: RouteHandler, middlewares?: Middleware[], controllerClass?: Constructor<unknown>, methodName?: string);
42
42
  /**
43
43
  * 解析路径,生成匹配模式和参数名列表
44
- * @param path - 路由路径
45
- * @returns 匹配模式和参数名列表
46
44
  */
47
- private parsePath;
45
+ private static parsePath;
48
46
  /**
49
47
  * 匹配路由
50
48
  * @param method - HTTP 方法
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/router/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,qBAAa,KAAK;IAChB;;OAEG;IACH,SAAgB,MAAM,EAAE,UAAU,CAAC;IAEnC;;OAEG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,SAAgB,OAAO,EAAE,YAAY,CAAC;IAEtC;;OAEG;IACH,SAAgB,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAEvD;;OAEG;IACH,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IAEtC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,SAAgB,QAAQ,EAAE,OAAO,CAAC;gBAGhC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM;IAmBrB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAajB;;;;;OAKG;IACI,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU;IAqB1D;;;;OAIG;IACU,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQzD;;OAEG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;CAG1C"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/router/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,qBAAa,KAAK;IAChB;;OAEG;IACH,SAAgB,MAAM,EAAE,UAAU,CAAC;IAEnC;;OAEG;IACH,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,SAAgB,OAAO,EAAE,YAAY,CAAC;IAEtC;;OAEG;IACH,SAAgB,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAEvD;;OAEG;IACH,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAElC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAW;IAEvC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA4B;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAS;IACpC,SAAgB,QAAQ,EAAE,OAAO,CAAC;gBAGhC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,WAAW,GAAE,UAAU,EAAO,EAC9B,eAAe,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EACtC,UAAU,CAAC,EAAE,MAAM;IAmBrB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAYxB;;;;;OAKG;IACI,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU;IAwB1D;;;;OAIG;IACU,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAQzD;;OAEG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;CAG1C"}
@@ -9,6 +9,16 @@ export declare class SwaggerGenerator {
9
9
  * 生成 Swagger 文档
10
10
  */
11
11
  generate(): SwaggerDocument;
12
+ /**
13
+ * 生成 Markdown 格式的 API 文档
14
+ * 利用 Bun 1.3.8+ 原生 Bun.markdown 内置解析器
15
+ */
16
+ generateMarkdown(): string;
17
+ /**
18
+ * 生成 Markdown 并渲染为 HTML
19
+ * 利用 Bun.markdown.html() 进行高性能渲染
20
+ */
21
+ generateMarkdownHtml(): string;
12
22
  /**
13
23
  * 规范化路径
14
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/swagger/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAmB,MAAM,SAAS,CAAC;AAWhF;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAEtB,OAAO,EAAE,cAAc;IAI1C;;OAEG;IACI,QAAQ,IAAI,eAAe;IAgMlC;;OAEG;IACH,OAAO,CAAC,aAAa;CAatB"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/swagger/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAmB,MAAM,SAAS,CAAC;AAWhF;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAEtB,OAAO,EAAE,cAAc;IAI1C;;OAEG;IACI,QAAQ,IAAI,eAAe;IAgMlC;;;OAGG;IACI,gBAAgB,IAAI,MAAM;IAuFjC;;;OAGG;IACI,oBAAoB,IAAI,MAAM;IAKrC;;OAEG;IACH,OAAO,CAAC,aAAa;CAatB"}
@@ -0,0 +1,49 @@
1
+ import type { Application } from '../core/application';
2
+ interface RequestOptions {
3
+ headers?: Record<string, string>;
4
+ body?: unknown;
5
+ query?: Record<string, string>;
6
+ }
7
+ interface TestResponse {
8
+ status: number;
9
+ headers: Headers;
10
+ body: unknown;
11
+ text: string;
12
+ ok: boolean;
13
+ }
14
+ /**
15
+ * HTTP 测试客户端
16
+ * 基于 fetch API,提供简洁的 HTTP 请求方法
17
+ */
18
+ export declare class TestHttpClient {
19
+ private readonly baseUrl;
20
+ private readonly app;
21
+ constructor(baseUrl: string, app: Application);
22
+ /**
23
+ * 发送 GET 请求
24
+ */
25
+ get(path: string, options?: RequestOptions): Promise<TestResponse>;
26
+ /**
27
+ * 发送 POST 请求
28
+ */
29
+ post(path: string, options?: RequestOptions): Promise<TestResponse>;
30
+ /**
31
+ * 发送 PUT 请求
32
+ */
33
+ put(path: string, options?: RequestOptions): Promise<TestResponse>;
34
+ /**
35
+ * 发送 DELETE 请求
36
+ */
37
+ delete(path: string, options?: RequestOptions): Promise<TestResponse>;
38
+ /**
39
+ * 发送 PATCH 请求
40
+ */
41
+ patch(path: string, options?: RequestOptions): Promise<TestResponse>;
42
+ /**
43
+ * 关闭测试服务器
44
+ */
45
+ close(): Promise<void>;
46
+ private request;
47
+ }
48
+ export {};
49
+ //# sourceMappingURL=test-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-client.d.ts","sourceRoot":"","sources":["../../src/testing/test-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;CACb;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAEf,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW;IAKpD;;OAEG;IACU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/E;;OAEG;IACU,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAIhF;;OAEG;IACU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/E;;OAEG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAIlF;;OAEG;IACU,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAIjF;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIrB,OAAO;CAwCtB"}
@@ -0,0 +1,90 @@
1
+ import 'reflect-metadata';
2
+ import { Application, type ApplicationOptions } from '../core/application';
3
+ import { Container } from '../di/container';
4
+ import { type ModuleMetadata, type ModuleProvider, type ProviderToken } from '../di/module';
5
+ import type { Constructor } from '../core/types';
6
+ import { TestHttpClient } from './test-client';
7
+ interface ProviderOverride {
8
+ token: ProviderToken;
9
+ useValue?: unknown;
10
+ useClass?: Constructor<unknown>;
11
+ useFactory?: () => unknown;
12
+ }
13
+ /**
14
+ * 测试模块构建器
15
+ * 提供流畅的 API 来创建测试用的隔离模块环境
16
+ */
17
+ export declare class TestingModuleBuilder {
18
+ private readonly metadata;
19
+ private readonly overrides;
20
+ constructor(metadata: ModuleMetadata);
21
+ /**
22
+ * 覆盖指定 provider
23
+ * @param token - 要覆盖的 provider token
24
+ */
25
+ overrideProvider(token: ProviderToken): ProviderOverrideBuilder;
26
+ /**
27
+ * 编译测试模块,返回可用的 TestingModule 实例
28
+ */
29
+ compile(): Promise<TestingModule>;
30
+ private buildProviders;
31
+ }
32
+ declare class ProviderOverrideBuilder {
33
+ private readonly builder;
34
+ private readonly token;
35
+ constructor(builder: TestingModuleBuilder, token: ProviderToken);
36
+ /**
37
+ * 使用固定值覆盖
38
+ */
39
+ useValue(value: unknown): TestingModuleBuilder;
40
+ /**
41
+ * 使用替代类覆盖
42
+ */
43
+ useClass(cls: Constructor<unknown>): TestingModuleBuilder;
44
+ /**
45
+ * 使用工厂函数覆盖
46
+ */
47
+ useFactory(factory: () => unknown): TestingModuleBuilder;
48
+ }
49
+ /**
50
+ * 编译后的测试模块
51
+ * 提供 DI 容器访问和 HTTP 测试客户端创建
52
+ */
53
+ export declare class TestingModule {
54
+ private readonly metadata;
55
+ private readonly providers;
56
+ private readonly overrides;
57
+ private app?;
58
+ private container?;
59
+ constructor(metadata: ModuleMetadata, providers: ModuleProvider[], overrides: ProviderOverride[]);
60
+ /**
61
+ * 从容器中获取 provider 实例
62
+ */
63
+ get<T>(token: Constructor<T> | string | symbol): T;
64
+ /**
65
+ * 创建一个 Application 实例并注册所有 providers、controllers
66
+ * @param options - 应用配置
67
+ */
68
+ createApplication(options?: ApplicationOptions): Application;
69
+ /**
70
+ * 创建 HTTP 测试客户端
71
+ * 自动启动应用,获取随机端口,返回 TestHttpClient
72
+ */
73
+ createHttpClient(options?: ApplicationOptions): Promise<TestHttpClient>;
74
+ /**
75
+ * 获取 DI 容器
76
+ */
77
+ getContainer(): Container;
78
+ }
79
+ /**
80
+ * 测试工具入口
81
+ */
82
+ export declare class Test {
83
+ /**
84
+ * 创建测试模块
85
+ * @param metadata - 模块元数据
86
+ */
87
+ static createTestingModule(metadata: ModuleMetadata): TestingModuleBuilder;
88
+ }
89
+ export {};
90
+ //# sourceMappingURL=testing-module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing-module.d.ts","sourceRoot":"","sources":["../../src/testing/testing-module.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAuB,KAAK,cAAc,EAAoB,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACnI,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,UAAU,gBAAgB;IACxB,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAEjC,QAAQ,EAAE,cAAc;IAI3C;;;OAGG;IACI,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,uBAAuB;IAItE;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IAU9C,OAAO,CAAC,cAAc;CA0CvB;AAED,cAAM,uBAAuB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAEnB,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,aAAa;IAKtE;;OAEG;IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB;IAKrD;;OAEG;IACI,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,oBAAoB;IAKhE;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,MAAM,OAAO,GAAG,oBAAoB;CAIhE;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,GAAG,CAAC,CAAc;IAC1B,OAAO,CAAC,SAAS,CAAC,CAAY;gBAG5B,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,cAAc,EAAE,EAC3B,SAAS,EAAE,gBAAgB,EAAE;IAO/B;;OAEG;IACI,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC;IAIzD;;;OAGG;IACI,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW;IA2CvE;;;OAGG;IACU,gBAAgB,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,cAAc,CAAC;IAQxF;;OAEG;IACI,YAAY,IAAI,SAAS;CAKjC;AAED;;GAEG;AACH,qBAAa,IAAI;IACf;;;OAGG;WACW,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,oBAAoB;CAGlF"}
@@ -15,12 +15,7 @@ export declare class WebSocketGatewayRegistry {
15
15
  private readonly dynamicGateways;
16
16
  private constructor();
17
17
  static getInstance(): WebSocketGatewayRegistry;
18
- /**
19
- * 解析路径,生成匹配模式和参数名列表
20
- * @param path - 路由路径
21
- * @returns 匹配模式和参数名列表
22
- */
23
- private parsePath;
18
+ private static parsePath;
24
19
  register(gatewayClass: Constructor<unknown>): void;
25
20
  /**
26
21
  * 检查是否有匹配的网关(支持动态路径匹配)
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/websocket/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAO3C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAehD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA2B;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2B;IAE3D,OAAO;WAIO,WAAW,IAAI,wBAAwB;IAOrD;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAaV,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI;IAsCzD;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAgBjC,KAAK,IAAI,IAAI;IAMpB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAuBlB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;OAMG;YACW,aAAa;IA0Gd,UAAU,CAAC,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvE,aAAa,CACxB,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,EAC5C,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,GAC9C,OAAO,CAAC,IAAI,CAAC;IAcH,WAAW,CACtB,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;CAQjB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/websocket/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAO3C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAehD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,qBAAa,wBAAwB;IACnC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA2B;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2B;IAE3D,OAAO;WAIO,WAAW,IAAI,wBAAwB;IAOrD,OAAO,CAAC,MAAM,CAAC,SAAS;IAYjB,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI;IAoCzD;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAcjC,KAAK,IAAI,IAAI;IAMpB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAoBlB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;OAMG;YACW,aAAa;IA0Gd,UAAU,CAAC,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvE,aAAa,CACxB,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,EAC5C,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,eAAe,GAC9C,OAAO,CAAC,IAAI,CAAC;IAcH,WAAW,CACtB,EAAE,EAAE,eAAe,CAAC,uBAAuB,CAAC,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;CAQjB"}
@@ -0,0 +1,59 @@
1
+ # Async Module Configuration
2
+
3
+ Some modules support `forRootAsync()` for configuration that depends on asynchronous sources (remote config, secrets, database lookups). The async factory runs during `Application.listen()` before the server starts.
4
+
5
+ ## AsyncModuleOptions<T>
6
+
7
+ ```ts
8
+ interface AsyncModuleOptions<T> {
9
+ imports?: ModuleClass[]; // Modules providing inject dependencies
10
+ inject?: ProviderToken[]; // Tokens to inject into useFactory
11
+ useFactory: (...deps: unknown[]) => T | Promise<T>;
12
+ }
13
+ ```
14
+
15
+ ## Available Modules
16
+
17
+ - **ConfigModule** – Load config from remote sources
18
+ - **DatabaseModule** – Get DB options from ConfigService or secrets
19
+ - **CacheModule** – Get cache config asynchronously
20
+
21
+ ## Example: ConfigModule.forRootAsync
22
+
23
+ ```ts
24
+ @Module({
25
+ imports: [
26
+ ConfigModule.forRootAsync({
27
+ useFactory: async () => {
28
+ const remoteConfig = await loadRemoteConfig();
29
+ return { defaultConfig: remoteConfig };
30
+ },
31
+ }),
32
+ ],
33
+ controllers: [AppController],
34
+ })
35
+ class AppModule {}
36
+ ```
37
+
38
+ ## Example: DatabaseModule.forRootAsync with ConfigService
39
+
40
+ ```ts
41
+ import { ConfigModule, CONFIG_SERVICE_TOKEN } from '@dangao/bun-server';
42
+
43
+ @Module({
44
+ imports: [
45
+ ConfigModule.forRoot({ defaultConfig: { db: { url: '...' } } }),
46
+ DatabaseModule.forRootAsync({
47
+ imports: [ConfigModule],
48
+ inject: [CONFIG_SERVICE_TOKEN],
49
+ useFactory: (config: ConfigService) => ({
50
+ url: config.get<string>('db.url'),
51
+ // ...other options
52
+ }),
53
+ }),
54
+ ],
55
+ })
56
+ class AppModule {}
57
+ ```
58
+
59
+ The `useFactory` receives resolved dependencies in the order of `inject`. Async providers are initialized sequentially during `listen()`.
@@ -0,0 +1,100 @@
1
+ # Type-Safe Client Generation
2
+
3
+ Generate a type-safe API client from your server's route manifest. The client is grouped by controller name and mirrors your controller methods.
4
+
5
+ ## Workflow
6
+
7
+ 1. Register controllers and start the application (or at least register routes)
8
+ 2. Call `ClientGenerator.generate()` to extract the route manifest
9
+ 3. Call `createClient(manifest, config)` to build the client
10
+
11
+ ## ClientGenerator.generate()
12
+
13
+ Extracts route metadata from the current `RouteRegistry`:
14
+
15
+ ```ts
16
+ const manifest = ClientGenerator.generate();
17
+ // { routes: [{ method, path, controllerName, methodName }, ...] }
18
+ ```
19
+
20
+ Use `ClientGenerator.generateJSON()` for a JSON string.
21
+
22
+ ## createClient(manifest, config)
23
+
24
+ Creates an API client:
25
+
26
+ ```ts
27
+ const client = createClient(manifest, {
28
+ baseUrl: 'http://localhost:3000',
29
+ headers: { 'X-API-Key': 'secret' },
30
+ });
31
+ ```
32
+
33
+ ## Client Structure
34
+
35
+ The client is grouped by controller name (with `Controller` suffix removed and first letter lowercased). Each method maps to a function:
36
+
37
+ ```ts
38
+ client.user.listUsers(); // GET /api/users/
39
+ client.user.getUser({ params: { id: '1' } }); // GET /api/users/:id
40
+ client.user.createUser({ body: { name: 'Alice' } }); // POST /api/users/
41
+ ```
42
+
43
+ ## ClientRequestOptions
44
+
45
+ ```ts
46
+ {
47
+ params?: Record<string, string>; // Path params (:id -> params.id)
48
+ query?: Record<string, string>; // Query string
49
+ body?: unknown; // Request body (JSON)
50
+ headers?: Record<string, string>; // Extra headers
51
+ }
52
+ ```
53
+
54
+ ## Full Example
55
+
56
+ ```ts
57
+ import {
58
+ Application,
59
+ Controller,
60
+ GET,
61
+ POST,
62
+ Param,
63
+ Body,
64
+ Module,
65
+ ClientGenerator,
66
+ createClient,
67
+ } from '@dangao/bun-server';
68
+
69
+ @Controller('/api/users')
70
+ class UserController {
71
+ @GET('/')
72
+ public listUsers(): object {
73
+ return [{ id: '1', name: 'Alice' }];
74
+ }
75
+
76
+ @GET('/:id')
77
+ public getUser(@Param('id') id: string): object {
78
+ return { id, name: 'Alice' };
79
+ }
80
+
81
+ @POST('/')
82
+ public createUser(@Body() body: unknown): object {
83
+ return { ...(body as object), id: '3' };
84
+ }
85
+ }
86
+
87
+ @Module({ controllers: [UserController] })
88
+ class AppModule {}
89
+
90
+ const app = new Application({ port: 3001 });
91
+ app.registerModule(AppModule);
92
+ await app.listen();
93
+
94
+ const manifest = ClientGenerator.generate();
95
+ const client = createClient(manifest, { baseUrl: 'http://localhost:3001' });
96
+
97
+ const users = await client.user.listUsers();
98
+ const user = await client.user.getUser({ params: { id: '42' } });
99
+ const created = await client.user.createUser({ body: { name: 'Charlie' } });
100
+ ```
@@ -0,0 +1,81 @@
1
+ # Zero-Config Cluster
2
+
3
+ `ClusterManager` spawns multiple worker processes that share a single port via SO_REUSEPORT. Each worker runs your application; the master process monitors and restarts crashed workers.
4
+
5
+ ## ClusterManager Class
6
+
7
+ ```ts
8
+ const manager = new ClusterManager({
9
+ workers: 'auto' | number, // 'auto' = CPU cores
10
+ scriptPath: import.meta.path,
11
+ port: 3000,
12
+ hostname?: string,
13
+ });
14
+
15
+ manager.start();
16
+ await manager.stop();
17
+ ```
18
+
19
+ ## Static Methods
20
+
21
+ - **ClusterManager.isWorker()**: Returns `true` in worker processes; `false` in master
22
+ - **ClusterManager.getWorkerId()**: Returns worker index (0, 1, ...) in workers; `-1` in master
23
+
24
+ ## Master/Worker Pattern
25
+
26
+ ```ts
27
+ if (!ClusterManager.isWorker()) {
28
+ // Master: spawn workers
29
+ const manager = new ClusterManager({
30
+ workers: 'auto',
31
+ scriptPath: import.meta.path,
32
+ port: PORT,
33
+ });
34
+ manager.start();
35
+
36
+ process.on('SIGINT', async () => {
37
+ await manager.stop();
38
+ process.exit(0);
39
+ });
40
+ } else {
41
+ // Worker: run app
42
+ const app = new Application({
43
+ port: PORT,
44
+ reusePort: true,
45
+ enableSignalHandlers: true,
46
+ });
47
+ app.registerModule(WorkerModule);
48
+ await app.listen();
49
+ }
50
+ ```
51
+
52
+ ## Linux-Only: reusePort
53
+
54
+ SO_REUSEPORT works on Linux. On macOS and Windows it is ignored; the app may still run but only one worker will bind the port.
55
+
56
+ ## Example
57
+
58
+ ```ts
59
+ const PORT = Number(process.env.PORT ?? 3300);
60
+
61
+ if (!ClusterManager.isWorker()) {
62
+ const manager = new ClusterManager({
63
+ workers: process.env.WORKERS ? Number(process.env.WORKERS) : 'auto',
64
+ scriptPath: import.meta.path,
65
+ port: PORT,
66
+ });
67
+ manager.start();
68
+ process.on('SIGINT', () => manager.stop().then(() => process.exit(0)));
69
+ } else {
70
+ @Controller('/api')
71
+ class PerfController {
72
+ @GET('/ping')
73
+ public ping(): object {
74
+ return { pong: true, worker: ClusterManager.getWorkerId() };
75
+ }
76
+ }
77
+ const app = new Application({ port: PORT, reusePort: true });
78
+ app.registerModule(WorkerModule);
79
+ await app.listen();
80
+ }
81
+ ```
@@ -27,11 +27,9 @@ Bun Server Framework provides a powerful interceptor mechanism that allows you t
27
27
 
28
28
  ### Basic Decorator Pattern
29
29
 
30
- A custom decorator is a function that returns a `MethodDecorator`. It uses `reflect-metadata` to store metadata on the method.
30
+ A custom decorator is a function that returns a `MethodDecorator`. It uses the Reflect metadata API to store metadata on the method.
31
31
 
32
32
  ```typescript
33
- import 'reflect-metadata';
34
-
35
33
  // 1. Define a metadata key (use Symbol for uniqueness)
36
34
  export const MY_METADATA_KEY = Symbol('@my-app:my-decorator');
37
35
 
@@ -260,8 +258,6 @@ class MyInterceptor extends BaseInterceptor {
260
258
  ### Storing Metadata
261
259
 
262
260
  ```typescript
263
- import 'reflect-metadata';
264
-
265
261
  const METADATA_KEY = Symbol('my-metadata');
266
262
 
267
263
  // Store metadata
@@ -337,7 +333,6 @@ class MyInterceptor extends BaseInterceptor {
337
333
  ### Example 1: Simple Logging Interceptor
338
334
 
339
335
  ```typescript
340
- import 'reflect-metadata';
341
336
  import { BaseInterceptor } from '@dangao/bun-server';
342
337
  import type { Container } from '@dangao/bun-server';
343
338
  import type { Context } from '@dangao/bun-server';
@@ -375,7 +370,6 @@ export class LogInterceptor extends BaseInterceptor {
375
370
  ### Example 2: Rate Limiting Interceptor
376
371
 
377
372
  ```typescript
378
- import 'reflect-metadata';
379
373
  import { BaseInterceptor, HttpException } from '@dangao/bun-server';
380
374
  import type { Container } from '@dangao/bun-server';
381
375
  import type { Context } from '@dangao/bun-server';
@@ -0,0 +1,54 @@
1
+ # Dashboard Module
2
+
3
+ The Dashboard Module provides a monitoring Web UI with system metrics, route listing, and health status.
4
+
5
+ ## Configuration
6
+
7
+ ```ts
8
+ DashboardModule.forRoot({
9
+ path: '/_dashboard', // default
10
+ auth: { username: 'admin', password: 'admin' },
11
+ })
12
+ ```
13
+
14
+ - **path**: Base path for the dashboard (default `/_dashboard`)
15
+ - **auth**: Optional Basic Auth. If omitted, the dashboard is unauthenticated.
16
+
17
+ ## Endpoints
18
+
19
+ | Path | Description |
20
+ |------|--------------|
21
+ | `/{path}` | Dashboard UI (HTML) |
22
+ | `/{path}/api/system` | System info (uptime, memory, platform, Bun version) |
23
+ | `/{path}/api/routes` | Registered routes (method, path, controller, methodName) |
24
+ | `/{path}/api/health` | Health check results (if HealthModule is used) |
25
+
26
+ ## Basic Auth
27
+
28
+ When `auth` is set, all dashboard endpoints require Basic Auth. The browser will prompt for credentials.
29
+
30
+ ## UI Description
31
+
32
+ The dashboard is a dark-themed single-page UI with:
33
+
34
+ - **Header**: "Bun Server Dashboard" and a short description
35
+ - **Cards**: System (uptime, memory, platform), Routes (count and list), Health (status and details)
36
+ - **Layout**: Responsive grid of cards with monospace values
37
+ - **Links**: Quick links to system, routes, and health API endpoints
38
+
39
+ ## Example
40
+
41
+ ```ts
42
+ @Module({
43
+ imports: [
44
+ DashboardModule.forRoot({
45
+ path: '/_dashboard',
46
+ auth: { username: 'admin', password: 'admin' },
47
+ }),
48
+ ],
49
+ controllers: [AppController],
50
+ })
51
+ class AppModule {}
52
+ ```
53
+
54
+ Access at `http://localhost:3000/_dashboard` (credentials: admin/admin).
package/docs/debug.md ADDED
@@ -0,0 +1,58 @@
1
+ # Debug & Request Replay Module
2
+
3
+ The Debug Module records HTTP requests in development and provides a UI to inspect and replay them.
4
+
5
+ ## Configuration
6
+
7
+ ```ts
8
+ DebugModule.forRoot({
9
+ enabled: true, // default
10
+ maxRecords: 500, // default, ring buffer size
11
+ recordBody: true, // default, capture request/response bodies
12
+ path: '/_debug', // default
13
+ })
14
+ ```
15
+
16
+ ## Recorded Data
17
+
18
+ Each `RequestRecord` includes:
19
+
20
+ - **id**: Unique record ID
21
+ - **timestamp**: Request time
22
+ - **request**: method, path, headers, body (if `recordBody`)
23
+ - **response**: status, headers, bodySize
24
+ - **timing**: total duration (ms)
25
+ - **metadata**: matchedRoute, controller, methodName
26
+
27
+ ## Debug UI Endpoints
28
+
29
+ | Path | Method | Description |
30
+ |------|--------|-------------|
31
+ | `/{path}` | GET | Debug UI (HTML) |
32
+ | `/{path}/api/records` | GET | List all records |
33
+ | `/{path}/api/records` | DELETE | Clear all records |
34
+ | `/{path}/api/records/:id` | GET | Get single record |
35
+ | `/{path}/api/replay/:id` | POST | Replay a request |
36
+
37
+ ## Request Replay
38
+
39
+ `POST /_debug/api/replay/:id` replays the recorded request against the current server. The response includes `ok`, `status`, `body`, or `error` on failure.
40
+
41
+ ## Example
42
+
43
+ ```ts
44
+ @Module({
45
+ imports: [
46
+ DebugModule.forRoot({
47
+ enabled: true,
48
+ maxRecords: 100,
49
+ recordBody: true,
50
+ path: '/_debug',
51
+ }),
52
+ ],
53
+ controllers: [AppController],
54
+ })
55
+ class AppModule {}
56
+ ```
57
+
58
+ Visit `http://localhost:3000/_debug` to view recorded requests and replay them.
@@ -499,8 +499,6 @@ You can create custom decorators to extend controller and route functionality.
499
499
  ### Creating Decorators
500
500
 
501
501
  ```typescript
502
- import 'reflect-metadata';
503
-
504
502
  // Cache decorator
505
503
  export function Cache(ttl: number) {
506
504
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
package/docs/guide.md CHANGED
@@ -15,7 +15,6 @@ For detailed lifecycle documentation, see [Request Lifecycle](./request-lifecycl
15
15
  ## 1. Initialize Application
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 });