monsqlize 1.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 (77) hide show
  1. package/CHANGELOG.md +2474 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1368 -0
  4. package/index.d.ts +1052 -0
  5. package/lib/cache.js +491 -0
  6. package/lib/common/cursor.js +58 -0
  7. package/lib/common/docs-urls.js +72 -0
  8. package/lib/common/index-options.js +222 -0
  9. package/lib/common/log.js +60 -0
  10. package/lib/common/namespace.js +21 -0
  11. package/lib/common/normalize.js +33 -0
  12. package/lib/common/page-result.js +42 -0
  13. package/lib/common/runner.js +56 -0
  14. package/lib/common/server-features.js +231 -0
  15. package/lib/common/shape-builders.js +26 -0
  16. package/lib/common/validation.js +49 -0
  17. package/lib/connect.js +76 -0
  18. package/lib/constants.js +54 -0
  19. package/lib/count-queue.js +187 -0
  20. package/lib/distributed-cache-invalidator.js +259 -0
  21. package/lib/errors.js +157 -0
  22. package/lib/index.js +352 -0
  23. package/lib/logger.js +224 -0
  24. package/lib/model/examples/test.js +114 -0
  25. package/lib/mongodb/common/accessor-helpers.js +44 -0
  26. package/lib/mongodb/common/agg-pipeline.js +32 -0
  27. package/lib/mongodb/common/iid.js +27 -0
  28. package/lib/mongodb/common/lexicographic-expr.js +52 -0
  29. package/lib/mongodb/common/shape.js +31 -0
  30. package/lib/mongodb/common/sort.js +38 -0
  31. package/lib/mongodb/common/transaction-aware.js +24 -0
  32. package/lib/mongodb/connect.js +178 -0
  33. package/lib/mongodb/index.js +458 -0
  34. package/lib/mongodb/management/admin-ops.js +199 -0
  35. package/lib/mongodb/management/bookmark-ops.js +166 -0
  36. package/lib/mongodb/management/cache-ops.js +49 -0
  37. package/lib/mongodb/management/collection-ops.js +386 -0
  38. package/lib/mongodb/management/database-ops.js +201 -0
  39. package/lib/mongodb/management/index-ops.js +474 -0
  40. package/lib/mongodb/management/index.js +16 -0
  41. package/lib/mongodb/management/namespace.js +30 -0
  42. package/lib/mongodb/management/validation-ops.js +267 -0
  43. package/lib/mongodb/queries/aggregate.js +133 -0
  44. package/lib/mongodb/queries/chain.js +623 -0
  45. package/lib/mongodb/queries/count.js +88 -0
  46. package/lib/mongodb/queries/distinct.js +68 -0
  47. package/lib/mongodb/queries/find-and-count.js +183 -0
  48. package/lib/mongodb/queries/find-by-ids.js +235 -0
  49. package/lib/mongodb/queries/find-one-by-id.js +170 -0
  50. package/lib/mongodb/queries/find-one.js +61 -0
  51. package/lib/mongodb/queries/find-page.js +565 -0
  52. package/lib/mongodb/queries/find.js +161 -0
  53. package/lib/mongodb/queries/index.js +49 -0
  54. package/lib/mongodb/writes/delete-many.js +181 -0
  55. package/lib/mongodb/writes/delete-one.js +173 -0
  56. package/lib/mongodb/writes/find-one-and-delete.js +193 -0
  57. package/lib/mongodb/writes/find-one-and-replace.js +222 -0
  58. package/lib/mongodb/writes/find-one-and-update.js +223 -0
  59. package/lib/mongodb/writes/increment-one.js +243 -0
  60. package/lib/mongodb/writes/index.js +41 -0
  61. package/lib/mongodb/writes/insert-batch.js +498 -0
  62. package/lib/mongodb/writes/insert-many.js +218 -0
  63. package/lib/mongodb/writes/insert-one.js +171 -0
  64. package/lib/mongodb/writes/replace-one.js +199 -0
  65. package/lib/mongodb/writes/result-handler.js +236 -0
  66. package/lib/mongodb/writes/update-many.js +205 -0
  67. package/lib/mongodb/writes/update-one.js +207 -0
  68. package/lib/mongodb/writes/upsert-one.js +190 -0
  69. package/lib/multi-level-cache.js +189 -0
  70. package/lib/operators.js +330 -0
  71. package/lib/redis-cache-adapter.js +237 -0
  72. package/lib/transaction/CacheLockManager.js +161 -0
  73. package/lib/transaction/DistributedCacheLockManager.js +239 -0
  74. package/lib/transaction/Transaction.js +314 -0
  75. package/lib/transaction/TransactionManager.js +266 -0
  76. package/lib/transaction/index.js +10 -0
  77. package/package.json +111 -0
