@dangao/bun-server 1.2.0 → 1.4.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 (162) hide show
  1. package/README.md +15 -0
  2. package/dist/config/config-module.d.ts +17 -0
  3. package/dist/config/config-module.d.ts.map +1 -1
  4. package/dist/config/service.d.ts +18 -1
  5. package/dist/config/service.d.ts.map +1 -1
  6. package/dist/config/types.d.ts +25 -0
  7. package/dist/config/types.d.ts.map +1 -1
  8. package/dist/controller/controller.d.ts +5 -0
  9. package/dist/controller/controller.d.ts.map +1 -1
  10. package/dist/controller/decorators.d.ts +30 -1
  11. package/dist/controller/decorators.d.ts.map +1 -1
  12. package/dist/controller/index.d.ts +2 -2
  13. package/dist/controller/index.d.ts.map +1 -1
  14. package/dist/controller/param-binder.d.ts +12 -0
  15. package/dist/controller/param-binder.d.ts.map +1 -1
  16. package/dist/core/application.d.ts +15 -0
  17. package/dist/core/application.d.ts.map +1 -1
  18. package/dist/core/context.d.ts +1 -0
  19. package/dist/core/context.d.ts.map +1 -1
  20. package/dist/core/server.d.ts +8 -0
  21. package/dist/core/server.d.ts.map +1 -1
  22. package/dist/index.d.ts +8 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +6487 -4178
  25. package/dist/microservice/config-center/config-center-module.d.ts +43 -0
  26. package/dist/microservice/config-center/config-center-module.d.ts.map +1 -0
  27. package/dist/microservice/config-center/decorators.d.ts +58 -0
  28. package/dist/microservice/config-center/decorators.d.ts.map +1 -0
  29. package/dist/microservice/config-center/index.d.ts +9 -0
  30. package/dist/microservice/config-center/index.d.ts.map +1 -0
  31. package/dist/microservice/config-center/nacos-config-center.d.ts +37 -0
  32. package/dist/microservice/config-center/nacos-config-center.d.ts.map +1 -0
  33. package/dist/microservice/config-center/nacos-decorators.d.ts +24 -0
  34. package/dist/microservice/config-center/nacos-decorators.d.ts.map +1 -0
  35. package/dist/microservice/config-center/types.d.ts +63 -0
  36. package/dist/microservice/config-center/types.d.ts.map +1 -0
  37. package/dist/microservice/governance/circuit-breaker.d.ts +54 -0
  38. package/dist/microservice/governance/circuit-breaker.d.ts.map +1 -0
  39. package/dist/microservice/governance/decorators.d.ts +51 -0
  40. package/dist/microservice/governance/decorators.d.ts.map +1 -0
  41. package/dist/microservice/governance/index.d.ts +9 -0
  42. package/dist/microservice/governance/index.d.ts.map +1 -0
  43. package/dist/microservice/governance/rate-limiter.d.ts +26 -0
  44. package/dist/microservice/governance/rate-limiter.d.ts.map +1 -0
  45. package/dist/microservice/governance/redis-rate-limiter.d.ts +76 -0
  46. package/dist/microservice/governance/redis-rate-limiter.d.ts.map +1 -0
  47. package/dist/microservice/governance/retry-strategy.d.ts +21 -0
  48. package/dist/microservice/governance/retry-strategy.d.ts.map +1 -0
  49. package/dist/microservice/governance/types.d.ts +212 -0
  50. package/dist/microservice/governance/types.d.ts.map +1 -0
  51. package/dist/microservice/index.d.ts +10 -0
  52. package/dist/microservice/index.d.ts.map +1 -0
  53. package/dist/microservice/monitoring/index.d.ts +4 -0
  54. package/dist/microservice/monitoring/index.d.ts.map +1 -0
  55. package/dist/microservice/monitoring/metrics-collector.d.ts +54 -0
  56. package/dist/microservice/monitoring/metrics-collector.d.ts.map +1 -0
  57. package/dist/microservice/monitoring/metrics-integration.d.ts +24 -0
  58. package/dist/microservice/monitoring/metrics-integration.d.ts.map +1 -0
  59. package/dist/microservice/monitoring/types.d.ts +99 -0
  60. package/dist/microservice/monitoring/types.d.ts.map +1 -0
  61. package/dist/microservice/service-client/call-decorators.d.ts +52 -0
  62. package/dist/microservice/service-client/call-decorators.d.ts.map +1 -0
  63. package/dist/microservice/service-client/decorators.d.ts +35 -0
  64. package/dist/microservice/service-client/decorators.d.ts.map +1 -0
  65. package/dist/microservice/service-client/index.d.ts +7 -0
  66. package/dist/microservice/service-client/index.d.ts.map +1 -0
  67. package/dist/microservice/service-client/interceptors.d.ts +96 -0
  68. package/dist/microservice/service-client/interceptors.d.ts.map +1 -0
  69. package/dist/microservice/service-client/load-balancer.d.ts +59 -0
  70. package/dist/microservice/service-client/load-balancer.d.ts.map +1 -0
  71. package/dist/microservice/service-client/service-client.d.ts +74 -0
  72. package/dist/microservice/service-client/service-client.d.ts.map +1 -0
  73. package/dist/microservice/service-client/types.d.ts +155 -0
  74. package/dist/microservice/service-client/types.d.ts.map +1 -0
  75. package/dist/microservice/service-registry/decorators.d.ts +84 -0
  76. package/dist/microservice/service-registry/decorators.d.ts.map +1 -0
  77. package/dist/microservice/service-registry/discovery-decorators.d.ts +58 -0
  78. package/dist/microservice/service-registry/discovery-decorators.d.ts.map +1 -0
  79. package/dist/microservice/service-registry/health-integration.d.ts +32 -0
  80. package/dist/microservice/service-registry/health-integration.d.ts.map +1 -0
  81. package/dist/microservice/service-registry/index.d.ts +10 -0
  82. package/dist/microservice/service-registry/index.d.ts.map +1 -0
  83. package/dist/microservice/service-registry/nacos-service-registry.d.ts +68 -0
  84. package/dist/microservice/service-registry/nacos-service-registry.d.ts.map +1 -0
  85. package/dist/microservice/service-registry/service-registry-module.d.ts +48 -0
  86. package/dist/microservice/service-registry/service-registry-module.d.ts.map +1 -0
  87. package/dist/microservice/service-registry/types.d.ts +121 -0
  88. package/dist/microservice/service-registry/types.d.ts.map +1 -0
  89. package/dist/microservice/tracing/collectors.d.ts +27 -0
  90. package/dist/microservice/tracing/collectors.d.ts.map +1 -0
  91. package/dist/microservice/tracing/index.d.ts +4 -0
  92. package/dist/microservice/tracing/index.d.ts.map +1 -0
  93. package/dist/microservice/tracing/tracer.d.ts +59 -0
  94. package/dist/microservice/tracing/tracer.d.ts.map +1 -0
  95. package/dist/microservice/tracing/types.d.ts +179 -0
  96. package/dist/microservice/tracing/types.d.ts.map +1 -0
  97. package/dist/request/request.d.ts +1 -0
  98. package/dist/request/request.d.ts.map +1 -1
  99. package/docs/microservice-config-center.md +258 -0
  100. package/docs/microservice-nacos.md +346 -0
  101. package/docs/microservice-service-registry.md +306 -0
  102. package/docs/microservice.md +680 -0
  103. package/docs/troubleshooting.md +41 -0
  104. package/docs/zh/troubleshooting.md +41 -0
  105. package/package.json +5 -4
  106. package/src/config/config-module.ts +210 -0
  107. package/src/config/service.ts +52 -1
  108. package/src/config/types.ts +31 -0
  109. package/src/controller/controller.ts +8 -0
  110. package/src/controller/decorators.ts +55 -0
  111. package/src/controller/index.ts +16 -2
  112. package/src/controller/param-binder.ts +87 -1
  113. package/src/core/application.ts +100 -2
  114. package/src/core/context.ts +1 -0
  115. package/src/core/server.ts +14 -0
  116. package/src/index.ts +98 -2
  117. package/src/microservice/config-center/config-center-module.ts +98 -0
  118. package/src/microservice/config-center/decorators.ts +159 -0
  119. package/src/microservice/config-center/index.ts +13 -0
  120. package/src/microservice/config-center/nacos-config-center.ts +126 -0
  121. package/src/microservice/config-center/nacos-decorators.ts +34 -0
  122. package/src/microservice/config-center/types.ts +80 -0
  123. package/src/microservice/governance/circuit-breaker.ts +229 -0
  124. package/src/microservice/governance/decorators.ts +113 -0
  125. package/src/microservice/governance/index.ts +18 -0
  126. package/src/microservice/governance/rate-limiter.ts +72 -0
  127. package/src/microservice/governance/redis-rate-limiter.ts +154 -0
  128. package/src/microservice/governance/retry-strategy.ts +74 -0
  129. package/src/microservice/governance/types.ts +247 -0
  130. package/src/microservice/index.ts +12 -0
  131. package/src/microservice/monitoring/index.ts +8 -0
  132. package/src/microservice/monitoring/metrics-collector.ts +223 -0
  133. package/src/microservice/monitoring/metrics-integration.ts +154 -0
  134. package/src/microservice/monitoring/types.ts +118 -0
  135. package/src/microservice/service-client/call-decorators.ts +107 -0
  136. package/src/microservice/service-client/decorators.ts +87 -0
  137. package/src/microservice/service-client/index.ts +37 -0
  138. package/src/microservice/service-client/interceptors.ts +182 -0
  139. package/src/microservice/service-client/load-balancer.ts +205 -0
  140. package/src/microservice/service-client/service-client.ts +488 -0
  141. package/src/microservice/service-client/types.ts +186 -0
  142. package/src/microservice/service-registry/decorators.ts +238 -0
  143. package/src/microservice/service-registry/discovery-decorators.ts +156 -0
  144. package/src/microservice/service-registry/health-integration.ts +146 -0
  145. package/src/microservice/service-registry/index.ts +20 -0
  146. package/src/microservice/service-registry/nacos-service-registry.ts +259 -0
  147. package/src/microservice/service-registry/service-registry-module.ts +105 -0
  148. package/src/microservice/service-registry/types.ts +149 -0
  149. package/src/microservice/tracing/collectors.ts +50 -0
  150. package/src/microservice/tracing/index.ts +15 -0
  151. package/src/microservice/tracing/tracer.ts +293 -0
  152. package/src/microservice/tracing/types.ts +213 -0
  153. package/src/request/request.ts +1 -0
  154. package/tests/config/set-value-by-path.test.ts +53 -0
  155. package/tests/controller/param-map.test.ts +237 -0
  156. package/tests/microservice/config-center.test.ts +77 -0
  157. package/tests/microservice/governance.test.ts +157 -0
  158. package/tests/microservice/monitoring.test.ts +75 -0
  159. package/tests/microservice/service-client.test.ts +136 -0
  160. package/tests/microservice/service-registry.test.ts +80 -0
  161. package/tests/microservice/tracing.test.ts +143 -0
  162. package/tests/utils/test-port.ts +29 -19
