monsqlize 1.3.1 → 2.0.1

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 (114) hide show
  1. package/CHANGELOG.md +506 -235
  2. package/LICENSE +201 -21
  3. package/README.md +542 -928
  4. package/changelogs/README.md +163 -0
  5. package/changelogs/v2.0.0.md +222 -0
  6. package/changelogs/v2.0.1.md +39 -0
  7. package/dist/cjs/index.cjs +10788 -0
  8. package/dist/cjs/mongodb/common/transaction-aware.cjs +10 -0
  9. package/dist/cjs/transaction/CacheLockManager.cjs +100 -0
  10. package/dist/cjs/transaction/Transaction.cjs +158 -0
  11. package/dist/cjs/transaction/TransactionManager.cjs +298 -0
  12. package/dist/esm/index.mjs +10838 -0
  13. package/dist/types/base.d.ts +81 -0
  14. package/dist/types/collection.d.ts +1031 -0
  15. package/dist/types/expression.d.ts +115 -0
  16. package/dist/types/index.d.ts +23 -0
  17. package/dist/types/lock.d.ts +74 -0
  18. package/dist/types/model.d.ts +530 -0
  19. package/dist/types/mongodb.d.ts +49 -0
  20. package/dist/types/monsqlize.d.ts +491 -0
  21. package/dist/types/pool.d.ts +84 -0
  22. package/dist/types/runtime.d.ts +362 -0
  23. package/dist/types/saga.d.ts +143 -0
  24. package/dist/types/slow-query-log.d.ts +126 -0
  25. package/dist/types/sync.d.ts +103 -0
  26. package/dist/types/transaction.d.ts +132 -0
  27. package/package.json +120 -117
  28. package/index.d.ts +0 -1289
  29. package/lib/cache.js +0 -491
  30. package/lib/common/cursor.js +0 -58
  31. package/lib/common/docs-urls.js +0 -72
  32. package/lib/common/index-options.js +0 -222
  33. package/lib/common/log.js +0 -60
  34. package/lib/common/namespace.js +0 -21
  35. package/lib/common/normalize.js +0 -33
  36. package/lib/common/page-result.js +0 -42
  37. package/lib/common/runner.js +0 -56
  38. package/lib/common/server-features.js +0 -231
  39. package/lib/common/shape-builders.js +0 -26
  40. package/lib/common/validation.js +0 -112
  41. package/lib/connect.js +0 -76
  42. package/lib/constants.js +0 -54
  43. package/lib/count-queue.js +0 -187
  44. package/lib/distributed-cache-invalidator.js +0 -259
  45. package/lib/errors.js +0 -167
  46. package/lib/index.js +0 -461
  47. package/lib/infrastructure/ssh-tunnel-ssh2.js +0 -211
  48. package/lib/infrastructure/ssh-tunnel.js +0 -40
  49. package/lib/infrastructure/uri-parser.js +0 -35
  50. package/lib/lock/Lock.js +0 -66
  51. package/lib/lock/errors.js +0 -27
  52. package/lib/lock/index.js +0 -12
  53. package/lib/logger.js +0 -224
  54. package/lib/model/examples/test.js +0 -114
  55. package/lib/mongodb/common/accessor-helpers.js +0 -58
  56. package/lib/mongodb/common/agg-pipeline.js +0 -32
  57. package/lib/mongodb/common/iid.js +0 -27
  58. package/lib/mongodb/common/lexicographic-expr.js +0 -52
  59. package/lib/mongodb/common/shape.js +0 -31
  60. package/lib/mongodb/common/sort.js +0 -38
  61. package/lib/mongodb/common/transaction-aware.js +0 -24
  62. package/lib/mongodb/connect.js +0 -233
  63. package/lib/mongodb/index.js +0 -591
  64. package/lib/mongodb/management/admin-ops.js +0 -199
  65. package/lib/mongodb/management/bookmark-ops.js +0 -166
  66. package/lib/mongodb/management/cache-ops.js +0 -49
  67. package/lib/mongodb/management/collection-ops.js +0 -386
  68. package/lib/mongodb/management/database-ops.js +0 -201
  69. package/lib/mongodb/management/index-ops.js +0 -474
  70. package/lib/mongodb/management/index.js +0 -16
  71. package/lib/mongodb/management/namespace.js +0 -30
  72. package/lib/mongodb/management/validation-ops.js +0 -267
  73. package/lib/mongodb/queries/aggregate.js +0 -142
  74. package/lib/mongodb/queries/chain.js +0 -630
  75. package/lib/mongodb/queries/count.js +0 -98
  76. package/lib/mongodb/queries/distinct.js +0 -77
  77. package/lib/mongodb/queries/find-and-count.js +0 -192
  78. package/lib/mongodb/queries/find-by-ids.js +0 -235
  79. package/lib/mongodb/queries/find-one-by-id.js +0 -170
  80. package/lib/mongodb/queries/find-one.js +0 -70
  81. package/lib/mongodb/queries/find-page.js +0 -577
  82. package/lib/mongodb/queries/find.js +0 -170
  83. package/lib/mongodb/queries/index.js +0 -50
  84. package/lib/mongodb/queries/watch.js +0 -537
  85. package/lib/mongodb/writes/delete-many.js +0 -190
  86. package/lib/mongodb/writes/delete-one.js +0 -182
  87. package/lib/mongodb/writes/find-one-and-delete.js +0 -202
  88. package/lib/mongodb/writes/find-one-and-replace.js +0 -238
  89. package/lib/mongodb/writes/find-one-and-update.js +0 -239
  90. package/lib/mongodb/writes/increment-one.js +0 -252
  91. package/lib/mongodb/writes/index.js +0 -41
  92. package/lib/mongodb/writes/insert-batch.js +0 -507
  93. package/lib/mongodb/writes/insert-many.js +0 -227
  94. package/lib/mongodb/writes/insert-one.js +0 -180
  95. package/lib/mongodb/writes/replace-one.js +0 -215
  96. package/lib/mongodb/writes/result-handler.js +0 -236
  97. package/lib/mongodb/writes/update-many.js +0 -221
  98. package/lib/mongodb/writes/update-one.js +0 -223
  99. package/lib/mongodb/writes/upsert-one.js +0 -206
  100. package/lib/multi-level-cache.js +0 -189
  101. package/lib/operators.js +0 -330
  102. package/lib/redis-cache-adapter.js +0 -237
  103. package/lib/slow-query-log/base-storage.js +0 -69
  104. package/lib/slow-query-log/batch-queue.js +0 -96
  105. package/lib/slow-query-log/config-manager.js +0 -195
  106. package/lib/slow-query-log/index.js +0 -237
  107. package/lib/slow-query-log/mongodb-storage.js +0 -323
  108. package/lib/slow-query-log/query-hash.js +0 -38
  109. package/lib/transaction/CacheLockManager.js +0 -161
  110. package/lib/transaction/DistributedCacheLockManager.js +0 -474
  111. package/lib/transaction/Transaction.js +0 -314
  112. package/lib/transaction/TransactionManager.js +0 -266
  113. package/lib/transaction/index.js +0 -10
  114. package/lib/utils/objectid-converter.js +0 -566
