@heybox/hb-sdk 0.6.7 → 0.6.8-alpha.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/CHANGELOG.md +226 -0
- package/README.md +65 -583
- package/dist/cli-chunks/{build-DaHCCSLH.cjs → build-BfhZ07Qv.cjs} +2 -2
- package/dist/cli-chunks/{context-cQXupHub.cjs → context-CqoGNt7d.cjs} +1 -1
- package/dist/cli-chunks/{create-D2dSw7bl.cjs → create-us7swTbU.cjs} +1 -1
- package/dist/cli-chunks/{dev-D6WhI3cC.cjs → dev-Bf49EoR8.cjs} +5 -5
- package/dist/cli-chunks/{doctor-CtNS5Tt2.cjs → doctor-CzETlRvH.cjs} +1 -1
- package/dist/cli-chunks/{index-B1w-Jpba.cjs → index-BMhV2-vd.cjs} +14 -14
- package/dist/cli-chunks/{index-C4y2G95g.cjs → index-Cd37cCQM.cjs} +1 -1
- package/dist/cli-chunks/{login-D-ZK-n1E.cjs → login-Cb5ShNVQ.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-J4lrUja0.cjs → project-vite-WP6NzC3p.cjs} +1 -1
- package/dist/cli-chunks/{remote-BZNHAL5_.cjs → remote-Co84uKvV.cjs} +4 -4
- package/dist/cli-chunks/{session-5ryBp2wZ.cjs → session-9A8AY7YK.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.esm.js +1 -1
- package/package.json +3 -1
- package/skill/references/api-protocol.md +0 -10
- package/skill/references/api-root.md +153 -353
- package/skill/references/safety-boundaries.md +6 -9
- package/skill/scripts/sync-references.mjs +10 -20
- package/skill/skill.json +4 -4
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
- packages/hb-sdk/src/index.ts
|
|
9
9
|
- packages/hb-sdk/src/vite/index.ts
|
|
10
10
|
- packages/hb-sdk/README.md
|
|
11
|
+
- apps/docs/hb-sdk/guide/quick-start.md
|
|
12
|
+
- apps/docs/hb-sdk/guide/error-handling.md
|
|
13
|
+
- apps/docs/hb-sdk/guide/lifecycle.md
|
|
14
|
+
- apps/docs/hb-sdk/guide/cli.md
|
|
11
15
|
|
|
12
16
|
## Contents
|
|
13
17
|
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
## Package metadata
|
|
20
24
|
|
|
21
25
|
- Package: `@heybox/hb-sdk`
|
|
22
|
-
- Version at generation time: `0.6.
|
|
26
|
+
- Version at generation time: `0.6.8-alpha.0`
|
|
23
27
|
- Public root export: `@heybox/hb-sdk`
|
|
24
28
|
- Protocol export: `@heybox/hb-sdk/protocol`
|
|
25
29
|
- Vite plugin export: `@heybox/hb-sdk/vite`
|
|
@@ -357,435 +361,231 @@ function resolveHmrWebSocketUrl(resolved: MiniappManifestResolvedConfig) {
|
|
|
357
361
|
}
|
|
358
362
|
```
|
|
359
363
|
|
|
360
|
-
##
|
|
361
|
-
|
|
362
|
-
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()`。项目通过 `hb-sdk build` 完成生产构建后,会在固定的 `dist/` 中写入 `manifest.json`:
|
|
363
|
-
|
|
364
|
-
```json
|
|
365
|
-
{
|
|
366
|
-
"version": "1.2.3",
|
|
367
|
-
"sdkVersion": "0.6.1"
|
|
368
|
-
}
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
`version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk build` 要求项目显式注册这个插件;`hb-sdk create` 生成的模板默认已注册,现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
|
|
372
|
-
|
|
373
|
-
```ts
|
|
374
|
-
import { miniappManifest } from '@heybox/hb-sdk/vite';
|
|
375
|
-
import { defineConfig } from 'vite';
|
|
376
|
-
|
|
377
|
-
export default defineConfig({
|
|
378
|
-
base: './',
|
|
379
|
-
plugins: [miniappManifest()],
|
|
380
|
-
});
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
`base: './'` 用于让构建产物里的 JS/CSS/图片资源以 `./assets/...` 相对路径引用,避免小程序资源目录不是站点根路径时访问 `/assets/...` 失败。若没有显式配置 `base`,`miniappManifest()` 也会在 build 时默认补成 `./`。
|
|
384
|
-
|
|
385
|
-
工坊小程序构建产物只能在兼容的小黑盒 Runtime 中启动。普通浏览器直接打开时不会执行标准业务脚本,并会提示在小黑盒 APP 内打开。项目应使用标准 Vite module 入口。
|
|
386
|
-
|
|
387
|
-
插件只接受单页应用:输出目录只能存在入口 `index.html`。build 和 dev 都会把平台 CSP 插入 `<head>` 首位,已有 CSP 始终原样保留;两份策略按浏览器交集生效。平台 CSP 在脚本、样式、图片、字体和媒体指令中放行 `xiaoheihe.cn`、`max-c.com`、`debugmode.cn`、`maxjia.com` 的 HTTPS 根域及子域;入口 HTML 中相应资源标签也可使用这些官方 HTTPS URL。
|
|
388
|
-
|
|
389
|
-
平台 CSP 会禁止 `fetch`、XHR、WebSocket、EventSource、Beacon、Worker、iframe、表单和对象加载等浏览器原生出口;`connect-src` 始终为 `'none'`,dev 只额外放行当前 Vite 的精确 HMR WebSocket 地址。需要宿主授权的业务网络请求仍应使用 `network.request()`。
|
|
390
|
-
|
|
391
|
-
meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、非官方外部资源 URL 和额外 HTML 会使 build 失败。内联 script/style 允许,但 `unsafe-eval` 不允许。`dev`、`hb-sdk build` 和手动 Vite build 都不请求远端最低 SDK 版本;构建仍会把当前 `sdkVersion` 写入 Manifest,`hb-sdk remote deploy` 仍校验 Manifest 结构并经过服务端 precheck / submit-audit 策略。
|
|
392
|
-
|
|
393
|
-
失败与警告语义:
|
|
394
|
-
|
|
395
|
-
- 读取 `package.json` 失败或 JSON 解析失败:build 直接失败,并输出具体原因。
|
|
396
|
-
- `package.json.version` 不是非空字符串:build 直接失败。
|
|
397
|
-
- `package.json.version` 仍是模板默认值 `0.0.0`:build 直接失败,必须改成实际 SemVer。
|
|
398
|
-
- 版本号不是严格 SemVer、包含 build metadata 或缺少 `sdkVersion`:build/deploy 直接失败。
|
|
399
|
-
|
|
400
|
-
`manifest.json` 不部署到 CDN,只交给发布流水线读取后上送后台;Host 通过后台 API 间接读取版本信息。第一阶段只支持 Vite 项目,非 Vite 打包器未来通过其他子入口扩展。
|
|
401
|
-
|
|
402
|
-
## App-facing concepts
|
|
403
|
-
|
|
404
|
-
## 快速开始
|
|
405
|
-
|
|
406
|
-
创建一个新的外部小程序项目:
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
npx @heybox/hb-sdk create my-miniapp
|
|
410
|
-
cd my-miniapp
|
|
411
|
-
npm install
|
|
412
|
-
npm run dev
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
模板默认使用 Vue 3、Vite、TypeScript 和 npm。`npm run dev` 会启动小程序页面服务,并打开 `hb-sdk` 内置的浏览器 mock 宿主环境,适合在普通浏览器里调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面,也可以选择局域网网卡后用手机小黑盒 APP 扫码调试。手机需要与电脑处在同一局域网,并使用支持小程序调试壳的新版小黑盒 APP。Codex、VSCode 等内嵌浏览器可能无法转交 `heybox://` 协议;需要从调试页唤起 Mac 版 APP 时,请先在系统浏览器中打开调试页。
|
|
416
|
-
|
|
417
|
-
在已有项目中安装:
|
|
364
|
+
## 生产构建
|
|
418
365
|
|
|
419
366
|
```bash
|
|
420
|
-
|
|
367
|
+
hb-sdk build [--env <name>] [--verbose]
|
|
421
368
|
```
|
|
422
369
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
```ts
|
|
426
|
-
import hbSDK from '@heybox/hb-sdk';
|
|
427
|
-
|
|
428
|
-
await hbSDK.ready();
|
|
370
|
+
`hb-sdk build` 直接使用项目安装的 Vite,先清理再生成固定的 `dist/`,并校验小程序入口、Manifest 和可上传产物。它不执行类型检查,不要求 CLI 登录或绑定小程序,也不访问远端服务。项目必须在 `vite.config.ts` 中显式注册 `miniappManifest()`。
|
|
429
371
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (user.isLogin) {
|
|
433
|
-
console.log(user.userInfo.nickname);
|
|
434
|
-
}
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
也可以按需导入:
|
|
438
|
-
|
|
439
|
-
```ts
|
|
440
|
-
import { auth, ready, user } from '@heybox/hb-sdk';
|
|
441
|
-
|
|
442
|
-
await ready();
|
|
443
|
-
|
|
444
|
-
const currentUser = await user.getInfo();
|
|
445
|
-
|
|
446
|
-
if (!currentUser.isLogin) {
|
|
447
|
-
await auth.login();
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
## 运行环境
|
|
452
|
-
|
|
453
|
-
SDK 需要在黑盒小程序 iframe 容器内运行。父容器会为页面注入 bridge nonce,并通过 `postMessage` 与 SDK 通信。普通浏览器直接打开小程序页面时通常无法完成握手;本地开发请优先使用:
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
npm run dev
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
调试页会通过 iframe 加载本地页面并补齐小程序 bridge 环境。`hb-sdk dev` 的基础启动只依赖本地页面地址:即使项目未绑定、CLI 未登录或远端暂时不可用,浏览器 Mock、Mac 启动协议和手机二维码也会继续生成,真机 dev shell 以匿名本地沙箱加载 `mini_url`,不会把公开 `detail` 查询作为启动门禁。项目已绑定时会限时 3 秒读取远端 dev context;成功后 Mock Host 用真实 Runtime 权限快照初始化本地模拟,失败或超时则显示脱敏警告,并默认拒绝 `network.request` 等受管能力。需要定位降级原因时可使用 `hb-sdk dev --verbose`;详细错误只写入本地调试日志,其中 URL 用户名、密码和敏感 query/hash 会被遮蔽,不会进入 LAN bootstrap。
|
|
460
|
-
|
|
461
|
-
Mock Host 可以切换开发会话的 `network.request` 权限,不会重建 iframe,因此不影响 Vite HMR。权限覆盖会持久化到 `hb-sdk` 的用户级本地缓存,并按项目真实路径与启动时绑定的 `miniProgramId` 隔离;即使远端权限暂时读取失败,也会继续使用已知绑定 scope。刷新调试页或重启 `hb-sdk dev` 后仍会恢复,直到点击“恢复初始权限”。未绑定项目使用独立匿名 scope,之后绑定小程序时不会继承匿名覆盖。调试页会分别展示远端基线与本地覆盖;多个调试页或进程写入同一 scope 时以最后成功写入的完整配置为准,不提供冲突合并。缓存写入失败时当前页面仍立即生效,同时明确提示刷新或重启后会丢失。已绑定项目重置时会先重新读取远端权限,读取失败则保留当前覆盖并显示错误;匿名项目直接清除本地覆盖。
|
|
462
|
-
|
|
463
|
-
切换或恢复权限时,Mobile App 二维码会同步重生成,重新扫码后的局域网页面使用同一开发权限。二维码不会携带权限内容,只携带指向本机 Mock Host 的 `dev_context_url`;该 URL 使用 256-bit 随机 token,5 分钟后失效,调试页会在会话到期时自动生成新二维码。Runtime Host 会在创建小程序 Runtime 前拉取 token 对应的不可变权限快照,并校验开发页面 origin、会话期限和快照结构。
|
|
464
|
-
|
|
465
|
-
Dev Session 中的 `network.request` 通过同一 token 绑定的本地代理转发,不会调用黑盒原生凭据 adapter,也不会携带 Cookie、pkey 等宿主凭据;`useOfficialDomain` 固定为 `false`。旧 `dev_network_request` query 不再提供授权,不能作为 Dev Session 快照的降级或覆盖入口。此链路只调整 Web 侧 CLI、Mock Host 和 Runtime Host,Android/iOS 客户端继续透传 URL,无需修改。官方域名权限只读取线上快照,本地设置不会修改线上权限;调试页会对比已读取的线上快照,提示本地放开但上线后会返回 `PERMISSION_DENIED` 的差异。真实容器加载开发 `mini_url` 前会提示“即将打开未经验证的开发网页。该页面可能由本机或局域网服务提供,请确认来源可信后继续。”,用户确认后才继续加载。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP;遇到这种情况时,请在系统浏览器中打开同一个调试页后重试。
|
|
466
|
-
|
|
467
|
-
在未使用脚手架的 Vite 项目中,可以把命令加到 `package.json`:
|
|
372
|
+
推荐由项目的 `scripts.build` 保留类型检查:
|
|
468
373
|
|
|
469
374
|
```json
|
|
470
375
|
{
|
|
471
376
|
"scripts": {
|
|
472
|
-
"
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
```
|
|
476
|
-
|
|
477
|
-
## 错误处理
|
|
478
|
-
|
|
479
|
-
bridge、父容器运行时、协议校验或能力调用失败时会抛出 `HbMiniProgramSDKError`,其中包含稳定的 `code`、开发者可读的 `message` 和可选 `data`。
|
|
480
|
-
|
|
481
|
-
```ts
|
|
482
|
-
import { HbMiniProgramSDKError, ready } from '@heybox/hb-sdk';
|
|
483
|
-
|
|
484
|
-
try {
|
|
485
|
-
await ready();
|
|
486
|
-
} catch (error) {
|
|
487
|
-
if (error instanceof HbMiniProgramSDKError) {
|
|
488
|
-
console.log(error.code, error.message, error.data);
|
|
377
|
+
"build": "vue-tsc --noEmit && hb-sdk build"
|
|
489
378
|
}
|
|
490
379
|
}
|
|
491
380
|
```
|
|
492
381
|
|
|
493
|
-
|
|
382
|
+
构建命令只支持 `--env` 和 `--verbose`。已有项目继续使用 `vite build` 仍然兼容,不会自动迁移。
|
|
494
383
|
|
|
495
|
-
##
|
|
384
|
+
## App-facing concepts
|
|
496
385
|
|
|
497
|
-
## 常用能力
|
|
498
386
|
|
|
499
|
-
|
|
387
|
+
# 快速开始
|
|
500
388
|
|
|
501
|
-
|
|
389
|
+
如果页面不需要小黑盒开放能力,可以不接入 SDK。这是最短接入路径:等待 SDK 就绪,然后读取当前用户登录态。
|
|
502
390
|
|
|
503
391
|
```ts
|
|
504
|
-
import
|
|
392
|
+
import hbSDK from '@heybox/hb-sdk'
|
|
505
393
|
|
|
506
|
-
|
|
394
|
+
async function bootstrap() {
|
|
395
|
+
await hbSDK.ready()
|
|
507
396
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
397
|
+
const result = await hbSDK.user.getInfo()
|
|
398
|
+
if (result.isLogin && result.userInfo) {
|
|
399
|
+
console.log(result.userInfo.nickname)
|
|
400
|
+
return
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
console.log('当前用户未登录')
|
|
511
404
|
}
|
|
405
|
+
|
|
406
|
+
bootstrap()
|
|
512
407
|
```
|
|
513
408
|
|
|
514
|
-
|
|
409
|
+
## 推荐业务写法
|
|
515
410
|
|
|
516
|
-
|
|
411
|
+
业务页通常还需要监听登录态变化。下面以 Vue 3 为例:初始化只读取状态,登录必须由按钮等明确的用户操作触发,监听在组件卸载时清理。
|
|
517
412
|
|
|
518
413
|
```ts
|
|
519
|
-
|
|
414
|
+
import { onUnmounted } from 'vue'
|
|
415
|
+
import hbSDK from '@heybox/hb-sdk'
|
|
520
416
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
417
|
+
const stopAuthChange = hbSDK.on('authChange', result => {
|
|
418
|
+
if (result.isLogin) {
|
|
419
|
+
console.log('用户已登录', result.userInfo?.heybox_id)
|
|
420
|
+
}
|
|
421
|
+
})
|
|
524
422
|
|
|
525
|
-
|
|
423
|
+
await hbSDK.ready()
|
|
526
424
|
|
|
527
|
-
|
|
528
|
-
console.log(steam.account_info.steamid);
|
|
529
|
-
}
|
|
425
|
+
const initialUser = await hbSDK.user.getInfo()
|
|
530
426
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
427
|
+
async function loginFromUserAction() {
|
|
428
|
+
const result = await hbSDK.auth.login()
|
|
429
|
+
if (!result.isLogin || !result.userInfo) {
|
|
430
|
+
return
|
|
431
|
+
}
|
|
535
432
|
|
|
536
|
-
|
|
537
|
-
console.log(games.data.gameList);
|
|
433
|
+
console.log('用户已登录', result.userInfo.heybox_id)
|
|
538
434
|
}
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
`user.getCurrentUserDetail()` 返回当前用户展示资料,`user.getCurrentUserProfile()` 返回更敏感的个人资料字段。`user.getPlatformAccountOverview()` 返回 `steam`、`epic`、`xbox`、`psn`、`switch`、`pc_hardware`、`mobile` 的绑定/隐藏状态;`user.getPlatformAccountInfo(platform)` 只支持这些平台字面量,未绑定平台返回 `account_info: null`,不会抛出未绑定错误。`user.getSteamGameList(options)` 返回当前用户 Steam 游戏库,未登录或未绑定 Steam 时返回状态对象;分页 `limit` 默认 20、最大 100,`sort` 支持 `weeks`、`all`、`achieved`。
|
|
542
435
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
### 分享
|
|
546
|
-
|
|
547
|
-
```ts
|
|
548
|
-
import { share } from '@heybox/hb-sdk';
|
|
549
|
-
|
|
550
|
-
await share.showShareMenu({
|
|
551
|
-
title: '我的小程序页面',
|
|
552
|
-
desc: '来自黑盒小程序的分享',
|
|
553
|
-
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
554
|
-
post: {
|
|
555
|
-
topicIds: [235709],
|
|
556
|
-
topics: ['无畏契约战绩'],
|
|
557
|
-
},
|
|
558
|
-
});
|
|
436
|
+
onUnmounted(stopAuthChange)
|
|
559
437
|
```
|
|
560
438
|
|
|
561
|
-
|
|
562
|
-
`/tools/common_share?user_miniprogram_id=...` 分享落地页。只有确实要分享外部
|
|
563
|
-
HTTP(S) 页面时才显式传 `url`。
|
|
564
|
-
|
|
565
|
-
`post` 用于给“转发到社区”预置可编辑的分区与话题。`topicIds` 接受正整数或非空字符串并按首次出现顺序去重;`topics` 只传话题内容,不要包含首尾 `#`。`showShareMenu()` 只支持一个默认分区,并且不能与 `channel` 同时使用;本地 Mock、App Dev Shell 和开发 Runtime 会直接拒绝这类错误,生产 Runtime 会过滤非法项、只取第一个分区并继续普通分享。`post: null` 等同于不配置。
|
|
439
|
+
把 `loginFromUserAction` 绑定到登录按钮;不要在页面 bootstrap 阶段自动调用 `auth.login()`。
|
|
566
440
|
|
|
567
|
-
|
|
441
|
+
## ready 的含义
|
|
568
442
|
|
|
569
|
-
|
|
570
|
-
await share.screenshot({
|
|
571
|
-
delay: 100,
|
|
572
|
-
saveToAlbum: true,
|
|
573
|
-
post: {
|
|
574
|
-
topicIds: [235709, 66739],
|
|
575
|
-
topics: ['无畏契约战绩'],
|
|
576
|
-
},
|
|
577
|
-
});
|
|
578
|
-
```
|
|
443
|
+
`ready()` 表示 SDK 已就绪,可以安全调用开放能力。如果当前不在可用的小程序运行环境中,它会抛出公开错误。`ready()` 不等价于“用户已登录”,用户状态需要通过 `user.getInfo()` 或 `authChange` 判断。
|
|
579
444
|
|
|
580
|
-
|
|
445
|
+
## 默认单例适合什么场景
|
|
581
446
|
|
|
582
|
-
|
|
447
|
+
大多数小程序页面都应该使用默认实例。0.6 起不再对业务代码提供独立实例工厂。
|
|
583
448
|
|
|
584
|
-
```ts
|
|
585
|
-
import { ui } from '@heybox/hb-sdk';
|
|
586
449
|
|
|
587
|
-
|
|
588
|
-
message: '保存成功',
|
|
589
|
-
status: 'success',
|
|
590
|
-
});
|
|
450
|
+
# 错误处理
|
|
591
451
|
|
|
592
|
-
|
|
593
|
-
dismissible: true,
|
|
594
|
-
});
|
|
452
|
+
SDK 公开两类标准错误:
|
|
595
453
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
`showToast()` 的 `message` 会 trim 后发送给宿主,不能为空,最长 120 个字符;`status` 只支持 `success` 和 `error`,不传时展示普通文本 toast。loading 是全局单例,多次 `showLoading()` 会覆盖当前配置,`hideLoading()` 在未展示时也会成功。
|
|
600
|
-
|
|
601
|
-
### 设备能力
|
|
454
|
+
- `HbMiniProgramSDKError`:SDK 初始化或开放能力调用失败。
|
|
455
|
+
- `HbMiniProgramNetworkError`:网络请求已返回,但 HTTP 状态未通过 `validateStatus`。
|
|
602
456
|
|
|
603
457
|
```ts
|
|
604
|
-
import {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
await device.setClipboard({
|
|
612
|
-
text: 'hello',
|
|
613
|
-
});
|
|
614
|
-
```
|
|
458
|
+
import {
|
|
459
|
+
HbMiniProgramNetworkError,
|
|
460
|
+
HbMiniProgramSDKError,
|
|
461
|
+
network,
|
|
462
|
+
} from '@heybox/hb-sdk'
|
|
615
463
|
|
|
616
|
-
|
|
464
|
+
try {
|
|
465
|
+
await network.request({ url: 'https://api.example.com/data' })
|
|
466
|
+
} catch (error) {
|
|
467
|
+
if (error instanceof HbMiniProgramNetworkError) {
|
|
468
|
+
console.log(error.status, error.data, error.headers)
|
|
469
|
+
return
|
|
470
|
+
}
|
|
617
471
|
|
|
618
|
-
|
|
472
|
+
if (error instanceof HbMiniProgramSDKError) {
|
|
473
|
+
console.log(error.code, error.message, error.data)
|
|
474
|
+
return
|
|
475
|
+
}
|
|
619
476
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
await navigation.reload();
|
|
624
|
-
await navigation.close();
|
|
625
|
-
|
|
626
|
-
await navigation.openAppPage({
|
|
627
|
-
target: 'game_detail',
|
|
628
|
-
appId: 578080,
|
|
629
|
-
gameType: 'pc',
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
await navigation.openAppPage({
|
|
633
|
-
target: 'user_detail',
|
|
634
|
-
userId: '239040',
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
await navigation.openAppPage({
|
|
638
|
-
target: 'post_detail',
|
|
639
|
-
linkId: 57670836,
|
|
640
|
-
rootCommentId: 123,
|
|
641
|
-
commentId: 456,
|
|
642
|
-
});
|
|
477
|
+
throw error
|
|
478
|
+
}
|
|
643
479
|
```
|
|
644
480
|
|
|
645
|
-
|
|
481
|
+
## 处理原则
|
|
646
482
|
|
|
647
|
-
|
|
483
|
+
- 根据 `error.code` 区分运行环境、权限、超时和业务失败,不要只比对错误文案。
|
|
484
|
+
- 权限失败时给出可理解的提示,不要将它当成未登录。
|
|
485
|
+
- 超时或运行环境不可用时,允许用户重试或退出当前流程。
|
|
486
|
+
- 上报 `code`、`message` 和必要的业务上下文,不要上报用户凭据或敏感数据。
|
|
648
487
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
```ts
|
|
652
|
-
import { viewport } from '@heybox/hb-sdk';
|
|
488
|
+
完整错误码和字段见 [HbMiniProgramSDKError](api-root.md) 与 [HbMiniProgramNetworkError](api-root.md)。
|
|
653
489
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
console.log(windowInfo.windowWidth, windowInfo.windowHeight, windowInfo.safeArea.top);
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
### 导航栏样式
|
|
490
|
+
## 业务层建议
|
|
660
491
|
|
|
661
492
|
```ts
|
|
662
|
-
import {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
493
|
+
import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
|
|
494
|
+
|
|
495
|
+
type UserViewState =
|
|
496
|
+
| { status: 'ready'; user: Awaited<ReturnType<typeof hbSDK.user.getInfo>> }
|
|
497
|
+
| { status: 'failed'; error: HbMiniProgramSDKError }
|
|
498
|
+
|
|
499
|
+
async function loadUser(): Promise<UserViewState> {
|
|
500
|
+
try {
|
|
501
|
+
await hbSDK.ready()
|
|
502
|
+
return { status: 'ready', user: await hbSDK.user.getInfo() }
|
|
503
|
+
} catch (error) {
|
|
504
|
+
if (error instanceof HbMiniProgramSDKError) {
|
|
505
|
+
reportSDKError(error.code, error.message, error.data)
|
|
506
|
+
return { status: 'failed', error }
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
throw error
|
|
510
|
+
}
|
|
511
|
+
}
|
|
672
512
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
await storage.setStorage({
|
|
677
|
-
key: 'settings',
|
|
678
|
-
data: {
|
|
679
|
-
theme: 'dark',
|
|
680
|
-
},
|
|
681
|
-
});
|
|
682
|
-
|
|
683
|
-
const { data } = await storage.getStorage<{ theme: string }>({
|
|
684
|
-
key: 'settings',
|
|
685
|
-
});
|
|
513
|
+
function reportSDKError(code: string, message: string, data?: unknown) {
|
|
514
|
+
console.log('[hb-sdk]', code, message, data)
|
|
515
|
+
}
|
|
686
516
|
```
|
|
687
517
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
### 云端排行榜
|
|
691
|
-
|
|
692
|
-
`cloud.leaderboard` 是平台托管的远端排行榜能力,不是本地 storage,也不是通用网络请求。小程序页面不能传 `userId`;宿主和服务端会按当前登录用户注入身份。
|
|
693
|
-
|
|
694
|
-
```ts
|
|
695
|
-
import { cloud } from '@heybox/hb-sdk';
|
|
696
|
-
|
|
697
|
-
const entry = await cloud.leaderboard.submit({
|
|
698
|
-
key: 'cube_run_total',
|
|
699
|
-
score: 150,
|
|
700
|
-
extra: {
|
|
701
|
-
run: 2,
|
|
702
|
-
},
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
const list = await cloud.leaderboard.getList({
|
|
706
|
-
key: 'cube_run_total',
|
|
707
|
-
limit: 20,
|
|
708
|
-
});
|
|
709
|
-
|
|
710
|
-
const current = await cloud.leaderboard.getCurrentUserEntry({
|
|
711
|
-
key: 'cube_run_total',
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
await cloud.leaderboard.deleteCurrentUserEntry({
|
|
715
|
-
key: 'cube_run_total',
|
|
716
|
-
});
|
|
717
|
-
|
|
718
|
-
const info = await cloud.leaderboard.getInfo({
|
|
719
|
-
key: 'cube_run_total',
|
|
720
|
-
});
|
|
721
|
-
```
|
|
518
|
+
## Public modules
|
|
722
519
|
|
|
723
|
-
|
|
520
|
+
## 能力概览
|
|
724
521
|
|
|
725
|
-
|
|
522
|
+
除 `ready()` 外,SDK 还提供 `on()` 和 `off()` 处理前后台、登录态等生命周期事件。
|
|
726
523
|
|
|
727
|
-
|
|
524
|
+
| 模块 | 用途 |
|
|
525
|
+
| ------------ | -------------------------------- |
|
|
526
|
+
| `auth` | 由用户操作触发登录 |
|
|
527
|
+
| `user` | 读取当前用户、账号资料和游戏数据 |
|
|
528
|
+
| `share` | 打开分享或截图分享流程 |
|
|
529
|
+
| `ui` | 展示 Toast 和 Loading |
|
|
530
|
+
| `device` | 调用振动和剪贴板能力 |
|
|
531
|
+
| `navigation` | 关闭、刷新页面或打开小黑盒页面 |
|
|
532
|
+
| `viewport` | 读取窗口信息和设置导航栏样式 |
|
|
533
|
+
| `storage` | 读写当前小程序的隔离存储 |
|
|
534
|
+
| `cloud` | 使用小程序云端排行榜 |
|
|
535
|
+
| `network` | 发起经过平台授权的网络请求 |
|
|
728
536
|
|
|
729
|
-
|
|
537
|
+
具体方法、参数和返回值以 [API Reference](https://docs.xiaoheihe.cn/hb_sdk/reference/) 为准,常见组合写法见 [Recipes](https://docs.xiaoheihe.cn/hb_sdk/recipes/)。
|
|
730
538
|
|
|
731
|
-
排行榜后端错误会保留为 `HbMiniProgramSDKError.code`,常见值包括 `LEADERBOARD_DEFAULT_NOT_FOUND`、`LEADERBOARD_LIMIT_EXCEEDED`、`LEADERBOARD_SUBMIT_LOCKED`、`LEADERBOARD_TABLE_NOT_READY`、`InvalidArgument`、`NotFound`、`ResourceExhausted`、`Unauthenticated`。业务可以按 `code` 区分未建榜、并发提交、数据表配置异常、参数错误、容量限制和未登录等场景。
|
|
732
539
|
|
|
733
|
-
|
|
540
|
+
# 事件与生命周期
|
|
734
541
|
|
|
735
|
-
`
|
|
542
|
+
SDK 通过 `on` 监听小程序生命周期和业务事件。
|
|
736
543
|
|
|
737
544
|
```ts
|
|
738
|
-
import {
|
|
739
|
-
|
|
740
|
-
try {
|
|
741
|
-
const response = await network.request<{ ok: boolean }>({
|
|
742
|
-
url: 'https://api.example.com/demo',
|
|
743
|
-
method: 'GET',
|
|
744
|
-
headers: {
|
|
745
|
-
accept: 'application/json',
|
|
746
|
-
},
|
|
747
|
-
});
|
|
545
|
+
import { onUnmounted } from 'vue'
|
|
546
|
+
import { on } from '@heybox/hb-sdk'
|
|
748
547
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
if (error instanceof HbMiniProgramNetworkError) {
|
|
752
|
-
console.log(error.response.status, error.response.data);
|
|
753
|
-
}
|
|
548
|
+
function handleShow(payload: { timestamp: number; source?: string }) {
|
|
549
|
+
console.log('show from', payload.source)
|
|
754
550
|
}
|
|
755
|
-
```
|
|
756
551
|
|
|
757
|
-
|
|
552
|
+
const stopShow = on('show', handleShow)
|
|
553
|
+
const stopHide = on('hide', () => {
|
|
554
|
+
console.log('小程序页面隐藏')
|
|
555
|
+
})
|
|
758
556
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
});
|
|
764
|
-
```
|
|
765
|
-
|
|
766
|
-
支持的 HTTP method 为 `GET`、`POST`、`PUT`、`PATCH`、`DELETE`、`HEAD`、`OPTIONS`。
|
|
767
|
-
|
|
768
|
-
`network.request` 由平台 Runtime 权限控制。未授权时 SDK 会收到 `PERMISSION_DENIED` 和“当前小程序暂不支持网络请求”;即使已开启网络请求,访问黑盒官方域名仍需要运营侧单独开启官方域名配置。业务代码不能自行请求或注入 Cookie、pkey 等官方凭据。
|
|
557
|
+
function stopLifecycleEvents() {
|
|
558
|
+
stopShow()
|
|
559
|
+
stopHide()
|
|
560
|
+
}
|
|
769
561
|
|
|
770
|
-
|
|
562
|
+
onUnmounted(stopLifecycleEvents)
|
|
563
|
+
```
|
|
771
564
|
|
|
772
|
-
|
|
565
|
+
框架外也可以保存 `on()` 返回的取消函数,在页面或业务模块真正销毁时调用。需要按 handler 精确移除时再使用 `off(event, handler)`;不要在注册后的同一执行流里立即取消。
|
|
773
566
|
|
|
774
|
-
|
|
567
|
+
## 事件列表
|
|
775
568
|
|
|
776
|
-
|
|
777
|
-
|
|
569
|
+
| 事件 | 触发时机 | 典型用途 |
|
|
570
|
+
| ------------ | ------------------------ | ------------------ |
|
|
571
|
+
| `launch` | 小程序首次启动 | 初始化一次性数据 |
|
|
572
|
+
| `ready` | SDK 可安全调用开放能力 | 标记 SDK 可用 |
|
|
573
|
+
| `show` | 小程序页面展示 | 刷新可见态数据 |
|
|
574
|
+
| `hide` | 小程序页面隐藏 | 暂停轮询、暂停播放 |
|
|
575
|
+
| `unload` | 当前小程序运行环境终止 | 清理资源并停止请求 |
|
|
576
|
+
| `error` | 小程序或开放能力运行异常 | 统一错误上报 |
|
|
577
|
+
| `authChange` | 登录状态变化 | 刷新用户信息和权限 |
|
|
778
578
|
|
|
779
|
-
|
|
780
|
-
console.log('页面展示', payload.timestamp, payload.source);
|
|
781
|
-
});
|
|
579
|
+
完整载荷与事件名见:
|
|
782
580
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
});
|
|
581
|
+
- [MiniProgramEventPayloadMap](api-root.md)
|
|
582
|
+
- [MiniProgramEventName](api-root.md)
|
|
786
583
|
|
|
787
|
-
|
|
788
|
-
unsubscribeAuth();
|
|
789
|
-
```
|
|
584
|
+
## 生命周期建议
|
|
790
585
|
|
|
791
|
-
|
|
586
|
+
- 初始化开放能力前先 `await ready()`。
|
|
587
|
+
- UI 可见性相关逻辑放在 `show`、`hide`。
|
|
588
|
+
- 用户状态不要只在页面加载时读一次,登录入口附近要监听 `authChange`。
|
|
589
|
+
- 组件或页面销毁时清理 `on` 注册的监听,避免重复响应。
|
|
590
|
+
- 事件只派发给注册当时存在的监听器,不会重放;一次性 `launch`/`ready` 状态应以 `ready()` Promise 为准。
|
|
591
|
+
- 收到 `unload` 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
|
|
@@ -8,16 +8,13 @@
|
|
|
8
8
|
- apps/docs/hb-sdk/guide/auth.md
|
|
9
9
|
## Required boundaries
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 关键约束
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
- `
|
|
15
|
-
- `
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- `network.request()` 的 `validateStatus` 只在 SDK 本地执行,不会被序列化给父容器。
|
|
19
|
-
- `on()` 返回取消监听函数;组件卸载或页面销毁时应主动取消监听。
|
|
20
|
-
- 构建产物可以包含 `dist/manifest.json`,业务代码不应自行 fetch 已部署的 manifest;这个文件由发布流水线读取并上送后台。
|
|
13
|
+
- `ready()` 不代表用户已登录;使用 `user.getInfo()` 判断登录状态。
|
|
14
|
+
- `auth.login()` 只能由明确的用户操作触发,不要在页面初始化时自动登录。
|
|
15
|
+
- `on()` 返回取消监听函数,组件卸载或页面销毁时需要调用。
|
|
16
|
+
- 业务网络请求使用 `network.request()`,不要依赖浏览器原生网络出口。
|
|
17
|
+
- 构建必须启用 `miniappManifest()`,推荐统一使用 `hb-sdk build`。
|
|
21
18
|
|
|
22
19
|
## Agent rules
|
|
23
20
|
|