package/index.d.ts ADDED
@@ -0,0 +1,1052 @@
1
+ declare module 'monsqlize' {
2
+ type DbType = 'mongodb';
3
+
4
+ /**
5
+ * 日志记录器接口
6
+ * v2.0 新增:支持 traceId 和结构化日志
7
+ */
8
+ interface LoggerLike {
9
+ debug?: (...args: any[]) => void;
10
+ info?: (...args: any[]) => void;
11
+ warn?: (...args: any[]) => void;
12
+ error?: (...args: any[]) => void;
13
+ withTraceId?: (fn: Function, traceId?: string) => any;
14
+ getTraceId?: () => string | null;
15
+ }
16
+
17
+ /**
18
+ * 日志选项
19
+ */
20
+ interface LoggerOptions {
21
+ /** 是否使用结构化日志(JSON 格式) */
22
+ structured?: boolean;
23
+ /** 是否启用 traceId(分布式追踪) */
24
+ enableTraceId?: boolean;
25
+ }
26
+
27
+ /**
28
+ * 统一错误码
29
+ */
30
+ const enum ErrorCodes {
31
+ VALIDATION_ERROR = 'VALIDATION_ERROR',
32
+ INVALID_COLLECTION_NAME = 'INVALID_COLLECTION_NAME',
33
+ INVALID_DATABASE_NAME = 'INVALID_DATABASE_NAME',
34
+ INVALID_CURSOR = 'INVALID_CURSOR',
35
+ CURSOR_SORT_MISMATCH = 'CURSOR_SORT_MISMATCH',
36
+ JUMP_TOO_FAR = 'JUMP_TOO_FAR',
37
+ STREAM_NO_JUMP = 'STREAM_NO_JUMP',
38
+ STREAM_NO_TOTALS = 'STREAM_NO_TOTALS',
39
+ CONNECTION_TIMEOUT = 'CONNECTION_TIMEOUT',
40
+ CONNECTION_FAILED = 'CONNECTION_FAILED',
41
+ CONNECTION_CLOSED = 'CONNECTION_CLOSED',
42
+ DATABASE_ERROR = 'DATABASE_ERROR',
43
+ QUERY_TIMEOUT = 'QUERY_TIMEOUT',
44
+ CACHE_ERROR = 'CACHE_ERROR',
45
+ CACHE_TIMEOUT = 'CACHE_TIMEOUT',
46
+ INVALID_CONFIG = 'INVALID_CONFIG',
47
+ UNSUPPORTED_DATABASE = 'UNSUPPORTED_DATABASE',
48
+ }
49
+
50
+ // ============================================================================
51
+ // 事务相关类型定义(Transaction API)
52
+ // ============================================================================
53
+
54
+ /**
55
+ * MongoDB 事务会话(原生 ClientSession)
56
+ * @since v0.2.0
57
+ */
58
+ interface MongoSession {
59
+ /** 会话 ID */
60
+ id: any;
61
+ /** 是否在事务中 */
62
+ inTransaction(): boolean;
63
+ /** 事务状态 */
64
+ transaction?: {
65
+ state: string;
66
+ };
67
+ /** 结束会话 */
68
+ endSession(): void;
69
+ /** 其他 MongoDB 原生方法 */
70
+ [key: string]: any;
71
+ }
72
+
73
+ /**
74
+ * 事务选项配置
75
+ * @since v0.2.0
76
+ */
77
+ interface TransactionOptions {
78
+ /** 读关注级别(Read Concern) */
79
+ readConcern?: {
80
+ level: 'local' | 'majority' | 'snapshot' | 'linearizable' | 'available';
81
+ };
82
+ /** 读偏好(Read Preference) */
83
+ readPreference?: 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest';
84
+ /** 因果一致性(Causal Consistency) */
85
+ causalConsistency?: boolean;
86
+ /** 事务最大执行时间(毫秒) */
87
+ maxDuration?: number;
88
+ /** 是否启用自动重试 */
89
+ enableRetry?: boolean;
90
+ /** 最大重试次数 */
91
+ maxRetries?: number;
92
+ /** 重试延迟(毫秒) */
93
+ retryDelay?: number;
94
+ /** 重试退避系数 */
95
+ retryBackoff?: number;
96
+ /** 是否启用缓存锁 */
97
+ enableCacheLock?: boolean;
98
+ /** 缓存锁清理间隔(毫秒) */
99
+ lockCleanupInterval?: number;
100
+ }
101
+
102
+ /**
103
+ * Transaction 事务类
104
+ * 封装 MongoDB 原生会话,提供事务生命周期管理
105
+ * @since v0.2.0
106
+ */
107
+ interface Transaction {
108
+ /** 事务唯一 ID */
109
+ readonly id: string;
110
+
111
+ /** MongoDB 原生会话对象(传递给查询方法) */
112
+ readonly session: MongoSession;
113
+
114
+ /**
115
+ * 启动事务
116
+ * @returns Promise<void>
117
+ */
118
+ start(): Promise<void>;
119
+
120
+ /**
121
+ * 提交事务
122
+ * @returns Promise<void>
123
+ */
124
+ commit(): Promise<void>;
125
+
126
+ /**
127
+ * 中止(回滚)事务
128
+ * @returns Promise<void>
129
+ */
130
+ abort(): Promise<void>;
131
+
132
+ /**
133
+ * 结束会话(清理资源)
134
+ * @returns Promise<void>
135
+ */
136
+ end(): Promise<void>;
137
+
138
+ /**
139
+ * 获取事务执行时长(毫秒)
140
+ * @returns number
141
+ */
142
+ getDuration(): number;
143
+
144
+ /**
145
+ * 获取事务信息
146
+ * @returns 事务状态信息
147
+ */
148
+ getInfo(): {
149
+ id: string;
150
+ status: 'pending' | 'started' | 'committed' | 'aborted';
151
+ duration: number;
152
+ sessionId: string;
153
+ };
154
+ }
155
+
156
+ /**
157
+ * 标准错误接口
158
+ */
159
+ interface MonSQLizeError extends Error {
160
+ code: string;
161
+ details?: any[];
162
+ cause?: Error;
163
+ }
164
+
165
+ interface CacheLike {
166
+ get(key: string): Promise<any>;
167
+ set(key: string, val: any, ttl?: number): Promise<void>;
168
+ del(key: string): Promise<boolean>;
169
+ exists(key: string): Promise<boolean>;
170
+ getMany(keys: string[]): Promise<Record<string, any>>;
171
+ setMany(obj: Record<string, any>, ttl?: number): Promise<boolean>;
172
+ delMany(keys: string[]): Promise<number>;
173
+ delPattern(pattern: string): Promise<number>;
174
+ clear(): void;
175
+ keys(pattern?: string): string[];
176
+ getStats?(): any;
177
+ }
178
+
179
+ /**
180
+ * 内置内存缓存的配置(MemoryCacheOptions)
181
+ * - maxSize: 最大键数量(默认 100000)
182
+ * - maxMemory: 最大内存占用(字节;0 表示不限制)
183
+ * - enableStats: 是否启用统计,默认 true
184
+ */
185
+ interface MemoryCacheOptions {
186
+ maxSize?: number;
187
+ maxMemory?: number;
188
+ enableStats?: boolean;
189
+ // 允许透传其他实现细节,但不做强约束
190
+ [k: string]: any;
191
+ }
192
+
193
+ /**
194
+ * 多层缓存写策略
195
+ * - both:本地+远端双写(等待远端完成)
196
+ * - local-first-async-remote:本地先返回,远端异步写(降低尾延迟)
197
+ */
198
+ type WritePolicy = 'both' | 'local-first-async-remote';
199
+
200
+ interface MultiLevelCachePolicy {
201
+ writePolicy?: WritePolicy;
202
+ /** 远端命中后是否回填本地,默认 true */
203
+ backfillLocalOnRemoteHit?: boolean;
204
+ }
205
+
206
+ /**
207
+ * 多层缓存配置对象(配置式启用双层缓存)
208
+ * 说明:当 BaseOptions.cache 传入该对象时(且 multiLevel=true),框架会自动创建 MultiLevelCache:
209
+ * - local:始终使用内置内存缓存(仅接受配置对象 MemoryCacheOptions)
210
+ * - remote:可传 CacheLike 实例(推荐生产),或传配置对象以退化为“内存占位”
211
+ * - remote.timeoutMs:远端操作超时(毫秒,默认 50)
212
+ * - publish:可选的广播函数(例如用于 pub/sub 触发跨进程本地失效)
213
+ */
214
+ interface MultiLevelCacheOptions {
215
+ multiLevel: true;
216
+ local?: MemoryCacheOptions;
217
+ remote?: CacheLike | (MemoryCacheOptions & { timeoutMs?: number });
218
+ policy?: MultiLevelCachePolicy;
219
+ publish?: (msg: any) => void;
220
+ }
221
+ interface BaseOptions {
222
+ type: DbType;
223
+ databaseName: string;
224
+ config: any;
225
+ cache?: CacheLike | MemoryCacheOptions | MultiLevelCacheOptions | object;
226
+ logger?: LoggerLike;
227
+ maxTimeMS?: number; // 全局默认查询超时(毫秒)
228
+ findLimit?: number; // 全局默认 find limit(未传 limit 时使用;0 表示不限制)
229
+ namespace?: { instanceId?: string; scope?: 'database' | 'connection' };
230
+ slowQueryMs?: number; // 慢查询日志阈值(毫秒),默认 500
231
+ /** MongoDB 副本集读偏好(全局配置)
232
+ * - 'primary': 仅读主节点(默认)
233
+ * - 'primaryPreferred': 优先读主节点,主节点不可用时读从节点
234
+ * - 'secondary': 仅读从节点
235
+ * - 'secondaryPreferred': 优先读从节点,从节点不可用时读主节点
236
+ * - 'nearest': 读最近的节点(低延迟)
237
+ */
238
+ readPreference?: 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest';
239
+ /**
240
+ * 事务配置(MongoDB Transaction API)
241
+ * 需要 MongoDB 4.0+ 且部署在副本集或分片集群上
242
+ * @since v0.2.0
243
+ */
244
+ transaction?: TransactionOptions | false;
245
+ // 统一默认(新增可选项)
246
+ findPageMaxLimit?: number; // 深分页页大小上限(默认 500)
247
+ cursorSecret?: string; // 可选:游标签名密钥(如启用 HMAC 验签)
248
+ log?: {
249
+ slowQueryTag?: { event?: string; code?: string };
250
+ formatSlowQuery?: (meta: any) => any;
251
+ };
252
+ }
253
+ interface FindOptions {
254
+ projection?: Record<string, any> | string[];
255
+ sort?: Record<string, 1 | -1>;
256
+ limit?: number;
257
+ skip?: number;
258
+ cache?: number;
259
+ maxTimeMS?: number;
260
+ /** Mongo-only: 透传 hint 到驱动 */
261
+ hint?: any;
262
+ /** Mongo-only: 透传 collation 到驱动 */
263
+ collation?: any;
264
+ /** 查询注释(用于生产环境日志跟踪)*/
265
+ comment?: string;
266
+ meta?: boolean | MetaOptions; // 返回耗时元信息
267
+ }
268
+ interface CountOptions {
269
+ cache?: number;
270
+ maxTimeMS?: number;
271
+ /** Mongo-only: 透传 hint 到 countDocuments */
272
+ hint?: any;
273
+ /** Mongo-only: 透传 collation 到 countDocuments */
274
+ collation?: any;
275
+ /** 查询注释(用于生产环境日志跟踪)*/
276
+ comment?: string;
277
+ meta?: boolean | MetaOptions;
278
+ }
279
+
280
+ interface AggregateOptions {
281
+ cache?: number; // 缓存时间(毫秒),默认 0(不缓存)
282
+ maxTimeMS?: number; // 查询超时时间(毫秒)
283
+ allowDiskUse?: boolean; // 是否允许使用磁盘(默认 false)
284
+ collation?: any; // 排序规则(可选)
285
+ hint?: string | object; // 索引提示(可选)
286
+ comment?: string; // 查询注释(可选)
287
+ meta?: boolean | MetaOptions; // 返回耗时元信息
288
+ }
289
+
290
+ interface DistinctOptions {
291
+ cache?: number; // 缓存时间(毫秒),默认继承实例缓存配置
292
+ maxTimeMS?: number; // 查询超时时间(毫秒)
293
+ collation?: any; // 排序规则(可选)
294
+ hint?: string | object; // 索引提示(可选)
295
+ meta?: boolean | MetaOptions; // 返回耗时元信息
296
+ }
297
+
298
+ // 写入操作相关接口
299
+ interface WriteConcern {
300
+ w?: number | 'majority'; // 写确认级别(默认 1)
301
+ j?: boolean; // 是否等待日志落盘(默认 false)
302
+ wtimeout?: number; // 写超时时间(毫秒)
303
+ }
304
+
305
+ interface InsertOneOptions {
306
+ document: any; // 要插入的文档
307
+ writeConcern?: WriteConcern; // 写确认级别(可选)
308
+ bypassDocumentValidation?: boolean; // 跳过文档验证(可选)
309
+ comment?: string; // 查询注释(用于生产环境日志跟踪)
310
+ }
311
+
312
+ interface InsertOneResult {
313
+ acknowledged: boolean; // 是否被确认
314
+ insertedId: any; // 插入的文档 _id
315
+ }
316
+
317
+ interface InsertManyOptions {
318
+ documents: any[]; // 要插入的文档数组
319
+ ordered?: boolean; // 是否有序插入(默认 true)
320
+ writeConcern?: WriteConcern; // 写确认级别(可选)
321
+ bypassDocumentValidation?: boolean; // 跳过文档验证(可选)
322
+ comment?: string; // 查询注释(用于生产环境日志跟踪)
323
+ }
324
+
325
+ interface InsertManyResult {
326
+ acknowledged: boolean; // 是否被确认
327
+ insertedCount: number; // 成功插入的文档数量
328
+ insertedIds: { [key: number]: any }; // 插入的文档 _id 映射表
329
+ }
330
+
331
+ interface StreamOptions {
332
+ projection?: Record<string, any> | string[]; // 字段投影
333
+ sort?: Record<string, 1 | -1>; // 排序配置
334
+ limit?: number; // 限制返回数量
335
+ skip?: number; // 跳过数量
336
+ batchSize?: number; // 每批次大小(默认 1000)
337
+ maxTimeMS?: number; // 查询超时时间(毫秒)
338
+ hint?: any; // 索引提示
339
+ collation?: any; // 排序规则
340
+ noCursorTimeout?: boolean; // 禁用游标超时(默认 false)
341
+ }
342
+
343
+ // Explain 选项(查询执行计划诊断)
344
+ interface ExplainOptions {
345
+ projection?: object; // 字段投影
346
+ sort?: Record<string, 1 | -1>; // 排序配置
347
+ limit?: number; // 限制返回数量
348
+ skip?: number; // 跳过数量
349
+ maxTimeMS?: number; // 查询超时时间(毫秒)
350
+ hint?: any; // 索引提示
351
+ collation?: any; // 排序规则
352
+ verbosity?: 'queryPlanner' | 'executionStats' | 'allPlansExecution'; // 详细程度(默认 'queryPlanner')
353
+ }
354
+
355
+ // Bookmark 维护 APIs 相关接口
356
+ interface BookmarkKeyDims {
357
+ sort?: Record<string, 1 | -1>; // 排序配置(与 findPage 一致)
358
+ limit?: number; // 每页数量
359
+ query?: object; // 查询条件(用于计算 queryShape)
360
+ pipeline?: object[]; // 聚合管道(用于计算 pipelineShape)
361
+ }
362
+
363
+ interface PrewarmBookmarksResult {
364
+ warmed: number; // 成功预热的 bookmark 数量
365
+ failed: number; // 预热失败的 bookmark 数量
366
+ keys: string[]; // 已缓存的 bookmark 键列表
367
+ }
368
+
369
+ interface ListBookmarksResult {
370
+ count: number; // bookmark 总数
371
+ pages: number[]; // 已缓存的页码列表(排序后)
372
+ keys: string[]; // 缓存键列表
373
+ }
374
+
375
+ interface ClearBookmarksResult {
376
+ cleared: number; // 清除的 bookmark 数量
377
+ pattern: string; // 使用的匹配模式
378
+ keysBefore: number; // 清除前的 bookmark 数量
379
+ }
380
+
381
+ // 跳页相关类型
382
+ interface JumpOptions {
383
+ step?: number; // 书签密度:每隔 step 页存一个书签;默认 10
384
+ maxHops?: number; // 单次跳页允许的"连续 after 次数(累计)"上限;默认 20
385
+ keyDims?: object; // 可选;未传则自动生成去敏形状
386
+ getBookmark?: (params: { keyDims: any; page: number }) => Promise<string | null>;
387
+ saveBookmark?: (params: { keyDims: any; page: number; cursor: string; ttlMs?: number }) => Promise<void>;
388
+ }
389
+
390
+ interface OffsetJumpOptions {
391
+ enable?: boolean; // 开启后,当 skip=(page-1)*limit ≤ maxSkip 时走 `$skip+$limit`
392
+ maxSkip?: number; // 默认 50_000;超过则回退到"书签跳转"逻辑
393
+ }
394
+
395
+ interface TotalsOptions {
396
+ mode?: 'none' | 'async' | 'approx' | 'sync'; // 默认 'none'
397
+ maxTimeMS?: number; // 用于 `countDocuments` 的超时(sync/async)
398
+ ttlMs?: number; // 总数缓存 TTL(async/approx),默认 10 分钟
399
+ hint?: any; // 计数 hint(可选)
400
+ collation?: any; // 计数 collation(可选,与列表一致更安全)
401
+ }
402
+
403
+ interface MetaOptions {
404
+ level?: 'op' | 'sub'; // sub: 返回子步骤耗时(仅 findPage)
405
+ includeCache?: boolean; // 包含缓存相关信息
406
+ }
407
+
408
+ // 深度分页(统一版)选项与返回类型
409
+ interface FindPageOptions extends FindOptions {
410
+ pipeline?: object[];
411
+ after?: string;
412
+ before?: string;
413
+ limit: number;
414
+ allowDiskUse?: boolean;
415
+ /** Mongo-only: 透传 hint 到 aggregate */
416
+ hint?: any;
417
+ /** Mongo-only: 透传 collation 到 aggregate */
418
+ collation?: any;
419
+
420
+ // 新增:跳页相关参数
421
+ page?: number; // 目标页(≥1);与 after/before 互斥
422
+ jump?: JumpOptions; // 跳页(书签)配置
423
+ offsetJump?: OffsetJumpOptions; // 小范围 offset 兜底
424
+ totals?: TotalsOptions; // 总数/总页数配置
425
+ meta?: boolean | MetaOptions; // 返回耗时元信息
426
+ }
427
+
428
+ interface MetaInfo {
429
+ op: string;
430
+ ns: { iid: string; type: string; db: string; coll: string };
431
+ startTs: number;
432
+ endTs: number;
433
+ durationMs: number;
434
+ maxTimeMS?: number;
435
+ fromCache?: boolean;
436
+ cacheHit?: boolean;
437
+ cacheTtl?: number;
438
+ keyHash?: string;
439
+ // findPage 专用字段
440
+ page?: number;
441
+ after?: boolean;
442
+ before?: boolean;
443
+ hops?: number;
444
+ step?: number;
445
+ steps?: Array<{ phase: 'hop' | 'offset'; index?: number; durationMs: number }>; // level='sub' 时提供
446
+ error?: { code?: string; message: string };
447
+ }
448
+
449
+ interface TotalsInfo {
450
+ mode: 'async' | 'sync' | 'approx';
451
+ total?: number | null | undefined; // async: null(未就绪);approx: undefined(未知或近似)
452
+ totalPages?: number | null | undefined;
453
+ token?: string; // async 时返回的短标识(<keyHash>)
454
+ ts?: number; // 写入时间戳(毫秒),如果来自缓存
455
+ error?: string; // 仅 async:统计失败时可能附带的错误标识
456
+ }
457
+
458
+ interface PageInfo {
459
+ hasNext: boolean;
460
+ hasPrev: boolean;
461
+ startCursor: string | null;
462
+ endCursor: string | null;
463
+ currentPage?: number; // 仅跳页/offset 模式回显目标页号(逻辑页号)
464
+ }
465
+
466
+ interface PageResult<T = any> {
467
+ items: T[];
468
+ pageInfo: PageInfo;
469
+ totals?: TotalsInfo; // 当启用 totals 时返回
470
+ meta?: MetaInfo; // 当启用 meta 时返回
471
+ }
472
+
473
+ // 带 meta 的返回类型(用于 findOne/find/count)
474
+ interface ResultWithMeta<T = any> {
475
+ data: T;
476
+ meta: MetaInfo;
477
+ }
478
+
479
+ interface HealthView {
480
+ status: 'up' | 'down';
481
+ connected: boolean;
482
+ defaults?: any;
483
+ cache?: any;
484
+ driver?: { connected: boolean };
485
+ }
486
+
487
+ interface CollectionAccessor {
488
+ getNamespace(): { iid: string; type: string; db: string; collection: string };
489
+ dropCollection(): Promise<boolean>;
490
+ createCollection(name?: string | null, options?: any): Promise<boolean>;
491
+ createView(viewName: string, source: string, pipeline?: any[]): Promise<boolean>;
492
+
493
+ // findOne 重载:支持 meta 参数
494
+ findOne(query?: any, options?: Omit<FindOptions, 'meta'>): Promise<any | null>;
495
+ findOne(query: any, options: FindOptions & { meta: true | MetaOptions }): Promise<ResultWithMeta<any | null>>;
496
+ findOne(query?: any, options?: FindOptions): Promise<any | null | ResultWithMeta<any | null>>;
497
+
498
+ /**
499
+ * 通过 _id 查询单个文档(便利方法)
500
+ * @param id - 文档的 _id(字符串会自动转换为 ObjectId)
501
+ * @param options - 查询选项(支持 projection, cache, maxTimeMS, comment)
502
+ * @returns Promise<文档 | null>
503
+ * @throws {Error} 当 id 参数无效时
504
+ * @example
505
+ * // 字符串 ID(自动转换)
506
+ * const user = await collection('users').findOneById('507f1f77bcf86cd799439011');
507
+ *
508
+ * @example
509
+ * // ObjectId
510
+ * const user = await collection('users').findOneById(new ObjectId(userId));
511
+ *
512
+ * @example
513
+ * // 带选项
514
+ * const user = await collection('users').findOneById(userId, {
515
+ * projection: { name: 1, email: 1 },
516
+ * cache: 5000
517
+ * });
518
+ */
519
+ findOneById(id: string | any, options?: Omit<FindOptions, 'meta'>): Promise<any | null>;
520
+
521
+ u /**
522
+ * 批量通过 _id 查询多个文档(便利方法)
523
+ * @param ids - _id 数组(支持字符串和 ObjectId 混合)
524
+ * @param options - 查询选项
525
+ * @returns Promise<文档数组>
526
+ * @throws {Error} 当 ids 参数无效时
527
+ * @example
528
+ * // 字符串 ID 数组
529
+ * const users = await collection('users').findByIds([
530
+ * '507f1f77bcf86cd799439011',
531
+ * '507f1f77bcf86cd799439012'
532
+ * ]);
533
+ *
534
+ * @example
535
+ * // ObjectId 数组
536
+ * const users = await collection('users').findByIds([
537
+ * new ObjectId('507f1f77bcf86cd799439011'),
538
+ * new ObjectId('507f1f77bcf86cd799439012')
539
+ * ]);
540
+ *
541
+ * @example
542
+ * // 混合类型 + 选项
543
+ * const users = await collection('users').findByIds(
544
+ * ['507f1f77bcf86cd799439011', new ObjectId('507f1f77bcf86cd799439012')],
545
+ * {
546
+ * projection: { name: 1, email: 1 },
547
+ * sort: { name: 1 },
548
+ * cache: 5000,
549
+ * preserveOrder: true
550
+ * }
551
+ * );
552
+ */
553
+ findByIds(
554
+ ids: Array<string | any>,
555
+ options?: {
556
+ projection?: Record<string, any>;
557
+ sort?: Record<string, 1 | -1>;
558
+ cache?: number;
559
+ maxTimeMS?: number;
560
+ comment?: string;
561
+ preserveOrder?: boolean;
562
+ }
563
+ ): Promise<any[]>;
564
+
565
+ // find 重载:支持 meta 参数和链式调用 (v2.0+)
566
+ find<T = any>(query?: any): FindChain<T>;
567
+ find<T = any>(query: any, options: FindOptions & { meta: true | MetaOptions }): Promise<ResultWithMeta<T[]>>;
568
+ find<T = any>(query?: any, options?: FindOptions): Promise<T[]> | FindChain<T> | ResultWithMeta<T[]>;
569
+
570
+ // count 重载:支持 meta 参数
571
+ count(query?: any, options?: Omit<CountOptions, 'meta'>): Promise<number>;
572
+ count(query: any, options: CountOptions & { meta: true | MetaOptions }): Promise<ResultWithMeta<number>>;
573
+ count(query?: any, options?: CountOptions): Promise<number | ResultWithMeta<number>>;
574
+
575
+ // aggregate 重载:支持 meta 参数和链式调用 (v2.0+)
576
+ aggregate<T = any>(pipeline?: any[]): AggregateChain<T>;
577
+ aggregate<T = any>(pipeline: any[], options: AggregateOptions & { meta: true | MetaOptions }): Promise<ResultWithMeta<T[]>>;
578
+ aggregate<T = any>(pipeline?: any[], options?: AggregateOptions): Promise<T[]> | AggregateChain<T> | ResultWithMeta<T[]>;
579
+
580
+ // distinct 重载:支持 meta 参数
581
+ distinct<T = any>(field: string, query?: any, options?: Omit<DistinctOptions, 'meta'>): Promise<T[]>;
582
+ distinct<T = any>(field: string, query: any, options: DistinctOptions & { meta: true | MetaOptions }): Promise<ResultWithMeta<T[]>>;
583
+ distinct<T = any>(field: string, query?: any, options?: DistinctOptions): Promise<T[] | ResultWithMeta<T[]>>;
584
+
585
+ // stream:返回 Node.js 可读流
586
+ stream(query?: any, options?: StreamOptions): NodeJS.ReadableStream;
587
+
588
+ // explain:查询执行计划诊断
589
+ explain(query?: any, options?: ExplainOptions): Promise<any>;
590
+
591
+ // Bookmark 维护 APIs
592
+ prewarmBookmarks(keyDims: BookmarkKeyDims, pages: number[]): Promise<PrewarmBookmarksResult>;
593
+ listBookmarks(keyDims?: BookmarkKeyDims): Promise<ListBookmarksResult>;
594
+ clearBookmarks(keyDims?: BookmarkKeyDims): Promise<ClearBookmarksResult>;
595
+
596
+ // findPage:已在 PageResult 中包含 meta 字段,无需重载
597
+ findPage(options: FindPageOptions): Promise<PageResult>;
598
+
599
+ // 写入操作
600
+ insertOne(options: InsertOneOptions): Promise<InsertOneResult>;
601
+ insertMany(options: InsertManyOptions): Promise<InsertManyResult>;
602
+
603
+ /**
604
+ * Upsert 单个文档(存在则更新,不存在则插入)- 便利方法
605
+ * @param filter - 查询条件
606
+ * @param update - 更新内容(直接字段或操作符)
607
+ * @param options - 操作选项
608
+ * @returns Promise<UpsertOneResult>
609
+ * @example
610
+ * // 基础用法(自动包装 $set)
611
+ * const result = await collection('users').upsertOne(
612
+ * { userId: 'user123' },
613
+ * { name: 'Alice', age: 30 }
614
+ * );
615
+ *
616
+ * @example
617
+ * // 使用更新操作符
618
+ * const result = await collection('users').upsertOne(
619
+ * { userId: 'user123' },
620
+ * { $set: { name: 'Alice' }, $inc: { count: 1 } }
621
+ * );
622
+ *
623
+ * @example
624
+ * // 带选项
625
+ * const result = await collection('configs').upsertOne(
626
+ * { key: 'theme' },
627
+ * { value: 'dark' },
628
+ * { maxTimeMS: 5000, comment: 'sync-config' }
629
+ * );
630
+ */
631
+ upsertOne(
632
+ filter: Record<string, any>,
633
+ update: Record<string, any>,
634
+ options?: {
635
+ maxTimeMS?: number;
636
+ comment?: string;
637
+ }
638
+ ): Promise<{
639
+ acknowledged: boolean;
640
+ matchedCount: number;
641
+ modifiedCount: number;
642
+ upsertedId?: any;
643
+ upsertedCount: number;
644
+ }>;
645
+
646
+ /**
647
+ * 原子递增/递减字段值(便利方法)
648
+ * @param filter - 查询条件
649
+ * @param field - 字段名或字段-增量对象
650
+ * @param increment - 增量(默认 1,负数为递减)
651
+ * @param options - 操作选项
652
+ * @returns Promise<IncrementOneResult>
653
+ */
654
+ incrementOne(
655
+ filter: Record<string, any>,
656
+ field: string | Record<string, number>,
657
+ increment?: number,
658
+ options?: {
659
+ returnDocument?: 'before' | 'after';
660
+ projection?: Record<string, any>;
661
+ maxTimeMS?: number;
662
+ comment?: string;
663
+ }
664
+ ): Promise<{
665
+ acknowledged: boolean;
666
+ matchedCount: number;
667
+ modifiedCount: number;
668
+ value: any | null;
669
+ }>;
670
+
671
+ invalidate(op?: 'find' | 'findOne' | 'count' | 'findPage' | 'aggregate' | 'distinct'): Promise<number>;
672
+ }
673
+
674
+ type DbAccessor = {
675
+ collection: (name: string) => CollectionAccessor;
676
+ db: (dbName: string) => { collection: (name: string) => CollectionAccessor };
677
+ };
678
+
679
+ export default class MonSQLize {
680
+ constructor(options: BaseOptions);
681
+ connect(): Promise<DbAccessor>;
682
+ getCache(): CacheLike;
683
+ getDefaults(): { maxTimeMS?: number; findLimit?: number; namespace?: { instanceId?: string; scope?: 'database' | 'connection' }; slowQueryMs?: number };
684
+ close(): Promise<void>;
685
+
686
+ /** 事件订阅:connected/closed/error/slow-query/query */
687
+ on(event: 'connected', handler: (payload: { type: string; db: string; scope?: string; iid?: string }) => void): void;
688
+ on(event: 'closed', handler: (payload: { type: string; db: string; iid?: string }) => void): void;
689
+ on(event: 'error', handler: (payload: { type: string; db: string; error: string; iid?: string }) => void): void;
690
+ on(event: 'slow-query', handler: (meta: MetaInfo) => void): void;
691
+ on(event: 'query', handler: (meta: MetaInfo) => void): void;
692
+ on(event: string, handler: (payload: any) => void): void;
693
+
694
+ /** 一次性事件订阅 */
695
+ once(event: 'connected', handler: (payload: { type: string; db: string; scope?: string; iid?: string }) => void): void;
696
+ once(event: 'closed', handler: (payload: { type: string; db: string; iid?: string }) => void): void;
697
+ once(event: 'error', handler: (payload: { type: string; db: string; error: string; iid?: string }) => void): void;
698
+ once(event: 'slow-query', handler: (meta: MetaInfo) => void): void;
699
+ once(event: 'query', handler: (meta: MetaInfo) => void): void;
700
+ once(event: string, handler: (payload: any) => void): void;
701
+
702
+ /** 取消事件订阅 */
703
+ off(event: 'connected', handler: (payload: { type: string; db: string; scope?: string; iid?: string }) => void): void;
704
+ off(event: 'closed', handler: (payload: { type: string; db: string; iid?: string }) => void): void;
705
+ off(event: 'error', handler: (payload: { type: string; db: string; error: string; iid?: string }) => void): void;
706
+ off(event: 'slow-query', handler: (meta: MetaInfo) => void): void;
707
+ off(event: 'query', handler: (meta: MetaInfo) => void): void;
708
+ off(event: string, handler: (payload: any) => void): void;
709
+
710
+ /** 触发事件 */
711
+ emit(event: string, payload: any): void;
712
+
713
+ /** 健康检查 */
714
+ health(): Promise<HealthView>;
715
+
716
+ /**
717
+ * 创建手动事务会话
718
+ * @param options - 事务选项
719
+ * @returns Transaction 实例
720
+ * @since v0.2.0
721
+ * @example
722
+ * const tx = await msq.startTransaction();
723
+ * try {
724
+ * await collection('users').updateOne({...}, {...}, { session: tx.session });
725
+ * await tx.commit();
726
+ * } catch (error) {
727
+ * await tx.abort();
728
+ * }
729
+ */
730
+ startTransaction(options?: TransactionOptions): Promise<Transaction>;
731
+
732
+ /**
733
+ * 自动管理事务生命周期(推荐)
734
+ * @param callback - 事务回调函数
735
+ * @param options - 事务选项
736
+ * @returns 回调函数的返回值
737
+ * @since v0.2.0
738
+ * @example
739
+ * await msq.withTransaction(async (tx) => {
740
+ * await collection('accounts').updateOne({ _id: 'A' }, { $inc: { balance: -100 } }, { session: tx.session });
741
+ * await collection('accounts').updateOne({ _id: 'B' }, { $inc: { balance: 100 } }, { session: tx.session });
742
+ * });
743
+ */
744
+ withTransaction<T = any>(
745
+ callback: (transaction: Transaction) => Promise<T>,
746
+ options?: TransactionOptions
747
+ ): Promise<T>;
748
+ }
749
+
750
+ // ============================================================================
751
+ // 链式调用 API (v2.0+)
752
+ // ============================================================================
753
+
754
+ /**
755
+ * Collation 选项(字符串排序规则)
756
+ */
757
+ interface CollationOptions {
758
+ locale: string; // 语言代码,如 'zh', 'en'
759
+ strength?: number; // 比较级别:1=基本, 2=重音, 3=大小写
760
+ caseLevel?: boolean; // 是否区分大小写
761
+ caseFirst?: 'upper' | 'lower'; // 大小写优先级
762
+ numericOrdering?: boolean; // 数字排序
763
+ alternate?: 'non-ignorable' | 'shifted'; // 空格和标点处理
764
+ maxVariable?: 'punct' | 'space'; // 最大可变字符
765
+ backwards?: boolean; // 反向比较
766
+ }
767
+
768
+ /**
769
+ * Explain 执行计划结果
770
+ */
771
+ interface ExplainResult {
772
+ queryPlanner: {
773
+ plannerVersion: number;
774
+ namespace: string;
775
+ indexFilterSet: boolean;
776
+ parsedQuery?: any;
777
+ winningPlan: any;
778
+ rejectedPlans: any[];
779
+ };
780
+ executionStats?: {
781
+ executionSuccess: boolean;
782
+ nReturned: number;
783
+ executionTimeMillis: number;
784
+ totalKeysExamined: number;
785
+ totalDocsExamined: number;
786
+ executionStages: any;
787
+ allPlansExecution?: any[];
788
+ };
789
+ serverInfo?: {
790
+ host: string;
791
+ port: number;
792
+ version: string;
793
+ gitVersion: string;
794
+ };
795
+ ok: number;
796
+ }
797
+
798
+ /**
799
+ * FindChain - find 查询的链式调用构建器
800
+ *
801
+ * @template T - 文档类型
802
+ *
803
+ * @example
804
+ * // 基础链式调用
805
+ * const results = await collection<Product>('products')
806
+ * .find({ category: 'electronics' })
807
+ * .limit(10)
808
+ * .skip(5)
809
+ * .sort({ price: -1 });
810
+ *
811
+ * @example
812
+ * // 复杂链式调用
813
+ * const results = await collection<Product>('products')
814
+ * .find({ inStock: true })
815
+ * .sort({ rating: -1 })
816
+ * .skip(10)
817
+ * .limit(20)
818
+ * .project({ name: 1, price: 1 })
819
+ * .hint({ category: 1, price: -1 })
820
+ * .maxTimeMS(5000);
821
+ */
822
+ interface FindChain<T = any> extends PromiseLike<T[]> {
823
+ /**
824
+ * 限制返回文档数量
825
+ * @param n - 限制数量,必须为非负数
826
+ * @returns 返回自身以支持链式调用
827
+ * @throws {Error} 如果 n 不是非负数
828
+ */
829
+ limit(n: number): FindChain<T>;
830
+
831
+ /**
832
+ * 跳过指定数量的文档
833
+ * @param n - 跳过数量,必须为非负数
834
+ * @returns 返回自身以支持链式调用
835
+ * @throws {Error} 如果 n 不是非负数
836
+ */
837
+ skip(n: number): FindChain<T>;
838
+
839
+ /**
840
+ * 设置排序规则
841
+ * @param spec - 排序配置,如 { price: -1, name: 1 }
842
+ * @returns 返回自身以支持链式调用
843
+ * @throws {Error} 如果 spec 不是对象或数组
844
+ */
845
+ sort(spec: Record<string, 1 | -1> | Array<[string, 1 | -1]>): FindChain<T>;
846
+
847
+ /**
848
+ * 设置字段投影
849
+ * @param spec - 投影配置,如 { name: 1, price: 1 }
850
+ * @returns 返回带有投影类型的新链
851
+ * @throws {Error} 如果 spec 不是对象或数组
852
+ */
853
+ project<K extends keyof T>(spec: Record<K, 1 | 0> | Array<K>): FindChain<Pick<T, K>>;
854
+ project(spec: Record<string, 1 | 0> | string[]): FindChain<Partial<T>>;
855
+
856
+ /**
857
+ * 设置索引提示(强制使用指定索引)
858
+ * @param spec - 索引名称或索引规格
859
+ * @returns 返回自身以支持链式调用
860
+ * @throws {Error} 如果 spec 为空
861
+ */
862
+ hint(spec: Record<string, 1 | -1> | string): FindChain<T>;
863
+
864
+ /**
865
+ * 设置排序规则(用于字符串排序)
866
+ * @param spec - 排序规则配置
867
+ * @returns 返回自身以支持链式调用
868
+ * @throws {Error} 如果 spec 不是对象
869
+ */
870
+ collation(spec: CollationOptions): FindChain<T>;
871
+
872
+ /**
873
+ * 设置查询注释(用于日志追踪)
874
+ * @param str - 注释内容
875
+ * @returns 返回自身以支持链式调用
876
+ * @throws {Error} 如果 str 不是字符串
877
+ */
878
+ comment(str: string): FindChain<T>;
879
+
880
+ /**
881
+ * 设置查询超时时间
882
+ * @param ms - 超时时间(毫秒)
883
+ * @returns 返回自身以支持链式调用
884
+ * @throws {Error} 如果 ms 不是非负数
885
+ */
886
+ maxTimeMS(ms: number): FindChain<T>;
887
+
888
+ /**
889
+ * 设置批处理大小
890
+ * @param n - 批处理大小
891
+ * @returns 返回自身以支持链式调用
892
+ * @throws {Error} 如果 n 不是非负数
893
+ */
894
+ batchSize(n: number): FindChain<T>;
895
+
896
+ /**
897
+ * 返回查询执行计划(不执行查询)
898
+ * @param verbosity - 详细级别
899
+ * @returns 执行计划
900
+ */
901
+ explain(verbosity?: 'queryPlanner' | 'executionStats' | 'allPlansExecution'): Promise<ExplainResult>;
902
+
903
+ /**
904
+ * 返回流式结果
905
+ * @returns MongoDB 游标流
906
+ */
907
+ stream(): NodeJS.ReadableStream;
908
+
909
+ /**
910
+ * 显式转换为数组(执行查询)
911
+ * @returns 查询结果数组
912
+ * @throws {Error} 如果查询已执行
913
+ */
914
+ toArray(): Promise<T[]>;
915
+
916
+ /**
917
+ * Promise.then 接口
918
+ */
919
+ then<TResult1 = T[], TResult2 = never>(
920
+ onfulfilled?: ((value: T[]) => TResult1 | PromiseLike<TResult1>) | null,
921
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
922
+ ): Promise<TResult1 | TResult2>;
923
+
924
+ /**
925
+ * Promise.catch 接口
926
+ */
927
+ catch<TResult = never>(
928
+ onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
929
+ ): Promise<T[] | TResult>;
930
+
931
+ /**
932
+ * Promise.finally 接口
933
+ */
934
+ finally(onfinally?: (() => void) | null): Promise<T[]>;
935
+ }
936
+
937
+ /**
938
+ * AggregateChain - aggregate 查询的链式调用构建器
939
+ *
940
+ * @template T - 文档类型
941
+ *
942
+ * @example
943
+ * // 基础聚合
944
+ * const results = await collection<Order>('orders')
945
+ * .aggregate([
946
+ * { $match: { status: 'paid' } },
947
+ * { $group: { _id: '$category', total: { $sum: '$amount' } } }
948
+ * ])
949
+ * .allowDiskUse(true);
950
+ *
951
+ * @example
952
+ * // 复杂聚合
953
+ * const results = await collection<Order>('orders')
954
+ * .aggregate([
955
+ * { $match: { status: 'paid' } },
956
+ * { $sort: { createdAt: -1 } },
957
+ * { $limit: 100 }
958
+ * ])
959
+ * .hint({ status: 1, createdAt: -1 })
960
+ * .allowDiskUse(true)
961
+ * .maxTimeMS(10000);
962
+ */
963
+ interface AggregateChain<T = any> extends PromiseLike<T[]> {
964
+ /**
965
+ * 设置索引提示(强制使用指定索引)
966
+ * @param spec - 索引名称或索引规格
967
+ * @returns 返回自身以支持链式调用
968
+ * @throws {Error} 如果 spec 为空
969
+ */
970
+ hint(spec: Record<string, 1 | -1> | string): AggregateChain<T>;
971
+
972
+ /**
973
+ * 设置排序规则(用于字符串排序)
974
+ * @param spec - 排序规则配置
975
+ * @returns 返回自身以支持链式调用
976
+ * @throws {Error} 如果 spec 不是对象
977
+ */
978
+ collation(spec: CollationOptions): AggregateChain<T>;
979
+
980
+ /**
981
+ * 设置查询注释(用于日志追踪)
982
+ * @param str - 注释内容
983
+ * @returns 返回自身以支持链式调用
984
+ * @throws {Error} 如果 str 不是字符串
985
+ */
986
+ comment(str: string): AggregateChain<T>;
987
+
988
+ /**
989
+ * 设置查询超时时间
990
+ * @param ms - 超时时间(毫秒)
991
+ * @returns 返回自身以支持链式调用
992
+ * @throws {Error} 如果 ms 不是非负数
993
+ */
994
+ maxTimeMS(ms: number): AggregateChain<T>;
995
+
996
+ /**
997
+ * 允许使用磁盘进行大数据量排序/分组
998
+ * @param bool - 是否允许
999
+ * @returns 返回自身以支持链式调用
1000
+ * @throws {Error} 如果 bool 不是布尔值
1001
+ */
1002
+ allowDiskUse(bool: boolean): AggregateChain<T>;
1003
+
1004
+ /**
1005
+ * 设置批处理大小
1006
+ * @param n - 批处理大小
1007
+ * @returns 返回自身以支持链式调用
1008
+ * @throws {Error} 如果 n 不是非负数
1009
+ */
1010
+ batchSize(n: number): AggregateChain<T>;
1011
+
1012
+ /**
1013
+ * 返回聚合执行计划(不执行聚合)
1014
+ * @param verbosity - 详细级别
1015
+ * @returns 执行计划
1016
+ */
1017
+ explain(verbosity?: 'queryPlanner' | 'executionStats' | 'allPlansExecution'): Promise<ExplainResult>;
1018
+
1019
+ /**
1020
+ * 返回流式结果
1021
+ * @returns MongoDB 游标流
1022
+ */
1023
+ stream(): NodeJS.ReadableStream;
1024
+
1025
+ /**
1026
+ * 显式转换为数组(执行聚合)
1027
+ * @returns 聚合结果数组
1028
+ * @throws {Error} 如果查询已执行
1029
+ */
1030
+ toArray(): Promise<T[]>;
1031
+
1032
+ /**
1033
+ * Promise.then 接口
1034
+ */
1035
+ then<TResult1 = T[], TResult2 = never>(
1036
+ onfulfilled?: ((value: T[]) => TResult1 | PromiseLike<TResult1>) | null,
1037
+ onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
1038
+ ): Promise<TResult1 | TResult2>;
1039
+
1040
+ /**
1041
+ * Promise.catch 接口
1042
+ */
1043
+ catch<TResult = never>(
1044
+ onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
1045
+ ): Promise<T[] | TResult>;
1046
+
1047
+ /**
1048
+ * Promise.finally 接口
1049
+ */
1050
+ finally(onfinally?: (() => void) | null): Promise<T[]>;
1051
+ }
1052
+ }