monsqlize 1.3.0 → 2.0.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 (172) hide show
  1. package/CHANGELOG.md +56 -60
  2. package/LICENSE +201 -21
  3. package/README.md +537 -1828
  4. package/changelogs/README.md +160 -0
  5. package/changelogs/v2.0.0.md +222 -0
  6. package/dist/cjs/index.cjs +10600 -0
  7. package/dist/cjs/mongodb/common/transaction-aware.cjs +10 -0
  8. package/dist/cjs/transaction/CacheLockManager.cjs +100 -0
  9. package/dist/cjs/transaction/Transaction.cjs +158 -0
  10. package/dist/cjs/transaction/TransactionManager.cjs +298 -0
  11. package/dist/esm/index.mjs +10650 -0
  12. package/dist/types/base.d.ts +81 -0
  13. package/dist/types/collection.d.ts +1031 -0
  14. package/dist/types/expression.d.ts +115 -0
  15. package/dist/types/index.d.ts +23 -0
  16. package/dist/types/lock.d.ts +74 -0
  17. package/dist/types/model.d.ts +526 -0
  18. package/dist/types/mongodb.d.ts +49 -0
  19. package/dist/types/monsqlize.d.ts +491 -0
  20. package/dist/types/pool.d.ts +84 -0
  21. package/dist/types/runtime.d.ts +362 -0
  22. package/dist/types/saga.d.ts +143 -0
  23. package/dist/types/slow-query-log.d.ts +126 -0
  24. package/dist/types/sync.d.ts +103 -0
  25. package/dist/types/transaction.d.ts +132 -0
  26. package/package.json +67 -69
  27. package/index.d.ts +0 -206
  28. package/index.mjs +0 -52
  29. package/lib/cache-invalidation.js +0 -279
  30. package/lib/cache.js +0 -530
  31. package/lib/common/cursor.js +0 -59
  32. package/lib/common/docs-urls.js +0 -73
  33. package/lib/common/index-options.js +0 -223
  34. package/lib/common/log.js +0 -61
  35. package/lib/common/namespace.js +0 -22
  36. package/lib/common/normalize.js +0 -34
  37. package/lib/common/page-result.js +0 -43
  38. package/lib/common/runner.js +0 -57
  39. package/lib/common/server-features.js +0 -232
  40. package/lib/common/shape-builders.js +0 -27
  41. package/lib/common/validation.js +0 -113
  42. package/lib/connect.js +0 -99
  43. package/lib/constants.js +0 -55
  44. package/lib/count-queue.js +0 -188
  45. package/lib/distributed-cache-invalidator.js +0 -260
  46. package/lib/errors.js +0 -168
  47. package/lib/expression/cache/ExpressionCache.js +0 -114
  48. package/lib/expression/compiler/ExpressionCompiler.js +0 -1090
  49. package/lib/expression/compiler/ExpressionCompilerExtensions.js +0 -531
  50. package/lib/expression/detector.js +0 -84
  51. package/lib/expression/factory.js +0 -29
  52. package/lib/expression/index.js +0 -19
  53. package/lib/function-cache.js +0 -533
  54. package/lib/index.js +0 -1251
  55. package/lib/infrastructure/ConnectionPoolManager.js +0 -464
  56. package/lib/infrastructure/HealthChecker.js +0 -281
  57. package/lib/infrastructure/PoolConfig.js +0 -199
  58. package/lib/infrastructure/PoolSelector.js +0 -225
  59. package/lib/infrastructure/PoolStats.js +0 -244
  60. package/lib/infrastructure/ssh-tunnel-ssh2.js +0 -212
  61. package/lib/infrastructure/ssh-tunnel.js +0 -41
  62. package/lib/infrastructure/uri-parser.js +0 -36
  63. package/lib/lock/Lock.js +0 -67
  64. package/lib/lock/errors.js +0 -28
  65. package/lib/lock/index.js +0 -13
  66. package/lib/logger.js +0 -225
  67. package/lib/model/examples/test.js +0 -311
  68. package/lib/model/features/defaults.js +0 -161
  69. package/lib/model/features/populate.js +0 -568
  70. package/lib/model/features/relations.js +0 -120
  71. package/lib/model/features/soft-delete.js +0 -349
  72. package/lib/model/features/version.js +0 -157
  73. package/lib/model/features/virtuals.js +0 -219
  74. package/lib/model/index.js +0 -1265
  75. package/lib/mongodb/common/accessor-helpers.js +0 -59
  76. package/lib/mongodb/common/agg-pipeline.js +0 -36
  77. package/lib/mongodb/common/aggregation-validator.js +0 -127
  78. package/lib/mongodb/common/iid.js +0 -28
  79. package/lib/mongodb/common/lexicographic-expr.js +0 -53
  80. package/lib/mongodb/common/shape.js +0 -32
  81. package/lib/mongodb/common/sort.js +0 -39
  82. package/lib/mongodb/common/transaction-aware.js +0 -25
  83. package/lib/mongodb/connect.js +0 -234
  84. package/lib/mongodb/index.js +0 -639
  85. package/lib/mongodb/management/admin-ops.js +0 -200
  86. package/lib/mongodb/management/bookmark-ops.js +0 -167
  87. package/lib/mongodb/management/cache-ops.js +0 -50
  88. package/lib/mongodb/management/collection-ops.js +0 -387
  89. package/lib/mongodb/management/database-ops.js +0 -202
  90. package/lib/mongodb/management/index-ops.js +0 -475
  91. package/lib/mongodb/management/index.js +0 -17
  92. package/lib/mongodb/management/namespace.js +0 -31
  93. package/lib/mongodb/management/validation-ops.js +0 -268
  94. package/lib/mongodb/queries/aggregate.js +0 -172
  95. package/lib/mongodb/queries/chain.js +0 -631
  96. package/lib/mongodb/queries/count.js +0 -99
  97. package/lib/mongodb/queries/distinct.js +0 -78
  98. package/lib/mongodb/queries/find-and-count.js +0 -193
  99. package/lib/mongodb/queries/find-by-ids.js +0 -236
  100. package/lib/mongodb/queries/find-one-by-id.js +0 -171
  101. package/lib/mongodb/queries/find-one.js +0 -71
  102. package/lib/mongodb/queries/find-page.js +0 -618
  103. package/lib/mongodb/queries/find.js +0 -171
  104. package/lib/mongodb/queries/index.js +0 -51
  105. package/lib/mongodb/queries/watch.js +0 -538
  106. package/lib/mongodb/writes/common/batch-retry.js +0 -65
  107. package/lib/mongodb/writes/delete-batch.js +0 -323
  108. package/lib/mongodb/writes/delete-many.js +0 -181
  109. package/lib/mongodb/writes/delete-one.js +0 -173
  110. package/lib/mongodb/writes/find-one-and-delete.js +0 -203
  111. package/lib/mongodb/writes/find-one-and-replace.js +0 -239
  112. package/lib/mongodb/writes/find-one-and-update.js +0 -240
  113. package/lib/mongodb/writes/increment-one.js +0 -259
  114. package/lib/mongodb/writes/index.js +0 -46
  115. package/lib/mongodb/writes/insert-batch.js +0 -508
  116. package/lib/mongodb/writes/insert-many.js +0 -223
  117. package/lib/mongodb/writes/insert-one.js +0 -169
  118. package/lib/mongodb/writes/replace-one.js +0 -226
  119. package/lib/mongodb/writes/result-handler.js +0 -237
  120. package/lib/mongodb/writes/update-batch.js +0 -416
  121. package/lib/mongodb/writes/update-many.js +0 -275
  122. package/lib/mongodb/writes/update-one.js +0 -273
  123. package/lib/mongodb/writes/upsert-one.js +0 -203
  124. package/lib/multi-level-cache.js +0 -244
  125. package/lib/operators.js +0 -330
  126. package/lib/redis-cache-adapter.js +0 -267
  127. package/lib/saga/SagaContext.js +0 -67
  128. package/lib/saga/SagaDefinition.js +0 -32
  129. package/lib/saga/SagaExecutor.js +0 -201
  130. package/lib/saga/SagaOrchestrator.js +0 -186
  131. package/lib/saga/index.js +0 -11
  132. package/lib/slow-query-log/base-storage.js +0 -70
  133. package/lib/slow-query-log/batch-queue.js +0 -97
  134. package/lib/slow-query-log/config-manager.js +0 -196
  135. package/lib/slow-query-log/index.js +0 -238
  136. package/lib/slow-query-log/mongodb-storage.js +0 -324
  137. package/lib/slow-query-log/query-hash.js +0 -39
  138. package/lib/sync/ChangeStreamSyncManager.js +0 -405
  139. package/lib/sync/ResumeTokenStore.js +0 -192
  140. package/lib/sync/SyncConfig.js +0 -127
  141. package/lib/sync/SyncTarget.js +0 -240
  142. package/lib/sync/index.js +0 -20
  143. package/lib/transaction/CacheLockManager.js +0 -162
  144. package/lib/transaction/DistributedCacheLockManager.js +0 -475
  145. package/lib/transaction/Transaction.js +0 -315
  146. package/lib/transaction/TransactionManager.js +0 -267
  147. package/lib/transaction/index.js +0 -11
  148. package/lib/utils/objectid-converter.js +0 -632
  149. package/types/README.md +0 -122
  150. package/types/base.ts +0 -94
  151. package/types/batch.ts +0 -187
  152. package/types/cache.ts +0 -71
  153. package/types/chain.ts +0 -254
  154. package/types/collection.ts +0 -357
  155. package/types/expression.ts +0 -109
  156. package/types/function-cache.d.ts +0 -135
  157. package/types/lock.ts +0 -95
  158. package/types/model/definition.ts +0 -152
  159. package/types/model/index.ts +0 -10
  160. package/types/model/instance.ts +0 -121
  161. package/types/model/relations.ts +0 -121
  162. package/types/model/virtuals.ts +0 -32
  163. package/types/monsqlize.ts +0 -245
  164. package/types/options.ts +0 -192
  165. package/types/pagination.ts +0 -154
  166. package/types/pool.ts +0 -125
  167. package/types/query.ts +0 -71
  168. package/types/saga.ts +0 -125
  169. package/types/stream.ts +0 -64
  170. package/types/sync.ts +0 -79
  171. package/types/transaction.ts +0 -79
  172. package/types/write.ts +0 -77
