@taicode/common-base 3.7.5 → 3.7.7

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 (167) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +7 -8
  3. package/output/batching-buffer/batching-buffer.d.ts +0 -133
  4. package/output/batching-buffer/batching-buffer.d.ts.map +0 -1
  5. package/output/batching-buffer/batching-buffer.js +0 -264
  6. package/output/batching-buffer/batching-buffer.test.d.ts +0 -2
  7. package/output/batching-buffer/batching-buffer.test.d.ts.map +0 -1
  8. package/output/batching-buffer/batching-buffer.test.js +0 -358
  9. package/output/batching-buffer/index.d.ts +0 -3
  10. package/output/batching-buffer/index.d.ts.map +0 -1
  11. package/output/batching-buffer/index.js +0 -1
  12. package/output/catch/catch.d.ts +0 -46
  13. package/output/catch/catch.d.ts.map +0 -1
  14. package/output/catch/catch.js +0 -48
  15. package/output/catch/catch.test.d.ts +0 -2
  16. package/output/catch/catch.test.d.ts.map +0 -1
  17. package/output/catch/catch.test.js +0 -43
  18. package/output/catch/index.d.ts +0 -2
  19. package/output/catch/index.d.ts.map +0 -1
  20. package/output/catch/index.js +0 -1
  21. package/output/color/color.d.ts +0 -6
  22. package/output/color/color.d.ts.map +0 -1
  23. package/output/color/color.js +0 -56
  24. package/output/color/color.test.d.ts +0 -2
  25. package/output/color/color.test.d.ts.map +0 -1
  26. package/output/color/color.test.js +0 -110
  27. package/output/color/index.d.ts +0 -2
  28. package/output/color/index.d.ts.map +0 -1
  29. package/output/color/index.js +0 -1
  30. package/output/debounce/debounce.d.ts +0 -7
  31. package/output/debounce/debounce.d.ts.map +0 -1
  32. package/output/debounce/debounce.js +0 -36
  33. package/output/debounce/debounce.test.d.ts +0 -2
  34. package/output/debounce/debounce.test.d.ts.map +0 -1
  35. package/output/debounce/debounce.test.js +0 -135
  36. package/output/debounce/index.d.ts +0 -2
  37. package/output/debounce/index.d.ts.map +0 -1
  38. package/output/debounce/index.js +0 -1
  39. package/output/disposer/disposer.d.ts +0 -8
  40. package/output/disposer/disposer.d.ts.map +0 -1
  41. package/output/disposer/disposer.js +0 -21
  42. package/output/disposer/disposer.test.d.ts +0 -2
  43. package/output/disposer/disposer.test.d.ts.map +0 -1
  44. package/output/disposer/disposer.test.js +0 -216
  45. package/output/disposer/index.d.ts +0 -2
  46. package/output/disposer/index.d.ts.map +0 -1
  47. package/output/disposer/index.js +0 -1
  48. package/output/error/error.d.ts +0 -128
  49. package/output/error/error.d.ts.map +0 -1
  50. package/output/error/error.js +0 -141
  51. package/output/error/error.test.d.ts +0 -2
  52. package/output/error/error.test.d.ts.map +0 -1
  53. package/output/error/error.test.js +0 -420
  54. package/output/error/index.d.ts +0 -3
  55. package/output/error/index.d.ts.map +0 -1
  56. package/output/error/index.js +0 -1
  57. package/output/event-emitter/event-emitter.d.ts +0 -33
  58. package/output/event-emitter/event-emitter.d.ts.map +0 -1
  59. package/output/event-emitter/event-emitter.js +0 -66
  60. package/output/event-emitter/event-emitter.test.d.ts +0 -2
  61. package/output/event-emitter/event-emitter.test.d.ts.map +0 -1
  62. package/output/event-emitter/event-emitter.test.js +0 -177
  63. package/output/event-emitter/index.d.ts +0 -2
  64. package/output/event-emitter/index.d.ts.map +0 -1
  65. package/output/event-emitter/index.js +0 -1
  66. package/output/flow-queue/flow-queue.d.ts +0 -486
  67. package/output/flow-queue/flow-queue.d.ts.map +0 -1
  68. package/output/flow-queue/flow-queue.js +0 -654
  69. package/output/flow-queue/flow-queue.test.d.ts +0 -2
  70. package/output/flow-queue/flow-queue.test.d.ts.map +0 -1
  71. package/output/flow-queue/flow-queue.test.js +0 -1205
  72. package/output/flow-queue/index.d.ts +0 -3
  73. package/output/flow-queue/index.d.ts.map +0 -1
  74. package/output/flow-queue/index.js +0 -3
  75. package/output/index.d.ts +0 -18
  76. package/output/index.d.ts.map +0 -1
  77. package/output/index.js +0 -26
  78. package/output/logger/formatter.d.ts +0 -70
  79. package/output/logger/formatter.d.ts.map +0 -1
  80. package/output/logger/formatter.js +0 -206
  81. package/output/logger/formatter.test.d.ts +0 -2
  82. package/output/logger/formatter.test.d.ts.map +0 -1
  83. package/output/logger/formatter.test.js +0 -296
  84. package/output/logger/index.d.ts +0 -4
  85. package/output/logger/index.d.ts.map +0 -1
  86. package/output/logger/index.js +0 -3
  87. package/output/logger/logger.d.ts +0 -64
  88. package/output/logger/logger.d.ts.map +0 -1
  89. package/output/logger/logger.js +0 -179
  90. package/output/logger/logger.test.d.ts +0 -2
  91. package/output/logger/logger.test.d.ts.map +0 -1
  92. package/output/logger/logger.test.js +0 -299
  93. package/output/logger/transport.d.ts +0 -124
  94. package/output/logger/transport.d.ts.map +0 -1
  95. package/output/logger/transport.js +0 -153
  96. package/output/logger/transport.test.d.ts +0 -2
  97. package/output/logger/transport.test.d.ts.map +0 -1
  98. package/output/logger/transport.test.js +0 -309
  99. package/output/lru-cache/index.d.ts +0 -2
  100. package/output/lru-cache/index.d.ts.map +0 -1
  101. package/output/lru-cache/index.js +0 -1
  102. package/output/lru-cache/lru-cache.d.ts +0 -22
  103. package/output/lru-cache/lru-cache.d.ts.map +0 -1
  104. package/output/lru-cache/lru-cache.js +0 -147
  105. package/output/lru-cache/lru-cache.test.d.ts +0 -2
  106. package/output/lru-cache/lru-cache.test.d.ts.map +0 -1
  107. package/output/lru-cache/lru-cache.test.js +0 -239
  108. package/output/number/index.d.ts +0 -2
  109. package/output/number/index.d.ts.map +0 -1
  110. package/output/number/index.js +0 -1
  111. package/output/number/number.d.ts +0 -2
  112. package/output/number/number.d.ts.map +0 -1
  113. package/output/number/number.js +0 -23
  114. package/output/number/number.test.d.ts +0 -2
  115. package/output/number/number.test.d.ts.map +0 -1
  116. package/output/number/number.test.js +0 -50
  117. package/output/object/index.d.ts +0 -2
  118. package/output/object/index.d.ts.map +0 -1
  119. package/output/object/index.js +0 -1
  120. package/output/object/object.d.ts +0 -7
  121. package/output/object/object.d.ts.map +0 -1
  122. package/output/object/object.js +0 -27
  123. package/output/object/object.test.d.ts +0 -2
  124. package/output/object/object.test.d.ts.map +0 -1
  125. package/output/object/object.test.js +0 -42
  126. package/output/ring-cache/index.d.ts +0 -6
  127. package/output/ring-cache/index.d.ts.map +0 -1
  128. package/output/ring-cache/index.js +0 -5
  129. package/output/ring-cache/ring-cache.d.ts +0 -125
  130. package/output/ring-cache/ring-cache.d.ts.map +0 -1
  131. package/output/ring-cache/ring-cache.js +0 -197
  132. package/output/ring-cache/ring-cache.test.d.ts +0 -2
  133. package/output/ring-cache/ring-cache.test.d.ts.map +0 -1
  134. package/output/ring-cache/ring-cache.test.js +0 -196
  135. package/output/service/index.d.ts +0 -2
  136. package/output/service/index.d.ts.map +0 -1
  137. package/output/service/index.js +0 -1
  138. package/output/service/service.d.ts +0 -6
  139. package/output/service/service.d.ts.map +0 -1
  140. package/output/service/service.js +0 -3
  141. package/output/string/index.d.ts +0 -2
  142. package/output/string/index.d.ts.map +0 -1
  143. package/output/string/index.js +0 -1
  144. package/output/string/string.d.ts +0 -3
  145. package/output/string/string.d.ts.map +0 -1
  146. package/output/string/string.js +0 -9
  147. package/output/string/string.test.d.ts +0 -2
  148. package/output/string/string.test.d.ts.map +0 -1
  149. package/output/string/string.test.js +0 -77
  150. package/output/throttle/index.d.ts +0 -2
  151. package/output/throttle/index.d.ts.map +0 -1
  152. package/output/throttle/index.js +0 -1
  153. package/output/throttle/throttle.d.ts +0 -12
  154. package/output/throttle/throttle.d.ts.map +0 -1
  155. package/output/throttle/throttle.js +0 -55
  156. package/output/throttle/throttle.test.d.ts +0 -2
  157. package/output/throttle/throttle.test.d.ts.map +0 -1
  158. package/output/throttle/throttle.test.js +0 -177
  159. package/output/ttl-cache/index.d.ts +0 -2
  160. package/output/ttl-cache/index.d.ts.map +0 -1
  161. package/output/ttl-cache/index.js +0 -1
  162. package/output/ttl-cache/ttl-cache.d.ts +0 -148
  163. package/output/ttl-cache/ttl-cache.d.ts.map +0 -1
  164. package/output/ttl-cache/ttl-cache.js +0 -313
  165. package/output/ttl-cache/ttl-cache.test.d.ts +0 -2
  166. package/output/ttl-cache/ttl-cache.test.d.ts.map +0 -1
  167. package/output/ttl-cache/ttl-cache.test.js +0 -222
