@taicode/common-base 1.7.4 → 1.7.5

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 (34) hide show
  1. package/output/error/error.d.ts +104 -67
  2. package/output/error/error.d.ts.map +1 -1
  3. package/output/error/error.js +85 -59
  4. package/output/error/error.test.d.ts +0 -17
  5. package/output/error/error.test.d.ts.map +1 -1
  6. package/output/error/error.test.js +172 -99
  7. package/output/error/index.d.ts +2 -1
  8. package/output/error/index.d.ts.map +1 -1
  9. package/output/error/index.js +1 -1
  10. package/output/events/disposer.d.ts +6 -0
  11. package/output/events/disposer.d.ts.map +1 -0
  12. package/output/events/disposer.js +19 -0
  13. package/output/events/disposer.test.d.ts +2 -0
  14. package/output/events/disposer.test.d.ts.map +1 -0
  15. package/output/events/disposer.test.js +192 -0
  16. package/output/events/event-emitter.d.ts +33 -0
  17. package/output/events/event-emitter.d.ts.map +1 -0
  18. package/output/events/event-emitter.js +66 -0
  19. package/output/events/event-emitter.test.d.ts +2 -0
  20. package/output/events/event-emitter.test.d.ts.map +1 -0
  21. package/output/events/event-emitter.test.js +213 -0
  22. package/output/events/index.d.ts +3 -0
  23. package/output/events/index.d.ts.map +1 -0
  24. package/output/events/index.js +3 -0
  25. package/output/logger/formatter.d.ts +0 -1
  26. package/output/logger/formatter.d.ts.map +1 -1
  27. package/output/logger/formatter.js +1 -17
  28. package/output/logger/formatter.test.d.ts +0 -24
  29. package/output/logger/formatter.test.d.ts.map +1 -1
  30. package/output/logger/formatter.test.js +11 -30
  31. package/output/logger/logger.test.d.ts +0 -19
  32. package/output/logger/logger.test.d.ts.map +1 -1
  33. package/output/logger/logger.test.js +6 -16
  34. package/package.json +3 -2