@@ -1,387 +0,0 @@
1
- /**
2
- * 集合管理操作模块
3
- * @module management/collection-ops
4
- */
5
-
6
- const { createValidationError } = require('../../errors');
7
-
8
- /**
9
- * 创建集合管理操作方法
10
- * @param {Object} context - 上下文对象
11
- * @param {Object} context.db - MongoDB 数据库实例
12
- * @param {Object} context.collection - MongoDB 集合实例
13
- * @param {Object} context.logger - 日志记录器
14
- * @returns {Object} 集合管理操作方法
15
- */
16
- module.exports = function createCollectionOps(context) {
17
- const { db, collection, logger } = context;
18
-
19
- return {
20
- /**
21
- * 删除集合
22
- * @returns {Promise<boolean>} 删除操作的结果
23
- */
24
- dropCollection: async () => {
25
- return await collection.drop();
26
- },
27
-
28
- /**
29
- * 创建集合
30
- * @param {string} [name] - 集合名称;省略则使用当前绑定的集合名
31
- * @param {Object} [options={}] - 创建集合的配置选项
32
- * @param {boolean} [options.capped] - 是否创建固定大小集合
33
- * @param {number} [options.size] - 固定大小集合的字节数
34
- * @param {number} [options.max] - 固定大小集合的最大文档数
35
- * @param {Object} [options.timeseries] - 时间序列集合配置
36
- * @param {Object} [options.validator] - 文档验证规则
37
- * @returns {Promise<boolean>} 创建成功返回true
38
- * @example
39
- * // 创建普通集合
40
- * await db.createCollection('users');
41
- *
42
- * // 创建固定大小集合
43
- * await db.createCollection('logs', {
44
- * capped: true,
45
- * size: 10485760, // 10MB
46
- * max: 5000
47
- * });
48
- *
49
- * // 创建时间序列集合
50
- * await db.createCollection('measurements', {
51
- * timeseries: {
52
- * timeField: 'timestamp',
53
- * metaField: 'sensor',
54
- * granularity: 'seconds'
55
- * }
56
- * });
57
- */
58
- createCollection: async (name, options = {}) => {
59
- const collName = name || collection.collectionName;
60
- await db.createCollection(collName, options);
61
- return true;
62
- },
63
-
64
- /**
65
- * 创建视图集合
66
- * @param {string} name - 视图名称
67
- * @param {string} source - 源集合名称
68
- * @param {Array} [pipeline=[]] - 聚合管道数组
69
- * @returns {Promise<boolean>} 创建成功返回true
70
- */
71
- createView: async (name, source, pipeline = []) => {
72
- await db.createCollection(name, {
73
- viewOn: source,
74
- pipeline: pipeline || []
75
- });
76
- return true;
77
- },
78
-
79
- /**
80
- * 获取集合统计信息
81
- * @param {Object} [options] - 选项
82
- * @param {number} [options.scale=1] - 缩放因子(1=字节, 1024=KB, 1048576=MB)
83
- * @returns {Promise<Object>} 集合统计对象
84
- * @property {string} ns - 命名空间(数据库.集合)
85
- * @property {number} count - 文档数量
86
- * @property {number} size - 数据大小
87
- * @property {number} storageSize - 存储大小
88
- * @property {number} totalIndexSize - 索引总大小
89
- * @property {number} avgObjSize - 平均文档大小
90
- * @property {Object} indexSizes - 各索引大小
91
- * @example
92
- * const stats = await collection.stats();
93
- * console.log('Documents:', stats.count);
94
- * console.log('Data size:', stats.size, 'bytes');
95
- * console.log('Index size:', stats.totalIndexSize, 'bytes');
96
- *
97
- * // 使用 MB 为单位
98
- * const statsMB = await collection.stats({ scale: 1048576 });
99
- * console.log('Data size:', statsMB.size, 'MB');
100
- */
101
- stats: async (options = {}) => {
102
- try {
103
- const scale = options.scale || 1;
104
- // 使用 MongoDB 原生命令获取集合统计
105
- const result = await db.command({
106
- collStats: collection.collectionName,
107
- scale
108
- });
109
-
110
- return {
111
- ns: result.ns,
112
- count: result.count,
113
- size: result.size,
114
- storageSize: result.storageSize,
115
- totalIndexSize: result.totalIndexSize,
116
- avgObjSize: result.avgObjSize,
117
- indexSizes: result.indexSizes,
118
- nindexes: result.nindexes,
119
- scaleFactor: result.scaleFactor
120
- };
121
- } catch (error) {
122
- if (logger) {
123
- logger.error('Collection stats failed', { error: error.message });
124
- }
125
- throw createValidationError(
126
- `Failed to get collection stats: ${error.message}`,
127
- { code: 'COLLECTION_STATS_ERROR' }
128
- );
129
- }
130
- },
131
-
132
- /**
133
- * 列出数据库中的所有集合
134
- * @param {Object} [options] - 选项
135
- * @param {boolean} [options.nameOnly=false] - 仅返回集合名称
136
- * @returns {Promise<Array<Object>|Array<string>>} 集合列表
137
- * @example
138
- * // 获取详细信息
139
- * const collections = await db.listCollections();
140
- * console.log(collections);
141
- * // [
142
- * // { name: 'users', type: 'collection' },
143
- * // { name: 'orders', type: 'collection' }
144
- * // ]
145
- *
146
- * // 仅获取名称
147
- * const names = await db.listCollections({ nameOnly: true });
148
- * console.log(names); // ['users', 'orders']
149
- */
150
- listCollections: async (options = {}) => {
151
- try {
152
- const collections = await db.listCollections().toArray();
153
-
154
- if (options.nameOnly) {
155
- return collections.map(c => c.name);
156
- }
157
-
158
- return collections.map(c => ({
159
- name: c.name,
160
- type: c.type,
161
- options: c.options,
162
- info: c.info
163
- }));
164
- } catch (error) {
165
- if (logger) {
166
- logger.error('listCollections failed', { error: error.message });
167
- }
168
- throw createValidationError(
169
- `Failed to list collections: ${error.message}`,
170
- 'LIST_COLLECTIONS_ERROR'
171
- );
172
- }
173
- },
174
-
175
- /**
176
- * 重命名集合
177
- * @param {string} newName - 新集合名称
178
- * @param {Object} [options] - 选项
179
- * @param {boolean} [options.dropTarget=false] - 如果目标集合存在,是否删除
180
- * @returns {Promise<Object>} 重命名结果
181
- * @example
182
- * await collection.rename('users_new');
183
- *
184
- * // 如果目标已存在,删除并替换
185
- * await collection.rename('users_backup', { dropTarget: true });
186
- */
187
- renameCollection: async (newName, options = {}) => {
188
- try {
189
- if (!newName || typeof newName !== 'string') {
190
- throw createValidationError(
191
- 'New collection name is required and must be a string',
192
- 'INVALID_COLLECTION_NAME'
193
- );
194
- }
195
-
196
- const result = await collection.rename(newName, {
197
- dropTarget: options.dropTarget || false
198
- });
199
-
200
- if (logger) {
201
- logger.info('Collection renamed', {
202
- from: collection.collectionName,
203
- to: newName
204
- });
205
- }
206
-
207
- return {
208
- renamed: true,
209
- from: collection.collectionName,
210
- to: newName
211
- };
212
- } catch (error) {
213
- if (logger) {
214
- logger.error('renameCollection failed', { error: error.message });
215
- }
216
- throw createValidationError(
217
- `Failed to rename collection: ${error.message}`,
218
- 'RENAME_COLLECTION_ERROR'
219
- );
220
- }
221
- },
222
-
223
- /**
224
- * 修改集合属性
225
- * @param {Object} modifications - 修改选项
226
- * @param {Object} [modifications.validator] - 新的验证规则
227
- * @param {string} [modifications.validationLevel] - 验证级别
228
- * @param {string} [modifications.validationAction] - 验证行为
229
- * @param {Object} [modifications.index] - 索引修改
230
- * @returns {Promise<Object>} 修改结果
231
- * @example
232
- * // 修改验证级别
233
- * await collection.collMod({
234
- * validationLevel: 'moderate'
235
- * });
236
- *
237
- * // 修改 TTL 索引过期时间
238
- * await collection.collMod({
239
- * index: {
240
- * keyPattern: { createdAt: 1 },
241
- * expireAfterSeconds: 7200
242
- * }
243
- * });
244
- */
245
- collMod: async (modifications) => {
246
- try {
247
- if (!modifications || typeof modifications !== 'object') {
248
- throw createValidationError(
249
- 'Modifications object is required',
250
- 'INVALID_MODIFICATIONS'
251
- );
252
- }
253
-
254
- const result = await db.command({
255
- collMod: collection.collectionName,
256
- ...modifications
257
- });
258
-
259
- if (logger) {
260
- logger.info('Collection modified', {
261
- collection: collection.collectionName,
262
- modifications: Object.keys(modifications)
263
- });
264
- }
265
-
266
- return {
267
- ok: result.ok,
268
- collection: collection.collectionName
269
- };
270
- } catch (error) {
271
- if (logger) {
272
- logger.error('collMod failed', { error: error.message });
273
- }
274
- throw createValidationError(
275
- `Failed to modify collection: ${error.message}`,
276
- 'COLLMOD_ERROR'
277
- );
278
- }
279
- },
280
-
281
- /**
282
- * 转换为固定大小集合
283
- * @param {number} size - 集合大小(字节)
284
- * @param {Object} [options] - 选项
285
- * @param {number} [options.max] - 最大文档数
286
- * @returns {Promise<Object>} 转换结果
287
- * @example
288
- * // 转换为 10MB 固定大小集合
289
- * await collection.convertToCapped(10485760);
290
- *
291
- * // 限制最大文档数
292
- * await collection.convertToCapped(10485760, { max: 5000 });
293
- */
294
- convertToCapped: async (size, options = {}) => {
295
- try {
296
- if (!size || typeof size !== 'number' || size <= 0) {
297
- throw createValidationError(
298
- 'Size must be a positive number',
299
- 'INVALID_SIZE'
300
- );
301
- }
302
-
303
- const command = {
304
- convertToCapped: collection.collectionName,
305
- size
306
- };
307
-
308
- if (options.max) {
309
- command.max = options.max;
310
- }
311
-
312
- const result = await db.command(command);
313
-
314
- if (logger) {
315
- logger.info('Collection converted to capped', {
316
- collection: collection.collectionName,
317
- size,
318
- max: options.max
319
- });
320
- }
321
-
322
- return {
323
- ok: result.ok,
324
- collection: collection.collectionName,
325
- capped: true,
326
- size
327
- };
328
- } catch (error) {
329
- if (logger) {
330
- logger.error('convertToCapped failed', { error: error.message });
331
- }
332
- throw createValidationError(
333
- `Failed to convert to capped collection: ${error.message}`,
334
- 'CONVERT_CAPPED_ERROR'
335
- );
336
- }
337
- },
338
-
339
- /**
340
- * 执行任意 MongoDB 命令
341
- * @param {Object} command - MongoDB 命令对象
342
- * @param {Object} [options] - 选项
343
- * @returns {Promise<Object>} 命令执行结果
344
- * @example
345
- * // 执行 collStats 命令
346
- * const result = await db.runCommand({
347
- * collStats: 'users',
348
- * scale: 1024
349
- * });
350
- *
351
- * // 执行 ping 命令
352
- * const ping = await db.runCommand({ ping: 1 });
353
- */
354
- runCommand: async (command, options = {}) => {
355
- try {
356
- if (!command || typeof command !== 'object') {
357
- throw createValidationError(
358
- 'Command must be an object',
359
- 'INVALID_COMMAND'
360
- );
361
- }
362
-
363
- const result = await db.command(command, options);
364
-
365
- if (logger) {
366
- logger.debug('Command executed', {
367
- command: Object.keys(command)[0]
368
- });
369
- }
370
-
371
- return result;
372
- } catch (error) {
373
- if (logger) {
374
- logger.error('runCommand failed', {
375
- command: Object.keys(command)[0],
376
- error: error.message
377
- });
378
- }
379
- throw createValidationError(
380
- `Failed to execute command: ${error.message}`,
381
- 'COMMAND_ERROR'
382
- );
383
- }
384
- }
385
- };
386
- };
387
-
@@ -1,202 +0,0 @@
1
- /**
2
- * 数据库级别操作方法工厂函数
3
- * 提供数据库列表和删除等方法
4
- * @module mongodb/management/database-ops
5
- */
6
-
7
- const { createValidationError } = require('../../errors');
8
-
9
- /**
10
- * 创建数据库操作方法
11
- * @param {Object} context - 上下文对象
12
- * @param {Object} context.adapter - MongoDB 适配器
13
- * @param {Object} context.logger - 日志记录器
14
- * @returns {Object} 数据库操作方法集合
15
- */
16
- function createDatabaseOps(context) {
17
- const { adapter, logger } = context;
18
-
19
- return {
20
- /**
21
- * 列出所有数据库
22
- * @param {Object} [options] - 选项
23
- * @param {boolean} [options.nameOnly=false] - 仅返回数据库名称数组
24
- * @returns {Promise<Array<Object>|Array<string>>} 数据库列表
25
- * @property {string} name - 数据库名称
26
- * @property {number} sizeOnDisk - 磁盘占用大小(字节)
27
- * @property {boolean} empty - 是否为空数据库
28
- * @example
29
- * // 获取详细信息
30
- * const databases = await monSQLize.listDatabases();
31
- * console.log(databases);
32
- * // [
33
- * // { name: 'mydb', sizeOnDisk: 83886080, empty: false },
34
- * // { name: 'test', sizeOnDisk: 0, empty: true }
35
- * // ]
36
- *
37
- * // 仅获取名称
38
- * const dbNames = await monSQLize.listDatabases({ nameOnly: true });
39
- * console.log(dbNames); // ['mydb', 'test', 'admin']
40
- */
41
- async listDatabases(options = {}) {
42
- try {
43
- const admin = adapter.db.admin();
44
- const result = await admin.listDatabases();
45
-
46
- if (options.nameOnly) {
47
- return result.databases.map(db => db.name);
48
- }
49
-
50
- return result.databases.map(db => ({
51
- name: db.name,
52
- sizeOnDisk: db.sizeOnDisk,
53
- empty: db.empty
54
- }));
55
- } catch (error) {
56
- logger.error('listDatabases failed', { error: error.message });
57
- throw createValidationError(
58
- `Failed to list databases: ${error.message}`,
59
- 'LIST_DATABASES_ERROR'
60
- );
61
- }
62
- },
63
-
64
- /**
65
- * 删除整个数据库(危险操作)
66
- *
67
- * ⚠️ 警告:此操作将永久删除数据库中的所有数据,无法恢复!
68
- *
69
- * 安全机制:
70
- * 1. 必须显式传入 { confirm: true } 才能执行
71
- * 2. 生产环境默认禁止,需要额外传入 { allowProduction: true }
72
- * 3. 所有删除操作都会记录审计日志
73
- *
74
- * @param {string} databaseName - 数据库名称
75
- * @param {Object} options - 选项
76
- * @param {boolean} options.confirm - 必须为 true 才能执行
77
- * @param {boolean} [options.allowProduction=false] - 是否允许在生产环境执行
78
- * @param {string} [options.user] - 操作用户(用于审计日志)
79
- * @returns {Promise<Object>} 删除结果
80
- * @property {boolean} dropped - 是否删除成功
81
- * @property {string} database - 被删除的数据库名称
82
- * @throws {ValidationError} 如果未确认或在生产环境禁止执行
83
- *
84
- * @example
85
- * // ❌ 错误:未提供确认
86
- * try {
87
- * await monSQLize.dropDatabase('mydb');
88
- * } catch (error) {
89
- * console.error(error.message);
90
- * // "dropDatabase requires explicit confirmation..."
91
- * }
92
- *
93
- * // ✅ 正确:提供确认
94
- * const result = await monSQLize.dropDatabase('test_db', {
95
- * confirm: true,
96
- * user: 'admin@example.com'
97
- * });
98
- * console.log('Database dropped:', result.database);
99
- *
100
- * // ⚠️ 生产环境:需要额外确认
101
- * const result = await monSQLize.dropDatabase('prod_db', {
102
- * confirm: true,
103
- * allowProduction: true,
104
- * user: 'admin@example.com'
105
- * });
106
- */
107
- async dropDatabase(databaseName, options = {}) {
108
- // 1. 参数验证
109
- if (!databaseName || typeof databaseName !== 'string') {
110
- throw createValidationError(
111
- 'Database name is required and must be a string',
112
- 'INVALID_DATABASE_NAME'
113
- );
114
- }
115
-
116
- // 2. 强制确认机制
117
- if (!options.confirm) {
118
- const error = new Error(
119
- 'dropDatabase requires explicit confirmation. ' +
120
- 'Pass { confirm: true } to proceed.\n\n' +
121
- '⚠️ WARNING: This will DELETE ALL DATA in the database!\n' +
122
- '⚠️ This operation CANNOT BE UNDONE!\n\n' +
123
- 'Example:\n' +
124
- ` await db.dropDatabase('${databaseName}', { confirm: true })`
125
- );
126
- error.code = 'CONFIRMATION_REQUIRED';
127
- throw error;
128
- }
129
-
130
- // 3. 生产环境保护
131
- const isProduction = process.env.NODE_ENV === 'production';
132
- if (isProduction && !options.allowProduction) {
133
- const error = new Error(
134
- 'dropDatabase is blocked in production environment.\n\n' +
135
- '⚠️ You are in PRODUCTION mode!\n\n' +
136
- 'If you really want to proceed, pass { allowProduction: true }.\n' +
137
- 'Make sure you have:\n' +
138
- ' 1. Created a backup\n' +
139
- ' 2. Verified this is the correct database\n' +
140
- ' 3. Obtained necessary approvals\n\n' +
141
- 'Example:\n' +
142
- ` await db.dropDatabase('${databaseName}', {\n` +
143
- ' confirm: true,\n' +
144
- ' allowProduction: true,\n' +
145
- " user: 'your-email@example.com'\n" +
146
- ' })'
147
- );
148
- error.code = 'PRODUCTION_BLOCKED';
149
- throw error;
150
- }
151
-
152
- // 4. 审计日志(记录所有删除尝试)
153
- logger.warn('dropDatabase called', {
154
- event: 'DROP_DATABASE',
155
- database: databaseName,
156
- user: options.user || 'unknown',
157
- timestamp: new Date().toISOString(),
158
- environment: process.env.NODE_ENV || 'development',
159
- confirmed: true
160
- });
161
-
162
- try {
163
- // 5. 执行删除 - 使用 admin 数据库执行 dropDatabase 命令
164
- const client = adapter.client;
165
- const targetDb = client.db(databaseName);
166
- await targetDb.dropDatabase();
167
-
168
- // 6. 成功日志
169
- logger.info('dropDatabase successful', {
170
- event: 'DROP_DATABASE_SUCCESS',
171
- database: databaseName,
172
- user: options.user || 'unknown',
173
- timestamp: new Date().toISOString()
174
- });
175
-
176
- return {
177
- dropped: true,
178
- database: databaseName,
179
- timestamp: new Date()
180
- };
181
- } catch (error) {
182
- // 7. 失败日志
183
- logger.error('dropDatabase failed', {
184
- event: 'DROP_DATABASE_FAILED',
185
- database: databaseName,
186
- user: options.user || 'unknown',
187
- error: error.message,
188
- timestamp: new Date().toISOString()
189
- });
190
-
191
- throw createValidationError(
192
- `Failed to drop database '${databaseName}': ${error.message}`,
193
- 'DROP_DATABASE_ERROR'
194
- );
195
- }
196
- }
197
- };
198
- }
199
-
200
- module.exports = { createDatabaseOps };
201
-
202
-