@cloudcome/utils-uni 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/database.mjs CHANGED
@@ -1,19 +1,3 @@
1
- var __typeError = (msg) => {
2
- throw TypeError(msg);
3
- };
4
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
- var __privateWrapper = (obj, member, setter, getter) => ({
9
- set _(value) {
10
- __privateSet(obj, member, value, setter);
11
- },
12
- get _() {
13
- return __privateGet(obj, member, getter);
14
- }
15
- });
16
- var _host, _isTransaction, _hasWhere, _hasWhereId, _hasSelect, _hasOrder, _hasSkip, _hasLimit;
17
1
  import { errorAssign } from "@cloudcome/utils-core/error";
18
2
  import { objectEach, objectOmit } from "@cloudcome/utils-core/object";
19
3
  import { tryFlatten } from "@cloudcome/utils-core/try";
@@ -22,97 +6,114 @@ const db0 = uniCloud.database();
22
6
  const dbCmd = db0.command;
23
7
  const dbAgg = db0.command.aggregate;
24
8
  class Db {
9
+ #host;
10
+ /**
11
+ * 是否为事务环境
12
+ * - 查询条件只能是 id
13
+ * - 不能聚合操作
14
+ */
15
+ #isTransaction;
25
16
  /**
26
17
  * 构造函数,初始化数据库集合引用
27
- * @param collection 集合名称
18
+ * @param collection 数据表名称
28
19
  * @param _mockDatabase 模拟数据库,用于单元测试
29
20
  */
30
21
  constructor(options) {
31
- __privateAdd(this, _host);
32
- /**
33
- * 是否为事务环境
34
- * - 查询条件只能是 id
35
- * - 不能聚合操作
36
- */
37
- __privateAdd(this, _isTransaction);
38
- __privateAdd(this, _hasWhere, 0);
39
- __privateAdd(this, _hasWhereId, 0);
40
- __privateAdd(this, _hasSelect, 0);
41
- __privateAdd(this, _hasOrder, 0);
42
- __privateAdd(this, _hasSkip, 0);
43
- __privateAdd(this, _hasLimit, 0);
44
- __privateSet(this, _host, options._mockDatabase || options.transaction || db0.collection(options.collection));
45
- __privateSet(this, _isTransaction, !!options.transaction);
22
+ this.#host = options._mockDatabase || options.transaction || db0.collection(options.table);
23
+ this.#isTransaction = !!options.transaction;
46
24
  }
47
25
  /**
48
26
  * 创建聚合操作实例
49
27
  * @returns 聚合操作实例
50
28
  */
51
29
  aggregate() {
52
- if (!__privateGet(this, _isTransaction)) throw new Error("db.aggregate() 不支持事务模式");
53
- return __privateGet(this, _host).aggregate();
30
+ if (!this.#isTransaction) throw new Error("db.aggregate() 不支持事务模式");
31
+ return this.#host.aggregate();
54
32
  }
55
- /**
56
- * 设置查询条件
57
- * @param where 查询条件对象
58
- * @returns 当前Db实例,支持链式执行
59
- */
60
- where(where) {
61
- if (__privateGet(this, _hasWhere)) throw new Error("db.where() 方法只能执行一次");
33
+ #hasWhere = void 0;
34
+ #hasWhereId = void 0;
35
+ #where(where, from) {
36
+ if (this.#hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this.#hasWhere)} 了`);
62
37
  const whereKeys = Object.keys(where);
63
38
  const isWhereId = whereKeys.length === 1 && whereKeys[0] === "_id";
64
- __privateWrapper(this, _hasWhere)._++;
39
+ if (isWhereId && this.#hasLimit) {
40
+ throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);
41
+ }
42
+ this.#hasWhere = from;
65
43
  if (isWhereId) {
66
- __privateWrapper(this, _hasWhereId)._++;
67
- __privateSet(this, _host, __privateGet(this, _host).doc(where._id));
44
+ this.#hasWhereId = from;
45
+ this.#host = this.#host.doc(where._id);
68
46
  } else {
69
- __privateSet(this, _host, __privateGet(this, _host).where(where));
47
+ this.#host = this.#host.where(where);
70
48
  }
71
49
  return this;
72
50
  }
51
+ /**
52
+ * 设置查询条件
53
+ * @param where 查询条件对象
54
+ * @returns 当前Db实例,支持链式调用
55
+ */
56
+ where(where) {
57
+ return this.#where(where, "where");
58
+ }
59
+ /**
60
+ * 根据ID设置查询条件
61
+ * @param id 记录ID
62
+ * @returns 当前Db实例,支持链式调用
63
+ */
64
+ whereId(id) {
65
+ return this.#where({ _id: id }, "whereId");
66
+ }
67
+ #hasSelect = 0;
73
68
  /**
74
69
  * 指定要返回的字段
75
70
  * @param fields 要返回的字段对象,true表示返回,false表示不返回
76
- * @returns 当前Db实例,支持链式执行
71
+ * @returns 当前Db实例,支持链式调用
77
72
  */
78
73
  select(fields) {
79
- if (__privateGet(this, _hasSelect)) throw new Error("db.select() 方法只能执行一次");
80
- __privateWrapper(this, _hasSelect)._++;
81
- __privateSet(this, _host, __privateGet(this, _host).field(fields));
74
+ if (this.#hasSelect) throw new Error("db.select() 方法只能调用一次");
75
+ this.#hasSelect++;
76
+ this.#host = this.#host.field(fields);
82
77
  return this;
83
78
  }
79
+ #hasOrder = 0;
84
80
  /**
85
81
  * 设置排序规则
86
82
  * @param order 排序规则对象,key为字段名,value为"asc"或"desc"
87
- * @returns 当前Db实例,支持链式执行
83
+ * @returns 当前Db实例,支持链式调用
88
84
  */
89
85
  order(order) {
90
- __privateWrapper(this, _hasOrder)._++;
86
+ this.#hasOrder++;
91
87
  objectEach(order, (val, key) => {
92
- __privateSet(this, _host, __privateGet(this, _host).orderBy(key, val));
88
+ this.#host = this.#host.orderBy(key, val);
93
89
  });
94
90
  return this;
95
91
  }
92
+ #hasSkip = 0;
96
93
  /**
97
94
  * 跳过指定数量的记录
98
95
  * @param skip 要跳过的记录数
99
- * @returns 当前Db实例,支持链式执行
96
+ * @returns 当前Db实例,支持链式调用
100
97
  */
101
98
  skip(skip) {
102
- if (__privateGet(this, _hasSkip)) throw new Error("db.skip() 方法只能执行一次");
103
- __privateWrapper(this, _hasSkip)._++;
104
- __privateSet(this, _host, __privateGet(this, _host).skip(skip));
99
+ if (this.#hasSkip) throw new Error("db.skip() 方法只能调用一次");
100
+ this.#hasSkip++;
101
+ this.#host = this.#host.skip(skip);
105
102
  return this;
106
103
  }
104
+ #hasLimit = 0;
107
105
  /**
108
106
  * 限制返回的记录数量
109
107
  * @param limit 最大返回记录数
110
- * @returns 当前Db实例,支持链式执行
108
+ * @returns 当前Db实例,支持链式调用
111
109
  */
112
110
  limit(limit) {
113
- if (__privateGet(this, _hasLimit)) throw new Error("db.limit() 方法只能执行一次");
114
- __privateWrapper(this, _hasLimit)._++;
115
- __privateSet(this, _host, __privateGet(this, _host).limit(limit));
111
+ if (this.#hasLimit) throw new Error("db.limit() 方法只能调用一次");
112
+ if (this.#hasWhereId) {
113
+ throw new Error(`db.limit() 方法不能与 ${_toWhereIdMethod(this.#hasWhereId)} 方法同时调用`);
114
+ }
115
+ this.#hasLimit++;
116
+ this.#host = this.#host.limit(limit);
116
117
  return this;
117
118
  }
118
119
  /**
@@ -121,26 +122,28 @@ class Db {
121
122
  * @returns 创建结果
122
123
  */
123
124
  async create(data) {
124
- if (__privateGet(this, _hasWhere)) throw new Error("db.create() 方法不支持 where 条件");
125
- if (__privateGet(this, _hasSelect)) throw new Error("db.create() 方法不支持 select 条件");
126
- if (__privateGet(this, _hasOrder)) throw new Error("db.create() 方法不支持 order 条件");
127
- if (__privateGet(this, _hasSkip)) throw new Error("db.create() 方法不支持 skip 条件");
128
- if (__privateGet(this, _hasLimit)) throw new Error("db.create() 方法不支持 limit 条件");
129
- const res = await __privateGet(this, _host).add(data);
130
- return parseDatabaseOutput(res);
125
+ if (this.#hasWhere) throw new Error("db.create() 方法不支持 where 条件");
126
+ if (this.#hasSelect) throw new Error("db.create() 方法不支持 select 条件");
127
+ if (this.#hasOrder) throw new Error("db.create() 方法不支持 order 条件");
128
+ if (this.#hasSkip) throw new Error("db.create() 方法不支持 skip 条件");
129
+ if (this.#hasLimit) throw new Error("db.create() 方法不支持 limit 条件");
130
+ const res = await this.#host.add(data);
131
+ const { id } = parseDatabaseOutput(res);
132
+ return id;
131
133
  }
132
134
  /**
133
135
  * 执行查询操作
134
136
  * @returns 查询结果
135
137
  */
136
138
  async query() {
137
- const res = await __privateGet(this, _host).get();
138
- return parseDatabaseOutput(res);
139
+ const res = await this.#host.get();
140
+ const { data } = parseDatabaseOutput(res);
141
+ return data;
139
142
  }
140
143
  async queryOne(ignoreMiss = false) {
141
- if (__privateGet(this, _hasLimit)) throw new Error("db.queryOne() 方法不支持 limit 条件");
142
- this.limit(1);
143
- const { data } = await this.query();
144
+ if (this.#hasLimit) throw new Error("db.queryOne() 方法不支持 limit 条件");
145
+ if (!this.#hasWhereId) this.limit(1);
146
+ const data = await this.query();
144
147
  const res = data.at(0);
145
148
  if (!ignoreMiss && !res) throw new Error("未找到匹配记录");
146
149
  return res;
@@ -150,12 +153,13 @@ class Db {
150
153
  * @returns 记录总数
151
154
  */
152
155
  async count() {
153
- if (__privateGet(this, _hasSelect)) throw new Error("db.count() 方法不支持 select 条件");
154
- if (__privateGet(this, _hasOrder)) throw new Error("db.count() 方法不支持 order 条件");
155
- if (__privateGet(this, _hasSkip)) throw new Error("db.count() 方法不支持 skip 条件");
156
- if (__privateGet(this, _hasLimit)) throw new Error("db.count() 方法不支持 limit 条件");
157
- const res = await __privateGet(this, _host).count();
158
- return parseDatabaseOutput(res);
156
+ if (this.#hasSelect) throw new Error("db.count() 方法不支持 select 条件");
157
+ if (this.#hasOrder) throw new Error("db.count() 方法不支持 order 条件");
158
+ if (this.#hasSkip) throw new Error("db.count() 方法不支持 skip 条件");
159
+ if (this.#hasLimit) throw new Error("db.count() 方法不支持 limit 条件");
160
+ const res = await this.#host.count();
161
+ const { total } = parseDatabaseOutput(res);
162
+ return total;
159
163
  }
160
164
  /**
161
165
  * 更新记录
@@ -163,46 +167,40 @@ class Db {
163
167
  * @returns 更新结果
164
168
  */
165
169
  async update(data) {
166
- if (!__privateGet(this, _hasWhere)) throw new Error("设置 where 条件后才能执行 db.update() 方法");
167
- if (__privateGet(this, _hasSelect)) throw new Error("db.update() 方法不支持 select 条件");
168
- if (__privateGet(this, _hasOrder)) throw new Error("db.update() 方法不支持 order 条件");
169
- if (__privateGet(this, _hasSkip)) throw new Error("db.update() 方法不支持 skip 条件");
170
- if (__privateGet(this, _hasLimit)) throw new Error("db.update() 方法不支持 limit 条件");
171
- if (__privateGet(this, _isTransaction) && !__privateGet(this, _hasWhereId)) throw new Error("事务模式下 db.update() 的 where 条件必须是 _id");
172
- const res = await __privateGet(this, _host).update(data);
173
- return parseDatabaseOutput(res);
170
+ if (!this.#hasWhere) throw new Error("设置 where 条件后才能执行 db.update() 方法");
171
+ if (this.#hasSelect) throw new Error("db.update() 方法不支持 select 条件");
172
+ if (this.#hasOrder) throw new Error("db.update() 方法不支持 order 条件");
173
+ if (this.#hasSkip) throw new Error("db.update() 方法不支持 skip 条件");
174
+ if (this.#hasLimit) throw new Error("db.update() 方法不支持 limit 条件");
175
+ if (this.#isTransaction && !this.#hasWhereId) throw new Error("事务模式下 db.update() 的 where 条件必须是 _id");
176
+ const res = await this.#host.update(data);
177
+ const { updated } = parseDatabaseOutput(res);
178
+ return updated;
174
179
  }
175
180
  /**
176
181
  * 删除记录
177
182
  * @returns 删除结果
178
183
  */
179
184
  async remove() {
180
- if (!__privateGet(this, _hasWhere)) throw new Error("设置 where 条件后才能执行 db.remove() 方法");
181
- if (__privateGet(this, _hasSelect)) throw new Error("db.remove() 方法不支持 select 条件");
182
- if (__privateGet(this, _hasOrder)) throw new Error("db.remove() 方法不支持 order 条件");
183
- if (__privateGet(this, _hasSkip)) throw new Error("db.remove() 方法不支持 skip 条件");
184
- if (__privateGet(this, _hasLimit)) throw new Error("db.remove() 方法不支持 limit 条件");
185
- if (__privateGet(this, _isTransaction) && !__privateGet(this, _hasWhereId)) throw new Error("事务模式下 db.remove() 的 where 条件必须是 _id");
186
- const res = await __privateGet(this, _host).remove();
187
- return parseDatabaseOutput(res);
185
+ if (!this.#hasWhere) throw new Error("设置 where 条件后才能执行 db.remove() 方法");
186
+ if (this.#hasSelect) throw new Error("db.remove() 方法不支持 select 条件");
187
+ if (this.#hasOrder) throw new Error("db.remove() 方法不支持 order 条件");
188
+ if (this.#hasSkip) throw new Error("db.remove() 方法不支持 skip 条件");
189
+ if (this.#hasLimit) throw new Error("db.remove() 方法不支持 limit 条件");
190
+ if (this.#isTransaction && !this.#hasWhereId) throw new Error("事务模式下 db.remove() 的 where 条件必须是 _id");
191
+ const res = await this.#host.remove();
192
+ const { deleted } = parseDatabaseOutput(res);
193
+ return deleted;
188
194
  }
189
195
  }
190
- _host = new WeakMap();
191
- _isTransaction = new WeakMap();
192
- _hasWhere = new WeakMap();
193
- _hasWhereId = new WeakMap();
194
- _hasSelect = new WeakMap();
195
- _hasOrder = new WeakMap();
196
- _hasSkip = new WeakMap();
197
- _hasLimit = new WeakMap();
198
196
  const db = {
199
197
  /**
200
198
  * 获取指定名称的数据库集合实例
201
- * @param collection 集合名称
199
+ * @param table 数据表名称
202
200
  * @returns Db类实例,用于执行数据库操作
203
201
  */
204
- collection(collection) {
205
- return new Db({ collection });
202
+ table(table) {
203
+ return new Db({ table });
206
204
  }
207
205
  };
208
206
  function parseDatabaseOutput(res) {
@@ -215,27 +213,45 @@ function parseDatabaseOutput(res) {
215
213
  }
216
214
  return res;
217
215
  }
216
+ function _toWhereMethod(whereFrom) {
217
+ return whereFrom === "where" ? "where({...})" : "whereId(id)";
218
+ }
219
+ function _toWhereIdMethod(whereFrom) {
220
+ return whereFrom === "where" ? "where({ _id })" : "whereId(id)";
221
+ }
218
222
  async function dbUpsert(options) {
219
- const { collection, where, create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDb } = options;
220
- const _db = () => (_mockDb == null ? void 0 : _mockDb(collection)) || db.collection(collection);
221
- const found = await _db().where(where).limit(1).queryOne(true);
223
+ const {
224
+ collection,
225
+ where,
226
+ select = {},
227
+ create,
228
+ update,
229
+ onBeforeCreate,
230
+ onAfterCreate,
231
+ onBeforeUpdate,
232
+ onAfterUpdate,
233
+ _mockDb
234
+ } = options;
235
+ if ("_id" in select) throw new Error("select 条件不能包含 _id 字段");
236
+ const _db = () => _mockDb?.(collection) || db.table(collection);
237
+ const found = await _db().where(where).select(select || {}).limit(1).queryOne(true);
222
238
  if (found) {
223
- await (onBeforeUpdate == null ? void 0 : onBeforeUpdate(found));
239
+ await onBeforeUpdate?.(found);
224
240
  const updateData = isFunction(update) ? update(found) : update;
225
- const updated = await _db().where({ _id: found._id }).update(updateData);
226
- onAfterUpdate == null ? void 0 : onAfterUpdate();
241
+ const updated = await _db().whereId(found._id).update(updateData);
242
+ onAfterUpdate?.();
227
243
  return updated;
228
244
  }
229
- await (onBeforeCreate == null ? void 0 : onBeforeCreate());
230
- const created = await _db().create(create);
231
- await (onAfterCreate == null ? void 0 : onAfterCreate(created.id));
232
- return created;
245
+ await onBeforeCreate?.();
246
+ const createdId = await _db().create(create);
247
+ await onAfterCreate?.(createdId);
248
+ return createdId;
233
249
  }
234
250
  async function dbTransaction(transact, _mockDatabase) {
235
251
  const db2 = _mockDatabase || uniCloud.database();
236
252
  const [err1, transaction] = await tryFlatten(db2.startTransaction());
237
253
  if (err1) throw err1;
238
- const ta = new Db({ collection: "", transaction });
254
+ const ta = new Db({ table: "", transaction });
239
255
  const [err2, result] = await tryFlatten(async () => {
240
256
  const result2 = await transact(ta);
241
257
  await transaction.commit();
@@ -1 +1 @@
1
- {"version":3,"file":"database.mjs","sources":["../src/database/db.ts","../src/database/fns.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectEach, objectOmit } from '@cloudcome/utils-core/object';\nimport type { AnyObject, LowercaseStartString } from '@cloudcome/utils-core/types';\nimport type { UniClientDatabaseOutput, UniCloudDatabaseOutput } from './types';\n\ntype DbSelectPositive = {\n [key: LowercaseStartString]: true;\n};\ntype DbSelectNegative = { _id?: false };\nexport type DbSelect = Omit<DbSelectPositive, '_id'> & DbSelectNegative;\nexport type DbOrder = Record<string, 'asc' | 'desc'>;\nexport type DbRecord<S extends Record<string, boolean>> = {\n [K in keyof S as S[K] extends true ? K : never]: unknown;\n};\n\nconst db0 = uniCloud.database();\n/**\n * 数据库操作符命令\n */\nexport const dbCmd = db0.command;\n\n/**\n * 数据库聚合操作符命令\n */\nexport const dbAgg = db0.command.aggregate;\n\nclass Aggregate {\n #db: UniCloud.CollectionReference;\n\n constructor(db: UniCloud.CollectionReference) {\n this.#db = db;\n }\n\n start() {\n return this.#db.aggregate();\n }\n}\n\nexport type DbOptions = {\n /**\n * 集合名称\n */\n collection: 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\nexport class Db {\n #host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n #isTransaction: boolean;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 集合名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this.#host = options._mockDatabase || options.transaction || db0.collection(options.collection);\n this.#isTransaction = !!options.transaction;\n }\n\n /**\n * 创建聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n if (!this.#isTransaction) throw new Error('db.aggregate() 不支持事务模式');\n\n return this.#host.aggregate();\n }\n\n #hasWhere = 0;\n #hasWhereId = 0;\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式执行\n */\n where(where: AnyObject) {\n if (this.#hasWhere) throw new Error('db.where() 方法只能执行一次');\n\n const whereKeys = Object.keys(where);\n const isWhereId = whereKeys.length === 1 && whereKeys[0] === '_id';\n this.#hasWhere++;\n\n if (isWhereId) {\n this.#hasWhereId++;\n // @ts-ignore\n this.#host = this.#host.doc(where._id);\n } else {\n // @ts-ignore\n this.#host = this.#host.where(where);\n }\n\n return this;\n }\n\n #hasSelect = 0;\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式执行\n */\n select(fields: DbSelect) {\n if (this.#hasSelect) throw new Error('db.select() 方法只能执行一次');\n\n this.#hasSelect++;\n // @ts-ignore\n this.#host = this.#host.field(fields);\n return this;\n }\n\n #hasOrder = 0;\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式执行\n */\n order(order: DbOrder) {\n this.#hasOrder++;\n objectEach(order, (val, key) => {\n // @ts-ignore\n this.#host = this.#host.orderBy(key, val);\n });\n\n return this;\n }\n\n #hasSkip = 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 // @ts-ignore\n this.#host = this.#host.skip(skip);\n return this;\n }\n\n #hasLimit = 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 this.#hasLimit++;\n // @ts-ignore\n this.#host = this.#host.limit(limit);\n return this;\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: AnyObject) {\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 const res = await this.#host.add(data);\n return parseDatabaseOutput<{ id: string }>(res);\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async query<T>() {\n const res = await this.#host.get();\n return parseDatabaseOutput<{ data: T[] }>(res);\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * @param ignoreMiss 是否忽略没有匹配到记录\n * @returns 查询结果\n */\n async queryOne<T>(): Promise<T>;\n async queryOne<T>(ignoreMiss: false): Promise<T>;\n async queryOne<T>(ignoreMiss: true): Promise<T | undefined>;\n async queryOne<T>(ignoreMiss = false): Promise<T | undefined> {\n if (this.#hasLimit) throw new Error('db.queryOne() 方法不支持 limit 条件');\n\n this.limit(1);\n const { data } = await this.query<T>();\n const res = data.at(0);\n\n if (!ignoreMiss && !res) throw new Error('未找到匹配记录');\n return res;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\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 const res = await this.#host.count();\n return parseDatabaseOutput<{ total: number }>(res);\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: AnyObject) {\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 const res = await this.#host.update(data);\n return parseDatabaseOutput<{ updated: number }>(res);\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\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 const res = await this.#host.remove();\n return parseDatabaseOutput<{ deleted: number }>(res);\n }\n}\n\n/**\n * 数据库操作对象\n */\nexport const db = {\n /**\n * 获取指定名称的数据库集合实例\n * @param collection 集合名称\n * @returns Db类实例,用于执行数据库操作\n */\n collection(collection: string) {\n return new Db({ collection });\n },\n};\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: UniClientDatabaseOutput<T> | UniCloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as UniClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg', 'code', 'message']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\n}\n","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MaybeCallable } from '@cloudcome/utils-core/types';\nimport { Db, type DbSelect, db } from './db';\n\n/**\n * 数据库 upsert 操作的配置选项\n *\n * @template W - 查询条件类型\n * @template S - 查询返回字段类型\n * @template C - 创建数据类型\n * @template U - 更新数据类型\n * @template R - 查询结果类型\n */\nexport type DbUpsertOptions<\n W extends AnyObject,\n S extends DbSelect,\n C extends AnyObject,\n U extends AnyObject,\n R extends AnyObject,\n> = {\n /** 集合名称 */\n collection: string;\n\n /** 查询条件 */\n where: W;\n\n /** 查询返回字段 */\n select?: S;\n\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n update: U | ((row: R) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param row 查询到的文档\n */\n onBeforeUpdate?: (row: R) => unknown;\n\n /** 更新后回调函数 */\n onAfterUpdate?: () => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDb?: (collection: string) => any;\n};\n\nexport async function dbUpsert<\n W extends AnyObject,\n S extends DbSelect,\n C extends AnyObject,\n U extends AnyObject,\n R extends AnyObject,\n>(options: DbUpsertOptions<W, S, C, U, R>) {\n const { collection, where, create, update, onBeforeCreate, onAfterCreate, onBeforeUpdate, onAfterUpdate, _mockDb } =\n options;\n const _db = () => (_mockDb?.(collection) || db.collection(collection)) as Db;\n const found = await _db().where(where).limit(1).queryOne<R>(true);\n\n if (found) {\n await onBeforeUpdate?.(found);\n const updateData = isFunction(update) ? update(found) : update;\n const updated = await _db().where({ _id: found._id }).update(updateData);\n onAfterUpdate?.();\n\n return updated;\n }\n\n await onBeforeCreate?.();\n const created = await _db().create(create);\n await onAfterCreate?.(created.id);\n\n return created;\n}\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\n/**\n * 在数据库事务中执行操作\n *\n * @template T - 事务操作返回值类型\n * @param transact - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (ta) => {\n * const user = await ta.collection('users').create({ name: 'John' });\n * const order = await ta.collection('orders').create({ userId: user.id, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\nexport async function dbTransaction<T>(transact: (ta: Db) => Promise<T>, _mockDatabase?: _TransactionDb) {\n const db = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(db.startTransaction());\n if (err1) throw err1;\n\n const ta = new Db({ collection: '', transaction });\n const [err2, result] = await tryFlatten(async () => {\n const result = await transact(ta);\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;\n}\n"],"names":["db","result"],"mappings":"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"}
1
+ {"version":3,"file":"database.mjs","sources":["../src/database/db.ts","../src/database/fns.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectEach, objectOmit } from '@cloudcome/utils-core/object';\nimport type {\n AnyObject,\n HasProperty,\n IsEmptyObject,\n IsOnlyProperty,\n LowercaseStartString,\n} from '@cloudcome/utils-core/types';\nimport type { UniClientDatabaseOutput, UniCloudDatabaseOutput } from './types';\n\nexport type DbWhere<T> = {\n [K in keyof T]?: unknown;\n};\nexport type DbSelect<T> = {\n [K in keyof T]?: K extends '_id' ? false : true;\n};\nexport type DbFieldsDefault<T> = {\n [K in keyof T]: true;\n};\ntype _DbFields<T, S extends DbSelect<T>> = IsEmptyObject<S> extends true // 判断是否为空对象\n ? // 默认全部字段\n DbFieldsDefault<T>\n : // 判断 _id 是否为唯一属性\n IsOnlyProperty<S, '_id'> extends true\n ? // 从默认字段里排除 _id\n Omit<DbFieldsDefault<T>, '_id'>\n : // 判断是否有 _id\n HasProperty<S, '_id'> extends true\n ? // 有的话保留 {_id, ...}\n S\n : // 没有的话补上 {_id, ...}\n S & { _id: true };\ntype _DbQuery<T, S extends Record<keyof T, boolean>> = {\n [K in keyof T as S[K] extends true ? K : never]: T[K];\n};\n// @ts-ignore\nexport type DbQuery<T, S extends DbSelect<T>> = _DbQuery<T, _DbFields<T, S>>;\nexport type DbCreate<T> = Partial<T>;\nexport type DbUpdate<T> = Partial<T>;\nexport type DbOrder<T> = Record<keyof T, 'asc' | 'desc'>;\n\ntype _WhereFrom = 'where' | 'whereId';\n\nconst db0 = uniCloud.database();\n/**\n * 数据库操作符命令\n */\nexport const dbCmd = db0.command;\n\n/**\n * 数据库聚合操作符命令\n */\nexport const dbAgg = db0.command.aggregate;\n\nclass Aggregate {\n #db: UniCloud.CollectionReference;\n\n constructor(db: UniCloud.CollectionReference) {\n this.#db = db;\n }\n\n start() {\n return this.#db.aggregate();\n }\n}\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\nexport class Db<T, S extends DbSelect<T> = Record<string, never>> {\n #host: UniCloud.CollectionReference;\n\n /**\n * 是否为事务环境\n * - 查询条件只能是 id\n * - 不能聚合操作\n */\n #isTransaction: boolean;\n\n /**\n * 构造函数,初始化数据库集合引用\n * @param collection 数据表名称\n * @param _mockDatabase 模拟数据库,用于单元测试\n */\n constructor(options: DbOptions) {\n this.#host = options._mockDatabase || options.transaction || db0.collection(options.table);\n this.#isTransaction = !!options.transaction;\n }\n\n /**\n * 创建聚合操作实例\n * @returns 聚合操作实例\n */\n aggregate() {\n if (!this.#isTransaction) throw new Error('db.aggregate() 不支持事务模式');\n\n return this.#host.aggregate();\n }\n\n #hasWhere: _WhereFrom | undefined = undefined;\n #hasWhereId: _WhereFrom | undefined = undefined;\n\n #where(where: DbWhere<T>, from: _WhereFrom) {\n if (this.#hasWhere) throw new Error(`已调用过一次 db.${_toWhereMethod(this.#hasWhere)} 了`);\n\n const whereKeys = Object.keys(where);\n const isWhereId = whereKeys.length === 1 && whereKeys[0] === '_id';\n\n if (isWhereId && this.#hasLimit) {\n throw new Error(`db.${_toWhereIdMethod(from)} 方法不能与 db.limit() 方法同时调用`);\n }\n\n this.#hasWhere = from;\n\n if (isWhereId) {\n this.#hasWhereId = from;\n // @ts-ignore\n this.#host = this.#host.doc(where._id);\n } else {\n // @ts-ignore\n this.#host = this.#host.where(where);\n }\n\n return this;\n }\n\n /**\n * 设置查询条件\n * @param where 查询条件对象\n * @returns 当前Db实例,支持链式调用\n */\n where(where: DbWhere<T>) {\n return this.#where(where, 'where');\n }\n\n /**\n * 根据ID设置查询条件\n * @param id 记录ID\n * @returns 当前Db实例,支持链式调用\n */\n whereId(id: string) {\n // @ts-ignore\n return this.#where({ _id: id }, 'whereId');\n }\n\n #hasSelect = 0;\n\n /**\n * 指定要返回的字段\n * @param fields 要返回的字段对象,true表示返回,false表示不返回\n * @returns 当前Db实例,支持链式调用\n */\n select<U extends DbSelect<T>>(fields: U): Db<T, U> {\n if (this.#hasSelect) throw new Error('db.select() 方法只能调用一次');\n\n this.#hasSelect++;\n // @ts-ignore\n this.#host = this.#host.field(fields);\n // @ts-ignore\n return this;\n }\n\n #hasOrder = 0;\n\n /**\n * 设置排序规则\n * @param order 排序规则对象,key为字段名,value为\"asc\"或\"desc\"\n * @returns 当前Db实例,支持链式调用\n */\n order(order: DbOrder<T>) {\n this.#hasOrder++;\n objectEach(order, (val, key) => {\n // @ts-ignore\n this.#host = this.#host.orderBy(key, val);\n });\n\n return this;\n }\n\n #hasSkip = 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 // @ts-ignore\n this.#host = this.#host.skip(skip);\n return this;\n }\n\n #hasLimit = 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 // @ts-ignore\n this.#host = this.#host.limit(limit);\n return this;\n }\n\n /**\n * 创建新记录\n * @param data 要创建的数据\n * @returns 创建结果\n */\n async create(data: DbCreate<T>) {\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 const res = await this.#host.add(data);\n const { id } = parseDatabaseOutput<{ id: string }>(res);\n return id;\n }\n\n /**\n * 执行查询操作\n * @returns 查询结果\n */\n async query() {\n const res = await this.#host.get();\n const { data } = parseDatabaseOutput<{ data: DbQuery<T, S>[] }>(res);\n return data;\n }\n\n /**\n * 只查询一条,自动添加 limit(1) 条件\n * @param ignoreMiss 是否忽略没有匹配到记录\n * @returns 查询结果\n */\n async queryOne(): Promise<DbQuery<T, S>>;\n async queryOne(ignoreMiss: false): Promise<DbQuery<T, S>>;\n async queryOne(ignoreMiss: true): Promise<DbQuery<T, S> | undefined>;\n async queryOne(ignoreMiss = false): Promise<DbQuery<T, S> | undefined> {\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 (!ignoreMiss && !res) throw new Error('未找到匹配记录');\n return res;\n }\n\n /**\n * 获取匹配记录的数量\n * @returns 记录总数\n */\n async count() {\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 const res = await this.#host.count();\n const { total } = parseDatabaseOutput<{ total: number }>(res);\n return total;\n }\n\n /**\n * 更新记录\n * @param data 要更新的数据\n * @returns 更新结果\n */\n async update(data: AnyObject) {\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 const res = await this.#host.update(data);\n const { updated } = parseDatabaseOutput<{ updated: number }>(res);\n return updated;\n }\n\n /**\n * 删除记录\n * @returns 删除结果\n */\n async remove() {\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 const res = await this.#host.remove();\n const { deleted } = parseDatabaseOutput<{ deleted: number }>(res);\n return deleted;\n }\n}\n\n/**\n * 数据库操作对象\n */\nexport const db = {\n /**\n * 获取指定名称的数据库集合实例\n * @param table 数据表名称\n * @returns Db类实例,用于执行数据库操作\n */\n table<T, S extends DbSelect<T> = Record<never, never>>(table: string) {\n return new Db<T, S>({ table });\n },\n};\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: UniClientDatabaseOutput<T> | UniCloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as UniClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg', 'code', 'message']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\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","import { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { AnyObject, MaybeCallable } from '@cloudcome/utils-core/types';\nimport { Db, type DbCreate, type DbQuery, type DbSelect, type DbUpdate, type DbWhere, db } from './db';\n\n/**\n * 数据库 upsert 操作的配置选项\n *\n * @template W - 查询条件类型\n * @template S - 查询返回字段类型\n * @template C - 创建数据类型\n * @template U - 更新数据类型\n * @template R - 查询结果类型\n */\nexport type DbUpsertOptions<\n T,\n W extends DbWhere<T>,\n S extends DbSelect<T>,\n C extends DbCreate<T>,\n U extends DbUpdate<T>,\n> = {\n /** 集合名称 */\n collection: string;\n\n /** 查询条件 */\n where: W;\n\n /** 查询返回字段 */\n select?: S;\n\n /** 创建数据 */\n create: C;\n\n /**\n * 更新数据,可以是对象或根据查询结果生成更新对象的函数\n * @param row 查询到的文档数据,仅在传入函数时可用\n */\n update: U | ((row: DbQuery<T, S>) => U);\n\n /** 创建前回调函数 */\n onBeforeCreate?: () => unknown;\n\n /**\n * 创建后回调函数\n * @param id 创建的文档ID\n */\n onAfterCreate?: (id: string) => unknown;\n\n /**\n * 更新前回调函数\n * @param row 查询到的文档\n */\n onBeforeUpdate?: (row: DbQuery<T, S>) => unknown;\n\n /** 更新后回调函数 */\n onAfterUpdate?: () => unknown;\n\n /** 用于测试的模拟数据库实例 */\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n _mockDb?: (collection: string) => any;\n};\n\nexport async function dbUpsert<\n T,\n W extends DbWhere<T>,\n S extends DbSelect<T>,\n C extends DbCreate<T>,\n U extends DbUpdate<T>,\n>(options: DbUpsertOptions<T, W, S, C, U>) {\n const {\n collection,\n where,\n select = {},\n create,\n update,\n onBeforeCreate,\n onAfterCreate,\n onBeforeUpdate,\n onAfterUpdate,\n _mockDb,\n } = options;\n\n // @ts-ignore\n if ('_id' in select) throw new Error('select 条件不能包含 _id 字段');\n\n const _db = () => (_mockDb?.(collection) || db.table(collection)) as Db<T, S>;\n const found = (await _db()\n .where(where)\n .select(select || {})\n .limit(1)\n .queryOne(true)) as DbQuery<T, S> | undefined;\n\n if (found) {\n await onBeforeUpdate?.(found);\n const updateData = isFunction(update) ? update(found) : update;\n // @ts-ignore\n const updated = await _db().whereId(found._id).update(updateData);\n onAfterUpdate?.();\n\n return updated;\n }\n\n await onBeforeCreate?.();\n const createdId = await _db().create(create);\n await onAfterCreate?.(createdId);\n\n return createdId;\n}\n\ntype _TransactionDb = {\n startTransaction: () => Promise<_Transaction>;\n};\n\ntype _Transaction = {\n commit: () => Promise<unknown>;\n rollback: () => Promise<unknown>;\n};\n\n/**\n * 在数据库事务中执行操作\n *\n * @template T - 事务操作返回值类型\n * @param transact - 事务执行函数,接收事务数据库实例作为参数\n * @param _mockDatabase - 用于测试的模拟数据库实例\n * @returns 事务操作的返回结果\n *\n * @example\n * ```typescript\n * const result = await dbTransaction(async (ta) => {\n * const user = await ta.collection('users').create({ name: 'John' });\n * const order = await ta.collection('orders').create({ userId: user.id, amount: 100 });\n * return { user, order };\n * });\n * ```\n */\n// biome-ignore lint/complexity/noBannedTypes: <explanation>\nexport async function dbTransaction<T, S extends DbSelect<T> = {}>(\n transact: (ta: Db<T, S>) => Promise<unknown>,\n _mockDatabase?: _TransactionDb,\n) {\n const db = (_mockDatabase || uniCloud.database()) as _TransactionDb;\n\n const [err1, transaction] = await tryFlatten(db.startTransaction());\n if (err1) throw err1;\n\n const ta = new Db<T, S>({ table: '', transaction });\n const [err2, result] = await tryFlatten(async () => {\n const result = await transact(ta);\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;\n}\n"],"names":["db","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.4.0";
3
+ const VERSION = "1.5.1";
4
4
  exports.VERSION = VERSION;
5
5
  //# sourceMappingURL=index.cjs.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = "1.4.0";
1
+ const VERSION = "1.5.1";
2
2
  export {
3
3
  VERSION
4
4
  };
package/dist/page.cjs CHANGED
@@ -6,7 +6,7 @@ function usePageQuery(onPageLoad) {
6
6
  const query = vue.reactive({});
7
7
  uniApp.onLoad((_query) => {
8
8
  Object.assign(query, _query);
9
- onPageLoad == null ? void 0 : onPageLoad(query);
9
+ onPageLoad?.(query);
10
10
  });
11
11
  return query;
12
12
  }
package/dist/page.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"page.cjs","sources":["../src/page.ts"],"sourcesContent":["import type { AnyObject } from '@cloudcome/utils-core/types';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { type Reactive, reactive, unref } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n"],"names":["reactive","onLoad"],"mappings":";;;;AA0BO,SAAS,aAAkC,YAA2C;AACrF,QAAA,QAAQA,IAAY,SAAA,EAAO;AAEjCC,SAAA,OAAO,CAAC,WAAW;AACV,WAAA,OAAO,OAAO,MAAM;AAC3B,6CAAa;AAAA,EAAK,CACnB;AAEM,SAAA;AACT;;"}
1
+ {"version":3,"file":"page.cjs","sources":["../src/page.ts"],"sourcesContent":["import type { AnyObject } from '@cloudcome/utils-core/types';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { type Reactive, reactive, unref } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n"],"names":["reactive","onLoad"],"mappings":";;;;AA0BO,SAAS,aAAkC,YAA2C;AACrF,QAAA,QAAQA,IAAY,SAAA,EAAO;AAEjCC,SAAA,OAAO,CAAC,WAAW;AACV,WAAA,OAAO,OAAO,MAAM;AAC3B,iBAAa,KAAK;AAAA,EAAA,CACnB;AAEM,SAAA;AACT;;"}
package/dist/page.mjs CHANGED
@@ -4,7 +4,7 @@ function usePageQuery(onPageLoad) {
4
4
  const query = reactive({});
5
5
  onLoad((_query) => {
6
6
  Object.assign(query, _query);
7
- onPageLoad == null ? void 0 : onPageLoad(query);
7
+ onPageLoad?.(query);
8
8
  });
9
9
  return query;
10
10
  }
package/dist/page.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"page.mjs","sources":["../src/page.ts"],"sourcesContent":["import type { AnyObject } from '@cloudcome/utils-core/types';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { type Reactive, reactive, unref } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,aAAkC,YAA2C;AACrF,QAAA,QAAQ,SAAY,EAAO;AAEjC,SAAO,CAAC,WAAW;AACV,WAAA,OAAO,OAAO,MAAM;AAC3B,6CAAa;AAAA,EAAK,CACnB;AAEM,SAAA;AACT;"}
1
+ {"version":3,"file":"page.mjs","sources":["../src/page.ts"],"sourcesContent":["import type { AnyObject } from '@cloudcome/utils-core/types';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { type Reactive, reactive, unref } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n"],"names":[],"mappings":";;AA0BO,SAAS,aAAkC,YAA2C;AACrF,QAAA,QAAQ,SAAY,EAAO;AAEjC,SAAO,CAAC,WAAW;AACV,WAAA,OAAO,OAAO,MAAM;AAC3B,iBAAa,KAAK;AAAA,EAAA,CACnB;AAEM,SAAA;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-uni",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "cloudcome utils for uni-app",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -58,8 +58,8 @@
58
58
  "dist"
59
59
  ],
60
60
  "dependencies": {
61
- "@cloudcome/utils-core": "~1.7.0",
62
- "@cloudcome/utils-vue": "~1.9.3",
61
+ "@cloudcome/utils-core": "~1.9.0",
62
+ "@cloudcome/utils-vue": "~1.9.5",
63
63
  "@dcloudio/types": "^3.4.21",
64
64
  "@dcloudio/uni-app": "vue3",
65
65
  "vue": "^3.5.13",