@@ -1,64 +0,0 @@
1
- import type { LogTransport } from './transport.js';
2
- import { type LogFormatter } from './formatter.js';
3
- export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
4
- export interface LoggerOptions {
5
- level?: LogLevel;
6
- /** LogTransport 实例数组,用于处理结构化日志数据 */
7
- transports?: LogTransport[];
8
- /** 格式化器实例 */
9
- formatter?: LogFormatter;
10
- /** 传统的 print 函数,用于向后兼容 */
11
- print?: (level: LogLevel, ...args: any[]) => void;
12
- }
13
- export declare class Logger {
14
- private _level;
15
- private formatter;
16
- private transports;
17
- private print?;
18
- constructor(options?: LoggerOptions);
19
- private defaultPrint;
20
- private shouldLog;
21
- /**
22
- * 记录日志到所有 transports
23
- */
24
- private logToTransports;
25
- /**
26
- * 使用传统 print 方式记录日志(向后兼容)
27
- */
28
- private logToPrint;
29
- trace(...args: any[]): void;
30
- debug(...args: any[]): void;
31
- info(...args: any[]): void;
32
- warn(...args: any[]): void;
33
- error(...args: any[]): void;
34
- fatal(...args: any[]): void;
35
- silent(): void;
36
- /**
37
- * 添加 LogTransport
38
- */
39
- addTransport(transport: LogTransport): void;
40
- /**
41
- * 移除 LogTransport
42
- */
43
- removeTransport(transportName: string): void;
44
- /**
45
- * 获取所有 LogTransports
46
- */
47
- getTransports(): readonly LogTransport[];
48
- /**
49
- * 关闭所有 LogTransports
50
- */
51
- closeTransports(): Promise<void>;
52
- /**
53
- * Pino 兼容的 child 方法
54
- * 创建一个共享配置的子 logger
55
- */
56
- child(bindings?: Record<string, any>, options?: Partial<LoggerOptions>): Logger;
57
- /**
58
- * Pino 兼容的 level getter/setter
59
- */
60
- get level(): LogLevel;
61
- set level(newLevel: LogLevel);
62
- }
63
- export declare const logger: Logger;
64
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../source/logger/logger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,gBAAgB,CAAA;AAC7D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEvE,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAE9E,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,oCAAoC;IACpC,UAAU,CAAC,EAAE,YAAY,EAAE,CAAA;IAC3B,aAAa;IACb,SAAS,CAAC,EAAE,YAAY,CAAA;IACxB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;CAClD;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,KAAK,CAAC,CAA2C;gBAE7C,OAAO,GAAE,aAAkB;IAYvC,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,SAAS;IAKjB;;OAEG;IACH,OAAO,CAAC,eAAe;IA2BvB;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOpB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOpB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOnB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOnB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOpB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE;IAOpB,MAAM;IAIN;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAI3C;;OAEG;IACH,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAI5C;;OAEG;IACH,aAAa,IAAI,SAAS,YAAY,EAAE;IAIxC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtC;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM;IAkB/E;;OAEG;IACH,IAAI,KAAK,IAAI,QAAQ,CAEpB;IAED,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAE3B;CACF;AAED,eAAO,MAAM,MAAM,QAAe,CAAA"}
@@ -1,179 +0,0 @@
1
- import { defaultLogFormatter } from './formatter.js';
2
- export class Logger {
3
- _level;
4
- formatter;
5
- transports;
6
- print;
7
- constructor(options = {}) {
8
- this._level = options.level || 'info';
9
- this.formatter = options.formatter || defaultLogFormatter;
10
- this.transports = options.transports || [];
11
- this.print = options.print;
12
- // 如果没有 transports 且没有 print,使用默认的控制台输出
13
- if (this.transports.length === 0 && !this.print) {
14
- this.print = this.defaultPrint;
15
- }
16
- }
17
- defaultPrint(level, ...args) {
18
- const prefix = `[${level.toUpperCase()}]`;
19
- // 映射 pino 兼容的 level 到 console 方法
20
- let consoleMethod;
21
- switch (level) {
22
- case 'trace':
23
- case 'debug':
24
- consoleMethod = console.debug || console.log;
25
- break;
26
- case 'info':
27
- consoleMethod = console.info || console.log;
28
- break;
29
- case 'warn':
30
- consoleMethod = console.warn || console.log;
31
- break;
32
- case 'error':
33
- case 'fatal':
34
- consoleMethod = console.error || console.log;
35
- break;
36
- default:
37
- consoleMethod = console.log;
38
- }
39
- // eslint-disable-next-line no-console
40
- consoleMethod(prefix, ...args);
41
- }
42
- shouldLog(level) {
43
- const order = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
44
- return order.indexOf(level) >= order.indexOf(this._level);
45
- }
46
- /**
47
- * 记录日志到所有 transports
48
- */
49
- logToTransports(level, args) {
50
- if (this.transports.length === 0) {
51
- return;
52
- }
53
- const record = {
54
- level,
55
- timestamp: new Date(),
56
- args: [...args] // 创建副本避免引用问题
57
- };
58
- // 并行发送到所有 transports
59
- this.transports.forEach(transport => {
60
- try {
61
- const result = transport.log(record);
62
- // 如果返回 Promise,静默处理错误
63
- if (result && typeof result.catch === 'function') {
64
- result.catch(() => {
65
- // 静默处理 transport 错误,避免影响主程序
66
- });
67
- }
68
- }
69
- catch {
70
- // 静默处理 transport 错误,避免影响主程序
71
- }
72
- });
73
- }
74
- /**
75
- * 使用传统 print 方式记录日志(向后兼容)
76
- */
77
- logToPrint(level, args) {
78
- if (!this.print) {
79
- return;
80
- }
81
- // 为了向后兼容,保持原始行为:传递格式化后的参数
82
- const formattedArgs = this.formatter.formatArguments(args);
83
- this.print(level, ...formattedArgs);
84
- }
85
- trace(...args) {
86
- if (this.shouldLog('trace')) {
87
- this.logToTransports('trace', args);
88
- this.logToPrint('trace', args);
89
- }
90
- }
91
- debug(...args) {
92
- if (this.shouldLog('debug')) {
93
- this.logToTransports('debug', args);
94
- this.logToPrint('debug', args);
95
- }
96
- }
97
- info(...args) {
98
- if (this.shouldLog('info')) {
99
- this.logToTransports('info', args);
100
- this.logToPrint('info', args);
101
- }
102
- }
103
- warn(...args) {
104
- if (this.shouldLog('warn')) {
105
- this.logToTransports('warn', args);
106
- this.logToPrint('warn', args);
107
- }
108
- }
109
- error(...args) {
110
- if (this.shouldLog('error')) {
111
- this.logToTransports('error', args);
112
- this.logToPrint('error', args);
113
- }
114
- }
115
- fatal(...args) {
116
- if (this.shouldLog('fatal')) {
117
- this.logToTransports('fatal', args);
118
- this.logToPrint('fatal', args);
119
- }
120
- }
121
- silent() {
122
- // Pino 兼容的 silent 方法 - 无操作
123
- }
124
- /**
125
- * 添加 LogTransport
126
- */
127
- addTransport(transport) {
128
- this.transports.push(transport);
129
- }
130
- /**
131
- * 移除 LogTransport
132
- */
133
- removeTransport(transportName) {
134
- this.transports = this.transports.filter(t => t.name !== transportName);
135
- }
136
- /**
137
- * 获取所有 LogTransports
138
- */
139
- getTransports() {
140
- return [...this.transports];
141
- }
142
- /**
143
- * 关闭所有 LogTransports
144
- */
145
- async closeTransports() {
146
- const closePromises = this.transports
147
- .map(transport => transport.close?.())
148
- .filter(Boolean);
149
- await Promise.all(closePromises);
150
- }
151
- /**
152
- * Pino 兼容的 child 方法
153
- * 创建一个共享配置的子 logger
154
- */
155
- child(bindings, options) {
156
- // 合并选项,子 logger 继承父 logger 的配置
157
- const childOptions = {
158
- level: options?.level || this._level,
159
- transports: options?.transports || this.transports,
160
- formatter: options?.formatter || this.formatter,
161
- print: options?.print || this.print
162
- };
163
- const childLogger = new Logger(childOptions);
164
- // 如果提供了 bindings,我们可以在这里处理
165
- // 目前的实现中,bindings 主要用于标识,不直接影响日志输出
166
- // 在更完整的实现中,这些 bindings 会被添加到每个日志条目中
167
- return childLogger;
168
- }
169
- /**
170
- * Pino 兼容的 level getter/setter
171
- */
172
- get level() {
173
- return this._level;
174
- }
175
- set level(newLevel) {
176
- this._level = newLevel;
177
- }
178
- }
179
- export const logger = new Logger();
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=logger.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../../source/logger/logger.test.ts"],"names":[],"mappings":""}
@@ -1,299 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { Logger } from './logger.js';
3
- import { DefaultLogFormatter } from './formatter.js';
4
- import { UserError, SystemError } from '../error/index.js';
5
- import { MemoryTransport } from './transport.js'; // 测试向后兼容性
6
- describe('Logger', () => {
7
- it('应该默认记录 info 及以上级别', () => {
8
- const print = vi.fn();
9
- const logger = new Logger({ print });
10
- logger.trace('trace');
11
- logger.debug('debug');
12
- logger.info('info');
13
- logger.warn('warn');
14
- logger.error('error');
15
- logger.fatal('fatal');
16
- expect(print).not.toHaveBeenCalledWith('trace', 'trace');
17
- expect(print).not.toHaveBeenCalledWith('debug', 'debug');
18
- expect(print).toHaveBeenCalledWith('info', 'info');
19
- expect(print).toHaveBeenCalledWith('warn', 'warn');
20
- expect(print).toHaveBeenCalledWith('error', 'error');
21
- expect(print).toHaveBeenCalledWith('fatal', 'fatal');
22
- });
23
- it('应该遵守日志级别', () => {
24
- const print = vi.fn();
25
- const logger = new Logger({ level: 'warn', print });
26
- logger.trace('trace');
27
- logger.debug('debug');
28
- logger.info('info');
29
- logger.warn('warn');
30
- logger.error('error');
31
- logger.fatal('fatal');
32
- expect(print).not.toHaveBeenCalledWith('trace', 'trace');
33
- expect(print).not.toHaveBeenCalledWith('debug', 'debug');
34
- expect(print).not.toHaveBeenCalledWith('info', 'info');
35
- expect(print).toHaveBeenCalledWith('warn', 'warn');
36
- expect(print).toHaveBeenCalledWith('error', 'error');
37
- expect(print).toHaveBeenCalledWith('fatal', 'fatal');
38
- });
39
- it('应该支持 trace 级别日志', () => {
40
- const print = vi.fn();
41
- const logger = new Logger({ level: 'trace', print });
42
- logger.trace('trace message');
43
- expect(print).toHaveBeenCalledWith('trace', 'trace message');
44
- });
45
- it('应该支持 fatal 级别日志', () => {
46
- const print = vi.fn();
47
- const logger = new Logger({ level: 'fatal', print });
48
- logger.fatal('fatal error');
49
- expect(print).toHaveBeenCalledWith('fatal', 'fatal error');
50
- });
51
- it('silent 方法应该是无操作函数', () => {
52
- const print = vi.fn();
53
- const logger = new Logger({ print });
54
- logger.silent();
55
- expect(print).not.toHaveBeenCalled();
56
- });
57
- it('应该允许自定义处理器', () => {
58
- const logs = [];
59
- const print = (level, ...args) => logs.push([level, ...args]);
60
- const logger = new Logger({ print });
61
- logger.error('err', 123);
62
- expect(logs).toContainEqual(['error', 'err', "123"]);
63
- });
64
- });
65
- describe('Logger 错误处理', () => {
66
- it('应该正确格式化 UserError', () => {
67
- const mockPrint = vi.fn();
68
- const logger = new Logger({ print: mockPrint });
69
- const userError = new UserError('validation-failed', {
70
- field: 'email',
71
- value: 'invalid-email',
72
- rule: 'email-format'
73
- }, '邮箱格式无效');
74
- logger.error('测试用户错误:', userError);
75
- expect(mockPrint).toHaveBeenCalledWith('error', '测试用户错误:', expect.stringContaining('🚫 User Error [validation-failed]'));
76
- expect(mockPrint).toHaveBeenCalledWith('error', '测试用户错误:', expect.stringContaining('邮箱格式无效'));
77
- });
78
- it('应该正确格式化 SystemError', () => {
79
- const mockPrint = vi.fn();
80
- const logger = new Logger({ print: mockPrint });
81
- const systemError = new SystemError('database-error', {
82
- table: 'users',
83
- query: 'SELECT * FROM users',
84
- operation: 'select'
85
- }, '数据库连接失败');
86
- logger.error('测试系统错误:', systemError);
87
- expect(mockPrint).toHaveBeenCalledWith('error', '测试系统错误:', expect.stringContaining('⚠️ System Error [database-error]'));
88
- expect(mockPrint).toHaveBeenCalledWith('error', '测试系统错误:', expect.stringContaining('数据库连接失败'));
89
- });
90
- it('应该正确格式化普通 Error', () => {
91
- const mockPrint = vi.fn();
92
- const logger = new Logger({ print: mockPrint });
93
- const genericError = new Error('普通错误');
94
- logger.error('测试普通错误:', genericError);
95
- expect(mockPrint).toHaveBeenCalledWith('error', '测试普通错误:', expect.stringContaining('💥 Error'));
96
- expect(mockPrint).toHaveBeenCalledWith('error', '测试普通错误:', expect.stringContaining('普通错误'));
97
- });
98
- it('应该支持自定义 LogFormatter 实例', () => {
99
- const customFormatter = new DefaultLogFormatter({}, {
100
- showStack: false,
101
- useColors: false
102
- });
103
- const mockPrint = vi.fn();
104
- const logger = new Logger({
105
- print: mockPrint,
106
- formatter: customFormatter
107
- });
108
- const error = new Error('测试错误');
109
- logger.error(error);
110
- const formattedError = mockPrint.mock.calls[0][1];
111
- expect(formattedError).not.toContain('Stack:');
112
- expect(formattedError).not.toContain('\x1b['); // ANSI color codes
113
- });
114
- it('应该支持自定义格式化选项', () => {
115
- const customFormatter = new DefaultLogFormatter({}, {
116
- showStack: false,
117
- showContext: false,
118
- useColors: false
119
- });
120
- const mockPrint = vi.fn();
121
- const logger = new Logger({
122
- print: mockPrint,
123
- formatter: customFormatter
124
- });
125
- const userError = new UserError('test-error', { field: 'test' }, '测试错误');
126
- logger.error(userError);
127
- const formattedError = mockPrint.mock.calls[0][1];
128
- expect(formattedError).not.toContain('Stack:');
129
- expect(formattedError).not.toContain('Context:');
130
- expect(formattedError).not.toContain('\x1b['); // ANSI color codes
131
- });
132
- });
133
- describe('Logger Transport 集成', () => {
134
- it('应该支持 Transport 记录日志', () => {
135
- const transport = new MemoryTransport();
136
- const logger = new Logger({ transports: [transport] });
137
- logger.info('测试消息', { data: 'value' });
138
- const records = transport.getRecords();
139
- expect(records).toHaveLength(1);
140
- expect(records[0].level).toBe('info');
141
- expect(records[0].args).toEqual(['测试消息', { data: 'value' }]);
142
- expect(records[0].timestamp).toBeInstanceOf(Date);
143
- });
144
- it('应该支持多个 Transport', () => {
145
- const transport1 = new MemoryTransport({ maxRecords: 10 });
146
- const transport2 = new MemoryTransport({ maxRecords: 10 });
147
- const logger = new Logger({ transports: [transport1, transport2] });
148
- logger.error('错误消息');
149
- expect(transport1.getRecords()).toHaveLength(1);
150
- expect(transport2.getRecords()).toHaveLength(1);
151
- expect(transport1.getRecords()[0].args).toEqual(['错误消息']);
152
- expect(transport2.getRecords()[0].args).toEqual(['错误消息']);
153
- });
154
- it('应该支持动态添加和移除 Transport', () => {
155
- const logger = new Logger();
156
- const transport = new MemoryTransport();
157
- // 添加 transport
158
- logger.addTransport(transport);
159
- logger.info('消息1');
160
- expect(transport.getRecords()).toHaveLength(1);
161
- // 移除 transport
162
- logger.removeTransport('memory');
163
- logger.info('消息2');
164
- expect(transport.getRecords()).toHaveLength(1); // 应该还是1条
165
- });
166
- it('应该获取所有 Transport', () => {
167
- const transport1 = new MemoryTransport();
168
- const transport2 = new MemoryTransport();
169
- const logger = new Logger({ transports: [transport1, transport2] });
170
- const transports = logger.getTransports();
171
- expect(transports).toHaveLength(2);
172
- expect(transports[0].name).toBe('memory');
173
- expect(transports[1].name).toBe('memory');
174
- });
175
- it('应该同时支持 Transport 和 print', () => {
176
- const transport = new MemoryTransport();
177
- const mockPrint = vi.fn();
178
- const logger = new Logger({
179
- transports: [transport],
180
- print: mockPrint
181
- });
182
- logger.warn('警告消息');
183
- // Transport 应该收到结构化数据
184
- const records = transport.getRecords();
185
- expect(records).toHaveLength(1);
186
- expect(records[0].args).toEqual(['警告消息']);
187
- // print 应该收到格式化的数据
188
- expect(mockPrint).toHaveBeenCalledWith('warn', '警告消息');
189
- });
190
- it('应该处理 Transport 错误而不影响主程序', () => {
191
- const faultyTransport = {
192
- name: 'faulty',
193
- log: () => { throw new Error('Transport 错误'); }
194
- };
195
- const logger = new Logger({ transports: [faultyTransport] });
196
- // 不应该抛出错误
197
- expect(() => {
198
- logger.error('测试消息');
199
- }).not.toThrow();
200
- });
201
- it('应该在没有 Transport 和 print 时使用默认输出', () => {
202
- const consoleSpy = vi.spyOn(console, 'info').mockImplementation(() => { });
203
- const logger = new Logger();
204
- logger.info('默认输出测试');
205
- expect(consoleSpy).toHaveBeenCalledWith('[INFO]', '默认输出测试');
206
- consoleSpy.mockRestore();
207
- });
208
- it('应该关闭所有 Transport', async () => {
209
- const mockClose1 = vi.fn();
210
- const mockClose2 = vi.fn();
211
- const transport1 = {
212
- name: 'test1',
213
- log: () => { },
214
- close: mockClose1
215
- };
216
- const transport2 = {
217
- name: 'test2',
218
- log: () => { },
219
- close: mockClose2
220
- };
221
- const logger = new Logger({ transports: [transport1, transport2] });
222
- await logger.closeTransports();
223
- expect(mockClose1).toHaveBeenCalled();
224
- expect(mockClose2).toHaveBeenCalled();
225
- });
226
- });
227
- describe('向后兼容性测试', () => {
228
- it('Transport 类型别名应该正常工作', () => {
229
- // 测试 Transport 类型别名是否可以正常使用
230
- const transport = new MemoryTransport();
231
- const logger = new Logger({ transports: [transport] });
232
- logger.info('测试向后兼容性');
233
- const records = transport.getRecords();
234
- expect(records).toHaveLength(1);
235
- expect(records[0].args).toEqual(['测试向后兼容性']);
236
- });
237
- });
238
- describe('Pino 兼容性测试', () => {
239
- it('应该支持 child 方法创建子 logger', () => {
240
- const print = vi.fn();
241
- const logger = new Logger({ print });
242
- const child = logger.child({ requestId: '123' });
243
- expect(child).toBeInstanceOf(Logger);
244
- expect(child.level).toBe(logger.level);
245
- child.info('child log');
246
- expect(print).toHaveBeenCalledWith('info', 'child log');
247
- });
248
- it('child logger 应该继承父 logger 的配置', () => {
249
- const print = vi.fn();
250
- const parent = new Logger({ level: 'warn', print });
251
- const child = parent.child();
252
- expect(child.level).toBe('warn');
253
- child.info('info message');
254
- child.warn('warn message');
255
- expect(print).not.toHaveBeenCalledWith('info', 'info message');
256
- expect(print).toHaveBeenCalledWith('warn', 'warn message');
257
- });
258
- it('child logger 可以有自己的配置选项', () => {
259
- const parentPrint = vi.fn();
260
- const childPrint = vi.fn();
261
- const parent = new Logger({ level: 'info', print: parentPrint });
262
- const child = parent.child({}, { level: 'debug', print: childPrint });
263
- expect(child.level).toBe('debug');
264
- child.debug('debug message');
265
- expect(parentPrint).not.toHaveBeenCalled();
266
- expect(childPrint).toHaveBeenCalledWith('debug', 'debug message');
267
- });
268
- it('应该支持 level 属性的 getter 和 setter', () => {
269
- const logger = new Logger();
270
- expect(logger.level).toBe('info'); // 默认级别
271
- logger.level = 'debug';
272
- expect(logger.level).toBe('debug');
273
- logger.level = 'error';
274
- expect(logger.level).toBe('error');
275
- });
276
- it('level 变更应该影响日志输出', () => {
277
- const print = vi.fn();
278
- const logger = new Logger({ print });
279
- logger.level = 'error';
280
- logger.info('info message');
281
- logger.error('error message');
282
- expect(print).not.toHaveBeenCalledWith('info', 'info message');
283
- expect(print).toHaveBeenCalledWith('error', 'error message');
284
- });
285
- it('应该包含所有 Pino 兼容的方法', () => {
286
- const logger = new Logger();
287
- // 检查所有必需的方法是否存在
288
- expect(typeof logger.trace).toBe('function');
289
- expect(typeof logger.debug).toBe('function');
290
- expect(typeof logger.info).toBe('function');
291
- expect(typeof logger.warn).toBe('function');
292
- expect(typeof logger.error).toBe('function');
293
- expect(typeof logger.fatal).toBe('function');
294
- expect(typeof logger.silent).toBe('function');
295
- expect(typeof logger.child).toBe('function');
296
- // 检查 level 属性
297
- expect(typeof logger.level).toBe('string');
298
- });
299
- });
@@ -1,124 +0,0 @@
1
- /**
2
- * LogTransport 抽象接口和实现
3
- * LogTransport 负责处理和存储结构化的日志数据
4
- */
5
- import type { LogLevel } from './logger.js';
6
- /**
7
- * 日志记录接口
8
- * 包含完整的结构化日志信息
9
- */
10
- export interface LogRecord {
11
- /** 日志级别 */
12
- level: LogLevel;
13
- /** 时间戳 */
14
- timestamp: Date;
15
- /** 原始参数数组 */
16
- args: any[];
17
- /** 可选的附加元数据 */
18
- metadata?: Record<string, any>;
19
- }
20
- /**
21
- * LogTransport 抽象接口
22
- * 负责处理结构化日志数据的存储和管理
23
- */
24
- export interface LogTransport {
25
- /** LogTransport 名称 */
26
- readonly name: string;
27
- /** 最低日志级别 */
28
- level?: LogLevel;
29
- /** 是否启用 */
30
- enabled?: boolean;
31
- /**
32
- * 处理日志记录
33
- * @param record 结构化的日志记录
34
- */
35
- log(record: LogRecord): void | Promise<void>;
36
- /**
37
- * 关闭 LogTransport,清理资源
38
- */
39
- close?(): void | Promise<void>;
40
- }
41
- /**
42
- * 内存 LogTransport 配置选项
43
- */
44
- export interface MemoryTransportOptions {
45
- /** 最大存储的日志条数 */
46
- maxRecords?: number;
47
- /** 最低日志级别 */
48
- level?: LogLevel;
49
- /** 是否启用 */
50
- enabled?: boolean;
51
- }
52
- /**
53
- * 内存中的日志条目
54
- */
55
- export interface MemoryLogEntry extends LogRecord {
56
- /** 唯一标识符 */
57
- id: string;
58
- }
59
- /**
60
- * 内存 LogTransport 实现
61
- * 将结构化日志数据存储在内存中,支持查询和分析
62
- * 使用RingCache实现高效的FIFO行为
63
- */
64
- export declare class MemoryTransport implements LogTransport {
65
- readonly name: string;
66
- level?: LogLevel;
67
- enabled: boolean;
68
- private cache;
69
- private static readonly LOG_LEVELS;
70
- constructor(options?: MemoryTransportOptions);
71
- /**
72
- * 检查是否应该处理此级别的日志
73
- */
74
- private shouldLog;
75
- log(record: LogRecord): void;
76
- /**
77
- * 获取所有日志记录
78
- */
79
- getRecords(): readonly MemoryLogEntry[];
80
- /**
81
- * 根据级别获取日志记录
82
- */
83
- getRecordsByLevel(level: LogLevel): MemoryLogEntry[];
84
- /**
85
- * 根据时间范围获取日志记录
86
- */
87
- getRecordsByTimeRange(start: Date, end: Date): MemoryLogEntry[];
88
- /**
89
- * 搜索日志记录
90
- * @param predicate 搜索条件函数
91
- */
92
- searchRecords(predicate: (record: MemoryLogEntry) => boolean): MemoryLogEntry[];
93
- /**
94
- * 根据参数内容搜索
95
- * @param searchText 搜索文本
96
- */
97
- searchByContent(searchText: string): MemoryLogEntry[];
98
- /**
99
- * 获取最近的 N 条记录
100
- */
101
- getRecentRecords(count: number): MemoryLogEntry[];
102
- /**
103
- * 获取统计信息
104
- */
105
- getStats(): {
106
- total: number;
107
- byLevel: Record<LogLevel, number>;
108
- oldestTimestamp?: Date;
109
- newestTimestamp?: Date;
110
- };
111
- /**
112
- * 清空所有记录
113
- */
114
- clear(): void;
115
- /**
116
- * 导出为 JSON 格式
117
- */
118
- exportToJSON(): string;
119
- /**
120
- * 关闭 LogTransport
121
- */
122
- close(): void;
123
- }
124
- //# sourceMappingURL=transport.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../source/logger/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,WAAW;IACX,KAAK,EAAE,QAAQ,CAAA;IACf,UAAU;IACV,SAAS,EAAE,IAAI,CAAA;IACf,aAAa;IACb,IAAI,EAAE,GAAG,EAAE,CAAA;IACX,eAAe;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB,aAAa;IACb,KAAK,CAAC,EAAE,QAAQ,CAAA;IAEhB,WAAW;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;OAGG;IACH,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5C;;OAEG;IACH,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,gBAAgB;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa;IACb,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,WAAW;IACX,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,YAAY;IACZ,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAClD,SAAgB,IAAI,EAAE,MAAM,CAAY;IACjC,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,OAAO,EAAE,OAAO,CAAQ;IAE/B,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAoE;gBAE1F,OAAO,GAAE,sBAA2B;IAQhD;;OAEG;IACH,OAAO,CAAC,SAAS;IAeV,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAQnC;;OAEG;IACI,UAAU,IAAI,SAAS,cAAc,EAAE;IAO9C;;OAEG;IACI,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc,EAAE;IAQ3D;;OAEG;IACI,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,cAAc,EAAE;IAQtE;;;OAGG;IACI,aAAa,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,GAAG,cAAc,EAAE;IAItF;;;OAGG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAsB5D;;OAEG;IACI,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE;IAOxD;;OAEG;IACI,QAAQ,IAAI;QACjB,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACjC,eAAe,CAAC,EAAE,IAAI,CAAA;QACtB,eAAe,CAAC,EAAE,IAAI,CAAA;KACvB;IA4BD;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;OAEG;IACI,YAAY,IAAI,MAAM;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;CAGrB"}