@@ -0,0 +1,33 @@
1
+ type OffFn = () => void;
2
+ type Listener<T = unknown> = (data: T) => void;
3
+ export declare class EventEmitter<Events extends object = object> {
4
+ private listeners;
5
+ constructor();
6
+ /**
7
+ * 订阅事件
8
+ * @param type 事件类型
9
+ * @param listener 回调函数
10
+ */
11
+ on<K extends keyof Events>(type: K, listener: Listener<Events[K]>): OffFn;
12
+ /**
13
+ * 取消订阅
14
+ * @param type 事件类型
15
+ * @param listener 要移除的回调函数(可选)
16
+ */
17
+ off<K extends keyof Events>(type: K, listener?: Listener<Events[K]>): void;
18
+ /**
19
+ * 触发事件
20
+ * @param type 事件类型
21
+ * @param data 要传递的数据
22
+ */
23
+ emit<K extends keyof Events>(type: K, data: Events[K]): void;
24
+ /**
25
+ * 一次性订阅
26
+ * @param type 事件类型
27
+ * @param listener 回调函数
28
+ */
29
+ once<K extends keyof Events>(type: K, listener: Listener<Events[K]>): void;
30
+ cleanup(): void;
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=event-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.d.ts","sourceRoot":"","sources":["../../source/events/event-emitter.ts"],"names":[],"mappings":"AAAA,KAAK,KAAK,GAAG,MAAM,IAAI,CAAA;AACvB,KAAK,QAAQ,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;AAE9C,qBAAa,YAAY,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IACtD,OAAO,CAAC,SAAS,CAAsD;;IAUvE;;;;OAIG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;IASzE;;;;OAIG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAc1E;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ5D;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ1E,OAAO;CAGR"}
@@ -0,0 +1,66 @@
1
+ export class EventEmitter {
2
+ listeners = {};
3
+ constructor() {
4
+ this.on = this.on.bind(this);
5
+ this.off = this.off.bind(this);
6
+ this.once = this.once.bind(this);
7
+ this.emit = this.emit.bind(this);
8
+ this.cleanup = this.cleanup.bind(this);
9
+ }
10
+ /**
11
+ * 订阅事件
12
+ * @param type 事件类型
13
+ * @param listener 回调函数
14
+ */
15
+ on(type, listener) {
16
+ if (!this.listeners[type]) {
17
+ this.listeners[type] = [];
18
+ }
19
+ this.listeners[type].push(listener);
20
+ return () => this.off(type, listener);
21
+ }
22
+ /**
23
+ * 取消订阅
24
+ * @param type 事件类型
25
+ * @param listener 要移除的回调函数(可选)
26
+ */
27
+ off(type, listener) {
28
+ if (!this.listeners[type])
29
+ return;
30
+ if (!listener) {
31
+ // 移除该事件的所有监听器
32
+ delete this.listeners[type];
33
+ }
34
+ else {
35
+ // 移除特定监听器
36
+ this.listeners[type] = this.listeners[type].filter((fn) => fn !== listener);
37
+ }
38
+ }
39
+ /**
40
+ * 触发事件
41
+ * @param type 事件类型
42
+ * @param data 要传递的数据
43
+ */
44
+ emit(type, data) {
45
+ const listeners = this.listeners[type];
46
+ // 复制数组避免回调中取消订阅导致的遍历问题
47
+ if (listeners) {
48
+ listeners.slice().forEach((fn) => fn(data));
49
+ }
50
+ }
51
+ /**
52
+ * 一次性订阅
53
+ * @param type 事件类型
54
+ * @param listener 回调函数
55
+ */
56
+ once(type, listener) {
57
+ const onceWrapper = (data) => {
58
+ listener(data);
59
+ this.off(type, onceWrapper);
60
+ };
61
+ this.on(type, onceWrapper);
62
+ }
63
+ cleanup() {
64
+ this.listeners = {};
65
+ }
66
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event-emitter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.test.d.ts","sourceRoot":"","sources":["../../source/events/event-emitter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,213 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { EventEmitter } from './event-emitter';
3
+ describe('EventEmitter', () => {
4
+ let emitter;
5
+ beforeEach(() => {
6
+ emitter = new EventEmitter();
7
+ });
8
+ describe('on', () => {
9
+ it('应该能够订阅事件', () => {
10
+ const listener = vi.fn();
11
+ emitter.on('test', listener);
12
+ emitter.emit('test', 'hello');
13
+ expect(listener).toHaveBeenCalledOnce();
14
+ expect(listener).toHaveBeenCalledWith('hello');
15
+ });
16
+ it('应该能够订阅多个监听器', () => {
17
+ const listener1 = vi.fn();
18
+ const listener2 = vi.fn();
19
+ emitter.on('test', listener1);
20
+ emitter.on('test', listener2);
21
+ emitter.emit('test', 'hello');
22
+ expect(listener1).toHaveBeenCalledOnce();
23
+ expect(listener2).toHaveBeenCalledOnce();
24
+ expect(listener1).toHaveBeenCalledWith('hello');
25
+ expect(listener2).toHaveBeenCalledWith('hello');
26
+ });
27
+ it('应该返回取消订阅函数', () => {
28
+ const listener = vi.fn();
29
+ const off = emitter.on('test', listener);
30
+ emitter.emit('test', 'hello');
31
+ expect(listener).toHaveBeenCalledOnce();
32
+ off();
33
+ emitter.emit('test', 'world');
34
+ expect(listener).toHaveBeenCalledOnce();
35
+ });
36
+ it('应该支持不同类型的事件数据', () => {
37
+ const stringListener = vi.fn();
38
+ const numberListener = vi.fn();
39
+ const objectListener = vi.fn();
40
+ const voidListener = vi.fn();
41
+ emitter.on('test', stringListener);
42
+ emitter.on('number', numberListener);
43
+ emitter.on('object', objectListener);
44
+ emitter.on('noData', voidListener);
45
+ const testObject = { id: 1, name: 'test' };
46
+ emitter.emit('test', 'hello');
47
+ emitter.emit('number', 42);
48
+ emitter.emit('object', testObject);
49
+ emitter.emit('noData', undefined);
50
+ expect(stringListener).toHaveBeenCalledWith('hello');
51
+ expect(numberListener).toHaveBeenCalledWith(42);
52
+ expect(objectListener).toHaveBeenCalledWith(testObject);
53
+ expect(voidListener).toHaveBeenCalledWith(undefined);
54
+ });
55
+ });
56
+ describe('off', () => {
57
+ it('应该能够取消订阅特定监听器', () => {
58
+ const listener1 = vi.fn();
59
+ const listener2 = vi.fn();
60
+ emitter.on('test', listener1);
61
+ emitter.on('test', listener2);
62
+ emitter.off('test', listener1);
63
+ emitter.emit('test', 'hello');
64
+ expect(listener1).not.toHaveBeenCalled();
65
+ expect(listener2).toHaveBeenCalledOnce();
66
+ });
67
+ it('应该能够取消订阅所有监听器', () => {
68
+ const listener1 = vi.fn();
69
+ const listener2 = vi.fn();
70
+ emitter.on('test', listener1);
71
+ emitter.on('test', listener2);
72
+ emitter.off('test');
73
+ emitter.emit('test', 'hello');
74
+ expect(listener1).not.toHaveBeenCalled();
75
+ expect(listener2).not.toHaveBeenCalled();
76
+ });
77
+ it('应该忽略不存在的事件类型', () => {
78
+ expect(() => {
79
+ emitter.off('test');
80
+ }).not.toThrow();
81
+ });
82
+ it('应该忽略不存在的监听器', () => {
83
+ const listener = vi.fn();
84
+ const anotherListener = vi.fn();
85
+ emitter.on('test', listener);
86
+ expect(() => {
87
+ emitter.off('test', anotherListener);
88
+ }).not.toThrow();
89
+ emitter.emit('test', 'hello');
90
+ expect(listener).toHaveBeenCalledOnce();
91
+ });
92
+ });
93
+ describe('emit', () => {
94
+ it('应该能够触发事件', () => {
95
+ const listener = vi.fn();
96
+ emitter.on('test', listener);
97
+ emitter.emit('test', 'hello');
98
+ expect(listener).toHaveBeenCalledWith('hello');
99
+ });
100
+ it('应该不抛出错误当没有监听器时', () => {
101
+ expect(() => {
102
+ emitter.emit('test', 'hello');
103
+ }).not.toThrow();
104
+ });
105
+ it('应该按顺序调用监听器', () => {
106
+ const calls = [];
107
+ emitter.on('test', () => calls.push(1));
108
+ emitter.on('test', () => calls.push(2));
109
+ emitter.on('test', () => calls.push(3));
110
+ emitter.emit('test', 'hello');
111
+ expect(calls).toEqual([1, 2, 3]);
112
+ });
113
+ it('应该处理监听器中的错误', () => {
114
+ const workingListener = vi.fn();
115
+ const errorListener = vi.fn(() => {
116
+ throw new Error('Test error');
117
+ });
118
+ const anotherWorkingListener = vi.fn();
119
+ emitter.on('test', workingListener);
120
+ emitter.on('test', errorListener);
121
+ emitter.on('test', anotherWorkingListener);
122
+ expect(() => {
123
+ emitter.emit('test', 'hello');
124
+ }).toThrow('Test error');
125
+ expect(workingListener).toHaveBeenCalled();
126
+ expect(errorListener).toHaveBeenCalled();
127
+ // 由于错误,后续监听器可能不会被调用
128
+ });
129
+ it('应该防止监听器修改监听器列表时的遍历问题', () => {
130
+ const listener1 = vi.fn();
131
+ const listener2 = vi.fn(() => {
132
+ // 在回调中取消订阅
133
+ emitter.off('test', listener3);
134
+ });
135
+ const listener3 = vi.fn();
136
+ emitter.on('test', listener1);
137
+ emitter.on('test', listener2);
138
+ emitter.on('test', listener3);
139
+ emitter.emit('test', 'hello');
140
+ expect(listener1).toHaveBeenCalled();
141
+ expect(listener2).toHaveBeenCalled();
142
+ expect(listener3).toHaveBeenCalled(); // 应该仍然被调用,因为使用了 slice()
143
+ });
144
+ });
145
+ describe('once', () => {
146
+ it('应该只执行一次监听器', () => {
147
+ const listener = vi.fn();
148
+ emitter.once('test', listener);
149
+ emitter.emit('test', 'first');
150
+ emitter.emit('test', 'second');
151
+ expect(listener).toHaveBeenCalledOnce();
152
+ expect(listener).toHaveBeenCalledWith('first');
153
+ });
154
+ it('应该在执行后自动取消订阅', () => {
155
+ const listener = vi.fn();
156
+ emitter.once('test', listener);
157
+ emitter.emit('test', 'hello');
158
+ // 验证监听器已被移除
159
+ emitter.emit('test', 'world');
160
+ expect(listener).toHaveBeenCalledOnce();
161
+ });
162
+ it('应该与普通监听器一起工作', () => {
163
+ const onceListener = vi.fn();
164
+ const normalListener = vi.fn();
165
+ emitter.once('test', onceListener);
166
+ emitter.on('test', normalListener);
167
+ emitter.emit('test', 'first');
168
+ emitter.emit('test', 'second');
169
+ expect(onceListener).toHaveBeenCalledOnce();
170
+ expect(normalListener).toHaveBeenCalledTimes(2);
171
+ });
172
+ });
173
+ describe('cleanup', () => {
174
+ it('应该清空所有监听器', () => {
175
+ const listener1 = vi.fn();
176
+ const listener2 = vi.fn();
177
+ emitter.on('test', listener1);
178
+ emitter.on('number', listener2);
179
+ emitter.cleanup();
180
+ emitter.emit('test', 'hello');
181
+ emitter.emit('number', 42);
182
+ expect(listener1).not.toHaveBeenCalled();
183
+ expect(listener2).not.toHaveBeenCalled();
184
+ });
185
+ it('清理后应该能够重新添加监听器', () => {
186
+ const listener = vi.fn();
187
+ emitter.on('test', listener);
188
+ emitter.cleanup();
189
+ const newListener = vi.fn();
190
+ emitter.on('test', newListener);
191
+ emitter.emit('test', 'hello');
192
+ expect(listener).not.toHaveBeenCalled();
193
+ expect(newListener).toHaveBeenCalledWith('hello');
194
+ });
195
+ });
196
+ describe('方法绑定', () => {
197
+ it('方法应该绑定到实例', () => {
198
+ const { on, off, emit, once, cleanup } = emitter;
199
+ const listener = vi.fn();
200
+ on('test', listener);
201
+ emit('test', 'hello');
202
+ expect(listener).toHaveBeenCalledWith('hello');
203
+ off('test', listener);
204
+ emit('test', 'world');
205
+ expect(listener).toHaveBeenCalledOnce();
206
+ // 测试其他方法
207
+ once('test', listener);
208
+ emit('test', 'once');
209
+ expect(listener).toHaveBeenCalledTimes(2);
210
+ cleanup();
211
+ });
212
+ });
213
+ });
@@ -0,0 +1,3 @@
1
+ export * from './event-emitter';
2
+ export * from './disposer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/events/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ // 事件系统相关功能
2
+ export * from './event-emitter';
3
+ export * from './disposer';
@@ -52,7 +52,6 @@ export declare class DefaultLogFormatter implements LogFormatter {
52
52
  private formatError;
53
53
  private formatUserError;
54
54
  private formatSystemError;
55
- private formatUnknownError;
56
55
  private formatGenericError;
57
56
  private formatUnknownValue;
58
57
  private formatContext;
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../source/logger/formatter.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,eAAe;IACf,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;IAClC,aAAa;IACb,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC7B,aAAa;IACb,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAA;IAC7B,aAAa;IACb,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,MAAM,CAAA;IAC9B,aAAa;IACb,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,CAAA;IACnC,eAAe;IACf,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc;IACd,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAA;IACxB,cAAc;IACd,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gBAAgB;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAA0C;gBAE5C,MAAM,GAAE,eAAoB,EAAE,YAAY,GAAE,qBAA0B;IAgBlF;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM;IAwBxB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE;IAItC;;OAEG;IACH,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;CAWpB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAA"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../source/logger/formatter.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,eAAe;IACf,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;IAClC,aAAa;IACb,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAA;IAC7B,aAAa;IACb,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,CAAA;IAC7B,aAAa;IACb,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,MAAM,CAAA;IAC9B,aAAa;IACb,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,MAAM,CAAA;IACnC,eAAe;IACf,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,MAAM,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc;IACd,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAAA;IACxB,cAAc;IACd,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,gBAAgB;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAA0C;gBAE5C,MAAM,GAAE,eAAoB,EAAE,YAAY,GAAE,qBAA0B;IAgBlF;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM;IAwBxB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,EAAE;IAItC;;OAEG;IACH,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,WAAW;CAWpB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,qBAA4B,CAAA"}
@@ -2,7 +2,7 @@
2
2
  * 格式化器配置模块
3
3
  * 提供各种类型数据的格式化功能
4
4
  */
5
- import { UserError, SystemError, UnknownError } from '../error';
5
+ import { UserError, SystemError } from '../error';
6
6
  /**
7
7
  * 日志格式化器
8
8
  * 负责根据配置格式化各种类型的参数
@@ -66,9 +66,6 @@ export class DefaultLogFormatter {
66
66
  if (SystemError.is(error)) {
67
67
  return this.formatSystemError(error, opts);
68
68
  }
69
- if (UnknownError.is(error)) {
70
- return this.formatUnknownError(error, opts);
71
- }
72
69
  if (error instanceof Error) {
73
70
  return this.formatGenericError(error, opts);
74
71
  }
@@ -100,19 +97,6 @@ export class DefaultLogFormatter {
100
97
  }
101
98
  return lines.join('\n ');
102
99
  }
103
- formatUnknownError(error, opts) {
104
- const lines = [
105
- this.colorize('❓ Unknown Error', 'magenta', opts.useColors),
106
- `Message: ${error.message}`,
107
- ];
108
- if (opts.showContext && error.context) {
109
- lines.push(`Context: ${this.formatContext(error.context)}`);
110
- }
111
- if (opts.showStack && error.stack) {
112
- lines.push(`Stack: ${error.stack}`);
113
- }
114
- return lines.join('\n ');
115
- }
116
100
  formatGenericError(error, opts) {
117
101
  const lines = [
118
102
  this.colorize(`💥 ${error.name}`, 'red', opts.useColors),
@@ -1,26 +1,2 @@
1
- declare module '../error' {
2
- interface UserErrorTypes {
3
- 'validation-failed': {
4
- field?: string;
5
- value?: unknown;
6
- rule?: string;
7
- };
8
- 'test-error': {
9
- field?: string;
10
- };
11
- }
12
- interface SystemErrorTypes {
13
- 'database-error': {
14
- query?: string;
15
- table?: string;
16
- operation?: string;
17
- };
18
- 'network-error': {
19
- url?: string;
20
- method?: string;
21
- status?: number;
22
- };
23
- }
24
- }
25
1
  export {};
26
2
  //# sourceMappingURL=formatter.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.test.d.ts","sourceRoot":"","sources":["../../source/logger/formatter.test.ts"],"names":[],"mappings":"AAKA,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,cAAc;QACtB,mBAAmB,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,OAAO,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QACvE,YAAY,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACjC;IAED,UAAU,gBAAgB;QACxB,gBAAgB,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QACxE,eAAe,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACpE;CACF"}
1
+ {"version":3,"file":"formatter.test.d.ts","sourceRoot":"","sources":["../../source/logger/formatter.test.ts"],"names":[],"mappings":""}
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
2
  import { DefaultLogFormatter } from './formatter';
3
- import { UserError, SystemError, UnknownError } from '../error';
3
+ import { UserError, SystemError } from '../error';
4
4
  describe('DefaultLogFormatter', () => {
5
5
  let formatter;
6
6
  beforeEach(() => {
@@ -119,11 +119,11 @@ describe('DefaultLogFormatter', () => {
119
119
  describe('错误格式化', () => {
120
120
  describe('UserError 格式化', () => {
121
121
  it('应该格式化带有完整信息的 UserError', () => {
122
- const error = new UserError('validation-failed', '验证失败', {
122
+ const error = new UserError('validation-failed', {
123
123
  field: 'email',
124
124
  value: 'invalid-email',
125
125
  rule: 'email-format'
126
- });
126
+ }, '验证失败');
127
127
  const result = formatter.format(error);
128
128
  expect(result).toContain('🚫 User Error [validation-failed]');
129
129
  expect(result).toContain('Message: 验证失败');
@@ -132,7 +132,7 @@ describe('DefaultLogFormatter', () => {
132
132
  });
133
133
  it('应该在禁用颜色时不包含 ANSI 代码', () => {
134
134
  const formatterWithoutColors = new DefaultLogFormatter({}, { useColors: false });
135
- const error = new UserError('test-error', '测试错误');
135
+ const error = new UserError('test-error', undefined, '测试错误');
136
136
  const result = formatterWithoutColors.format(error);
137
137
  expect(result).not.toContain('\x1b[');
138
138
  expect(result).toContain('🚫 User Error [test-error]');
@@ -140,14 +140,14 @@ describe('DefaultLogFormatter', () => {
140
140
  });
141
141
  it('应该在禁用堆栈时不显示堆栈信息', () => {
142
142
  const formatterWithoutStack = new DefaultLogFormatter({}, { showStack: false });
143
- const error = new UserError('test-error', '测试错误');
143
+ const error = new UserError('test-error', undefined, '测试错误');
144
144
  const result = formatterWithoutStack.format(error);
145
145
  expect(result).not.toContain('Stack:');
146
146
  expect(result).toContain('Message: 测试错误');
147
147
  });
148
148
  it('应该在禁用上下文时不显示上下文信息', () => {
149
149
  const formatterWithoutContext = new DefaultLogFormatter({}, { showContext: false });
150
- const error = new UserError('test-error', '测试错误', { field: 'test' });
150
+ const error = new UserError('test-error', { field: 'test' }, '测试错误');
151
151
  const result = formatterWithoutContext.format(error);
152
152
  expect(result).not.toContain('Context:');
153
153
  expect(result).toContain('Message: 测试错误');
@@ -155,11 +155,11 @@ describe('DefaultLogFormatter', () => {
155
155
  });
156
156
  describe('SystemError 格式化', () => {
157
157
  it('应该格式化带有完整信息的 SystemError', () => {
158
- const error = new SystemError('database-error', '数据库连接失败', {
158
+ const error = new SystemError('database-error', {
159
159
  table: 'users',
160
160
  query: 'SELECT * FROM users',
161
161
  operation: 'select'
162
- });
162
+ }, '数据库连接失败');
163
163
  const result = formatter.format(error);
164
164
  expect(result).toContain('⚠️ System Error [database-error]');
165
165
  expect(result).toContain('Message: 数据库连接失败');
@@ -168,31 +168,12 @@ describe('DefaultLogFormatter', () => {
168
168
  });
169
169
  it('应该在禁用颜色时不包含 ANSI 代码', () => {
170
170
  const formatterWithoutColors = new DefaultLogFormatter({}, { useColors: false });
171
- const error = new SystemError('network-error', '网络错误');
171
+ const error = new SystemError('network-error', undefined, '网络错误');
172
172
  const result = formatterWithoutColors.format(error);
173
173
  expect(result).not.toContain('\x1b[');
174
174
  expect(result).toContain('⚠️ System Error [network-error]');
175
175
  });
176
176
  });
177
- describe('UnknownError 格式化', () => {
178
- it('应该格式化带有完整信息的 UnknownError', () => {
179
- const error = new UnknownError('未知错误', {
180
- cause: 'something went wrong'
181
- });
182
- const result = formatter.format(error);
183
- expect(result).toContain('❓ Unknown Error');
184
- expect(result).toContain('Message: 未知错误');
185
- expect(result).toContain('Context:');
186
- expect(result).toContain('Stack:');
187
- });
188
- it('应该在禁用颜色时不包含 ANSI 代码', () => {
189
- const formatterWithoutColors = new DefaultLogFormatter({}, { useColors: false });
190
- const error = new UnknownError('测试未知错误');
191
- const result = formatterWithoutColors.format(error);
192
- expect(result).not.toContain('\x1b[');
193
- expect(result).toContain('❓ Unknown Error');
194
- });
195
- });
196
177
  describe('通用 Error 格式化', () => {
197
178
  it('应该格式化普通 Error', () => {
198
179
  const error = new Error('普通错误');
@@ -291,7 +272,7 @@ describe('DefaultLogFormatter', () => {
291
272
  showContext: false,
292
273
  useColors: false
293
274
  });
294
- const error = new UserError('test-error', '测试错误', { field: 'test' });
275
+ const error = new UserError('test-error', { field: 'test' }, '测试错误');
295
276
  const result = minimalistFormatter.format(error);
296
277
  expect(result).not.toContain('Stack:');
297
278
  expect(result).not.toContain('Context:');
@@ -305,7 +286,7 @@ describe('DefaultLogFormatter', () => {
305
286
  showContext: false,
306
287
  useColors: false
307
288
  });
308
- const error = new SystemError('database-error', '数据库错误', { table: 'users' });
289
+ const error = new SystemError('database-error', { table: 'users' }, '数据库错误');
309
290
  const result = stackOnlyFormatter.format(error);
310
291
  expect(result).toContain('Stack:');
311
292
  expect(result).not.toContain('Context:');
@@ -1,21 +1,2 @@
1
- declare module '../error' {
2
- interface UserErrorTypes {
3
- 'validation-failed': {
4
- field?: string;
5
- value?: unknown;
6
- rule?: string;
7
- };
8
- 'test-error': {
9
- field?: string;
10
- };
11
- }
12
- interface SystemErrorTypes {
13
- 'database-error': {
14
- query?: string;
15
- table?: string;
16
- operation?: string;
17
- };
18
- }
19
- }
20
1
  export {};
21
2
  //# sourceMappingURL=logger.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../source/logger/logger.test.ts"],"names":[],"mappings":"AAOA,OAAO,QAAQ,UAAU,CAAC;IACxB,UAAU,cAAc;QACtB,mBAAmB,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,OAAO,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QACvE,YAAY,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACjC;IAED,UAAU,gBAAgB;QACxB,gBAAgB,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KACzE;CACF"}
1
+ {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../source/logger/logger.test.ts"],"names":[],"mappings":""}
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, vi } from 'vitest';
2
2
  import { Logger } from './logger';
3
3
  import { DefaultLogFormatter } from './formatter';
4
- import { UserError, SystemError, UnknownError } from '../error';
4
+ import { UserError, SystemError } from '../error';
5
5
  import { MemoryTransport } from './transport'; // 测试向后兼容性
6
6
  describe('Logger', () => {
7
7
  it('应该默认记录 info 及以上级别', () => {
@@ -66,11 +66,11 @@ describe('Logger 错误处理', () => {
66
66
  it('应该正确格式化 UserError', () => {
67
67
  const mockPrint = vi.fn();
68
68
  const logger = new Logger({ print: mockPrint });
69
- const userError = new UserError('validation-failed', '邮箱格式无效', {
69
+ const userError = new UserError('validation-failed', {
70
70
  field: 'email',
71
71
  value: 'invalid-email',
72
72
  rule: 'email-format'
73
- });
73
+ }, '邮箱格式无效');
74
74
  logger.error('测试用户错误:', userError);
75
75
  expect(mockPrint).toHaveBeenCalledWith('error', '测试用户错误:', expect.stringContaining('🚫 User Error [validation-failed]'));
76
76
  expect(mockPrint).toHaveBeenCalledWith('error', '测试用户错误:', expect.stringContaining('邮箱格式无效'));
@@ -78,25 +78,15 @@ describe('Logger 错误处理', () => {
78
78
  it('应该正确格式化 SystemError', () => {
79
79
  const mockPrint = vi.fn();
80
80
  const logger = new Logger({ print: mockPrint });
81
- const systemError = new SystemError('database-error', '数据库连接失败', {
81
+ const systemError = new SystemError('database-error', {
82
82
  table: 'users',
83
83
  query: 'SELECT * FROM users',
84
84
  operation: 'select'
85
- });
85
+ }, '数据库连接失败');
86
86
  logger.error('测试系统错误:', systemError);
87
87
  expect(mockPrint).toHaveBeenCalledWith('error', '测试系统错误:', expect.stringContaining('⚠️ System Error [database-error]'));
88
88
  expect(mockPrint).toHaveBeenCalledWith('error', '测试系统错误:', expect.stringContaining('数据库连接失败'));
89
89
  });
90
- it('应该正确格式化 UnknownError', () => {
91
- const mockPrint = vi.fn();
92
- const logger = new Logger({ print: mockPrint });
93
- const unknownError = new UnknownError('未知错误', {
94
- cause: 'something went wrong'
95
- });
96
- logger.error('测试未知错误:', unknownError);
97
- expect(mockPrint).toHaveBeenCalledWith('error', '测试未知错误:', expect.stringContaining('❓ Unknown Error'));
98
- expect(mockPrint).toHaveBeenCalledWith('error', '测试未知错误:', expect.stringContaining('未知错误'));
99
- });
100
90
  it('应该正确格式化普通 Error', () => {
101
91
  const mockPrint = vi.fn();
102
92
  const logger = new Logger({ print: mockPrint });
@@ -132,7 +122,7 @@ describe('Logger 错误处理', () => {
132
122
  print: mockPrint,
133
123
  formatter: customFormatter
134
124
  });
135
- const userError = new UserError('test-error', '测试错误', { field: 'test' });
125
+ const userError = new UserError('test-error', { field: 'test' }, '测试错误');
136
126
  logger.error(userError);
137
127
  const formattedError = mockPrint.mock.calls[0][1];
138
128
  expect(formattedError).not.toContain('Stack:');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taicode/common-base",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "author": "Alain",
5
5
  "license": "ISC",
6
6
  "description": "",
@@ -28,6 +28,7 @@
28
28
  "output"
29
29
  ],
30
30
  "devDependencies": {
31
- "vitest": "^3.2.4"
31
+ "vitest": "^3.2.4",
32
+ "mobx": "^6.0.0"
32
33
  }
33
34
  }