@cloudbase/js-sdk 3.3.5 → 3.3.7

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/index.d.ts CHANGED
@@ -714,6 +714,7 @@ declare namespace cloudbase.auth {
714
714
  qqMiniOpenId?: string
715
715
  customUserId?: string
716
716
  name?: string
717
+ displayName?: string
717
718
  gender?: string
718
719
  email?: string
719
720
  username?: string
@@ -865,11 +866,53 @@ declare namespace cloudbase.auth {
865
866
  options?: { withCaptcha: boolean },
866
867
  ): Promise<authModels.GetVerificationResponse>
867
868
  /**
868
- * 匿名登录
869
+ * 匿名登录。无需用户注册即可使用应用功能,适合游客模式、临时体验等场景。
869
870
  *
871
+ * **前置条件**:需要在云开发控制台(环境 → 登录授权 → 身份源列表)开启「匿名登录」。
872
+ *
873
+ * **重要**:匿名登录必须在使用 `watch()` 等实时数据库功能**之前**完成,
874
+ * 否则 WebSocket 连接会因缺少认证信息而失败。
870
875
  *
871
876
  * 文档 {@link https://docs.cloudbase.net/api-reference/webv2/authentication#authsigninanonymously}
872
877
  *
878
+ * @example
879
+ * ```typescript
880
+ * import Cloudbase from '@cloudbase/js-sdk';
881
+ *
882
+ * const app = Cloudbase.init({
883
+ * env: 'your-env-id',
884
+ * region: 'ap-shanghai'
885
+ * });
886
+ * const auth = app.auth();
887
+ *
888
+ * // 匿名登录
889
+ * const { data, error } = await auth.signInAnonymously();
890
+ * if (error) {
891
+ * console.error('匿名登录失败:', error.message);
892
+ * return;
893
+ * }
894
+ * console.log('匿名登录成功, 用户ID:', data.user.id);
895
+ * console.log('是否匿名用户:', data.user.is_anonymous); // true
896
+ *
897
+ * // 登录成功后,即可使用 watch() 等实时功能
898
+ * const db = app.database();
899
+ * const listener = db.collection('rooms').where({ status: 'active' }).watch({
900
+ * onChange: (snapshot) => {
901
+ * console.log('数据变化:', snapshot.docs);
902
+ * },
903
+ * onError: (err) => {
904
+ * console.error('监听错误:', err);
905
+ * }
906
+ * });
907
+ *
908
+ * // 不再需要时关闭监听
909
+ * listener.close();
910
+ * ```
911
+ *
912
+ * @param data 可选参数
913
+ * @param data.provider_token 提供令牌(通常不需要手动传入)
914
+ * @returns 登录结果,包含 `data.user`(用户信息)和 `data.session`(会话信息),
915
+ * 或 `error`(登录失败时的错误信息)
873
916
  */
874
917
  signInAnonymously(data?: { provider_token?: string }): Promise<SignInRes>
875
918
  /**
@@ -1231,11 +1274,43 @@ declare namespace cloudbase.auth {
1231
1274
  */
1232
1275
  signInWithIdToken(params: SignInWithIdTokenReq): Promise<SignInRes>
1233
1276
  /**
1234
- * 使用一次性密码(OTP)登录
1277
+ * 使用一次性密码(OTP)登录,支持手机号和邮箱两种方式。
1278
+ *
1279
+ * **注意**:手机号验证码登录需要在初始化时设置 `region: 'ap-shanghai'`。
1235
1280
  *
1236
1281
  * 文档 {@link https://docs.cloudbase.net/api-reference/webv3/authentication#signinwithotp}
1237
1282
  *
1238
- * @param params
1283
+ * @example
1284
+ * ```typescript
1285
+ * // 完整的手机号验证码登录流程
1286
+ * import Cloudbase from '@cloudbase/js-sdk';
1287
+ *
1288
+ * // 第一步:初始化(region 必须为 ap-shanghai)
1289
+ * const app = Cloudbase.init({
1290
+ * env: 'your-env-id',
1291
+ * region: 'ap-shanghai'
1292
+ * });
1293
+ * const auth = app.auth();
1294
+ *
1295
+ * // 第二步:发送验证码
1296
+ * const { data, error } = await auth.signInWithOtp({ phone: '+8613800138000' });
1297
+ * if (error) {
1298
+ * console.error('发送验证码失败:', error.message);
1299
+ * return;
1300
+ * }
1301
+ *
1302
+ * // 第三步:用户输入验证码后,调用 verifyOtp 完成登录
1303
+ * const { data: loginData, error: loginError } = await data.verifyOtp({
1304
+ * token: userInputCode // 用户输入的验证码
1305
+ * });
1306
+ * if (loginError) {
1307
+ * console.error('验证失败:', loginError.message);
1308
+ * return;
1309
+ * }
1310
+ * console.log('登录成功:', loginData.user);
1311
+ * ```
1312
+ *
1313
+ * @param params 登录参数,包含 email 或 phone(二选一)
1239
1314
  */
1240
1315
  signInWithOtp(params: SignInWithOtpReq): Promise<SignInWithOtpRes>
1241
1316
  /**
@@ -1502,14 +1577,28 @@ declare namespace cloudbase.auth {
1502
1577
  /**
1503
1578
  * v1 API: 发送手机验证码
1504
1579
  *
1505
- * @deprecated 建议使用 auth.signInWithOtp({ phone }) 或 auth.getVerification({ phone_number }) 替代。
1580
+ * @deprecated 此方法仅发送验证码并返回布尔值,不返回 verifyOtp 回调。
1581
+ * 推荐使用 v3 API `auth.signInWithOtp({ phone })` 替代,它会返回包含 `verifyOtp` 方法的对象,
1582
+ * 可直接完成"发送验证码 → 用户输入 → 验证并登录"的完整流程。
1506
1583
  *
1507
- * @example
1508
- * ```javascript
1509
- * const success = await auth.sendPhoneCode('+8613800138000');
1584
+ * **迁移示例**:
1585
+ * ```typescript
1586
+ * // 旧方式 (v1)
1587
+ * await auth.sendPhoneCode('+8613800138000');
1588
+ * // 需要单独调用其他 API 验证
1589
+ *
1590
+ * // ✅ 新方式 (v3) - 完整的手机号验证码登录流程
1591
+ * // 注意:初始化时必须设置 region: 'ap-shanghai'
1592
+ * const app = Cloudbase.init({ env: 'your-env-id', region: 'ap-shanghai' });
1593
+ * const auth = app.auth();
1594
+ * const { data, error } = await auth.signInWithOtp({ phone: '+8613800138000' });
1595
+ * if (error) throw error;
1596
+ * // 用户输入验证码后调用 verifyOtp
1597
+ * const { data: loginData, error: loginError } = await data.verifyOtp({ token: '123456' });
1598
+ * console.log('登录成功', loginData.user);
1510
1599
  * ```
1511
1600
  *
1512
- * @param phoneNumber 手机号
1601
+ * @param phoneNumber 手机号(需含国际区号,如 +86)
1513
1602
  * @returns 是否发送成功
1514
1603
  */
1515
1604
  sendPhoneCode(phoneNumber: string): Promise<boolean>
@@ -1533,20 +1622,26 @@ declare namespace cloudbase.auth {
1533
1622
  /**
1534
1623
  * v1 API: 手机号登录(支持短信验证码 or 密码方式)
1535
1624
  *
1536
- * @deprecated 密码方式建议使用 auth.signInWithPassword({ phone, password }) 替代;
1537
- * 验证码方式建议使用 auth.signInWithOtp({ phone }) 替代。
1625
+ * @deprecated 推荐使用 v3 API 替代:
1626
+ * - 密码登录:`auth.signInWithPassword({ phone, password })`
1627
+ * - 验证码登录:`auth.signInWithOtp({ phone })`
1538
1628
  *
1539
- * @example
1540
- * ```javascript
1541
- * // 验证码登录
1629
+ * **迁移示例**:
1630
+ * ```typescript
1631
+ * // ❌ 旧方式 (v1) - 验证码登录
1542
1632
  * const loginState = await auth.signInWithPhoneCodeOrPassword({
1543
1633
  * phoneNumber: '+8613800138000',
1544
1634
  * phoneCode: '123456'
1545
1635
  * });
1546
1636
  *
1547
- * // 密码登录
1548
- * const loginState = await auth.signInWithPhoneCodeOrPassword({
1549
- * phoneNumber: '+8613800138000',
1637
+ * // ✅ 新方式 (v3) - 验证码登录
1638
+ * const { data, error } = await auth.signInWithOtp({ phone: '+8613800138000' });
1639
+ * if (error) throw error;
1640
+ * const { data: result } = await data.verifyOtp({ token: '123456' });
1641
+ *
1642
+ * // ✅ 新方式 (v3) - 密码登录
1643
+ * const { data, error } = await auth.signInWithPassword({
1644
+ * phone: '+8613800138000',
1550
1645
  * password: 'password123'
1551
1646
  * });
1552
1647
  * ```
@@ -2162,80 +2257,230 @@ declare namespace cloudbase.database {
2162
2257
  /**
2163
2258
  * realtime types
2164
2259
  */
2260
+ /**
2261
+ * watch() 监听选项
2262
+ */
2165
2263
  interface IWatchOptions {
2166
- // server realtime data init & change event
2264
+ /**
2265
+ * 数据变化回调。首次建立连接时会触发 `type: 'init'` 的初始化快照,
2266
+ * 后续每次数据变化(增/删/改)都会触发此回调。
2267
+ *
2268
+ * @param snapshot 数据快照,包含当前完整文档列表 `docs` 和本次变化详情 `docChanges`
2269
+ */
2167
2270
  onChange: (snapshot: ISnapshot) => void
2168
- // error while connecting / listening
2271
+ /**
2272
+ * 错误回调。在连接失败、token 过期、权限不足等异常时触发。
2273
+ *
2274
+ * **常见错误场景**:
2275
+ * - 未登录或 token 过期:需先调用 `auth.signInAnonymously()` 等方法完成认证
2276
+ * - 权限不足:检查安全规则配置
2277
+ * - 网络中断:SDK 会自动尝试重连,重连失败后触发此回调
2278
+ *
2279
+ * @param error 错误信息
2280
+ */
2169
2281
  onError: (error: any) => void
2170
2282
  }
2283
+
2284
+ /**
2285
+ * 实时数据推送监听器。通过 `watch()` 方法返回,用于管理实时监听的生命周期。
2286
+ *
2287
+ * **重要**:在 React 组件卸载或不再需要监听时,务必调用 `close()` 释放资源,
2288
+ * 避免内存泄漏和不必要的网络连接。
2289
+ */
2171
2290
  interface DBRealtimeListener {
2172
2291
  /**
2173
- * 关闭实时推送
2292
+ * 关闭实时推送,释放 WebSocket 连接和相关资源。
2174
2293
  *
2175
2294
  * {@link https://docs.cloudbase.net/api-reference/webv3-next/database.html#shu-ju-ku-shi-shi-tui-song}
2176
2295
  *
2177
2296
  * @example
2297
+ * ```typescript
2178
2298
  * // 启动监听
2179
- * const ref = db
2180
- * .collection("collName")
2181
- * .where({ test: _.gt(0) })
2299
+ * const listener = db
2300
+ * .collection('messages')
2301
+ * .where({ roomId: 'room-1' })
2182
2302
  * .watch({
2183
2303
  * onChange: (snapshot) => {
2184
- * console.log("收到snapshot**********", snapshot);
2304
+ * console.log('数据更新:', snapshot.docs);
2185
2305
  * },
2186
2306
  * onError: (error) => {
2187
- * console.log("收到error**********", error);
2307
+ * console.error('监听异常:', error);
2188
2308
  * }
2189
2309
  * });
2190
- * // 关闭监听
2191
- * ref.close();
2310
+ *
2311
+ * // 不再需要时关闭监听
2312
+ * listener.close();
2313
+ *
2314
+ * // React 组件中的最佳实践
2315
+ * useEffect(() => {
2316
+ * const listener = db.collection('xxx').watch({ onChange, onError });
2317
+ * return () => listener.close(); // 组件卸载时自动清理
2318
+ * }, []);
2319
+ * ```
2192
2320
  */
2193
2321
  close: () => void
2194
2322
  }
2323
+
2324
+ /**
2325
+ * 数据变化类型
2326
+ * - `'init'`:初始化数据(首次连接时返回的完整数据)
2327
+ * - `'update'`:文档被更新
2328
+ * - `'add'`:新增文档
2329
+ * - `'remove'`:文档被删除
2330
+ * - `'replace'`:文档被替换(set 操作)
2331
+ * - `'limit'`:因 limit 限制导致的数据变化
2332
+ */
2195
2333
  type DataType = 'init' | 'update' | 'add' | 'remove' | 'replace' | 'limit'
2334
+
2335
+ /**
2336
+ * 队列操作类型
2337
+ * - `'init'`:初始化(对应 DataType 的 init)
2338
+ * - `'enqueue'`:文档进入监听结果集(新增或开始匹配查询条件)
2339
+ * - `'dequeue'`:文档离开监听结果集(删除或不再匹配查询条件)
2340
+ * - `'update'`:文档在结果集中被更新
2341
+ */
2196
2342
  type QueueType = 'init' | 'enqueue' | 'dequeue' | 'update'
2343
+
2344
+ /**
2345
+ * 数据快照,每次 watch 回调都会收到此对象。
2346
+ *
2347
+ * **使用方式**:
2348
+ * - 获取当前完整数据列表:使用 `snapshot.docs`(数组,包含所有匹配文档的最新状态)
2349
+ * - 获取本次变化详情:使用 `snapshot.docChanges`(数组,仅包含本次变化的文档信息)
2350
+ * - 判断是否为初始化数据:检查 `snapshot.type === 'init'`
2351
+ *
2352
+ * @example
2353
+ * ```typescript
2354
+ * onChange: (snapshot) => {
2355
+ * if (snapshot.type === 'init') {
2356
+ * // 首次连接,snapshot.docs 包含初始完整数据
2357
+ * console.log('初始数据:', snapshot.docs);
2358
+ * } else {
2359
+ * // 后续变化
2360
+ * snapshot.docChanges.forEach(change => {
2361
+ * switch (change.dataType) {
2362
+ * case 'add':
2363
+ * console.log('新增文档:', change.doc);
2364
+ * break;
2365
+ * case 'update':
2366
+ * console.log('更新文档:', change.docId, change.updatedFields);
2367
+ * break;
2368
+ * case 'remove':
2369
+ * console.log('删除文档:', change.docId);
2370
+ * break;
2371
+ * }
2372
+ * });
2373
+ * // snapshot.docs 始终是变化后的完整数据列表
2374
+ * console.log('当前全部数据:', snapshot.docs);
2375
+ * }
2376
+ * }
2377
+ * ```
2378
+ */
2197
2379
  interface ISnapshot {
2380
+ /** 快照序列号,单调递增 */
2198
2381
  id: number
2382
+ /** 本次变化的文档详情列表 */
2199
2383
  docChanges: ISingleDBEvent[]
2200
- docs: Record<string, any>
2384
+ /** 当前完整的文档列表(变化后的最新状态) */
2385
+ docs: Record<string, any>[]
2386
+ /** 快照类型,`'init'` 表示初始化数据 */
2201
2387
  type?: SnapshotType
2202
2388
  }
2203
2389
 
2390
+ /**
2391
+ * 单个文档变化事件
2392
+ */
2204
2393
  interface ISingleDBEvent {
2394
+ /** 事件序列号 */
2205
2395
  id: number
2396
+ /** 数据变化类型:init/add/update/remove/replace/limit */
2206
2397
  dataType: DataType
2398
+ /** 队列操作类型:init/enqueue/dequeue/update */
2207
2399
  queueType: QueueType
2400
+ /** 变化文档的 ID */
2208
2401
  docId: string
2402
+ /** 变化后的完整文档内容(remove 时为删除前的文档) */
2209
2403
  doc: Record<string, any>
2404
+ /** 被更新的字段及新值(仅 dataType 为 update 时存在) */
2210
2405
  updatedFields?: any
2406
+ /** 被删除的字段列表(仅 dataType 为 update 时存在) */
2211
2407
  removedFields?: any
2212
2408
  }
2213
2409
 
2410
+ /** 快照类型。`'init'` 表示首次连接时返回的初始化数据 */
2214
2411
  type SnapshotType = 'init'
2215
2412
 
2216
2413
  interface IWatchable {
2217
2414
  /**
2218
- * 开启实时推送
2415
+ * 开启实时数据推送,监听集合或文档的数据变化。
2416
+ *
2417
+ * **前置条件**:使用 `watch()` 前必须先完成用户认证(如匿名登录),
2418
+ * 否则 WebSocket 连接会因缺少认证信息而失败。
2219
2419
  *
2220
2420
  * {@link https://docs.cloudbase.net/api-reference/webv3-next/database#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%9E%E6%97%B6%E6%8E%A8%E9%80%81}
2221
2421
  *
2222
2422
  * @example
2223
- * const ref = db
2224
- * .collection("collName")
2225
- * .where({ test: _.gt(0) })
2226
- * .watch({
2227
- * onChange: (snapshot) => {
2228
- * console.log("收到snapshot**********", snapshot);
2229
- * },
2230
- * onError: (error) => {
2231
- * console.log("收到error**********", error);
2423
+ * ```typescript
2424
+ * // === 完整示例:匿名登录 + watch + React 集成 ===
2425
+ * import Cloudbase from '@cloudbase/js-sdk';
2426
+ * import { useEffect, useState } from 'react';
2427
+ *
2428
+ * const app = Cloudbase.init({ env: 'your-env-id', region: 'ap-shanghai' });
2429
+ *
2430
+ * function RoomList() {
2431
+ * const [rooms, setRooms] = useState<any[]>([]);
2432
+ * const [error, setError] = useState<string | null>(null);
2433
+ *
2434
+ * useEffect(() => {
2435
+ * let listener: cloudbase.database.DBRealtimeListener | null = null;
2436
+ *
2437
+ * async function setup() {
2438
+ * // 第一步:必须先完成认证
2439
+ * const auth = app.auth();
2440
+ * const { error: authError } = await auth.signInAnonymously();
2441
+ * if (authError) {
2442
+ * setError('登录失败: ' + authError.message);
2443
+ * return;
2444
+ * }
2445
+ *
2446
+ * // 第二步:认证成功后开启 watch
2447
+ * const db = app.database();
2448
+ * listener = db.collection('rooms')
2449
+ * .where({ status: 'active' })
2450
+ * .watch({
2451
+ * onChange: (snapshot) => {
2452
+ * // snapshot.docs 包含当前所有匹配文档
2453
+ * setRooms(snapshot.docs as any[]);
2454
+ * },
2455
+ * onError: (err) => {
2456
+ * console.error('watch 错误:', err);
2457
+ * setError('实时同步异常: ' + (err?.message || err));
2458
+ * }
2459
+ * });
2232
2460
  * }
2233
- * });
2234
- * @param options
2235
- * @param options.onChange 监听数据变化的回调函数
2236
- * @param options.onError 监听出现错误的回调函数
2237
2461
  *
2238
- * @return 实时推送进程实例
2462
+ * setup();
2463
+ *
2464
+ * // 第三步:组件卸载时清理监听
2465
+ * return () => {
2466
+ * if (listener) listener.close();
2467
+ * };
2468
+ * }, []);
2469
+ *
2470
+ * if (error) return <div>错误: {error}</div>;
2471
+ * return (
2472
+ * <ul>
2473
+ * {rooms.map(room => <li key={room._id}>{room.name}</li>)}
2474
+ * </ul>
2475
+ * );
2476
+ * }
2477
+ * ```
2478
+ *
2479
+ * @param options 监听选项
2480
+ * @param options.onChange 数据变化回调,接收 {@link ISnapshot} 快照对象
2481
+ * @param options.onError 错误回调,在连接异常、认证失败等情况下触发
2482
+ *
2483
+ * @returns {@link DBRealtimeListener} 监听器实例,调用 `close()` 可停止监听
2239
2484
  */
2240
2485
  watch(options: IWatchOptions): DBRealtimeListener
2241
2486
  }
@@ -2255,11 +2500,11 @@ declare namespace cloudbase.database {
2255
2500
  * })
2256
2501
  * console.log('新增成功,文档 ID:', result.id)
2257
2502
  *
2258
- * @param data 要新增的数据对象,支持嵌套对象、数组、地理位置等数据类型
2503
+ * @param data 要新增的数据对象或数据对象数组,支持嵌套对象、数组、地理位置等数据类型
2259
2504
  *
2260
- * @return Promise<AddRes> 包含新增文档的 id requestId
2505
+ * @return Promise<AddRes> 包含新增文档的 id(单条)或 ids(批量)和 requestId
2261
2506
  */
2262
- add(data: Object): Promise<AddRes>
2507
+ add(data: Object | Object[]): Promise<AddRes>
2263
2508
  /**
2264
2509
  * 获取一条文档的引用
2265
2510
  *
@@ -2881,7 +3126,9 @@ declare namespace cloudbase.database {
2881
3126
  }
2882
3127
 
2883
3128
  interface AddRes {
2884
- id: string
3129
+ id?: string
3130
+ ids?: string[]
3131
+ insertedIds?: string[]
2885
3132
  requestId: string
2886
3133
  code?: string
2887
3134
  message?: string