@cloudcome/utils-uni 1.30.1 → 1.30.3

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.
package/README.md CHANGED
@@ -5,14 +5,120 @@
5
5
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fa1acaeb717469caddfe21a84c50bb2)](https://app.codacy.com/gh/cloudcome/utils/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
6
6
  [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/4fa1acaeb717469caddfe21a84c50bb2)](https://app.codacy.com/gh/cloudcome/utils/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_coverage)
7
7
 
8
+ 跨平台、多框架的 TypeScript 工具函数库,覆盖浏览器、Node.js、Vue、React、UniApp 等环境。
9
+
10
+ ## 包列表
8
11
 
9
12
  | 名称 | 版本 | 描述 |
10
13
  | --- | --- | --- |
11
- | @cloudcome/utils-core | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-core.svg)](https://npmjs.com/package/@cloudcome/utils-core) | 核心工具库 |
12
- | @cloudcome/utils-browser | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-browser.svg)](https://npmjs.com/package/@cloudcome/utils-browser) | 浏览器工具库 |
13
- | @cloudcome/utils-node| [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-node.svg)](https://npmjs.com/package/@cloudcome/utils-node) | Node.js 工具库 |
14
- | @cloudcome/utils-vue| [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-vue.svg)](https://npmjs.com/package/@cloudcome/utils-vue) | Vue 工具库 |
15
- | @cloudcome/utils-react| [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-react.svg)](https://npmjs.com/package/@cloudcome/utils-react) | React 工具库 |
16
- | @cloudcome/utils-uni| [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-uni.svg)](https://npmjs.com/package/@cloudcome/utils-uni) | UniApp 工具库 |
14
+ | [@cloudcome/utils-core](./packages/utils-core) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-core.svg)](https://npmjs.com/package/@cloudcome/utils-core) | 核心工具库,与运行环境无关的通用工具 |
15
+ | [@cloudcome/utils-browser](./packages/utils-browser) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-browser.svg)](https://npmjs.com/package/@cloudcome/utils-browser) | 浏览器端工具(DOM、Canvas、Cookie、剪贴板等) |
16
+ | [@cloudcome/utils-node](./packages/utils-node) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-node.svg)](https://npmjs.com/package/@cloudcome/utils-node) | Node.js 端工具(Base64、加密等) |
17
+ | [@cloudcome/utils-vue](./packages/utils-vue) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-vue.svg)](https://npmjs.com/package/@cloudcome/utils-vue) | Vue 3 工具库(组合式函数、组件、请求等) |
18
+ | [@cloudcome/utils-react](./packages/utils-react) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-react.svg)](https://npmjs.com/package/@cloudcome/utils-react) | React 工具库 |
19
+ | [@cloudcome/utils-uni](./packages/utils-uni) | [![npm version](https://badge.fury.io/js/@cloudcome%2Futils-uni.svg)](https://npmjs.com/package/@cloudcome/utils-uni) | UniApp 工具库(云函数、数据库、页面等) |
20
+ | [@cloudcome/docs](./packages/docs) | - | VitePress 文档站点 |
21
+
22
+ ## 功能概览
23
+
24
+ ### @cloudcome/utils-core
25
+
26
+ 核心工具库,提供以下子模块:
27
+
28
+ | 子模块 | 导入路径 | 功能 |
29
+ | --- | --- | --- |
30
+ | array | `@cloudcome/utils-core/array` | 数组操作 |
31
+ | async | `@cloudcome/utils-core/async` | 异步工具 |
32
+ | base64 | `@cloudcome/utils-core/base64` | Base64 编解码 |
33
+ | cache | `@cloudcome/utils-core/cache` | 缓存工具 |
34
+ | color | `@cloudcome/utils-core/color` | 颜色转换(RGB/HSL/HSV/HWB/LAB/XYZ)、对比度、亮度、混合 |
35
+ | crypto | `@cloudcome/utils-core/crypto` | 加密(MD5、SHA1、SHA256、SHA512) |
36
+ | date | `@cloudcome/utils-core/date` | 日期解析、格式化、时区、相对时间、周/天计算 |
37
+ | dict | `@cloudcome/utils-core/dict` | 字典/映射工具 |
38
+ | easing | `@cloudcome/utils-core/easing` | 缓动函数 |
39
+ | emitter | `@cloudcome/utils-core/emitter` | 事件发射器 |
40
+ | env | `@cloudcome/utils-core/env` | 环境检测 |
41
+ | error | `@cloudcome/utils-core/error` | 错误处理 |
42
+ | exception | `@cloudcome/utils-core/exception` | 异常处理 |
43
+ | function | `@cloudcome/utils-core/function` | 函数工具 |
44
+ | number | `@cloudcome/utils-core/number` | 数字工具 |
45
+ | object | `@cloudcome/utils-core/object` | 对象遍历、深层 get/set、合并、类型判断 |
46
+ | path | `@cloudcome/utils-core/path` | 路径工具 |
47
+ | promise | `@cloudcome/utils-core/promise` | Promise 工具 |
48
+ | qs | `@cloudcome/utils-core/qs` | 查询字符串解析与序列化 |
49
+ | regexp | `@cloudcome/utils-core/regexp` | 正则表达式工具 |
50
+ | string | `@cloudcome/utils-core/string` | 字符串工具 |
51
+ | time | `@cloudcome/utils-core/time` | 时间单位转换 |
52
+ | timer | `@cloudcome/utils-core/timer` | 定时器工具 |
53
+ | tree | `@cloudcome/utils-core/tree` | 树结构操作 |
54
+ | try | `@cloudcome/utils-core/try` | 安全调用(try-catch 包装,支持同步/异步/柯里化) |
55
+ | type | `@cloudcome/utils-core/type` | 类型判断 |
56
+ | types | `@cloudcome/utils-core/types` | 公共类型定义 |
57
+ | unique | `@cloudcome/utils-core/unique` | 唯一 ID 生成 |
58
+ | url | `@cloudcome/utils-core/url` | URL 解析与构建 |
59
+ | version | `@cloudcome/utils-core/version` | 版本号比较 |
60
+
61
+ ### @cloudcome/utils-browser
62
+
63
+ 浏览器端工具库,依赖 `@cloudcome/utils-core`:
64
+
65
+ | 子模块 | 导入路径 | 功能 |
66
+ | --- | --- | --- |
67
+ | base64 | `@cloudcome/utils-browser/base64` | 浏览器端 Base64 编解码 |
68
+ | cache | `@cloudcome/utils-browser/cache` | 浏览器缓存(localStorage/sessionStorage) |
69
+ | canvas | `@cloudcome/utils-browser/canvas` | Canvas 操作 |
70
+ | clipboard | `@cloudcome/utils-browser/clipboard` | 剪贴板读写 |
71
+ | cookie | `@cloudcome/utils-browser/cookie` | Cookie 读写 |
72
+ | dom | `@cloudcome/utils-browser/dom` | DOM 操作 |
73
+ | download | `@cloudcome/utils-browser/download` | 文件下载 |
74
+ | image | `@cloudcome/utils-browser/image` | 图片处理 |
75
+ | timer | `@cloudcome/utils-browser/timer` | 浏览器端定时器 |
76
+ | video | `@cloudcome/utils-browser/video` | 视频处理 |
77
+
78
+ ### @cloudcome/utils-node
79
+
80
+ Node.js 端工具库:
81
+
82
+ | 子模块 | 导入路径 | 功能 |
83
+ | --- | --- | --- |
84
+ | base64 | `@cloudcome/utils-node/base64` | Node.js 端 Base64 编解码 |
85
+ | crypto | `@cloudcome/utils-node/crypto` | Node.js 端加密工具 |
86
+
87
+ ### @cloudcome/utils-vue
88
+
89
+ Vue 3 工具库,依赖 `@cloudcome/utils-core` 和 `vue`:
90
+
91
+ | 子模块 | 导入路径 | 功能 |
92
+ | --- | --- | --- |
93
+ | async | `@cloudcome/utils-vue/async` | Vue 异步组合式函数 |
94
+ | component | `@cloudcome/utils-vue/component` | 组件工具(生命周期等) |
95
+ | event | `@cloudcome/utils-vue/event` | 事件工具 |
96
+ | request | `@cloudcome/utils-vue/request` | 请求组合式函数(useRequest) |
97
+ | shared | `@cloudcome/utils-vue/shared` | 共享工具 |
98
+ | state | `@cloudcome/utils-vue/state` | 状态管理工具 |
99
+ | time | `@cloudcome/utils-vue/time` | 时间相关组合式函数 |
100
+ | types | `@cloudcome/utils-vue/types` | 类型定义 |
101
+
102
+ ### @cloudcome/utils-react
103
+
104
+ React 工具库。
105
+
106
+ ### @cloudcome/utils-uni
107
+
108
+ UniApp 工具库,依赖 `@cloudcome/utils-core`、`@cloudcome/utils-vue`:
109
+
110
+ | 子模块 | 导入路径 | 功能 |
111
+ | --- | --- | --- |
112
+ | app | `@cloudcome/utils-uni/app` | App 相关工具 |
113
+ | client | `@cloudcome/utils-uni/client` | 客户端工具 |
114
+ | cloud | `@cloudcome/utils-uni/cloud` | 云函数工具(调用、错误处理、uni-id 等) |
115
+ | database | `@cloudcome/utils-uni/database` | 数据库操作(CRUD、事务、分页、upsert 等) |
116
+ | page | `@cloudcome/utils-uni/page` | 页面相关工具 |
117
+
118
+ ## 开发
119
+
120
+ 详见 [DEVELOPMENT.md](./DEVELOPMENT.md)。
17
121
 
122
+ ## 许可
18
123
 
124
+ [MIT](LICENSE)
@@ -152,15 +152,19 @@ export declare class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject =
152
152
  * 执行查询操作
153
153
  * @returns 查询结果
154
154
  */
155
- query(): Promise<DbQuery<D1, S1, D2>[]>;
155
+ many(): Promise<DbQuery<D1, S1, D2>[]>;
156
156
  /**
157
157
  * 只查询一条,自动添加 limit(1) 条件
158
- * @param allowMiss 是否允许没有匹配到记录,如果为 true,则可能返回 null
158
+ * 如果没有匹配到记录,会抛出错误
159
159
  * @returns 查询结果
160
160
  */
161
- queryOne(): Promise<DbQuery<D1, S1, D2>>;
162
- queryOne(allowMiss: false): Promise<DbQuery<D1, S1, D2>>;
163
- queryOne(allowMiss: true): Promise<DbQuery<D1, S1, D2> | null>;
161
+ firstOrThrow(): Promise<DbQuery<D1, S1, D2>>;
162
+ /**
163
+ * 只查询一条,自动添加 limit(1) 条件
164
+ * 如果没有匹配到记录,返回 null
165
+ * @returns 查询结果或 null
166
+ */
167
+ firstOrNull(): Promise<DbQuery<D1, S1, D2> | null>;
164
168
  /**
165
169
  * 获取匹配记录的数量
166
170
  * @returns 记录总数
package/dist/database.cjs CHANGED
@@ -399,9 +399,9 @@ class Db {
399
399
  * 执行查询操作
400
400
  * @returns 查询结果
401
401
  */
402
- async query() {
402
+ async many() {
403
403
  try {
404
- if (this._isTransaction) throw new Error("db.query() 方法不支持事务模式");
404
+ if (this._isTransaction) throw new Error("db.many() 方法不支持事务模式");
405
405
  let res;
406
406
  if (this._hasLookup) {
407
407
  const aggRef = this.aggregate();
@@ -418,14 +418,31 @@ class Db {
418
418
  throw this._options.parseError?.(dbErr) || dbErr;
419
419
  }
420
420
  }
421
- async queryOne(allowMiss = false) {
422
- if (this._isTransaction) throw new Error("db.queryOne() 方法不支持事务模式");
423
- if (this._hasLimit) throw new Error("db.queryOne() 方法不支持 limit 条件");
421
+ /**
422
+ * 只查询一条,自动添加 limit(1) 条件
423
+ * 如果没有匹配到记录,会抛出错误
424
+ * @returns 查询结果
425
+ */
426
+ async firstOrThrow() {
427
+ if (this._isTransaction) throw new Error("db.firstOrThrow() 方法不支持事务模式");
428
+ if (this._hasLimit) throw new Error("db.firstOrThrow() 方法不支持 limit 条件");
424
429
  if (!this._hasWhereId) this.limit(1);
425
- const data = await this.query();
430
+ const data = await this.many();
426
431
  const res = data.at(0);
427
- if (!allowMiss && !res) throw error.createCloudObjectError("查询数据为空", "queryOneMiss");
428
- return res || null;
432
+ if (!res) throw error.createCloudObjectError("查询数据为空", "firstOrThrow");
433
+ return res;
434
+ }
435
+ /**
436
+ * 只查询一条,自动添加 limit(1) 条件
437
+ * 如果没有匹配到记录,返回 null
438
+ * @returns 查询结果或 null
439
+ */
440
+ async firstOrNull() {
441
+ if (this._isTransaction) throw new Error("db.firstOrNull() 方法不支持事务模式");
442
+ if (this._hasLimit) throw new Error("db.firstOrNull() 方法不支持 limit 条件");
443
+ if (!this._hasWhereId) this.limit(1);
444
+ const data = await this.many();
445
+ return data.at(0) || null;
429
446
  }
430
447
  /**
431
448
  * 获取匹配记录的数量
@@ -560,7 +577,7 @@ async function dbUpsert(db, options) {
560
577
  const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;
561
578
  const _mutateDb = _mockDbInstance || db.clone();
562
579
  const _queryDb = _mockDbInstance || db.clone(true);
563
- const exist = await _queryDb.where(db.getWhere(true)).queryOne(true);
580
+ const exist = await _queryDb.where(db.getWhere(true)).firstOrNull();
564
581
  if (exist) {
565
582
  const skipUpdate = await onBeforeUpdate?.(exist) === false;
566
583
  if (skipUpdate) {
@@ -606,7 +623,7 @@ async function dbTransaction(transacting, _mockDatabase, _mockDbInstance) {
606
623
  async function dbPaging(queryDb) {
607
624
  const where = queryDb.getWhere(true);
608
625
  const countDb = queryDb.clone();
609
- const list = await queryDb.query();
626
+ const list = await queryDb.many();
610
627
  const total = await countDb.where(where).count();
611
628
  return {
612
629
  list,
@@ -1 +1 @@
1
- {"version":3,"file":"database.cjs","sources":["../src/database/_command.class.ts","../src/database/command.ts","../src/database/_db.class.ts","../src/database/proxy.ts","../src/database/upsert.ts","../src/database/unique.ts","../src/database/transaction.ts","../src/database/paging.ts"],"sourcesContent":["// 设置私有属性和静态方法是避免在 update 的时候提示类属性\n\nexport class DbBaseCommand {\n protected _isQuery = false;\n protected _isMutate = false;\n\n constructor(\n private _command: string,\n private _parameter: unknown,\n private _options?: {\n formatParameter?: (db: UniCloud.Database) => unknown;\n rewriteValue?: (db: UniCloud.Database, parameter: unknown) => unknown;\n },\n ) {}\n\n static getValue(cmd: DbBaseCommand, db: UniCloud.Database) {\n if (cmd._options?.rewriteValue) {\n return cmd._options.rewriteValue(db, cmd._parameter);\n }\n\n return (db.command as unknown as Record<string, (value: unknown) => unknown>)[cmd._command].call(\n db.command,\n cmd._options?.formatParameter?.(db) || cmd._parameter,\n );\n }\n\n static getExpression(cmd: DbBaseCommand, fieldName: string) {\n return {\n [`$${cmd._command}`]: [fieldName, cmd._parameter],\n };\n }\n\n static isQueryCommand(cmd: DbBaseCommand) {\n return cmd._isQuery;\n }\n\n static isMutateCommand(cmd: DbBaseCommand) {\n return cmd._isMutate;\n }\n}\n\nexport class DbQueryCommand extends DbBaseCommand {\n protected _isQuery = true;\n}\n\nexport class DbMutateCommand extends DbBaseCommand {\n protected _isMutate = true;\n}\n","import { DbBaseCommand, DbMutateCommand, DbQueryCommand } from './_command.class';\n\n/**\n * 数据库查询命令对象,提供各种查询操作符\n */\nexport const dbQuery = {\n /**\n * 等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n eq: (value: unknown) => new DbQueryCommand('eq', value),\n\n /**\n * 不等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n neq: (value: unknown) => new DbQueryCommand('neq', value),\n\n /**\n * 大于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gt: (value: unknown) => new DbQueryCommand('gt', value),\n\n /**\n * 大于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gte: (value: unknown) => new DbQueryCommand('gte', value),\n\n /**\n * 小于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lt: (value: unknown) => new DbQueryCommand('lt', value),\n\n /**\n * 小于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lte: (value: unknown) => new DbQueryCommand('lte', value),\n\n /**\n * 包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n in: (value: unknown[]) => new DbQueryCommand('in', value),\n\n /**\n * 不包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n nin: (value: unknown[]) => new DbQueryCommand('nin', value),\n\n /**\n * 数组长度匹配操作符\n * @param size 数组长度\n * @returns DbQueryCommand 查询命令对象\n */\n size: (size: number) => new DbQueryCommand('size', size),\n\n /**\n * 正则表达式匹配操作符\n * @param regExp 正则表达式\n * @returns DbQueryCommand 查询命令对象\n */\n regExp: (regExp: RegExp) =>\n new DbQueryCommand('regExp', regExp, {\n rewriteValue: (db, parameter) => parameter,\n }),\n\n /**\n * 逻辑与操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n and: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('and', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n\n /**\n * 逻辑或操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n or: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('or', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n};\n\n/**\n * 数据库变更命令对象,提供各种数据更新操作符\n */\nexport const dbMutate = {\n /**\n * 数值增加操作符\n * @param value 增加的数值\n * @returns DbMutateCommand 变更命令对象\n */\n inc: (value: number) => new DbMutateCommand('inc', value),\n\n /**\n * 数值乘法操作符\n * @param value 乘数\n * @returns DbMutateCommand 变更命令对象\n */\n mul: (value: number) => new DbMutateCommand('mul', value),\n\n /**\n * 设置字段值操作符\n * @param value 设置的值\n * @returns DbMutateCommand 变更命令对象\n */\n set: (value: unknown) => new DbMutateCommand('set', value),\n\n /**\n * 向数组末尾添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n push: (value: unknown) => new DbMutateCommand('push', value),\n\n /**\n * 向数组开头添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n unshift: (value: unknown) => new DbMutateCommand('unshift', value),\n\n /**\n * 从数组末尾移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n pop: () => new DbMutateCommand('pop', undefined),\n\n /**\n * 从数组开头移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n shift: () => new DbMutateCommand('shift', undefined),\n\n /**\n * 移除字段操作符\n * @returns DbMutateCommand 变更命令对象\n */\n remove: () => new DbMutateCommand('remove', undefined),\n};\n","import { parseDatabaseOutput } from '@/_helpers';\nimport type { UniError } from '@/_types';\nimport { createCloudObjectError } from '@/cloud';\nimport { objectEach, objectFilter, objectMap, objectOmit } from '@cloudcome/utils-core/object';\nimport { isArray, isNumber, isObject, isString } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MergeIntersection } from '@cloudcome/utils-core/types';\nimport { DbBaseCommand, type DbQueryCommand } from './_command.class';\nimport type { DbCreate, DbForeign, DbOrder, DbQuery, DbRelation, DbSelect, DbUpdate, DbWhere } from './types';\n\n/**\n * 数据库聚合操作符命令\n */\nconst dbAgg = uniCloud.database().command.aggregate as UniCloud.AggregateCommand & {\n pipeline: () => UniCloud.AggregateReference & {\n done: () => unknown;\n };\n};\n\ntype _WhereFrom = 'where' | 'whereId';\n\nconst db0 = uniCloud.database();\n\nexport type DbOptions = {\n /**\n * 数据表名称\n */\n table: string;\n\n /**\n * 事务对象,用于事务操作\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n transaction?: any;\n\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any;\n\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type DbLookupOptions<RL extends DbRelation, D1, FD1, AS, US extends boolean | undefined | void = undefined> = {\n /**\n * 关联类型\n */\n relation: RL;\n\n /**\n * 主表字段\n */\n localField: keyof D1 & string;\n\n /**\n * 关联表字段\n */\n foreignField: keyof FD1 & string;\n\n /**\n * 关联数据在结果中的字段名\n */\n as: AS;\n\n /**\n * 是否取消筛选关联数据\n */\n unselect?: US;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type DbLookup = DbLookupOptions<any, unknown, unknown, string, boolean> & {\n /**\n * 关联表\n */\n table: Db<unknown>;\n};\n\nlet gid = 0;\n\n/**\n * 数据库类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @template D2 - 副表数据\n * @template W2 - 副表查询\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}> {\n private _host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n private _isTransaction = false;\n\n private _options: DbOptions;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 数据表名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this._options = options;\n this._host =\n options._mockDatabase || options.transaction?.collection(options.table) || db0.collection(options.table);\n this._isTransaction = !!options.transaction;\n }\n\n /**\n * 创建一个新的数据库实例,可选是否移除事务\n * @param withoutTransaction 是否移除事务,默认 false\n * @returns 新的数据库实例\n */\n clone(withoutTransaction?: boolean) {\n return new Db({ ...this._options, transaction: withoutTransaction ? null : this._options.transaction });\n }\n\n get table() {\n return this._options.table;\n }\n\n get options() {\n return this._options;\n }\n\n get isTransaction() {\n return this._isTransaction;\n }\n\n /**\n * 获取聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n return this._host.aggregate();\n }\n\n private _hasWhere: _WhereFrom | undefined = undefined;\n private _hasWhereId: _WhereFrom | undefined = undefined;\n private _where = {};\n\n private _doWhere(where: DbWhere<D1>, from: _WhereFrom) {\n if (this._hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this._hasWhere)} 了`);\n\n // 过滤掉值为 undefined 的键值对,数据库不支持查询全 undefined 值\n const realWhere = objectFilter(where, (value) => value !== undefined);\n\n const whereKeys = Object.keys(realWhere);\n\n // 只有 _id 值为字符串或数字时,才能调用 doc 方法\n const isWhereId =\n whereKeys.length === 1 && '_id' in realWhere && (isString(realWhere._id) || isNumber(realWhere._id));\n\n if (isWhereId && this._hasLimit) {\n throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);\n }\n\n this._hasWhere = from;\n this._where = realWhere;\n if (isWhereId) this._hasWhereId = from;\n\n return this;\n }\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式调用\n */\n where(where: DbWhere<D1> & W2) {\n return this._doWhere(where, 'where');\n }\n\n /**\n * 获取当前查询条件\n * @param plain 是否返回原始查询条件对象,默认 false\n * @returns 当前查询条件对象\n */\n getWhere(plain?: boolean) {\n // @ts-ignore\n return plain ? objectOmit(this._where, Object.keys(this._lookupAs)) : this._where;\n }\n\n /**\n * 根据ID设置查询条件\n * @param id 记录ID\n * @returns 当前Db实例,支持链式调用\n */\n whereId(id: string | number) {\n // @ts-ignore\n return this._doWhere({ _id: id }, 'whereId');\n }\n\n private _hasSelect = 0;\n private _select = {};\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式调用\n */\n select<const S extends DbSelect<D1>>(fields: S) {\n if (this._hasSelect) throw new Error('db.select() 方法只能调用一次');\n\n this._hasSelect++;\n this._select = fields;\n\n // @ts-ignore\n return this as Db<D1, S, D2, W2>;\n }\n\n private _hasOrder = 0;\n private _order = {};\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式调用\n */\n order(order: DbOrder<D1>) {\n this._hasOrder++;\n this._order = order;\n\n return this;\n }\n\n private _hasSkip = 0;\n private _skip = 0;\n\n /**\n * 跳过指定数量的记录\n * @param skip 要跳过的记录数\n * @returns 当前Db实例,支持链式调用\n */\n skip(skip: number) {\n if (this._hasSkip) throw new Error('db.skip() 方法只能调用一次');\n\n this._hasSkip++;\n this._skip = skip;\n\n return this;\n }\n\n private _hasLimit = 0;\n private _limit = 0;\n\n /**\n * 限制返回的记录数量\n * @param limit 最大返回记录数\n * @returns 当前Db实例,支持链式调用\n */\n limit(limit: number) {\n if (this._hasLimit) throw new Error('db.limit() 方法只能调用一次');\n\n if (this._hasWhereId) {\n throw new Error(`db.limit() 方法不能与 ${_toWhereIdMethod(this._hasWhereId)} 方法同时调用`);\n }\n\n this._hasLimit++;\n this._limit = limit;\n\n return this;\n }\n\n private _hasLookup = 0;\n get hasLookup() {\n return this._hasLookup > 0;\n }\n\n private _lookups: DbLookup[] = [];\n lookup<\n FD1,\n FS1 extends DbSelect<FD1>,\n FD2 extends AnyObject,\n FW2 extends AnyObject,\n RL extends DbRelation,\n AS extends string,\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n US extends boolean | undefined | void = undefined,\n >(table: Db<FD1, FS1, FD2, FW2>, lookup: DbLookupOptions<RL, D1, FD1, AS, US>) {\n // 对方表也记为关联查询,避免做表更新操作\n table._hasLookup++;\n this._hasLookup++;\n this._lookups.push({\n ...lookup,\n table,\n } as unknown as DbLookup);\n\n // @ts-ignore\n return this as Db<\n D1,\n S1,\n US extends true ? D2 : MergeIntersection<D2 & DbForeign<FD1, FS1, FD2, RL, AS>>,\n MergeIntersection<W2 & Partial<Record<AS, DbQueryCommand>>>\n >;\n }\n\n private _aggregated = false;\n private _lookupAs = {} as Record<string, true>;\n private _endAggregate(aggRef: UniCloud.AggregateReference) {\n if (this._aggregated) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);\n\n this._aggregated = true;\n let returnAggRef = aggRef;\n let hasAggSelect = 0;\n const aggSelect = {} as Record<string, true>;\n let hasAggUnselect = 0;\n const aggUnselect = {} as Record<string, false>;\n\n // 后做关联查询\n for (const { relation: type, as, foreignField, localField, table, unselect } of this._lookups) {\n const letName = `let${gid++}`;\n let pipeline = dbAgg.pipeline();\n\n // 关联条件\n // @ts-ignore\n pipeline = pipeline.match({\n $expr: {\n $and: [\n type === 'n:1'\n ? { $in: [`$${foreignField}`, `$$${letName}`] }\n : { $eq: [`$${foreignField}`, `$$${letName}`] },\n ],\n },\n });\n\n // 其他查询条件\n // @ts-ignore\n pipeline = table._endAggregate(pipeline);\n\n // @ts-ignore\n pipeline = pipeline.done();\n\n returnAggRef = returnAggRef.lookup({\n let: {\n [letName]: `$${localField}`,\n },\n as,\n from: table.table,\n pipeline,\n });\n\n // 1对1,展开数组\n if (type === '1:1') {\n // @ts-ignore\n returnAggRef = returnAggRef.unwind({\n path: `$${as}`,\n preserveNullAndEmptyArrays: true,\n });\n }\n\n if (unselect) {\n hasAggUnselect++;\n aggUnselect[as] = false;\n } else {\n hasAggSelect++;\n aggSelect[as] = true;\n }\n\n this._lookupAs[as] = true;\n }\n\n // 主表查询,注意顺序,筛选->排序->跳过->限制\n if (this._hasWhere) returnAggRef = returnAggRef.match(_mapCommandRaw(this._where));\n if (this._hasOrder) returnAggRef = returnAggRef.sort(objectMap(this._order, (v) => (v === 'asc' ? 1 : -1)));\n if (this._hasSkip) returnAggRef = returnAggRef.skip(this._skip);\n if (this._hasLimit) returnAggRef = returnAggRef.limit(this._limit);\n\n // 如果主表有选择字段,则合并选择字段(包括关联查询的字段和排序字段)\n if (this._hasSelect) {\n returnAggRef = returnAggRef.project(_mergeSelect({ ...this._select, ...aggSelect }, this._order));\n }\n // 如果主表没有选择字段,则排除取消选择字段\n else if (hasAggUnselect) {\n returnAggRef = returnAggRef.project(aggUnselect);\n }\n\n return returnAggRef;\n }\n\n private _endHost(action: 'query' | 'create' | 'update' | 'remove' | 'count') {\n if (this._hasWhere) {\n // 事务模式更新只能用 doc(id)\n if (action === 'update' && this._isTransaction) {\n // @ts-ignore\n this._host = this._host.doc(this._where._id);\n } else {\n // @ts-ignore\n this._host = this._host.where(_mapCommandRaw(this._where));\n }\n }\n\n if (this._hasSelect) {\n // @ts-ignore\n this._host = this._host.field(_mergeSelect(this._select, this._order));\n }\n\n if (this._hasOrder) {\n objectEach(this._order, (val, key) => {\n // @ts-ignore\n this._host = this._host.orderBy(key, val);\n });\n }\n\n // @ts-ignore\n if (this._hasSkip) this._host = this._host.skip(this._skip);\n\n // @ts-ignore\n if (this._hasLimit && action === 'query') this._host = this._host.limit(this._limit);\n // @ts-ignore\n else if (this._hasWhereId && action === 'query') this._host = this._host.limit(1);\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async query() {\n try {\n if (this._isTransaction) throw new Error('db.query() 方法不支持事务模式');\n\n let res: { data: DbQuery<D1, S1, D2>[] };\n\n // 关联查询\n if (this._hasLookup) {\n const aggRef = this.aggregate();\n this._endAggregate(aggRef);\n res = await aggRef.end();\n }\n // 单表查询\n else {\n this._endHost('query');\n res = await this._host.get();\n }\n\n const { data } = parseDatabaseOutput(res);\n return data;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * @param allowMiss 是否允许没有匹配到记录,如果为 true,则可能返回 null\n * @returns 查询结果\n */\n async queryOne(): Promise<DbQuery<D1, S1, D2>>;\n async queryOne(allowMiss: false): Promise<DbQuery<D1, S1, D2>>;\n async queryOne(allowMiss: true): Promise<DbQuery<D1, S1, D2> | null>;\n async queryOne(allowMiss = false): Promise<DbQuery<D1, S1, D2> | null> {\n if (this._isTransaction) throw new Error('db.queryOne() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.queryOne() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.query();\n const res = data.at(0);\n\n if (!allowMiss && !res) throw createCloudObjectError('查询数据为空', 'queryOneMiss');\n return res || null;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\n if (this._hasLookup) throw new Error('db.count() 方法不支持 lookup 聚合');\n if (this._hasSelect) throw new Error('db.count() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.count() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.count() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.count() 方法不支持 limit 条件');\n\n try {\n this._endHost('count');\n const res = await this._host.count();\n const { total } = parseDatabaseOutput<{ total: number }>(res);\n return total;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: DbCreate<D1>) {\n if (this._hasLookup) throw new Error('db.create() 方法不支持 lookup 聚合');\n if (this._hasWhere) throw new Error('db.create() 方法不支持 where 条件');\n if (this._hasSelect) throw new Error('db.create() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.create() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.create() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.create() 方法不支持 limit 条件');\n\n try {\n this._endHost('create');\n const res = await this._host.add(data);\n const { id } = parseDatabaseOutput<{ id: string }>(res);\n return id;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: DbUpdate<D1>) {\n if (this._hasLookup) throw new Error('db.update() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.update() 方法');\n if (this._hasSelect) throw new Error('db.update() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.update() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.update() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.update() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.update() 的 where 条件必须是 _id');\n\n try {\n this._endHost('update');\n const res = await this._host.update(objectOmit(_mapCommandRaw(data), ['_id']));\n const { updated } = parseDatabaseOutput<{ updated: number }>(res);\n return updated;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\n if (this._hasLookup) throw new Error('db.remove() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.remove() 方法');\n if (this._hasSelect) throw new Error('db.remove() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.remove() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.remove() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.remove() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.remove() 的 where 条件必须是 _id');\n\n try {\n this._endHost('remove');\n const res = await this._host.remove();\n const { deleted } = parseDatabaseOutput<{ deleted: number }>(res);\n return deleted;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n}\n\nfunction _toWhereMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({...})' : 'whereId(id)';\n}\n\nfunction _toWhereIdMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({ _id })' : 'whereId(id)';\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nfunction _mapCommandRaw(data: any) {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const map = (val: any): any => {\n if (!isObject(val)) return val;\n if (val instanceof DbBaseCommand) return DbBaseCommand.getValue(val, db0);\n return objectMap(val, map);\n };\n\n return objectMap(data, map);\n}\n\nfunction _mapOrderSelect(order: DbOrder<unknown>) {\n return objectMap(order, (val, key) => true);\n}\n\nfunction _mergeSelect(select: DbSelect<unknown>, order: DbOrder<unknown>) {\n const noSelect = Object.keys(select).length === 0;\n // 如果没有 select 条件,默认返回所有字段\n if (noSelect) return select;\n\n const onlyOmitId = Object.keys(select).length === 1 && '_id' in select && select._id === false;\n // 如果只排除 _id 字段,则保持现状\n if (onlyOmitId) return select;\n\n return {\n ...select,\n ..._mapOrderSelect(order),\n };\n}\n","import type { UniError } from '@/_types';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\nexport type DbProxyOptions = {\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n/**\n * 创建一个数据库代理对象,用于延迟实例化数据库操作类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @param name - 数据库表名\n * @returns 返回一个代理对象,该对象会将属性访问转发到实际的数据库操作实例\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport function dbProxy<D1, S1 extends DbSelect<D1> = {}>(name: string, options?: DbProxyOptions) {\n return new Proxy(\n {},\n {\n get(target, prop) {\n if (prop === '_isProxy') return true;\n\n const table = new Db<D1, S1>({ table: name, ...options });\n const tableProp = prop as keyof Db<D1, S1>;\n const ref = table[tableProp];\n\n return isFunction(ref) ? ref.bind(table) : ref;\n },\n },\n ) as Db<D1, S1>;\n}\n","import { isFunction } from '@cloudcome/utils-core/type';\nimport type { Exact } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbCreate, DbQuery, DbSelect, DbUpdate, DbWhere } from './types';\n\nexport type DbUpsertOptions<T, C extends DbCreate<T>, U extends DbUpdate<T>> = {\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n update: U | ((exist: DbQuery<T, {}, {}>) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param exist 查询到的原始文档数据\n * @returns 如果返回 false,则取消更新操作\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onBeforeUpdate?: (exist: DbQuery<T, {}, {}>) => false | unknown;\n\n /**\n * 更新后回调函数\n * @param updateData 实际更新的数据\n * @param exist 查询到的原始文档数据\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onAfterUpdate?: (updateData: U, exist: DbQuery<T, {}, {}>) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUpsertOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n /** 是否为更新操作 */\n updated: boolean;\n};\n\nexport async function dbUpsert<D1, C extends DbCreate<D1>, U extends DbUpdate<D1>>(\n db: Db<D1>,\n options: DbUpsertOptions<D1, C, U>,\n): Promise<DbUpsertOutput> {\n const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;\n\n const _mutateDb = (_mockDbInstance || db.clone()) as Db<D1>;\n const _queryDb = (_mockDbInstance || db.clone(true)) as Db<D1>;\n\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n const exist = (await _queryDb.where(db.getWhere(true)).queryOne(true)) as DbQuery<D1, {}, {}> | null;\n\n if (exist) {\n const skipUpdate = (await onBeforeUpdate?.(exist)) === false;\n\n if (skipUpdate) {\n // @ts-ignore\n return { id: exist._id as string, updated: false, created: false };\n }\n\n const updateData = isFunction(update) ? update(exist) : update;\n // @ts-ignore\n await _mutateDb.whereId(exist._id).update(updateData);\n onAfterUpdate?.(updateData, exist);\n\n // @ts-ignore\n return { id: exist._id as string, updated: true, created: false };\n }\n\n await onBeforeCreate?.();\n const createdId = await _mutateDb.create(create);\n await onAfterCreate?.(createdId);\n\n return { id: createdId, updated: false, created: true };\n}\n","import type { Db } from './_db.class';\nimport type { DbCreate, DbWhere } from './types';\nimport { dbUpsert } from './upsert';\n\nexport type DbUniqueOptions<T, C extends DbCreate<T>> = {\n /** 创建数据 */\n create: C;\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUniqueOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n};\n\nexport async function dbUnique<T, C extends DbCreate<T>>(\n db: Db<T>,\n options: DbUniqueOptions<T, C>,\n): Promise<DbUniqueOutput> {\n const { id, created } = await dbUpsert(db, {\n ...options,\n // @ts-ignore\n update: {},\n onBeforeUpdate: () => false,\n });\n return { id, created };\n}\n","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { Db } from './_db.class';\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\nexport type WithTransaction = <D1>(db: Db<D1>) => Db<D1>;\n\n/**\n * 在数据库事务中执行操作\n *\n * @template K - 事务操作返回值类型\n * @param transacting - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库对象\n * @param _mockDbInstance - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (withTransaction) => {\n * const userId = await withTransaction(db.table('user')).create({ name: 'John' });\n * const order = await withTransaction(db.table('orders')).create({ userId, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\nexport async function dbTransaction<K>(\n transacting: (withTransaction: WithTransaction) => Promise<K>,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any,\n) {\n const transactionDb = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(transactionDb.startTransaction());\n if (err1) throw err1;\n\n const withTransaction: WithTransaction = <D1>(db: Db<D1>) => {\n return _mockDbInstance || new Db<D1>({ ...db.options, transaction });\n };\n\n const [err2, result] = await tryFlatten(async () => {\n const result = await transacting(withTransaction);\n await transaction.commit();\n return result;\n });\n\n if (err2) {\n await tryFlatten(transaction.rollback());\n throw err2;\n }\n\n return result as unknown as K;\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\n/**\n * 数据库分页查询函数\n * @template T - 数据类型\n * @param queryDb - 数据库查询实例\n * @returns 包含数据列表和总数的对象\n */\n\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport async function dbPaging<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}>(\n queryDb: Db<D1, S1, D2, W2>,\n) {\n // 获取原始查询条件,不包映射字段\n const where = queryDb.getWhere(true);\n\n // 克隆查询实例用于统计总数,避免影响原查询\n const countDb = queryDb.clone();\n\n // 执行查询获取数据列表\n const list = await queryDb.query();\n\n // 基于相同查询条件统计总数\n const total = await countDb.where(where).count();\n\n // 返回分页结果\n return {\n list,\n total,\n };\n}\n"],"names":["objectFilter","isString","isNumber","objectOmit","type","objectMap","objectEach","parseDatabaseOutput","createCloudObjectError","isObject","isFunction","tryFlatten","result"],"mappings":"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"}
1
+ {"version":3,"file":"database.cjs","sources":["../src/database/_command.class.ts","../src/database/command.ts","../src/database/_db.class.ts","../src/database/proxy.ts","../src/database/upsert.ts","../src/database/unique.ts","../src/database/transaction.ts","../src/database/paging.ts"],"sourcesContent":["// 设置私有属性和静态方法是避免在 update 的时候提示类属性\n\nexport class DbBaseCommand {\n protected _isQuery = false;\n protected _isMutate = false;\n\n constructor(\n private _command: string,\n private _parameter: unknown,\n private _options?: {\n formatParameter?: (db: UniCloud.Database) => unknown;\n rewriteValue?: (db: UniCloud.Database, parameter: unknown) => unknown;\n },\n ) {}\n\n static getValue(cmd: DbBaseCommand, db: UniCloud.Database) {\n if (cmd._options?.rewriteValue) {\n return cmd._options.rewriteValue(db, cmd._parameter);\n }\n\n return (db.command as unknown as Record<string, (value: unknown) => unknown>)[cmd._command].call(\n db.command,\n cmd._options?.formatParameter?.(db) || cmd._parameter,\n );\n }\n\n static getExpression(cmd: DbBaseCommand, fieldName: string) {\n return {\n [`$${cmd._command}`]: [fieldName, cmd._parameter],\n };\n }\n\n static isQueryCommand(cmd: DbBaseCommand) {\n return cmd._isQuery;\n }\n\n static isMutateCommand(cmd: DbBaseCommand) {\n return cmd._isMutate;\n }\n}\n\nexport class DbQueryCommand extends DbBaseCommand {\n protected _isQuery = true;\n}\n\nexport class DbMutateCommand extends DbBaseCommand {\n protected _isMutate = true;\n}\n","import { DbBaseCommand, DbMutateCommand, DbQueryCommand } from './_command.class';\n\n/**\n * 数据库查询命令对象,提供各种查询操作符\n */\nexport const dbQuery = {\n /**\n * 等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n eq: (value: unknown) => new DbQueryCommand('eq', value),\n\n /**\n * 不等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n neq: (value: unknown) => new DbQueryCommand('neq', value),\n\n /**\n * 大于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gt: (value: unknown) => new DbQueryCommand('gt', value),\n\n /**\n * 大于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gte: (value: unknown) => new DbQueryCommand('gte', value),\n\n /**\n * 小于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lt: (value: unknown) => new DbQueryCommand('lt', value),\n\n /**\n * 小于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lte: (value: unknown) => new DbQueryCommand('lte', value),\n\n /**\n * 包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n in: (value: unknown[]) => new DbQueryCommand('in', value),\n\n /**\n * 不包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n nin: (value: unknown[]) => new DbQueryCommand('nin', value),\n\n /**\n * 数组长度匹配操作符\n * @param size 数组长度\n * @returns DbQueryCommand 查询命令对象\n */\n size: (size: number) => new DbQueryCommand('size', size),\n\n /**\n * 正则表达式匹配操作符\n * @param regExp 正则表达式\n * @returns DbQueryCommand 查询命令对象\n */\n regExp: (regExp: RegExp) =>\n new DbQueryCommand('regExp', regExp, {\n rewriteValue: (db, parameter) => parameter,\n }),\n\n /**\n * 逻辑与操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n and: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('and', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n\n /**\n * 逻辑或操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n or: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('or', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n};\n\n/**\n * 数据库变更命令对象,提供各种数据更新操作符\n */\nexport const dbMutate = {\n /**\n * 数值增加操作符\n * @param value 增加的数值\n * @returns DbMutateCommand 变更命令对象\n */\n inc: (value: number) => new DbMutateCommand('inc', value),\n\n /**\n * 数值乘法操作符\n * @param value 乘数\n * @returns DbMutateCommand 变更命令对象\n */\n mul: (value: number) => new DbMutateCommand('mul', value),\n\n /**\n * 设置字段值操作符\n * @param value 设置的值\n * @returns DbMutateCommand 变更命令对象\n */\n set: (value: unknown) => new DbMutateCommand('set', value),\n\n /**\n * 向数组末尾添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n push: (value: unknown) => new DbMutateCommand('push', value),\n\n /**\n * 向数组开头添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n unshift: (value: unknown) => new DbMutateCommand('unshift', value),\n\n /**\n * 从数组末尾移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n pop: () => new DbMutateCommand('pop', undefined),\n\n /**\n * 从数组开头移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n shift: () => new DbMutateCommand('shift', undefined),\n\n /**\n * 移除字段操作符\n * @returns DbMutateCommand 变更命令对象\n */\n remove: () => new DbMutateCommand('remove', undefined),\n};\n","import { parseDatabaseOutput } from '@/_helpers';\nimport type { UniError } from '@/_types';\nimport { createCloudObjectError } from '@/cloud';\nimport { objectEach, objectFilter, objectMap, objectOmit } from '@cloudcome/utils-core/object';\nimport { isArray, isNumber, isObject, isString } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MergeIntersection } from '@cloudcome/utils-core/types';\nimport { DbBaseCommand, type DbQueryCommand } from './_command.class';\nimport type { DbCreate, DbForeign, DbOrder, DbQuery, DbRelation, DbSelect, DbUpdate, DbWhere } from './types';\n\n/**\n * 数据库聚合操作符命令\n */\nconst dbAgg = uniCloud.database().command.aggregate as UniCloud.AggregateCommand & {\n pipeline: () => UniCloud.AggregateReference & {\n done: () => unknown;\n };\n};\n\ntype _WhereFrom = 'where' | 'whereId';\n\nconst db0 = uniCloud.database();\n\nexport type DbOptions = {\n /**\n * 数据表名称\n */\n table: string;\n\n /**\n * 事务对象,用于事务操作\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n transaction?: any;\n\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any;\n\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type DbLookupOptions<RL extends DbRelation, D1, FD1, AS, US extends boolean | undefined | void = undefined> = {\n /**\n * 关联类型\n */\n relation: RL;\n\n /**\n * 主表字段\n */\n localField: keyof D1 & string;\n\n /**\n * 关联表字段\n */\n foreignField: keyof FD1 & string;\n\n /**\n * 关联数据在结果中的字段名\n */\n as: AS;\n\n /**\n * 是否取消筛选关联数据\n */\n unselect?: US;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type DbLookup = DbLookupOptions<any, unknown, unknown, string, boolean> & {\n /**\n * 关联表\n */\n table: Db<unknown>;\n};\n\nlet gid = 0;\n\n/**\n * 数据库类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @template D2 - 副表数据\n * @template W2 - 副表查询\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}> {\n private _host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n private _isTransaction = false;\n\n private _options: DbOptions;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 数据表名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this._options = options;\n this._host =\n options._mockDatabase || options.transaction?.collection(options.table) || db0.collection(options.table);\n this._isTransaction = !!options.transaction;\n }\n\n /**\n * 创建一个新的数据库实例,可选是否移除事务\n * @param withoutTransaction 是否移除事务,默认 false\n * @returns 新的数据库实例\n */\n clone(withoutTransaction?: boolean) {\n return new Db({ ...this._options, transaction: withoutTransaction ? null : this._options.transaction });\n }\n\n get table() {\n return this._options.table;\n }\n\n get options() {\n return this._options;\n }\n\n get isTransaction() {\n return this._isTransaction;\n }\n\n /**\n * 获取聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n return this._host.aggregate();\n }\n\n private _hasWhere: _WhereFrom | undefined = undefined;\n private _hasWhereId: _WhereFrom | undefined = undefined;\n private _where = {};\n\n private _doWhere(where: DbWhere<D1>, from: _WhereFrom) {\n if (this._hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this._hasWhere)} 了`);\n\n // 过滤掉值为 undefined 的键值对,数据库不支持查询全 undefined 值\n const realWhere = objectFilter(where, (value) => value !== undefined);\n\n const whereKeys = Object.keys(realWhere);\n\n // 只有 _id 值为字符串或数字时,才能调用 doc 方法\n const isWhereId =\n whereKeys.length === 1 && '_id' in realWhere && (isString(realWhere._id) || isNumber(realWhere._id));\n\n if (isWhereId && this._hasLimit) {\n throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);\n }\n\n this._hasWhere = from;\n this._where = realWhere;\n if (isWhereId) this._hasWhereId = from;\n\n return this;\n }\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式调用\n */\n where(where: DbWhere<D1> & W2) {\n return this._doWhere(where, 'where');\n }\n\n /**\n * 获取当前查询条件\n * @param plain 是否返回原始查询条件对象,默认 false\n * @returns 当前查询条件对象\n */\n getWhere(plain?: boolean) {\n // @ts-ignore\n return plain ? objectOmit(this._where, Object.keys(this._lookupAs)) : this._where;\n }\n\n /**\n * 根据ID设置查询条件\n * @param id 记录ID\n * @returns 当前Db实例,支持链式调用\n */\n whereId(id: string | number) {\n // @ts-ignore\n return this._doWhere({ _id: id }, 'whereId');\n }\n\n private _hasSelect = 0;\n private _select = {};\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式调用\n */\n select<const S extends DbSelect<D1>>(fields: S) {\n if (this._hasSelect) throw new Error('db.select() 方法只能调用一次');\n\n this._hasSelect++;\n this._select = fields;\n\n // @ts-ignore\n return this as Db<D1, S, D2, W2>;\n }\n\n private _hasOrder = 0;\n private _order = {};\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式调用\n */\n order(order: DbOrder<D1>) {\n this._hasOrder++;\n this._order = order;\n\n return this;\n }\n\n private _hasSkip = 0;\n private _skip = 0;\n\n /**\n * 跳过指定数量的记录\n * @param skip 要跳过的记录数\n * @returns 当前Db实例,支持链式调用\n */\n skip(skip: number) {\n if (this._hasSkip) throw new Error('db.skip() 方法只能调用一次');\n\n this._hasSkip++;\n this._skip = skip;\n\n return this;\n }\n\n private _hasLimit = 0;\n private _limit = 0;\n\n /**\n * 限制返回的记录数量\n * @param limit 最大返回记录数\n * @returns 当前Db实例,支持链式调用\n */\n limit(limit: number) {\n if (this._hasLimit) throw new Error('db.limit() 方法只能调用一次');\n\n if (this._hasWhereId) {\n throw new Error(`db.limit() 方法不能与 ${_toWhereIdMethod(this._hasWhereId)} 方法同时调用`);\n }\n\n this._hasLimit++;\n this._limit = limit;\n\n return this;\n }\n\n private _hasLookup = 0;\n get hasLookup() {\n return this._hasLookup > 0;\n }\n\n private _lookups: DbLookup[] = [];\n lookup<\n FD1,\n FS1 extends DbSelect<FD1>,\n FD2 extends AnyObject,\n FW2 extends AnyObject,\n RL extends DbRelation,\n AS extends string,\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n US extends boolean | undefined | void = undefined,\n >(table: Db<FD1, FS1, FD2, FW2>, lookup: DbLookupOptions<RL, D1, FD1, AS, US>) {\n // 对方表也记为关联查询,避免做表更新操作\n table._hasLookup++;\n this._hasLookup++;\n this._lookups.push({\n ...lookup,\n table,\n } as unknown as DbLookup);\n\n // @ts-ignore\n return this as Db<\n D1,\n S1,\n US extends true ? D2 : MergeIntersection<D2 & DbForeign<FD1, FS1, FD2, RL, AS>>,\n MergeIntersection<W2 & Partial<Record<AS, DbQueryCommand>>>\n >;\n }\n\n private _aggregated = false;\n private _lookupAs = {} as Record<string, true>;\n private _endAggregate(aggRef: UniCloud.AggregateReference) {\n if (this._aggregated) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);\n\n this._aggregated = true;\n let returnAggRef = aggRef;\n let hasAggSelect = 0;\n const aggSelect = {} as Record<string, true>;\n let hasAggUnselect = 0;\n const aggUnselect = {} as Record<string, false>;\n\n // 后做关联查询\n for (const { relation: type, as, foreignField, localField, table, unselect } of this._lookups) {\n const letName = `let${gid++}`;\n let pipeline = dbAgg.pipeline();\n\n // 关联条件\n // @ts-ignore\n pipeline = pipeline.match({\n $expr: {\n $and: [\n type === 'n:1'\n ? { $in: [`$${foreignField}`, `$$${letName}`] }\n : { $eq: [`$${foreignField}`, `$$${letName}`] },\n ],\n },\n });\n\n // 其他查询条件\n // @ts-ignore\n pipeline = table._endAggregate(pipeline);\n\n // @ts-ignore\n pipeline = pipeline.done();\n\n returnAggRef = returnAggRef.lookup({\n let: {\n [letName]: `$${localField}`,\n },\n as,\n from: table.table,\n pipeline,\n });\n\n // 1对1,展开数组\n if (type === '1:1') {\n // @ts-ignore\n returnAggRef = returnAggRef.unwind({\n path: `$${as}`,\n preserveNullAndEmptyArrays: true,\n });\n }\n\n if (unselect) {\n hasAggUnselect++;\n aggUnselect[as] = false;\n } else {\n hasAggSelect++;\n aggSelect[as] = true;\n }\n\n this._lookupAs[as] = true;\n }\n\n // 主表查询,注意顺序,筛选->排序->跳过->限制\n if (this._hasWhere) returnAggRef = returnAggRef.match(_mapCommandRaw(this._where));\n if (this._hasOrder) returnAggRef = returnAggRef.sort(objectMap(this._order, (v) => (v === 'asc' ? 1 : -1)));\n if (this._hasSkip) returnAggRef = returnAggRef.skip(this._skip);\n if (this._hasLimit) returnAggRef = returnAggRef.limit(this._limit);\n\n // 如果主表有选择字段,则合并选择字段(包括关联查询的字段和排序字段)\n if (this._hasSelect) {\n returnAggRef = returnAggRef.project(_mergeSelect({ ...this._select, ...aggSelect }, this._order));\n }\n // 如果主表没有选择字段,则排除取消选择字段\n else if (hasAggUnselect) {\n returnAggRef = returnAggRef.project(aggUnselect);\n }\n\n return returnAggRef;\n }\n\n private _endHost(action: 'query' | 'create' | 'update' | 'remove' | 'count') {\n if (this._hasWhere) {\n // 事务模式更新只能用 doc(id)\n if (action === 'update' && this._isTransaction) {\n // @ts-ignore\n this._host = this._host.doc(this._where._id);\n } else {\n // @ts-ignore\n this._host = this._host.where(_mapCommandRaw(this._where));\n }\n }\n\n if (this._hasSelect) {\n // @ts-ignore\n this._host = this._host.field(_mergeSelect(this._select, this._order));\n }\n\n if (this._hasOrder) {\n objectEach(this._order, (val, key) => {\n // @ts-ignore\n this._host = this._host.orderBy(key, val);\n });\n }\n\n // @ts-ignore\n if (this._hasSkip) this._host = this._host.skip(this._skip);\n\n // @ts-ignore\n if (this._hasLimit && action === 'query') this._host = this._host.limit(this._limit);\n // @ts-ignore\n else if (this._hasWhereId && action === 'query') this._host = this._host.limit(1);\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async many() {\n try {\n if (this._isTransaction) throw new Error('db.many() 方法不支持事务模式');\n\n let res: { data: DbQuery<D1, S1, D2>[] };\n\n // 关联查询\n if (this._hasLookup) {\n const aggRef = this.aggregate();\n this._endAggregate(aggRef);\n res = await aggRef.end();\n }\n // 单表查询\n else {\n this._endHost('query');\n res = await this._host.get();\n }\n\n const { data } = parseDatabaseOutput(res);\n return data;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * 如果没有匹配到记录,会抛出错误\n * @returns 查询结果\n */\n async firstOrThrow(): Promise<DbQuery<D1, S1, D2>> {\n if (this._isTransaction) throw new Error('db.firstOrThrow() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.firstOrThrow() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.many();\n const res = data.at(0);\n\n if (!res) throw createCloudObjectError('查询数据为空', 'firstOrThrow');\n return res;\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * 如果没有匹配到记录,返回 null\n * @returns 查询结果或 null\n */\n async firstOrNull(): Promise<DbQuery<D1, S1, D2> | null> {\n if (this._isTransaction) throw new Error('db.firstOrNull() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.firstOrNull() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.many();\n return data.at(0) || null;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\n if (this._hasLookup) throw new Error('db.count() 方法不支持 lookup 聚合');\n if (this._hasSelect) throw new Error('db.count() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.count() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.count() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.count() 方法不支持 limit 条件');\n\n try {\n this._endHost('count');\n const res = await this._host.count();\n const { total } = parseDatabaseOutput<{ total: number }>(res);\n return total;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: DbCreate<D1>) {\n if (this._hasLookup) throw new Error('db.create() 方法不支持 lookup 聚合');\n if (this._hasWhere) throw new Error('db.create() 方法不支持 where 条件');\n if (this._hasSelect) throw new Error('db.create() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.create() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.create() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.create() 方法不支持 limit 条件');\n\n try {\n this._endHost('create');\n const res = await this._host.add(data);\n const { id } = parseDatabaseOutput<{ id: string }>(res);\n return id;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: DbUpdate<D1>) {\n if (this._hasLookup) throw new Error('db.update() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.update() 方法');\n if (this._hasSelect) throw new Error('db.update() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.update() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.update() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.update() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.update() 的 where 条件必须是 _id');\n\n try {\n this._endHost('update');\n const res = await this._host.update(objectOmit(_mapCommandRaw(data), ['_id']));\n const { updated } = parseDatabaseOutput<{ updated: number }>(res);\n return updated;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\n if (this._hasLookup) throw new Error('db.remove() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.remove() 方法');\n if (this._hasSelect) throw new Error('db.remove() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.remove() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.remove() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.remove() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.remove() 的 where 条件必须是 _id');\n\n try {\n this._endHost('remove');\n const res = await this._host.remove();\n const { deleted } = parseDatabaseOutput<{ deleted: number }>(res);\n return deleted;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n}\n\nfunction _toWhereMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({...})' : 'whereId(id)';\n}\n\nfunction _toWhereIdMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({ _id })' : 'whereId(id)';\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nfunction _mapCommandRaw(data: any) {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const map = (val: any): any => {\n if (!isObject(val)) return val;\n if (val instanceof DbBaseCommand) return DbBaseCommand.getValue(val, db0);\n return objectMap(val, map);\n };\n\n return objectMap(data, map);\n}\n\nfunction _mapOrderSelect(order: DbOrder<unknown>) {\n return objectMap(order, (val, key) => true);\n}\n\nfunction _mergeSelect(select: DbSelect<unknown>, order: DbOrder<unknown>) {\n const noSelect = Object.keys(select).length === 0;\n // 如果没有 select 条件,默认返回所有字段\n if (noSelect) return select;\n\n const onlyOmitId = Object.keys(select).length === 1 && '_id' in select && select._id === false;\n // 如果只排除 _id 字段,则保持现状\n if (onlyOmitId) return select;\n\n return {\n ...select,\n ..._mapOrderSelect(order),\n };\n}\n","import type { UniError } from '@/_types';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\nexport type DbProxyOptions = {\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n/**\n * 创建一个数据库代理对象,用于延迟实例化数据库操作类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @param name - 数据库表名\n * @returns 返回一个代理对象,该对象会将属性访问转发到实际的数据库操作实例\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport function dbProxy<D1, S1 extends DbSelect<D1> = {}>(name: string, options?: DbProxyOptions) {\n return new Proxy(\n {},\n {\n get(target, prop) {\n if (prop === '_isProxy') return true;\n\n const table = new Db<D1, S1>({ table: name, ...options });\n const tableProp = prop as keyof Db<D1, S1>;\n const ref = table[tableProp];\n\n return isFunction(ref) ? ref.bind(table) : ref;\n },\n },\n ) as Db<D1, S1>;\n}\n","import { isFunction } from '@cloudcome/utils-core/type';\nimport type { Exact } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbCreate, DbQuery, DbSelect, DbUpdate, DbWhere } from './types';\n\nexport type DbUpsertOptions<T, C extends DbCreate<T>, U extends DbUpdate<T>> = {\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n update: U | ((exist: DbQuery<T, {}, {}>) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param exist 查询到的原始文档数据\n * @returns 如果返回 false,则取消更新操作\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onBeforeUpdate?: (exist: DbQuery<T, {}, {}>) => false | unknown;\n\n /**\n * 更新后回调函数\n * @param updateData 实际更新的数据\n * @param exist 查询到的原始文档数据\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onAfterUpdate?: (updateData: U, exist: DbQuery<T, {}, {}>) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUpsertOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n /** 是否为更新操作 */\n updated: boolean;\n};\n\nexport async function dbUpsert<D1, C extends DbCreate<D1>, U extends DbUpdate<D1>>(\n db: Db<D1>,\n options: DbUpsertOptions<D1, C, U>,\n): Promise<DbUpsertOutput> {\n const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;\n\n const _mutateDb = (_mockDbInstance || db.clone()) as Db<D1>;\n const _queryDb = (_mockDbInstance || db.clone(true)) as Db<D1>;\n\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n const exist = (await _queryDb.where(db.getWhere(true)).firstOrNull()) as DbQuery<D1, {}, {}> | null;\n\n if (exist) {\n const skipUpdate = (await onBeforeUpdate?.(exist)) === false;\n\n if (skipUpdate) {\n // @ts-ignore\n return { id: exist._id as string, updated: false, created: false };\n }\n\n const updateData = isFunction(update) ? update(exist) : update;\n // @ts-ignore\n await _mutateDb.whereId(exist._id).update(updateData);\n onAfterUpdate?.(updateData, exist);\n\n // @ts-ignore\n return { id: exist._id as string, updated: true, created: false };\n }\n\n await onBeforeCreate?.();\n const createdId = await _mutateDb.create(create);\n await onAfterCreate?.(createdId);\n\n return { id: createdId, updated: false, created: true };\n}\n","import type { Db } from './_db.class';\nimport type { DbCreate, DbWhere } from './types';\nimport { dbUpsert } from './upsert';\n\nexport type DbUniqueOptions<T, C extends DbCreate<T>> = {\n /** 创建数据 */\n create: C;\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUniqueOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n};\n\nexport async function dbUnique<T, C extends DbCreate<T>>(\n db: Db<T>,\n options: DbUniqueOptions<T, C>,\n): Promise<DbUniqueOutput> {\n const { id, created } = await dbUpsert(db, {\n ...options,\n // @ts-ignore\n update: {},\n onBeforeUpdate: () => false,\n });\n return { id, created };\n}\n","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { Db } from './_db.class';\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\nexport type WithTransaction = <D1>(db: Db<D1>) => Db<D1>;\n\n/**\n * 在数据库事务中执行操作\n *\n * @template K - 事务操作返回值类型\n * @param transacting - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库对象\n * @param _mockDbInstance - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (withTransaction) => {\n * const userId = await withTransaction(db.table('user')).create({ name: 'John' });\n * const order = await withTransaction(db.table('orders')).create({ userId, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\nexport async function dbTransaction<K>(\n transacting: (withTransaction: WithTransaction) => Promise<K>,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any,\n) {\n const transactionDb = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(transactionDb.startTransaction());\n if (err1) throw err1;\n\n const withTransaction: WithTransaction = <D1>(db: Db<D1>) => {\n return _mockDbInstance || new Db<D1>({ ...db.options, transaction });\n };\n\n const [err2, result] = await tryFlatten(async () => {\n const result = await transacting(withTransaction);\n await transaction.commit();\n return result;\n });\n\n if (err2) {\n await tryFlatten(transaction.rollback());\n throw err2;\n }\n\n return result as unknown as K;\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\n/**\n * 数据库分页查询函数\n * @template T - 数据类型\n * @param queryDb - 数据库查询实例\n * @returns 包含数据列表和总数的对象\n */\n\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport async function dbPaging<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}>(\n queryDb: Db<D1, S1, D2, W2>,\n) {\n // 获取原始查询条件,不包映射字段\n const where = queryDb.getWhere(true);\n\n // 克隆查询实例用于统计总数,避免影响原查询\n const countDb = queryDb.clone();\n\n // 执行查询获取数据列表\n const list = await queryDb.many();\n\n // 基于相同查询条件统计总数\n const total = await countDb.where(where).count();\n\n // 返回分页结果\n return {\n list,\n total,\n };\n}\n"],"names":["objectFilter","isString","isNumber","objectOmit","type","objectMap","objectEach","parseDatabaseOutput","createCloudObjectError","isObject","isFunction","tryFlatten","result"],"mappings":"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"}
package/dist/database.mjs CHANGED
@@ -397,9 +397,9 @@ class Db {
397
397
  * 执行查询操作
398
398
  * @returns 查询结果
399
399
  */
400
- async query() {
400
+ async many() {
401
401
  try {
402
- if (this._isTransaction) throw new Error("db.query() 方法不支持事务模式");
402
+ if (this._isTransaction) throw new Error("db.many() 方法不支持事务模式");
403
403
  let res;
404
404
  if (this._hasLookup) {
405
405
  const aggRef = this.aggregate();
@@ -416,14 +416,31 @@ class Db {
416
416
  throw this._options.parseError?.(dbErr) || dbErr;
417
417
  }
418
418
  }
419
- async queryOne(allowMiss = false) {
420
- if (this._isTransaction) throw new Error("db.queryOne() 方法不支持事务模式");
421
- if (this._hasLimit) throw new Error("db.queryOne() 方法不支持 limit 条件");
419
+ /**
420
+ * 只查询一条,自动添加 limit(1) 条件
421
+ * 如果没有匹配到记录,会抛出错误
422
+ * @returns 查询结果
423
+ */
424
+ async firstOrThrow() {
425
+ if (this._isTransaction) throw new Error("db.firstOrThrow() 方法不支持事务模式");
426
+ if (this._hasLimit) throw new Error("db.firstOrThrow() 方法不支持 limit 条件");
422
427
  if (!this._hasWhereId) this.limit(1);
423
- const data = await this.query();
428
+ const data = await this.many();
424
429
  const res = data.at(0);
425
- if (!allowMiss && !res) throw createCloudObjectError("查询数据为空", "queryOneMiss");
426
- return res || null;
430
+ if (!res) throw createCloudObjectError("查询数据为空", "firstOrThrow");
431
+ return res;
432
+ }
433
+ /**
434
+ * 只查询一条,自动添加 limit(1) 条件
435
+ * 如果没有匹配到记录,返回 null
436
+ * @returns 查询结果或 null
437
+ */
438
+ async firstOrNull() {
439
+ if (this._isTransaction) throw new Error("db.firstOrNull() 方法不支持事务模式");
440
+ if (this._hasLimit) throw new Error("db.firstOrNull() 方法不支持 limit 条件");
441
+ if (!this._hasWhereId) this.limit(1);
442
+ const data = await this.many();
443
+ return data.at(0) || null;
427
444
  }
428
445
  /**
429
446
  * 获取匹配记录的数量
@@ -558,7 +575,7 @@ async function dbUpsert(db, options) {
558
575
  const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;
559
576
  const _mutateDb = _mockDbInstance || db.clone();
560
577
  const _queryDb = _mockDbInstance || db.clone(true);
561
- const exist = await _queryDb.where(db.getWhere(true)).queryOne(true);
578
+ const exist = await _queryDb.where(db.getWhere(true)).firstOrNull();
562
579
  if (exist) {
563
580
  const skipUpdate = await onBeforeUpdate?.(exist) === false;
564
581
  if (skipUpdate) {
@@ -604,7 +621,7 @@ async function dbTransaction(transacting, _mockDatabase, _mockDbInstance) {
604
621
  async function dbPaging(queryDb) {
605
622
  const where = queryDb.getWhere(true);
606
623
  const countDb = queryDb.clone();
607
- const list = await queryDb.query();
624
+ const list = await queryDb.many();
608
625
  const total = await countDb.where(where).count();
609
626
  return {
610
627
  list,
@@ -1 +1 @@
1
- {"version":3,"file":"database.mjs","sources":["../src/database/_command.class.ts","../src/database/command.ts","../src/database/_db.class.ts","../src/database/proxy.ts","../src/database/upsert.ts","../src/database/unique.ts","../src/database/transaction.ts","../src/database/paging.ts"],"sourcesContent":["// 设置私有属性和静态方法是避免在 update 的时候提示类属性\n\nexport class DbBaseCommand {\n protected _isQuery = false;\n protected _isMutate = false;\n\n constructor(\n private _command: string,\n private _parameter: unknown,\n private _options?: {\n formatParameter?: (db: UniCloud.Database) => unknown;\n rewriteValue?: (db: UniCloud.Database, parameter: unknown) => unknown;\n },\n ) {}\n\n static getValue(cmd: DbBaseCommand, db: UniCloud.Database) {\n if (cmd._options?.rewriteValue) {\n return cmd._options.rewriteValue(db, cmd._parameter);\n }\n\n return (db.command as unknown as Record<string, (value: unknown) => unknown>)[cmd._command].call(\n db.command,\n cmd._options?.formatParameter?.(db) || cmd._parameter,\n );\n }\n\n static getExpression(cmd: DbBaseCommand, fieldName: string) {\n return {\n [`$${cmd._command}`]: [fieldName, cmd._parameter],\n };\n }\n\n static isQueryCommand(cmd: DbBaseCommand) {\n return cmd._isQuery;\n }\n\n static isMutateCommand(cmd: DbBaseCommand) {\n return cmd._isMutate;\n }\n}\n\nexport class DbQueryCommand extends DbBaseCommand {\n protected _isQuery = true;\n}\n\nexport class DbMutateCommand extends DbBaseCommand {\n protected _isMutate = true;\n}\n","import { DbBaseCommand, DbMutateCommand, DbQueryCommand } from './_command.class';\n\n/**\n * 数据库查询命令对象,提供各种查询操作符\n */\nexport const dbQuery = {\n /**\n * 等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n eq: (value: unknown) => new DbQueryCommand('eq', value),\n\n /**\n * 不等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n neq: (value: unknown) => new DbQueryCommand('neq', value),\n\n /**\n * 大于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gt: (value: unknown) => new DbQueryCommand('gt', value),\n\n /**\n * 大于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gte: (value: unknown) => new DbQueryCommand('gte', value),\n\n /**\n * 小于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lt: (value: unknown) => new DbQueryCommand('lt', value),\n\n /**\n * 小于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lte: (value: unknown) => new DbQueryCommand('lte', value),\n\n /**\n * 包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n in: (value: unknown[]) => new DbQueryCommand('in', value),\n\n /**\n * 不包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n nin: (value: unknown[]) => new DbQueryCommand('nin', value),\n\n /**\n * 数组长度匹配操作符\n * @param size 数组长度\n * @returns DbQueryCommand 查询命令对象\n */\n size: (size: number) => new DbQueryCommand('size', size),\n\n /**\n * 正则表达式匹配操作符\n * @param regExp 正则表达式\n * @returns DbQueryCommand 查询命令对象\n */\n regExp: (regExp: RegExp) =>\n new DbQueryCommand('regExp', regExp, {\n rewriteValue: (db, parameter) => parameter,\n }),\n\n /**\n * 逻辑与操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n and: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('and', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n\n /**\n * 逻辑或操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n or: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('or', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n};\n\n/**\n * 数据库变更命令对象,提供各种数据更新操作符\n */\nexport const dbMutate = {\n /**\n * 数值增加操作符\n * @param value 增加的数值\n * @returns DbMutateCommand 变更命令对象\n */\n inc: (value: number) => new DbMutateCommand('inc', value),\n\n /**\n * 数值乘法操作符\n * @param value 乘数\n * @returns DbMutateCommand 变更命令对象\n */\n mul: (value: number) => new DbMutateCommand('mul', value),\n\n /**\n * 设置字段值操作符\n * @param value 设置的值\n * @returns DbMutateCommand 变更命令对象\n */\n set: (value: unknown) => new DbMutateCommand('set', value),\n\n /**\n * 向数组末尾添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n push: (value: unknown) => new DbMutateCommand('push', value),\n\n /**\n * 向数组开头添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n unshift: (value: unknown) => new DbMutateCommand('unshift', value),\n\n /**\n * 从数组末尾移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n pop: () => new DbMutateCommand('pop', undefined),\n\n /**\n * 从数组开头移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n shift: () => new DbMutateCommand('shift', undefined),\n\n /**\n * 移除字段操作符\n * @returns DbMutateCommand 变更命令对象\n */\n remove: () => new DbMutateCommand('remove', undefined),\n};\n","import { parseDatabaseOutput } from '@/_helpers';\nimport type { UniError } from '@/_types';\nimport { createCloudObjectError } from '@/cloud';\nimport { objectEach, objectFilter, objectMap, objectOmit } from '@cloudcome/utils-core/object';\nimport { isArray, isNumber, isObject, isString } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MergeIntersection } from '@cloudcome/utils-core/types';\nimport { DbBaseCommand, type DbQueryCommand } from './_command.class';\nimport type { DbCreate, DbForeign, DbOrder, DbQuery, DbRelation, DbSelect, DbUpdate, DbWhere } from './types';\n\n/**\n * 数据库聚合操作符命令\n */\nconst dbAgg = uniCloud.database().command.aggregate as UniCloud.AggregateCommand & {\n pipeline: () => UniCloud.AggregateReference & {\n done: () => unknown;\n };\n};\n\ntype _WhereFrom = 'where' | 'whereId';\n\nconst db0 = uniCloud.database();\n\nexport type DbOptions = {\n /**\n * 数据表名称\n */\n table: string;\n\n /**\n * 事务对象,用于事务操作\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n transaction?: any;\n\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any;\n\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type DbLookupOptions<RL extends DbRelation, D1, FD1, AS, US extends boolean | undefined | void = undefined> = {\n /**\n * 关联类型\n */\n relation: RL;\n\n /**\n * 主表字段\n */\n localField: keyof D1 & string;\n\n /**\n * 关联表字段\n */\n foreignField: keyof FD1 & string;\n\n /**\n * 关联数据在结果中的字段名\n */\n as: AS;\n\n /**\n * 是否取消筛选关联数据\n */\n unselect?: US;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type DbLookup = DbLookupOptions<any, unknown, unknown, string, boolean> & {\n /**\n * 关联表\n */\n table: Db<unknown>;\n};\n\nlet gid = 0;\n\n/**\n * 数据库类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @template D2 - 副表数据\n * @template W2 - 副表查询\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}> {\n private _host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n private _isTransaction = false;\n\n private _options: DbOptions;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 数据表名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this._options = options;\n this._host =\n options._mockDatabase || options.transaction?.collection(options.table) || db0.collection(options.table);\n this._isTransaction = !!options.transaction;\n }\n\n /**\n * 创建一个新的数据库实例,可选是否移除事务\n * @param withoutTransaction 是否移除事务,默认 false\n * @returns 新的数据库实例\n */\n clone(withoutTransaction?: boolean) {\n return new Db({ ...this._options, transaction: withoutTransaction ? null : this._options.transaction });\n }\n\n get table() {\n return this._options.table;\n }\n\n get options() {\n return this._options;\n }\n\n get isTransaction() {\n return this._isTransaction;\n }\n\n /**\n * 获取聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n return this._host.aggregate();\n }\n\n private _hasWhere: _WhereFrom | undefined = undefined;\n private _hasWhereId: _WhereFrom | undefined = undefined;\n private _where = {};\n\n private _doWhere(where: DbWhere<D1>, from: _WhereFrom) {\n if (this._hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this._hasWhere)} 了`);\n\n // 过滤掉值为 undefined 的键值对,数据库不支持查询全 undefined 值\n const realWhere = objectFilter(where, (value) => value !== undefined);\n\n const whereKeys = Object.keys(realWhere);\n\n // 只有 _id 值为字符串或数字时,才能调用 doc 方法\n const isWhereId =\n whereKeys.length === 1 && '_id' in realWhere && (isString(realWhere._id) || isNumber(realWhere._id));\n\n if (isWhereId && this._hasLimit) {\n throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);\n }\n\n this._hasWhere = from;\n this._where = realWhere;\n if (isWhereId) this._hasWhereId = from;\n\n return this;\n }\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式调用\n */\n where(where: DbWhere<D1> & W2) {\n return this._doWhere(where, 'where');\n }\n\n /**\n * 获取当前查询条件\n * @param plain 是否返回原始查询条件对象,默认 false\n * @returns 当前查询条件对象\n */\n getWhere(plain?: boolean) {\n // @ts-ignore\n return plain ? objectOmit(this._where, Object.keys(this._lookupAs)) : this._where;\n }\n\n /**\n * 根据ID设置查询条件\n * @param id 记录ID\n * @returns 当前Db实例,支持链式调用\n */\n whereId(id: string | number) {\n // @ts-ignore\n return this._doWhere({ _id: id }, 'whereId');\n }\n\n private _hasSelect = 0;\n private _select = {};\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式调用\n */\n select<const S extends DbSelect<D1>>(fields: S) {\n if (this._hasSelect) throw new Error('db.select() 方法只能调用一次');\n\n this._hasSelect++;\n this._select = fields;\n\n // @ts-ignore\n return this as Db<D1, S, D2, W2>;\n }\n\n private _hasOrder = 0;\n private _order = {};\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式调用\n */\n order(order: DbOrder<D1>) {\n this._hasOrder++;\n this._order = order;\n\n return this;\n }\n\n private _hasSkip = 0;\n private _skip = 0;\n\n /**\n * 跳过指定数量的记录\n * @param skip 要跳过的记录数\n * @returns 当前Db实例,支持链式调用\n */\n skip(skip: number) {\n if (this._hasSkip) throw new Error('db.skip() 方法只能调用一次');\n\n this._hasSkip++;\n this._skip = skip;\n\n return this;\n }\n\n private _hasLimit = 0;\n private _limit = 0;\n\n /**\n * 限制返回的记录数量\n * @param limit 最大返回记录数\n * @returns 当前Db实例,支持链式调用\n */\n limit(limit: number) {\n if (this._hasLimit) throw new Error('db.limit() 方法只能调用一次');\n\n if (this._hasWhereId) {\n throw new Error(`db.limit() 方法不能与 ${_toWhereIdMethod(this._hasWhereId)} 方法同时调用`);\n }\n\n this._hasLimit++;\n this._limit = limit;\n\n return this;\n }\n\n private _hasLookup = 0;\n get hasLookup() {\n return this._hasLookup > 0;\n }\n\n private _lookups: DbLookup[] = [];\n lookup<\n FD1,\n FS1 extends DbSelect<FD1>,\n FD2 extends AnyObject,\n FW2 extends AnyObject,\n RL extends DbRelation,\n AS extends string,\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n US extends boolean | undefined | void = undefined,\n >(table: Db<FD1, FS1, FD2, FW2>, lookup: DbLookupOptions<RL, D1, FD1, AS, US>) {\n // 对方表也记为关联查询,避免做表更新操作\n table._hasLookup++;\n this._hasLookup++;\n this._lookups.push({\n ...lookup,\n table,\n } as unknown as DbLookup);\n\n // @ts-ignore\n return this as Db<\n D1,\n S1,\n US extends true ? D2 : MergeIntersection<D2 & DbForeign<FD1, FS1, FD2, RL, AS>>,\n MergeIntersection<W2 & Partial<Record<AS, DbQueryCommand>>>\n >;\n }\n\n private _aggregated = false;\n private _lookupAs = {} as Record<string, true>;\n private _endAggregate(aggRef: UniCloud.AggregateReference) {\n if (this._aggregated) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);\n\n this._aggregated = true;\n let returnAggRef = aggRef;\n let hasAggSelect = 0;\n const aggSelect = {} as Record<string, true>;\n let hasAggUnselect = 0;\n const aggUnselect = {} as Record<string, false>;\n\n // 后做关联查询\n for (const { relation: type, as, foreignField, localField, table, unselect } of this._lookups) {\n const letName = `let${gid++}`;\n let pipeline = dbAgg.pipeline();\n\n // 关联条件\n // @ts-ignore\n pipeline = pipeline.match({\n $expr: {\n $and: [\n type === 'n:1'\n ? { $in: [`$${foreignField}`, `$$${letName}`] }\n : { $eq: [`$${foreignField}`, `$$${letName}`] },\n ],\n },\n });\n\n // 其他查询条件\n // @ts-ignore\n pipeline = table._endAggregate(pipeline);\n\n // @ts-ignore\n pipeline = pipeline.done();\n\n returnAggRef = returnAggRef.lookup({\n let: {\n [letName]: `$${localField}`,\n },\n as,\n from: table.table,\n pipeline,\n });\n\n // 1对1,展开数组\n if (type === '1:1') {\n // @ts-ignore\n returnAggRef = returnAggRef.unwind({\n path: `$${as}`,\n preserveNullAndEmptyArrays: true,\n });\n }\n\n if (unselect) {\n hasAggUnselect++;\n aggUnselect[as] = false;\n } else {\n hasAggSelect++;\n aggSelect[as] = true;\n }\n\n this._lookupAs[as] = true;\n }\n\n // 主表查询,注意顺序,筛选->排序->跳过->限制\n if (this._hasWhere) returnAggRef = returnAggRef.match(_mapCommandRaw(this._where));\n if (this._hasOrder) returnAggRef = returnAggRef.sort(objectMap(this._order, (v) => (v === 'asc' ? 1 : -1)));\n if (this._hasSkip) returnAggRef = returnAggRef.skip(this._skip);\n if (this._hasLimit) returnAggRef = returnAggRef.limit(this._limit);\n\n // 如果主表有选择字段,则合并选择字段(包括关联查询的字段和排序字段)\n if (this._hasSelect) {\n returnAggRef = returnAggRef.project(_mergeSelect({ ...this._select, ...aggSelect }, this._order));\n }\n // 如果主表没有选择字段,则排除取消选择字段\n else if (hasAggUnselect) {\n returnAggRef = returnAggRef.project(aggUnselect);\n }\n\n return returnAggRef;\n }\n\n private _endHost(action: 'query' | 'create' | 'update' | 'remove' | 'count') {\n if (this._hasWhere) {\n // 事务模式更新只能用 doc(id)\n if (action === 'update' && this._isTransaction) {\n // @ts-ignore\n this._host = this._host.doc(this._where._id);\n } else {\n // @ts-ignore\n this._host = this._host.where(_mapCommandRaw(this._where));\n }\n }\n\n if (this._hasSelect) {\n // @ts-ignore\n this._host = this._host.field(_mergeSelect(this._select, this._order));\n }\n\n if (this._hasOrder) {\n objectEach(this._order, (val, key) => {\n // @ts-ignore\n this._host = this._host.orderBy(key, val);\n });\n }\n\n // @ts-ignore\n if (this._hasSkip) this._host = this._host.skip(this._skip);\n\n // @ts-ignore\n if (this._hasLimit && action === 'query') this._host = this._host.limit(this._limit);\n // @ts-ignore\n else if (this._hasWhereId && action === 'query') this._host = this._host.limit(1);\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async query() {\n try {\n if (this._isTransaction) throw new Error('db.query() 方法不支持事务模式');\n\n let res: { data: DbQuery<D1, S1, D2>[] };\n\n // 关联查询\n if (this._hasLookup) {\n const aggRef = this.aggregate();\n this._endAggregate(aggRef);\n res = await aggRef.end();\n }\n // 单表查询\n else {\n this._endHost('query');\n res = await this._host.get();\n }\n\n const { data } = parseDatabaseOutput(res);\n return data;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * @param allowMiss 是否允许没有匹配到记录,如果为 true,则可能返回 null\n * @returns 查询结果\n */\n async queryOne(): Promise<DbQuery<D1, S1, D2>>;\n async queryOne(allowMiss: false): Promise<DbQuery<D1, S1, D2>>;\n async queryOne(allowMiss: true): Promise<DbQuery<D1, S1, D2> | null>;\n async queryOne(allowMiss = false): Promise<DbQuery<D1, S1, D2> | null> {\n if (this._isTransaction) throw new Error('db.queryOne() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.queryOne() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.query();\n const res = data.at(0);\n\n if (!allowMiss && !res) throw createCloudObjectError('查询数据为空', 'queryOneMiss');\n return res || null;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\n if (this._hasLookup) throw new Error('db.count() 方法不支持 lookup 聚合');\n if (this._hasSelect) throw new Error('db.count() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.count() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.count() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.count() 方法不支持 limit 条件');\n\n try {\n this._endHost('count');\n const res = await this._host.count();\n const { total } = parseDatabaseOutput<{ total: number }>(res);\n return total;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: DbCreate<D1>) {\n if (this._hasLookup) throw new Error('db.create() 方法不支持 lookup 聚合');\n if (this._hasWhere) throw new Error('db.create() 方法不支持 where 条件');\n if (this._hasSelect) throw new Error('db.create() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.create() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.create() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.create() 方法不支持 limit 条件');\n\n try {\n this._endHost('create');\n const res = await this._host.add(data);\n const { id } = parseDatabaseOutput<{ id: string }>(res);\n return id;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: DbUpdate<D1>) {\n if (this._hasLookup) throw new Error('db.update() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.update() 方法');\n if (this._hasSelect) throw new Error('db.update() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.update() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.update() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.update() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.update() 的 where 条件必须是 _id');\n\n try {\n this._endHost('update');\n const res = await this._host.update(objectOmit(_mapCommandRaw(data), ['_id']));\n const { updated } = parseDatabaseOutput<{ updated: number }>(res);\n return updated;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\n if (this._hasLookup) throw new Error('db.remove() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.remove() 方法');\n if (this._hasSelect) throw new Error('db.remove() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.remove() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.remove() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.remove() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.remove() 的 where 条件必须是 _id');\n\n try {\n this._endHost('remove');\n const res = await this._host.remove();\n const { deleted } = parseDatabaseOutput<{ deleted: number }>(res);\n return deleted;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n}\n\nfunction _toWhereMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({...})' : 'whereId(id)';\n}\n\nfunction _toWhereIdMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({ _id })' : 'whereId(id)';\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nfunction _mapCommandRaw(data: any) {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const map = (val: any): any => {\n if (!isObject(val)) return val;\n if (val instanceof DbBaseCommand) return DbBaseCommand.getValue(val, db0);\n return objectMap(val, map);\n };\n\n return objectMap(data, map);\n}\n\nfunction _mapOrderSelect(order: DbOrder<unknown>) {\n return objectMap(order, (val, key) => true);\n}\n\nfunction _mergeSelect(select: DbSelect<unknown>, order: DbOrder<unknown>) {\n const noSelect = Object.keys(select).length === 0;\n // 如果没有 select 条件,默认返回所有字段\n if (noSelect) return select;\n\n const onlyOmitId = Object.keys(select).length === 1 && '_id' in select && select._id === false;\n // 如果只排除 _id 字段,则保持现状\n if (onlyOmitId) return select;\n\n return {\n ...select,\n ..._mapOrderSelect(order),\n };\n}\n","import type { UniError } from '@/_types';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\nexport type DbProxyOptions = {\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n/**\n * 创建一个数据库代理对象,用于延迟实例化数据库操作类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @param name - 数据库表名\n * @returns 返回一个代理对象,该对象会将属性访问转发到实际的数据库操作实例\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport function dbProxy<D1, S1 extends DbSelect<D1> = {}>(name: string, options?: DbProxyOptions) {\n return new Proxy(\n {},\n {\n get(target, prop) {\n if (prop === '_isProxy') return true;\n\n const table = new Db<D1, S1>({ table: name, ...options });\n const tableProp = prop as keyof Db<D1, S1>;\n const ref = table[tableProp];\n\n return isFunction(ref) ? ref.bind(table) : ref;\n },\n },\n ) as Db<D1, S1>;\n}\n","import { isFunction } from '@cloudcome/utils-core/type';\nimport type { Exact } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbCreate, DbQuery, DbSelect, DbUpdate, DbWhere } from './types';\n\nexport type DbUpsertOptions<T, C extends DbCreate<T>, U extends DbUpdate<T>> = {\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n update: U | ((exist: DbQuery<T, {}, {}>) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param exist 查询到的原始文档数据\n * @returns 如果返回 false,则取消更新操作\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onBeforeUpdate?: (exist: DbQuery<T, {}, {}>) => false | unknown;\n\n /**\n * 更新后回调函数\n * @param updateData 实际更新的数据\n * @param exist 查询到的原始文档数据\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onAfterUpdate?: (updateData: U, exist: DbQuery<T, {}, {}>) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUpsertOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n /** 是否为更新操作 */\n updated: boolean;\n};\n\nexport async function dbUpsert<D1, C extends DbCreate<D1>, U extends DbUpdate<D1>>(\n db: Db<D1>,\n options: DbUpsertOptions<D1, C, U>,\n): Promise<DbUpsertOutput> {\n const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;\n\n const _mutateDb = (_mockDbInstance || db.clone()) as Db<D1>;\n const _queryDb = (_mockDbInstance || db.clone(true)) as Db<D1>;\n\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n const exist = (await _queryDb.where(db.getWhere(true)).queryOne(true)) as DbQuery<D1, {}, {}> | null;\n\n if (exist) {\n const skipUpdate = (await onBeforeUpdate?.(exist)) === false;\n\n if (skipUpdate) {\n // @ts-ignore\n return { id: exist._id as string, updated: false, created: false };\n }\n\n const updateData = isFunction(update) ? update(exist) : update;\n // @ts-ignore\n await _mutateDb.whereId(exist._id).update(updateData);\n onAfterUpdate?.(updateData, exist);\n\n // @ts-ignore\n return { id: exist._id as string, updated: true, created: false };\n }\n\n await onBeforeCreate?.();\n const createdId = await _mutateDb.create(create);\n await onAfterCreate?.(createdId);\n\n return { id: createdId, updated: false, created: true };\n}\n","import type { Db } from './_db.class';\nimport type { DbCreate, DbWhere } from './types';\nimport { dbUpsert } from './upsert';\n\nexport type DbUniqueOptions<T, C extends DbCreate<T>> = {\n /** 创建数据 */\n create: C;\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUniqueOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n};\n\nexport async function dbUnique<T, C extends DbCreate<T>>(\n db: Db<T>,\n options: DbUniqueOptions<T, C>,\n): Promise<DbUniqueOutput> {\n const { id, created } = await dbUpsert(db, {\n ...options,\n // @ts-ignore\n update: {},\n onBeforeUpdate: () => false,\n });\n return { id, created };\n}\n","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { Db } from './_db.class';\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\nexport type WithTransaction = <D1>(db: Db<D1>) => Db<D1>;\n\n/**\n * 在数据库事务中执行操作\n *\n * @template K - 事务操作返回值类型\n * @param transacting - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库对象\n * @param _mockDbInstance - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (withTransaction) => {\n * const userId = await withTransaction(db.table('user')).create({ name: 'John' });\n * const order = await withTransaction(db.table('orders')).create({ userId, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\nexport async function dbTransaction<K>(\n transacting: (withTransaction: WithTransaction) => Promise<K>,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any,\n) {\n const transactionDb = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(transactionDb.startTransaction());\n if (err1) throw err1;\n\n const withTransaction: WithTransaction = <D1>(db: Db<D1>) => {\n return _mockDbInstance || new Db<D1>({ ...db.options, transaction });\n };\n\n const [err2, result] = await tryFlatten(async () => {\n const result = await transacting(withTransaction);\n await transaction.commit();\n return result;\n });\n\n if (err2) {\n await tryFlatten(transaction.rollback());\n throw err2;\n }\n\n return result as unknown as K;\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\n/**\n * 数据库分页查询函数\n * @template T - 数据类型\n * @param queryDb - 数据库查询实例\n * @returns 包含数据列表和总数的对象\n */\n\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport async function dbPaging<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}>(\n queryDb: Db<D1, S1, D2, W2>,\n) {\n // 获取原始查询条件,不包映射字段\n const where = queryDb.getWhere(true);\n\n // 克隆查询实例用于统计总数,避免影响原查询\n const countDb = queryDb.clone();\n\n // 执行查询获取数据列表\n const list = await queryDb.query();\n\n // 基于相同查询条件统计总数\n const total = await countDb.where(where).count();\n\n // 返回分页结果\n return {\n list,\n total,\n };\n}\n"],"names":["result"],"mappings":"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"}
1
+ {"version":3,"file":"database.mjs","sources":["../src/database/_command.class.ts","../src/database/command.ts","../src/database/_db.class.ts","../src/database/proxy.ts","../src/database/upsert.ts","../src/database/unique.ts","../src/database/transaction.ts","../src/database/paging.ts"],"sourcesContent":["// 设置私有属性和静态方法是避免在 update 的时候提示类属性\n\nexport class DbBaseCommand {\n protected _isQuery = false;\n protected _isMutate = false;\n\n constructor(\n private _command: string,\n private _parameter: unknown,\n private _options?: {\n formatParameter?: (db: UniCloud.Database) => unknown;\n rewriteValue?: (db: UniCloud.Database, parameter: unknown) => unknown;\n },\n ) {}\n\n static getValue(cmd: DbBaseCommand, db: UniCloud.Database) {\n if (cmd._options?.rewriteValue) {\n return cmd._options.rewriteValue(db, cmd._parameter);\n }\n\n return (db.command as unknown as Record<string, (value: unknown) => unknown>)[cmd._command].call(\n db.command,\n cmd._options?.formatParameter?.(db) || cmd._parameter,\n );\n }\n\n static getExpression(cmd: DbBaseCommand, fieldName: string) {\n return {\n [`$${cmd._command}`]: [fieldName, cmd._parameter],\n };\n }\n\n static isQueryCommand(cmd: DbBaseCommand) {\n return cmd._isQuery;\n }\n\n static isMutateCommand(cmd: DbBaseCommand) {\n return cmd._isMutate;\n }\n}\n\nexport class DbQueryCommand extends DbBaseCommand {\n protected _isQuery = true;\n}\n\nexport class DbMutateCommand extends DbBaseCommand {\n protected _isMutate = true;\n}\n","import { DbBaseCommand, DbMutateCommand, DbQueryCommand } from './_command.class';\n\n/**\n * 数据库查询命令对象,提供各种查询操作符\n */\nexport const dbQuery = {\n /**\n * 等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n eq: (value: unknown) => new DbQueryCommand('eq', value),\n\n /**\n * 不等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n neq: (value: unknown) => new DbQueryCommand('neq', value),\n\n /**\n * 大于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gt: (value: unknown) => new DbQueryCommand('gt', value),\n\n /**\n * 大于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n gte: (value: unknown) => new DbQueryCommand('gte', value),\n\n /**\n * 小于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lt: (value: unknown) => new DbQueryCommand('lt', value),\n\n /**\n * 小于等于操作符\n * @param value 比较值\n * @returns DbQueryCommand 查询命令对象\n */\n lte: (value: unknown) => new DbQueryCommand('lte', value),\n\n /**\n * 包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n in: (value: unknown[]) => new DbQueryCommand('in', value),\n\n /**\n * 不包含在数组中操作符\n * @param value 值数组\n * @returns DbQueryCommand 查询命令对象\n */\n nin: (value: unknown[]) => new DbQueryCommand('nin', value),\n\n /**\n * 数组长度匹配操作符\n * @param size 数组长度\n * @returns DbQueryCommand 查询命令对象\n */\n size: (size: number) => new DbQueryCommand('size', size),\n\n /**\n * 正则表达式匹配操作符\n * @param regExp 正则表达式\n * @returns DbQueryCommand 查询命令对象\n */\n regExp: (regExp: RegExp) =>\n new DbQueryCommand('regExp', regExp, {\n rewriteValue: (db, parameter) => parameter,\n }),\n\n /**\n * 逻辑与操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n and: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('and', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n\n /**\n * 逻辑或操作符\n * @param conditions 查询条件参数\n * @returns DbQueryCommand 查询命令对象\n */\n or: (conditions: DbQueryCommand[]) =>\n new DbQueryCommand('or', conditions, {\n formatParameter: (db) => conditions.map((c) => DbBaseCommand.getValue(c, db)),\n }),\n};\n\n/**\n * 数据库变更命令对象,提供各种数据更新操作符\n */\nexport const dbMutate = {\n /**\n * 数值增加操作符\n * @param value 增加的数值\n * @returns DbMutateCommand 变更命令对象\n */\n inc: (value: number) => new DbMutateCommand('inc', value),\n\n /**\n * 数值乘法操作符\n * @param value 乘数\n * @returns DbMutateCommand 变更命令对象\n */\n mul: (value: number) => new DbMutateCommand('mul', value),\n\n /**\n * 设置字段值操作符\n * @param value 设置的值\n * @returns DbMutateCommand 变更命令对象\n */\n set: (value: unknown) => new DbMutateCommand('set', value),\n\n /**\n * 向数组末尾添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n push: (value: unknown) => new DbMutateCommand('push', value),\n\n /**\n * 向数组开头添加元素操作符\n * @param value 添加的值\n * @returns DbMutateCommand 变更命令对象\n */\n unshift: (value: unknown) => new DbMutateCommand('unshift', value),\n\n /**\n * 从数组末尾移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n pop: () => new DbMutateCommand('pop', undefined),\n\n /**\n * 从数组开头移除元素操作符\n * @returns DbMutateCommand 变更命令对象\n */\n shift: () => new DbMutateCommand('shift', undefined),\n\n /**\n * 移除字段操作符\n * @returns DbMutateCommand 变更命令对象\n */\n remove: () => new DbMutateCommand('remove', undefined),\n};\n","import { parseDatabaseOutput } from '@/_helpers';\nimport type { UniError } from '@/_types';\nimport { createCloudObjectError } from '@/cloud';\nimport { objectEach, objectFilter, objectMap, objectOmit } from '@cloudcome/utils-core/object';\nimport { isArray, isNumber, isObject, isString } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MergeIntersection } from '@cloudcome/utils-core/types';\nimport { DbBaseCommand, type DbQueryCommand } from './_command.class';\nimport type { DbCreate, DbForeign, DbOrder, DbQuery, DbRelation, DbSelect, DbUpdate, DbWhere } from './types';\n\n/**\n * 数据库聚合操作符命令\n */\nconst dbAgg = uniCloud.database().command.aggregate as UniCloud.AggregateCommand & {\n pipeline: () => UniCloud.AggregateReference & {\n done: () => unknown;\n };\n};\n\ntype _WhereFrom = 'where' | 'whereId';\n\nconst db0 = uniCloud.database();\n\nexport type DbOptions = {\n /**\n * 数据表名称\n */\n table: string;\n\n /**\n * 事务对象,用于事务操作\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n transaction?: any;\n\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any;\n\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n// biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\nexport type DbLookupOptions<RL extends DbRelation, D1, FD1, AS, US extends boolean | undefined | void = undefined> = {\n /**\n * 关联类型\n */\n relation: RL;\n\n /**\n * 主表字段\n */\n localField: keyof D1 & string;\n\n /**\n * 关联表字段\n */\n foreignField: keyof FD1 & string;\n\n /**\n * 关联数据在结果中的字段名\n */\n as: AS;\n\n /**\n * 是否取消筛选关联数据\n */\n unselect?: US;\n};\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type DbLookup = DbLookupOptions<any, unknown, unknown, string, boolean> & {\n /**\n * 关联表\n */\n table: Db<unknown>;\n};\n\nlet gid = 0;\n\n/**\n * 数据库类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @template D2 - 副表数据\n * @template W2 - 副表查询\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}> {\n private _host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n private _isTransaction = false;\n\n private _options: DbOptions;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 数据表名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this._options = options;\n this._host =\n options._mockDatabase || options.transaction?.collection(options.table) || db0.collection(options.table);\n this._isTransaction = !!options.transaction;\n }\n\n /**\n * 创建一个新的数据库实例,可选是否移除事务\n * @param withoutTransaction 是否移除事务,默认 false\n * @returns 新的数据库实例\n */\n clone(withoutTransaction?: boolean) {\n return new Db({ ...this._options, transaction: withoutTransaction ? null : this._options.transaction });\n }\n\n get table() {\n return this._options.table;\n }\n\n get options() {\n return this._options;\n }\n\n get isTransaction() {\n return this._isTransaction;\n }\n\n /**\n * 获取聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n return this._host.aggregate();\n }\n\n private _hasWhere: _WhereFrom | undefined = undefined;\n private _hasWhereId: _WhereFrom | undefined = undefined;\n private _where = {};\n\n private _doWhere(where: DbWhere<D1>, from: _WhereFrom) {\n if (this._hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this._hasWhere)} 了`);\n\n // 过滤掉值为 undefined 的键值对,数据库不支持查询全 undefined 值\n const realWhere = objectFilter(where, (value) => value !== undefined);\n\n const whereKeys = Object.keys(realWhere);\n\n // 只有 _id 值为字符串或数字时,才能调用 doc 方法\n const isWhereId =\n whereKeys.length === 1 && '_id' in realWhere && (isString(realWhere._id) || isNumber(realWhere._id));\n\n if (isWhereId && this._hasLimit) {\n throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);\n }\n\n this._hasWhere = from;\n this._where = realWhere;\n if (isWhereId) this._hasWhereId = from;\n\n return this;\n }\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式调用\n */\n where(where: DbWhere<D1> & W2) {\n return this._doWhere(where, 'where');\n }\n\n /**\n * 获取当前查询条件\n * @param plain 是否返回原始查询条件对象,默认 false\n * @returns 当前查询条件对象\n */\n getWhere(plain?: boolean) {\n // @ts-ignore\n return plain ? objectOmit(this._where, Object.keys(this._lookupAs)) : this._where;\n }\n\n /**\n * 根据ID设置查询条件\n * @param id 记录ID\n * @returns 当前Db实例,支持链式调用\n */\n whereId(id: string | number) {\n // @ts-ignore\n return this._doWhere({ _id: id }, 'whereId');\n }\n\n private _hasSelect = 0;\n private _select = {};\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式调用\n */\n select<const S extends DbSelect<D1>>(fields: S) {\n if (this._hasSelect) throw new Error('db.select() 方法只能调用一次');\n\n this._hasSelect++;\n this._select = fields;\n\n // @ts-ignore\n return this as Db<D1, S, D2, W2>;\n }\n\n private _hasOrder = 0;\n private _order = {};\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式调用\n */\n order(order: DbOrder<D1>) {\n this._hasOrder++;\n this._order = order;\n\n return this;\n }\n\n private _hasSkip = 0;\n private _skip = 0;\n\n /**\n * 跳过指定数量的记录\n * @param skip 要跳过的记录数\n * @returns 当前Db实例,支持链式调用\n */\n skip(skip: number) {\n if (this._hasSkip) throw new Error('db.skip() 方法只能调用一次');\n\n this._hasSkip++;\n this._skip = skip;\n\n return this;\n }\n\n private _hasLimit = 0;\n private _limit = 0;\n\n /**\n * 限制返回的记录数量\n * @param limit 最大返回记录数\n * @returns 当前Db实例,支持链式调用\n */\n limit(limit: number) {\n if (this._hasLimit) throw new Error('db.limit() 方法只能调用一次');\n\n if (this._hasWhereId) {\n throw new Error(`db.limit() 方法不能与 ${_toWhereIdMethod(this._hasWhereId)} 方法同时调用`);\n }\n\n this._hasLimit++;\n this._limit = limit;\n\n return this;\n }\n\n private _hasLookup = 0;\n get hasLookup() {\n return this._hasLookup > 0;\n }\n\n private _lookups: DbLookup[] = [];\n lookup<\n FD1,\n FS1 extends DbSelect<FD1>,\n FD2 extends AnyObject,\n FW2 extends AnyObject,\n RL extends DbRelation,\n AS extends string,\n // biome-ignore lint/suspicious/noConfusingVoidType: <explanation>\n US extends boolean | undefined | void = undefined,\n >(table: Db<FD1, FS1, FD2, FW2>, lookup: DbLookupOptions<RL, D1, FD1, AS, US>) {\n // 对方表也记为关联查询,避免做表更新操作\n table._hasLookup++;\n this._hasLookup++;\n this._lookups.push({\n ...lookup,\n table,\n } as unknown as DbLookup);\n\n // @ts-ignore\n return this as Db<\n D1,\n S1,\n US extends true ? D2 : MergeIntersection<D2 & DbForeign<FD1, FS1, FD2, RL, AS>>,\n MergeIntersection<W2 & Partial<Record<AS, DbQueryCommand>>>\n >;\n }\n\n private _aggregated = false;\n private _lookupAs = {} as Record<string, true>;\n private _endAggregate(aggRef: UniCloud.AggregateReference) {\n if (this._aggregated) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);\n\n this._aggregated = true;\n let returnAggRef = aggRef;\n let hasAggSelect = 0;\n const aggSelect = {} as Record<string, true>;\n let hasAggUnselect = 0;\n const aggUnselect = {} as Record<string, false>;\n\n // 后做关联查询\n for (const { relation: type, as, foreignField, localField, table, unselect } of this._lookups) {\n const letName = `let${gid++}`;\n let pipeline = dbAgg.pipeline();\n\n // 关联条件\n // @ts-ignore\n pipeline = pipeline.match({\n $expr: {\n $and: [\n type === 'n:1'\n ? { $in: [`$${foreignField}`, `$$${letName}`] }\n : { $eq: [`$${foreignField}`, `$$${letName}`] },\n ],\n },\n });\n\n // 其他查询条件\n // @ts-ignore\n pipeline = table._endAggregate(pipeline);\n\n // @ts-ignore\n pipeline = pipeline.done();\n\n returnAggRef = returnAggRef.lookup({\n let: {\n [letName]: `$${localField}`,\n },\n as,\n from: table.table,\n pipeline,\n });\n\n // 1对1,展开数组\n if (type === '1:1') {\n // @ts-ignore\n returnAggRef = returnAggRef.unwind({\n path: `$${as}`,\n preserveNullAndEmptyArrays: true,\n });\n }\n\n if (unselect) {\n hasAggUnselect++;\n aggUnselect[as] = false;\n } else {\n hasAggSelect++;\n aggSelect[as] = true;\n }\n\n this._lookupAs[as] = true;\n }\n\n // 主表查询,注意顺序,筛选->排序->跳过->限制\n if (this._hasWhere) returnAggRef = returnAggRef.match(_mapCommandRaw(this._where));\n if (this._hasOrder) returnAggRef = returnAggRef.sort(objectMap(this._order, (v) => (v === 'asc' ? 1 : -1)));\n if (this._hasSkip) returnAggRef = returnAggRef.skip(this._skip);\n if (this._hasLimit) returnAggRef = returnAggRef.limit(this._limit);\n\n // 如果主表有选择字段,则合并选择字段(包括关联查询的字段和排序字段)\n if (this._hasSelect) {\n returnAggRef = returnAggRef.project(_mergeSelect({ ...this._select, ...aggSelect }, this._order));\n }\n // 如果主表没有选择字段,则排除取消选择字段\n else if (hasAggUnselect) {\n returnAggRef = returnAggRef.project(aggUnselect);\n }\n\n return returnAggRef;\n }\n\n private _endHost(action: 'query' | 'create' | 'update' | 'remove' | 'count') {\n if (this._hasWhere) {\n // 事务模式更新只能用 doc(id)\n if (action === 'update' && this._isTransaction) {\n // @ts-ignore\n this._host = this._host.doc(this._where._id);\n } else {\n // @ts-ignore\n this._host = this._host.where(_mapCommandRaw(this._where));\n }\n }\n\n if (this._hasSelect) {\n // @ts-ignore\n this._host = this._host.field(_mergeSelect(this._select, this._order));\n }\n\n if (this._hasOrder) {\n objectEach(this._order, (val, key) => {\n // @ts-ignore\n this._host = this._host.orderBy(key, val);\n });\n }\n\n // @ts-ignore\n if (this._hasSkip) this._host = this._host.skip(this._skip);\n\n // @ts-ignore\n if (this._hasLimit && action === 'query') this._host = this._host.limit(this._limit);\n // @ts-ignore\n else if (this._hasWhereId && action === 'query') this._host = this._host.limit(1);\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async many() {\n try {\n if (this._isTransaction) throw new Error('db.many() 方法不支持事务模式');\n\n let res: { data: DbQuery<D1, S1, D2>[] };\n\n // 关联查询\n if (this._hasLookup) {\n const aggRef = this.aggregate();\n this._endAggregate(aggRef);\n res = await aggRef.end();\n }\n // 单表查询\n else {\n this._endHost('query');\n res = await this._host.get();\n }\n\n const { data } = parseDatabaseOutput(res);\n return data;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * 如果没有匹配到记录,会抛出错误\n * @returns 查询结果\n */\n async firstOrThrow(): Promise<DbQuery<D1, S1, D2>> {\n if (this._isTransaction) throw new Error('db.firstOrThrow() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.firstOrThrow() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.many();\n const res = data.at(0);\n\n if (!res) throw createCloudObjectError('查询数据为空', 'firstOrThrow');\n return res;\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * 如果没有匹配到记录,返回 null\n * @returns 查询结果或 null\n */\n async firstOrNull(): Promise<DbQuery<D1, S1, D2> | null> {\n if (this._isTransaction) throw new Error('db.firstOrNull() 方法不支持事务模式');\n if (this._hasLimit) throw new Error('db.firstOrNull() 方法不支持 limit 条件');\n if (!this._hasWhereId) this.limit(1);\n\n const data = await this.many();\n return data.at(0) || null;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\n if (this._hasLookup) throw new Error('db.count() 方法不支持 lookup 聚合');\n if (this._hasSelect) throw new Error('db.count() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.count() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.count() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.count() 方法不支持 limit 条件');\n\n try {\n this._endHost('count');\n const res = await this._host.count();\n const { total } = parseDatabaseOutput<{ total: number }>(res);\n return total;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: DbCreate<D1>) {\n if (this._hasLookup) throw new Error('db.create() 方法不支持 lookup 聚合');\n if (this._hasWhere) throw new Error('db.create() 方法不支持 where 条件');\n if (this._hasSelect) throw new Error('db.create() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.create() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.create() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.create() 方法不支持 limit 条件');\n\n try {\n this._endHost('create');\n const res = await this._host.add(data);\n const { id } = parseDatabaseOutput<{ id: string }>(res);\n return id;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: DbUpdate<D1>) {\n if (this._hasLookup) throw new Error('db.update() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.update() 方法');\n if (this._hasSelect) throw new Error('db.update() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.update() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.update() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.update() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.update() 的 where 条件必须是 _id');\n\n try {\n this._endHost('update');\n const res = await this._host.update(objectOmit(_mapCommandRaw(data), ['_id']));\n const { updated } = parseDatabaseOutput<{ updated: number }>(res);\n return updated;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\n if (this._hasLookup) throw new Error('db.remove() 方法不支持 lookup 聚合');\n if (!this._hasWhere) throw new Error('设置 where 条件后才能执行 db.remove() 方法');\n if (this._hasSelect) throw new Error('db.remove() 方法不支持 select 条件');\n if (this._hasOrder) throw new Error('db.remove() 方法不支持 order 条件');\n if (this._hasSkip) throw new Error('db.remove() 方法不支持 skip 条件');\n if (this._hasLimit) throw new Error('db.remove() 方法不支持 limit 条件');\n\n if (this._isTransaction && !this._hasWhereId) throw new Error('事务模式下 db.remove() 的 where 条件必须是 _id');\n\n try {\n this._endHost('remove');\n const res = await this._host.remove();\n const { deleted } = parseDatabaseOutput<{ deleted: number }>(res);\n return deleted;\n } catch (err) {\n const dbErr = err as UniError;\n throw this._options.parseError?.(dbErr) || dbErr;\n }\n }\n}\n\nfunction _toWhereMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({...})' : 'whereId(id)';\n}\n\nfunction _toWhereIdMethod(whereFrom: _WhereFrom) {\n return whereFrom === 'where' ? 'where({ _id })' : 'whereId(id)';\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nfunction _mapCommandRaw(data: any) {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n const map = (val: any): any => {\n if (!isObject(val)) return val;\n if (val instanceof DbBaseCommand) return DbBaseCommand.getValue(val, db0);\n return objectMap(val, map);\n };\n\n return objectMap(data, map);\n}\n\nfunction _mapOrderSelect(order: DbOrder<unknown>) {\n return objectMap(order, (val, key) => true);\n}\n\nfunction _mergeSelect(select: DbSelect<unknown>, order: DbOrder<unknown>) {\n const noSelect = Object.keys(select).length === 0;\n // 如果没有 select 条件,默认返回所有字段\n if (noSelect) return select;\n\n const onlyOmitId = Object.keys(select).length === 1 && '_id' in select && select._id === false;\n // 如果只排除 _id 字段,则保持现状\n if (onlyOmitId) return select;\n\n return {\n ...select,\n ..._mapOrderSelect(order),\n };\n}\n","import type { UniError } from '@/_types';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\nexport type DbProxyOptions = {\n /**\n * 自定义错误处理函数\n * @param error 数据库错误对象\n * @returns 处理后的数据库错误对象\n */\n parseError?: (error: UniError) => UniError;\n};\n\n/**\n * 创建一个数据库代理对象,用于延迟实例化数据库操作类\n * @template D1 - 主表数据\n * @template S1 - 主表筛选\n * @param name - 数据库表名\n * @returns 返回一个代理对象,该对象会将属性访问转发到实际的数据库操作实例\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport function dbProxy<D1, S1 extends DbSelect<D1> = {}>(name: string, options?: DbProxyOptions) {\n return new Proxy(\n {},\n {\n get(target, prop) {\n if (prop === '_isProxy') return true;\n\n const table = new Db<D1, S1>({ table: name, ...options });\n const tableProp = prop as keyof Db<D1, S1>;\n const ref = table[tableProp];\n\n return isFunction(ref) ? ref.bind(table) : ref;\n },\n },\n ) as Db<D1, S1>;\n}\n","import { isFunction } from '@cloudcome/utils-core/type';\nimport type { Exact } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbCreate, DbQuery, DbSelect, DbUpdate, DbWhere } from './types';\n\nexport type DbUpsertOptions<T, C extends DbCreate<T>, U extends DbUpdate<T>> = {\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n update: U | ((exist: DbQuery<T, {}, {}>) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param exist 查询到的原始文档数据\n * @returns 如果返回 false,则取消更新操作\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onBeforeUpdate?: (exist: DbQuery<T, {}, {}>) => false | unknown;\n\n /**\n * 更新后回调函数\n * @param updateData 实际更新的数据\n * @param exist 查询到的原始文档数据\n */\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n onAfterUpdate?: (updateData: U, exist: DbQuery<T, {}, {}>) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUpsertOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n /** 是否为更新操作 */\n updated: boolean;\n};\n\nexport async function dbUpsert<D1, C extends DbCreate<D1>, U extends DbUpdate<D1>>(\n db: Db<D1>,\n options: DbUpsertOptions<D1, C, U>,\n): Promise<DbUpsertOutput> {\n const { create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDbInstance } = options;\n\n const _mutateDb = (_mockDbInstance || db.clone()) as Db<D1>;\n const _queryDb = (_mockDbInstance || db.clone(true)) as Db<D1>;\n\n // biome-ignore lint/complexity/noBannedTypes: <explanation>\n const exist = (await _queryDb.where(db.getWhere(true)).firstOrNull()) as DbQuery<D1, {}, {}> | null;\n\n if (exist) {\n const skipUpdate = (await onBeforeUpdate?.(exist)) === false;\n\n if (skipUpdate) {\n // @ts-ignore\n return { id: exist._id as string, updated: false, created: false };\n }\n\n const updateData = isFunction(update) ? update(exist) : update;\n // @ts-ignore\n await _mutateDb.whereId(exist._id).update(updateData);\n onAfterUpdate?.(updateData, exist);\n\n // @ts-ignore\n return { id: exist._id as string, updated: true, created: false };\n }\n\n await onBeforeCreate?.();\n const createdId = await _mutateDb.create(create);\n await onAfterCreate?.(createdId);\n\n return { id: createdId, updated: false, created: true };\n}\n","import type { Db } from './_db.class';\nimport type { DbCreate, DbWhere } from './types';\nimport { dbUpsert } from './upsert';\n\nexport type DbUniqueOptions<T, C extends DbCreate<T>> = {\n /** 创建数据 */\n create: C;\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any;\n};\n\n/**\n * 数据库 upsert 操作的返回结果类型\n */\nexport type DbUniqueOutput = {\n /** 操作的文档ID */\n id: string;\n /** 是否为创建操作 */\n created: boolean;\n};\n\nexport async function dbUnique<T, C extends DbCreate<T>>(\n db: Db<T>,\n options: DbUniqueOptions<T, C>,\n): Promise<DbUniqueOutput> {\n const { id, created } = await dbUpsert(db, {\n ...options,\n // @ts-ignore\n update: {},\n onBeforeUpdate: () => false,\n });\n return { id, created };\n}\n","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { Db } from './_db.class';\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\nexport type WithTransaction = <D1>(db: Db<D1>) => Db<D1>;\n\n/**\n * 在数据库事务中执行操作\n *\n * @template K - 事务操作返回值类型\n * @param transacting - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库对象\n * @param _mockDbInstance - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (withTransaction) => {\n * const userId = await withTransaction(db.table('user')).create({ name: 'John' });\n * const order = await withTransaction(db.table('orders')).create({ userId, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\nexport async function dbTransaction<K>(\n transacting: (withTransaction: WithTransaction) => Promise<K>,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDatabase?: any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDbInstance?: any,\n) {\n const transactionDb = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(transactionDb.startTransaction());\n if (err1) throw err1;\n\n const withTransaction: WithTransaction = <D1>(db: Db<D1>) => {\n return _mockDbInstance || new Db<D1>({ ...db.options, transaction });\n };\n\n const [err2, result] = await tryFlatten(async () => {\n const result = await transacting(withTransaction);\n await transaction.commit();\n return result;\n });\n\n if (err2) {\n await tryFlatten(transaction.rollback());\n throw err2;\n }\n\n return result as unknown as K;\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { Db } from './_db.class';\nimport type { DbSelect } from './types';\n\n/**\n * 数据库分页查询函数\n * @template T - 数据类型\n * @param queryDb - 数据库查询实例\n * @returns 包含数据列表和总数的对象\n */\n\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport async function dbPaging<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}>(\n queryDb: Db<D1, S1, D2, W2>,\n) {\n // 获取原始查询条件,不包映射字段\n const where = queryDb.getWhere(true);\n\n // 克隆查询实例用于统计总数,避免影响原查询\n const countDb = queryDb.clone();\n\n // 执行查询获取数据列表\n const list = await queryDb.many();\n\n // 基于相同查询条件统计总数\n const total = await countDb.where(where).count();\n\n // 返回分页结果\n return {\n list,\n total,\n };\n}\n"],"names":["result"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const VERSION = "1.30.0";
3
+ const VERSION = "1.30.2";
4
4
  exports.VERSION = VERSION;
5
5
  //# sourceMappingURL=index.cjs.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = "1.30.0";
1
+ const VERSION = "1.30.2";
2
2
  export {
3
3
  VERSION
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-uni",
3
- "version": "1.30.1",
3
+ "version": "1.30.3",
4
4
  "description": "cloudcome utils for uni-app",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -66,8 +66,8 @@
66
66
  "dist"
67
67
  ],
68
68
  "dependencies": {
69
- "@cloudcome/utils-core": "~1.18.1",
70
- "@cloudcome/utils-vue": "~1.12.3",
69
+ "@cloudcome/utils-core": "~1.18.2",
70
+ "@cloudcome/utils-vue": "~1.13.0",
71
71
  "@dcloudio/types": "^3.0.0",
72
72
  "@dcloudio/uni-app": "^3.0.0-0",
73
73
  "vue": "^3.5.13",