@@ -1,211 +0,0 @@
1
- /**
2
- * SSH隧道管理器 - ssh2实现
3
- * 支持密码认证和私钥认证
4
- */
5
-
6
- const { Client } = require('ssh2');
7
- const net = require('net');
8
- const fs = require('fs');
9
- const path = require('path');
10
- const os = require('os');
11
-
12
- /**
13
- * 基于ssh2的SSH隧道管理器
14
- * 支持密码认证和私钥认证
15
- */
16
- class SSHTunnelSSH2 {
17
- /**
18
- * @param {Object} sshConfig - SSH配置
19
- * @param {string} sshConfig.host - SSH服务器地址
20
- * @param {number} [sshConfig.port=22] - SSH端口
21
- * @param {string} sshConfig.username - SSH用户名
22
- * @param {string} [sshConfig.password] - SSH密码
23
- * @param {string} [sshConfig.privateKey] - 私钥内容
24
- * @param {string} [sshConfig.privateKeyPath] - 私钥路径
25
- * @param {string} [sshConfig.passphrase] - 私钥密码
26
- * @param {number} [sshConfig.localPort] - 本地监听端口(可选,默认随机)
27
- * @param {number} [sshConfig.readyTimeout=20000] - 连接超时(毫秒)
28
- * @param {number} [sshConfig.keepaliveInterval=30000] - 心跳间隔(毫秒)
29
- * @param {string} remoteHost - 远程主机(数据库服务器地址)
30
- * @param {number} remotePort - 远程端口(数据库端口)
31
- * @param {Object} options - 可选配置
32
- * @param {Object} options.logger - 日志记录器
33
- * @param {string} options.name - 隧道名称(用于日志)
34
- */
35
- constructor(sshConfig, remoteHost, remotePort, options = {}) {
36
- this.sshConfig = sshConfig;
37
- this.remoteHost = remoteHost;
38
- this.remotePort = remotePort;
39
- this.logger = options.logger;
40
- this.name = options.name || `${remoteHost}:${remotePort}`;
41
-
42
- this.sshClient = null;
43
- this.server = null;
44
- this.localPort = null;
45
- this.isConnected = false;
46
- }
47
-
48
- /**
49
- * 建立SSH隧道
50
- * @returns {Promise<number>} 本地监听端口
51
- */
52
- async connect() {
53
- if (this.isConnected) {
54
- this.logger?.warn?.(`SSH tunnel [${this.name}] already connected`);
55
- return this.localPort;
56
- }
57
-
58
- return new Promise((resolve, reject) => {
59
- this.sshClient = new Client();
60
-
61
- this.sshClient.on('ready', () => {
62
- this.logger?.info?.(`✅ SSH connection established [${this.name}]`);
63
-
64
- // 创建本地TCP服务器(端口转发)
65
- this.server = net.createServer((sock) => {
66
- this.sshClient.forwardOut(
67
- sock.remoteAddress,
68
- sock.remotePort,
69
- this.remoteHost,
70
- this.remotePort,
71
- (err, stream) => {
72
- if (err) {
73
- this.logger?.error?.(`SSH forward error [${this.name}]`, err);
74
- return sock.end();
75
- }
76
- sock.pipe(stream).pipe(sock);
77
- }
78
- );
79
- });
80
-
81
- // 监听本地端口(0 = 随机端口)
82
- const port = this.sshConfig.localPort || 0;
83
- this.server.listen(port, 'localhost', () => {
84
- this.localPort = this.server.address().port;
85
- this.isConnected = true;
86
-
87
- this.logger?.info?.(`✅ SSH tunnel ready [${this.name}]`, {
88
- localPort: this.localPort,
89
- remote: `${this.remoteHost}:${this.remotePort}`
90
- });
91
-
92
- resolve(this.localPort);
93
- });
94
-
95
- this.server.on('error', (err) => {
96
- this.logger?.error?.(`Local server error [${this.name}]`, err);
97
- reject(err);
98
- });
99
- });
100
-
101
- this.sshClient.on('error', (err) => {
102
- this.logger?.error?.(`SSH connection error [${this.name}]`, err);
103
- reject(err);
104
- });
105
-
106
- this.sshClient.on('end', () => {
107
- this.logger?.info?.(`SSH connection ended [${this.name}]`);
108
- this.isConnected = false;
109
- });
110
-
111
- // 构建认证配置并连接
112
- try {
113
- const authConfig = this._buildAuthConfig();
114
- this.sshClient.connect(authConfig);
115
- } catch (err) {
116
- reject(err);
117
- }
118
- });
119
- }
120
-
121
- /**
122
- * 关闭SSH隧道
123
- */
124
- async close() {
125
- if (this.server) {
126
- this.server.close();
127
- this.server = null;
128
- }
129
-
130
- if (this.sshClient) {
131
- this.sshClient.end();
132
- this.sshClient = null;
133
- }
134
-
135
- this.isConnected = false;
136
- this.localPort = null;
137
-
138
- this.logger?.info?.(`✅ SSH tunnel closed [${this.name}]`);
139
- }
140
-
141
- /**
142
- * 获取隧道连接URI
143
- * @param {string} protocol - 数据库协议(mongodb/postgresql/mysql/redis)
144
- * @param {string} originalUri - 原始URI
145
- * @returns {string} 替换后的本地URI
146
- */
147
- getTunnelUri(protocol, originalUri) {
148
- if (!this.isConnected) {
149
- throw new Error(`SSH tunnel [${this.name}] not connected`);
150
- }
151
-
152
- // 替换主机:端口为 localhost:本地端口
153
- const pattern = new RegExp(`${protocol}://([^@]*@)?([^:/]+):(\\d+)`);
154
- const replacement = `${protocol}://$1localhost:${this.localPort}`;
155
-
156
- return originalUri.replace(pattern, replacement);
157
- }
158
-
159
- /**
160
- * 获取本地连接地址
161
- * @returns {string} localhost:端口
162
- */
163
- getLocalAddress() {
164
- if (!this.isConnected) {
165
- throw new Error(`SSH tunnel [${this.name}] not connected`);
166
- }
167
- return `localhost:${this.localPort}`;
168
- }
169
-
170
- /**
171
- * 构建SSH认证配置
172
- * @private
173
- */
174
- _buildAuthConfig() {
175
- const { host, port, username, password, privateKey, privateKeyPath, passphrase } = this.sshConfig;
176
-
177
- if (!host || !username) {
178
- throw new Error('SSH config requires: host, username');
179
- }
180
-
181
- const config = {
182
- host,
183
- port: port || 22,
184
- username,
185
- readyTimeout: this.sshConfig.readyTimeout || 20000,
186
- keepaliveInterval: this.sshConfig.keepaliveInterval || 30000,
187
- };
188
-
189
- // 优先使用私钥认证
190
- if (privateKey) {
191
- config.privateKey = privateKey;
192
- if (passphrase) config.passphrase = passphrase;
193
- } else if (privateKeyPath) {
194
- const resolvedPath = privateKeyPath.startsWith('~')
195
- ? path.join(os.homedir(), privateKeyPath.slice(1))
196
- : privateKeyPath;
197
- config.privateKey = fs.readFileSync(resolvedPath);
198
- if (passphrase) config.passphrase = passphrase;
199
- } else if (password) {
200
- // 密码认证
201
- config.password = password;
202
- } else {
203
- throw new Error('SSH authentication required: privateKey, privateKeyPath, or password');
204
- }
205
-
206
- return config;
207
- }
208
- }
209
-
210
- module.exports = { SSHTunnelSSH2 };
211
-
@@ -1,40 +0,0 @@
1
- /**
2
- * SSH隧道管理器 - 统一入口
3
- * 使用ssh2库实现,支持密码认证和私钥认证
4
- */
5
-
6
- const { SSHTunnelSSH2 } = require('./ssh-tunnel-ssh2');
7
-
8
- /**
9
- * SSH隧道管理器
10
- * 直接使用ssh2实现
11
- */
12
- class SSHTunnelManager {
13
- /**
14
- * 创建SSH隧道实例
15
- * @param {Object} sshConfig - SSH配置
16
- * @param {string} remoteHost - 远程主机
17
- * @param {number} remotePort - 远程端口
18
- * @param {Object} options - 可选配置
19
- * @returns {Object} SSH隧道实例
20
- */
21
- static create(sshConfig, remoteHost, remotePort, options = {}) {
22
- return new SSHTunnelSSH2(sshConfig, remoteHost, remotePort, options);
23
- }
24
-
25
- /**
26
- * 获取当前实现信息
27
- * @returns {Object}
28
- */
29
- static getInfo() {
30
- return {
31
- implementation: 'ssh2',
32
- supportsPassword: true,
33
- supportsPrivateKey: true,
34
- dependencies: ['ssh2']
35
- };
36
- }
37
- }
38
-
39
- module.exports = { SSHTunnelManager };
40
-
@@ -1,35 +0,0 @@
1
- /**
2
- * 通用URI解析器
3
- * 支持:mongodb://、postgresql://、mysql://、redis://
4
- */
5
-
6
- /**
7
- * 解析数据库连接URI
8
- * @param {string} uri - 数据库连接URI
9
- * @returns {{protocol: string, auth: string|null, host: string, port: number}} 解析结果
10
- */
11
- function parseUri(uri) {
12
- const patterns = {
13
- mongodb: /mongodb:\/\/([^@]*@)?([^:/]+):(\d+)/,
14
- postgresql: /postgresql:\/\/([^@]*@)?([^:/]+):(\d+)/,
15
- mysql: /mysql:\/\/([^@]*@)?([^:/]+):(\d+)/,
16
- redis: /redis:\/\/([^@]*@)?([^:/]+):(\d+)/
17
- };
18
-
19
- for (const [protocol, pattern] of Object.entries(patterns)) {
20
- const match = uri.match(pattern);
21
- if (match) {
22
- return {
23
- protocol,
24
- auth: match[1] ? match[1].slice(0, -1) : null, // 去掉末尾的@
25
- host: match[2],
26
- port: parseInt(match[3], 10)
27
- };
28
- }
29
- }
30
-
31
- throw new Error(`Unsupported URI format: ${uri}`);
32
- }
33
-
34
- module.exports = { parseUri };
35
-
package/lib/lock/Lock.js DELETED
@@ -1,66 +0,0 @@
1
- /**
2
- * 业务锁对象
3
- * 表示一个已获取的锁,提供释放和续期方法
4
- */
5
- class Lock {
6
- /**
7
- * @param {string} key - 锁的标识
8
- * @param {string} lockId - 锁的唯一ID
9
- * @param {Object} manager - 锁管理器实例
10
- * @param {number} ttl - 锁的过期时间(毫秒)
11
- */
12
- constructor(key, lockId, manager, ttl) {
13
- this.key = key;
14
- this.lockId = lockId;
15
- this.manager = manager;
16
- this.ttl = ttl;
17
- this.released = false;
18
- this.acquiredAt = Date.now();
19
- }
20
-
21
- /**
22
- * 释放锁
23
- * @returns {Promise<boolean>}
24
- */
25
- async release() {
26
- if (this.released) {
27
- return false;
28
- }
29
-
30
- const result = await this.manager.releaseLock(this.key, this.lockId);
31
- this.released = true;
32
- return result;
33
- }
34
-
35
- /**
36
- * 续期(延长锁的过期时间)
37
- * @param {number} [ttl] - 新的过期时间,默认使用原TTL
38
- * @returns {Promise<boolean>}
39
- */
40
- async renew(ttl) {
41
- if (this.released) {
42
- return false;
43
- }
44
-
45
- return this.manager.renewLock(this.key, this.lockId, ttl || this.ttl);
46
- }
47
-
48
- /**
49
- * 检查锁是否仍被持有
50
- * @returns {boolean}
51
- */
52
- isHeld() {
53
- return !this.released;
54
- }
55
-
56
- /**
57
- * 获取锁持有时间
58
- * @returns {number} 毫秒
59
- */
60
- getHoldTime() {
61
- return Date.now() - this.acquiredAt;
62
- }
63
- }
64
-
65
- module.exports = Lock;
66
-
@@ -1,27 +0,0 @@
1
- /**
2
- * 锁获取失败错误
3
- */
4
- class LockAcquireError extends Error {
5
- constructor(message) {
6
- super(message);
7
- this.name = 'LockAcquireError';
8
- this.code = 'LOCK_ACQUIRE_FAILED';
9
- }
10
- }
11
-
12
- /**
13
- * 锁超时错误
14
- */
15
- class LockTimeoutError extends Error {
16
- constructor(message) {
17
- super(message);
18
- this.name = 'LockTimeoutError';
19
- this.code = 'LOCK_TIMEOUT';
20
- }
21
- }
22
-
23
- module.exports = {
24
- LockAcquireError,
25
- LockTimeoutError
26
- };
27
-
package/lib/lock/index.js DELETED
@@ -1,12 +0,0 @@
1
- /**
2
- * 业务锁模块导出
3
- */
4
- const Lock = require('./Lock');
5
- const { LockAcquireError, LockTimeoutError } = require('./errors');
6
-
7
- module.exports = {
8
- Lock,
9
- LockAcquireError,
10
- LockTimeoutError
11
- };
12
-
package/lib/logger.js DELETED
@@ -1,224 +0,0 @@
1
- /**
2
- * 默认日志记录器工具类
3
- * 提供标准的日志记录功能,支持不同级别的日志输出
4
- *
5
- * v2.0 新增功能:
6
- * - traceId 支持(用于分布式追踪)
7
- * - 结构化日志输出(JSON 格式)
8
- * - 上下文信息(数据库、集合、操作等)
9
- */
10
-
11
- const crypto = require('crypto');
12
-
13
- /**
14
- * 生成唯一的 traceId
15
- * @returns {string} 16 字符的唯一 ID
16
- */
17
- function generateTraceId() {
18
- return crypto.randomBytes(8).toString('hex');
19
- }
20
-
21
- /**
22
- * 异步本地存储(用于在异步调用链中传递 traceId)
23
- */
24
- let AsyncLocalStorage;
25
- try {
26
- AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;
27
- } catch (e) {
28
- // Node.js < 12.17.0 不支持 AsyncLocalStorage
29
- AsyncLocalStorage = null;
30
- }
31
-
32
- const traceStorage = AsyncLocalStorage ? new AsyncLocalStorage() : null;
33
-
34
- module.exports = class Logger {
35
-
36
- /**
37
- * 创建日志记录器实例
38
- * @param {Object} [customLogger] - 自定义日志记录器
39
- * @param {Function} customLogger.debug - debug级别日志方法
40
- * @param {Function} customLogger.info - info级别日志方法
41
- * @param {Function} customLogger.warn - warn级别日志方法
42
- * @param {Function} customLogger.error - error级别日志方法
43
- * @param {Object} [options] - 日志选项
44
- * @param {boolean} [options.structured=false] - 是否使用结构化日志(JSON)
45
- * @param {boolean} [options.enableTraceId=false] - 是否启用 traceId
46
- * @returns {Object} 日志记录器对象
47
- */
48
- static create(customLogger, options = {}) {
49
- if (customLogger && this.isValidLogger(customLogger)) {
50
- // 如果提供自定义 logger,包装它以支持新特性
51
- return this.wrapLogger(customLogger, options);
52
- }
53
-
54
- return this.createDefaultLogger(options);
55
- }
56
-
57
- /**
58
- * 验证自定义日志记录器是否有效
59
- * @param {Object} logger - 待验证的日志记录器
60
- * @returns {boolean} 是否为有效的日志记录器
61
- */
62
- static isValidLogger(logger) {
63
- const requiredMethods = ['debug', 'info', 'warn', 'error'];
64
- return requiredMethods.every(method =>
65
- typeof logger[method] === 'function'
66
- );
67
- }
68
-
69
- /**
70
- * 包装自定义 logger 以支持新特性
71
- * @param {Object} baseLogger - 基础 logger
72
- * @param {Object} options - 选项
73
- * @returns {Object} 包装后的 logger
74
- */
75
- static wrapLogger(baseLogger, options = {}) {
76
- const { structured = false, enableTraceId = false } = options;
77
-
78
- const wrap = (level) => (msg, ...args) => {
79
- const logData = this._prepareLogData(level, msg, args, { structured, enableTraceId });
80
-
81
- if (structured) {
82
- baseLogger[level](JSON.stringify(logData));
83
- } else {
84
- const prefix = enableTraceId && logData.traceId ? `[${logData.traceId}] ` : '';
85
- baseLogger[level](`${prefix}${msg}`, ...args);
86
- }
87
- };
88
-
89
- return {
90
- debug: wrap('debug'),
91
- info: wrap('info'),
92
- warn: wrap('warn'),
93
- error: wrap('error'),
94
- // 暴露 traceId 管理方法
95
- withTraceId: enableTraceId ? this.withTraceId : undefined,
96
- getTraceId: enableTraceId ? this.getTraceId : undefined,
97
- };
98
- }
99
-
100
- /**
101
- * 准备日志数据
102
- * @private
103
- */
104
- static _prepareLogData(level, msg, args, options) {
105
- const logData = {
106
- timestamp: new Date().toISOString(),
107
- level: level.toUpperCase(),
108
- message: msg,
109
- };
110
-
111
- // 添加 traceId
112
- if (options.enableTraceId) {
113
- const traceId = this.getTraceId();
114
- if (traceId) logData.traceId = traceId;
115
- }
116
-
117
- // 处理额外参数(上下文信息)
118
- if (args.length > 0) {
119
- const context = args[0];
120
- if (context && typeof context === 'object') {
121
- logData.context = context;
122
- }
123
- }
124
-
125
- return logData;
126
- }
127
-
128
- /**
129
- * 创建默认的控制台日志记录器
130
- * @param {Object} [options] - 日志选项
131
- * @returns {Object} 默认日志记录器对象
132
- */
133
- static createDefaultLogger(options = {}) {
134
- const { structured = false, enableTraceId = false } = options;
135
-
136
- const createLogFn = (level, consoleFn) => {
137
- return (msg, ...args) => {
138
- const logData = this._prepareLogData(level, msg, args, { structured, enableTraceId });
139
-
140
- if (structured) {
141
- consoleFn(JSON.stringify(logData));
142
- } else {
143
- const prefix = enableTraceId && logData.traceId ? `[${logData.traceId}] ` : '';
144
- consoleFn(`[${level.toUpperCase()}] ${prefix}${msg}`, ...args);
145
- }
146
- };
147
- };
148
-
149
- return {
150
- debug: createLogFn('debug', console.debug),
151
- info: createLogFn('info', console.log),
152
- warn: createLogFn('warn', console.warn),
153
- error: createLogFn('error', console.error),
154
- // 暴露 traceId 管理方法
155
- withTraceId: enableTraceId ? this.withTraceId.bind(this) : undefined,
156
- getTraceId: enableTraceId ? this.getTraceId.bind(this) : undefined,
157
- };
158
- }
159
-
160
- /**
161
- * 创建带时间戳的日志记录器
162
- * @param {Object} [customLogger] - 自定义日志记录器
163
- * @returns {Object} 带时间戳的日志记录器
164
- */
165
- static createWithTimestamp(customLogger) {
166
- const baseLogger = this.create(customLogger);
167
- const getTimestamp = () => new Date().toISOString();
168
-
169
- return {
170
- debug: (msg, ...args) => baseLogger.debug(`${getTimestamp()} ${msg}`, ...args),
171
- info: (msg, ...args) => baseLogger.info(`${getTimestamp()} ${msg}`, ...args),
172
- warn: (msg, ...args) => baseLogger.warn(`${getTimestamp()} ${msg}`, ...args),
173
- error: (msg, ...args) => baseLogger.error(`${getTimestamp()} ${msg}`, ...args)
174
- };
175
- }
176
-
177
- /**
178
- * 创建静默日志记录器(不输出任何内容)
179
- * @returns {Object} 静默日志记录器
180
- */
181
- static createSilent() {
182
- const noop = () => {};
183
- return {
184
- debug: noop,
185
- info: noop,
186
- warn: noop,
187
- error: noop
188
- };
189
- }
190
-
191
- /**
192
- * 在指定的 traceId 上下文中运行函数
193
- * @param {Function} fn - 要执行的函数
194
- * @param {string} [traceId] - 可选的 traceId,不提供则自动生成
195
- * @returns {*} 函数执行结果
196
- */
197
- static withTraceId(fn, traceId = null) {
198
- if (!traceStorage) {
199
- // 不支持 AsyncLocalStorage,直接执行
200
- return fn();
201
- }
202
-
203
- const id = traceId || generateTraceId();
204
- return traceStorage.run(id, fn);
205
- }
206
-
207
- /**
208
- * 获取当前上下文的 traceId
209
- * @returns {string|null} traceId 或 null
210
- */
211
- static getTraceId() {
212
- if (!traceStorage) return null;
213
- return traceStorage.getStore() || null;
214
- }
215
-
216
- /**
217
- * 生成新的 traceId
218
- * @returns {string} 新的 traceId
219
- */
220
- static generateTraceId() {
221
- return generateTraceId();
222
- }
223
- };
224
-