@@ -0,0 +1,80 @@
1
+ import { describe, expect, test, beforeEach } from 'bun:test';
2
+ import 'reflect-metadata';
3
+ import { ServiceRegistryModule, SERVICE_REGISTRY_TOKEN, type ServiceRegistry } from '../../src/microservice/service-registry';
4
+ import { MODULE_METADATA_KEY } from '../../src/di/module';
5
+ import { ControllerRegistry } from '../../src/controller/controller';
6
+
7
+ describe('ServiceRegistryModule', () => {
8
+ beforeEach(() => {
9
+ // 清除模块元数据
10
+ Reflect.deleteMetadata(MODULE_METADATA_KEY, ServiceRegistryModule);
11
+ ControllerRegistry.getInstance().clear();
12
+ });
13
+
14
+ test('should register service registry provider', () => {
15
+ ServiceRegistryModule.forRoot({
16
+ provider: 'nacos',
17
+ nacos: {
18
+ client: {
19
+ serverList: ['http://localhost:8848'],
20
+ namespaceId: 'public',
21
+ },
22
+ heartbeatInterval: 5000,
23
+ },
24
+ });
25
+
26
+ const metadata = Reflect.getMetadata(MODULE_METADATA_KEY, ServiceRegistryModule);
27
+ expect(metadata).toBeDefined();
28
+ expect(metadata.providers).toBeDefined();
29
+
30
+ const serviceRegistryProvider = metadata.providers.find(
31
+ (provider: any) => provider.provide === SERVICE_REGISTRY_TOKEN,
32
+ );
33
+ expect(serviceRegistryProvider).toBeDefined();
34
+ });
35
+
36
+ test('should throw error when provider is not supported', () => {
37
+ expect(() => {
38
+ ServiceRegistryModule.forRoot({
39
+ provider: 'unsupported' as any,
40
+ } as any);
41
+ }).toThrow('Unsupported service registry provider');
42
+ });
43
+
44
+ test('should throw error when nacos config is missing', () => {
45
+ expect(() => {
46
+ ServiceRegistryModule.forRoot({
47
+ provider: 'nacos',
48
+ } as any);
49
+ }).toThrow('Nacos configuration is required');
50
+ });
51
+ });
52
+
53
+ describe('ServiceRegistry Interface (Mock)', () => {
54
+ test('should implement ServiceRegistry interface', async () => {
55
+ const mockServiceRegistry: ServiceRegistry = {
56
+ async register(instance: any) {},
57
+ async deregister(instance: any) {},
58
+ async renew(instance: any) {},
59
+ async getInstances(serviceName: string, options?: any) {
60
+ return [
61
+ {
62
+ serviceName,
63
+ ip: '127.0.0.1',
64
+ port: 3000,
65
+ healthy: true,
66
+ },
67
+ ];
68
+ },
69
+ watchInstances(serviceName: string, listener: any, options?: any) {
70
+ return () => {}; // 返回取消监听的函数
71
+ },
72
+ async close() {},
73
+ };
74
+
75
+ const instances = await mockServiceRegistry.getInstances('test-service');
76
+ expect(instances).toBeDefined();
77
+ expect(instances.length).toBeGreaterThan(0);
78
+ });
79
+ });
80
+
@@ -0,0 +1,143 @@
1
+ import { describe, expect, test, beforeEach } from 'bun:test';
2
+ import { Tracer, SpanKind, SpanStatus } from '../../src/microservice/tracing';
3
+ import { ConsoleTraceCollector, MemoryTraceCollector } from '../../src/microservice/tracing';
4
+
5
+ describe('Tracer', () => {
6
+ let tracer: Tracer;
7
+
8
+ beforeEach(() => {
9
+ tracer = new Tracer({
10
+ samplingRate: 1.0,
11
+ enabled: true,
12
+ });
13
+ });
14
+
15
+ test('should create tracer instance', () => {
16
+ expect(tracer).toBeDefined();
17
+ });
18
+
19
+ test('should start and end span', () => {
20
+ const span = tracer.startSpan('test-span', SpanKind.CLIENT);
21
+ expect(span).toBeDefined();
22
+ expect(span.context.traceId).toBeDefined();
23
+ expect(span.context.spanId).toBeDefined();
24
+
25
+ tracer.endSpan(span.context.spanId, SpanStatus.OK);
26
+ // 验证 span 已结束(通过检查收集器)
27
+ });
28
+
29
+ test('should set span tags', () => {
30
+ const span = tracer.startSpan('test-span', SpanKind.CLIENT);
31
+ tracer.setSpanTags(span.context.spanId, {
32
+ 'service.name': 'test-service',
33
+ 'http.method': 'GET',
34
+ });
35
+
36
+ const context = tracer.getCurrentSpanContext(span.context.spanId);
37
+ expect(context).toBeDefined();
38
+ });
39
+
40
+ test('should add span event', () => {
41
+ const span = tracer.startSpan('test-span', SpanKind.CLIENT);
42
+ tracer.addSpanEvent(span.context.spanId, {
43
+ name: 'test-event',
44
+ attributes: { key: 'value' },
45
+ });
46
+
47
+ // 验证事件已添加
48
+ expect(span).toBeDefined();
49
+ });
50
+
51
+ test('should extract span context from headers', () => {
52
+ const headers = {
53
+ 'X-Trace-Id': 'trace123',
54
+ 'X-Span-Id': 'span456',
55
+ 'X-Parent-Span-Id': 'parent789',
56
+ 'X-Sampled': '1',
57
+ };
58
+
59
+ const context = tracer.extractFromHeaders(headers);
60
+ expect(context).toBeDefined();
61
+ expect(context?.traceId).toBe('trace123');
62
+ expect(context?.spanId).toBe('span456');
63
+ });
64
+
65
+ test('should inject span context to headers', () => {
66
+ const span = tracer.startSpan('test-span', SpanKind.CLIENT);
67
+ const headers = tracer.injectToHeaders(span.context);
68
+
69
+ expect(headers['X-Trace-Id']).toBe(span.context.traceId);
70
+ expect(headers['X-Span-Id']).toBe(span.context.spanId);
71
+ });
72
+
73
+ test('should add collector', () => {
74
+ const collector = new ConsoleTraceCollector();
75
+ tracer.addCollector(collector);
76
+ // 验证收集器已添加
77
+ expect(tracer).toBeDefined();
78
+ });
79
+ });
80
+
81
+ describe('MemoryTraceCollector', () => {
82
+ test('should collect spans', () => {
83
+ const collector = new MemoryTraceCollector();
84
+ const span = {
85
+ context: {
86
+ traceId: 'trace123',
87
+ spanId: 'span456',
88
+ },
89
+ name: 'test-span',
90
+ kind: SpanKind.CLIENT,
91
+ startTime: Date.now(),
92
+ status: SpanStatus.OK,
93
+ };
94
+
95
+ collector.collect(span as any);
96
+ const spans = collector.getSpans();
97
+ expect(spans.length).toBe(1);
98
+ expect(spans[0]?.context.traceId).toBe('trace123');
99
+ });
100
+
101
+ test('should get spans by trace id', () => {
102
+ const collector = new MemoryTraceCollector();
103
+ collector.collect({
104
+ context: { traceId: 'trace1', spanId: 'span1' },
105
+ name: 'span1',
106
+ kind: SpanKind.CLIENT,
107
+ startTime: Date.now(),
108
+ status: SpanStatus.OK,
109
+ } as any);
110
+ collector.collect({
111
+ context: { traceId: 'trace1', spanId: 'span2' },
112
+ name: 'span2',
113
+ kind: SpanKind.CLIENT,
114
+ startTime: Date.now(),
115
+ status: SpanStatus.OK,
116
+ } as any);
117
+ collector.collect({
118
+ context: { traceId: 'trace2', spanId: 'span3' },
119
+ name: 'span3',
120
+ kind: SpanKind.CLIENT,
121
+ startTime: Date.now(),
122
+ status: SpanStatus.OK,
123
+ } as any);
124
+
125
+ const trace1Spans = collector.getSpansByTraceId('trace1');
126
+ expect(trace1Spans.length).toBe(2);
127
+ });
128
+
129
+ test('should clear spans', () => {
130
+ const collector = new MemoryTraceCollector();
131
+ collector.collect({
132
+ context: { traceId: 'trace1', spanId: 'span1' },
133
+ name: 'span1',
134
+ kind: SpanKind.CLIENT,
135
+ startTime: Date.now(),
136
+ status: SpanStatus.OK,
137
+ } as any);
138
+
139
+ collector.clear();
140
+ expect(collector.getSpans().length).toBe(0);
141
+ });
142
+ });
143
+
@@ -4,26 +4,36 @@
4
4
  * @returns 不同测试之间不冲突的端口号
5
5
  */
6
6
  export function getTestPort(): number {
7
- // 选择 30000-59999 之间的随机端口,避免常用端口冲突
8
- // 并通过 Bun.serve 探测端口是否可用(可用则立刻 stop),避免 EADDRINUSE 造成测试雪崩失败
9
- let lastError: unknown;
10
- for (let i = 0; i < 50; i++) {
11
- const port = 30000 + Math.floor(Math.random() * 30000);
12
- try {
13
- const probe = Bun.serve({
14
- port,
15
- fetch: () => new Response('ok'),
16
- });
17
- probe.stop();
18
- return port;
19
- } catch (error) {
20
- lastError = error;
21
- // 端口占用,继续尝试
7
+ // 优先使用 port=0 让系统自动分配可用端口,避免随机端口碰撞导致的 flake
8
+ // 取到 probe.port 后立刻 stop,返回这个“刚刚可用”的端口供后续测试使用
9
+ try {
10
+ const probe = Bun.serve({
11
+ port: 0,
12
+ fetch: () => new Response('ok'),
13
+ });
14
+ const port = probe.port;
15
+ probe.stop();
16
+ return port;
17
+ } catch (error) {
18
+ // fallback:极端情况下(或运行环境限制监听端口)才会走到这里
19
+ let lastError: unknown = error;
20
+ for (let i = 0; i < 50; i++) {
21
+ const port = 30000 + Math.floor(Math.random() * 30000);
22
+ try {
23
+ const probe = Bun.serve({
24
+ port,
25
+ fetch: () => new Response('ok'),
26
+ });
27
+ probe.stop();
28
+ return port;
29
+ } catch (err) {
30
+ lastError = err;
31
+ }
22
32
  }
23
- }
24
33
 
25
- throw new Error(
26
- `Unable to find an available test port. Last error: ${String(lastError)}`,
27
- );
34
+ throw new Error(
35
+ `Unable to find an available test port. Last error: ${String(lastError)}`,
36
+ );
37
+ }
28
38
  }
29
39