@heybox/hb-sdk 0.6.4-alpha.0 → 0.6.4

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.
@@ -32,6 +32,58 @@ function isMiniProgramBridgeMessage(value) {
32
32
  typeof message.type === 'string');
33
33
  }
34
34
 
35
+ const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
36
+ /**
37
+ * 判断 permission key 是否由 Runtime 权限快照管理。
38
+ *
39
+ * @param key 待判断的 permission key。
40
+ * @returns 该 key 需要读取 Runtime 权限快照时返回 `true`。
41
+ */
42
+ function isManagedMiniProgramRuntimePermissionKey(key) {
43
+ return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
44
+ }
45
+ /**
46
+ * 解析服务端权限快照;格式不完整时整份快照失效并 fail closed。
47
+ *
48
+ * @param snapshot 待校验的服务端权限快照。
49
+ * @returns 解析状态和通过校验的受管权限。
50
+ */
51
+ function parseMiniProgramRuntimePermissions(snapshot) {
52
+ if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
53
+ return { valid: false, permissions: {} };
54
+ }
55
+ if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
56
+ return { valid: false, permissions: {} };
57
+ }
58
+ const seenKeys = new Set();
59
+ const permissions = {};
60
+ for (const rawEntry of snapshot.entries) {
61
+ if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
62
+ return { valid: false, permissions: {} };
63
+ }
64
+ const key = rawEntry.key.trim();
65
+ if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
66
+ return { valid: false, permissions: {} };
67
+ }
68
+ seenKeys.add(key);
69
+ if (!isManagedMiniProgramRuntimePermissionKey(key)) {
70
+ continue;
71
+ }
72
+ if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
73
+ return { valid: false, permissions: {} };
74
+ }
75
+ permissions[key] = {
76
+ key,
77
+ status: rawEntry.status,
78
+ config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
79
+ };
80
+ }
81
+ return { valid: true, permissions };
82
+ }
83
+ function isRecord(value) {
84
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
85
+ }
86
+
35
87
  /**
36
88
  * 登录授权能力方法名。
37
89
  *
@@ -364,4 +416,6 @@ exports.USER_GET_PLATFORM_ACCOUNT_OVERVIEW_METHOD = USER_GET_PLATFORM_ACCOUNT_OV
364
416
  exports.USER_GET_STEAM_GAME_LIST_METHOD = USER_GET_STEAM_GAME_LIST_METHOD;
365
417
  exports.VIEWPORT_GET_WINDOW_INFO_METHOD = VIEWPORT_GET_WINDOW_INFO_METHOD;
366
418
  exports.VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
419
+ exports.isManagedMiniProgramRuntimePermissionKey = isManagedMiniProgramRuntimePermissionKey;
367
420
  exports.isMiniProgramBridgeMessage = isMiniProgramBridgeMessage;
421
+ exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
@@ -30,6 +30,58 @@ function isMiniProgramBridgeMessage(value) {
30
30
  typeof message.type === 'string');
31
31
  }
32
32
 
33
+ const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
34
+ /**
35
+ * 判断 permission key 是否由 Runtime 权限快照管理。
36
+ *
37
+ * @param key 待判断的 permission key。
38
+ * @returns 该 key 需要读取 Runtime 权限快照时返回 `true`。
39
+ */
40
+ function isManagedMiniProgramRuntimePermissionKey(key) {
41
+ return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
42
+ }
43
+ /**
44
+ * 解析服务端权限快照;格式不完整时整份快照失效并 fail closed。
45
+ *
46
+ * @param snapshot 待校验的服务端权限快照。
47
+ * @returns 解析状态和通过校验的受管权限。
48
+ */
49
+ function parseMiniProgramRuntimePermissions(snapshot) {
50
+ if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
51
+ return { valid: false, permissions: {} };
52
+ }
53
+ if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
54
+ return { valid: false, permissions: {} };
55
+ }
56
+ const seenKeys = new Set();
57
+ const permissions = {};
58
+ for (const rawEntry of snapshot.entries) {
59
+ if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
60
+ return { valid: false, permissions: {} };
61
+ }
62
+ const key = rawEntry.key.trim();
63
+ if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
64
+ return { valid: false, permissions: {} };
65
+ }
66
+ seenKeys.add(key);
67
+ if (!isManagedMiniProgramRuntimePermissionKey(key)) {
68
+ continue;
69
+ }
70
+ if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
71
+ return { valid: false, permissions: {} };
72
+ }
73
+ permissions[key] = {
74
+ key,
75
+ status: rawEntry.status,
76
+ config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
77
+ };
78
+ }
79
+ return { valid: true, permissions };
80
+ }
81
+ function isRecord(value) {
82
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
83
+ }
84
+
33
85
  /**
34
86
  * 登录授权能力方法名。
35
87
  *
@@ -327,4 +379,4 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
327
379
  },
328
380
  ];
329
381
 
330
- export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_CURRENT_USER_DETAIL_METHOD, USER_GET_CURRENT_USER_PROFILE_METHOD, USER_GET_INFO_METHOD, USER_GET_PLATFORM_ACCOUNT_INFO_METHOD, USER_GET_PLATFORM_ACCOUNT_OVERVIEW_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isMiniProgramBridgeMessage };
382
+ export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_CURRENT_USER_DETAIL_METHOD, USER_GET_CURRENT_USER_PROFILE_METHOD, USER_GET_INFO_METHOD, USER_GET_PLATFORM_ACCOUNT_INFO_METHOD, USER_GET_PLATFORM_ACCOUNT_OVERVIEW_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, parseMiniProgramRuntimePermissions };
package/dist/vite.cjs.js CHANGED
@@ -7,7 +7,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
7
7
  /** 构建时替换为当前发布包的实际版本。 */
8
8
  const HB_SDK_VERSION = typeof undefined === 'string'
9
9
  ? undefined
10
- : '0.6.4-alpha.0';
10
+ : '0.6.4';
11
11
 
12
12
  var re = {exports: {}};
13
13
 
package/dist/vite.esm.js CHANGED
@@ -4,7 +4,7 @@ import path from 'node:path';
4
4
  /** 构建时替换为当前发布包的实际版本。 */
5
5
  const HB_SDK_VERSION = typeof undefined === 'string'
6
6
  ? undefined
7
- : '0.6.4-alpha.0';
7
+ : '0.6.4';
8
8
 
9
9
  var re = {exports: {}};
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.6.4-alpha.0",
3
+ "version": "0.6.4",
4
4
  "sideEffects": [
5
5
  "./src/index.ts",
6
6
  "./src/core/singleton.ts",
@@ -31,6 +31,13 @@ export {
31
31
  SDK_LOCATION_REPORT_METHOD,
32
32
  } from './protocol/constants';
33
33
  export { isMiniProgramBridgeMessage } from './protocol/guards';
34
+ export { isManagedMiniProgramRuntimePermissionKey, parseMiniProgramRuntimePermissions } from './protocol/runtime-permissions';
35
+ export type {
36
+ MiniProgramRuntimePermissionEntry,
37
+ MiniProgramRuntimePermissionStatus,
38
+ MiniProgramRuntimePermissionsSnapshot,
39
+ ParsedMiniProgramRuntimePermissions,
40
+ } from './protocol/runtime-permissions';
34
41
  export type {
35
42
  MiniProgramBridgeError,
36
43
  MiniProgramBridgeMessage,
@@ -139,11 +146,7 @@ export type {
139
146
  MiniProgramShareChannel,
140
147
  MiniProgramShowShareMenuOptions,
141
148
  } from './modules/share';
142
- export type {
143
- GetStoragePayload,
144
- GetStorageResult,
145
- SetStoragePayload,
146
- } from './modules/storage';
149
+ export type { GetStoragePayload, GetStorageResult, SetStoragePayload } from './modules/storage';
147
150
  export type {
148
151
  GetWindowInfoPayload,
149
152
  GetWindowInfoResult,
@@ -173,13 +176,7 @@ export type {
173
176
  ShowToastPayload,
174
177
  ShowToastResult,
175
178
  } from './modules/ui';
176
- export type {
177
- MiniProgramVibrateIntensity,
178
- SetClipboardPayload,
179
- SetClipboardResult,
180
- VibratePayload,
181
- VibrateResult,
182
- } from './modules/device';
179
+ export type { MiniProgramVibrateIntensity, SetClipboardPayload, SetClipboardResult, VibratePayload, VibrateResult } from './modules/device';
183
180
  export type {
184
181
  ClosePayload,
185
182
  CloseResult,
@@ -210,18 +207,22 @@ Reference 由 `@heybox/hb-sdk` 的公开导出与源码注释自动生成,不
210
207
 
211
208
  | 导出面 | 说明 |
212
209
  | --- | --- |
213
- | [Root API](api-root.md) | 来自 `src/index.ts` 的默认导出、命名导出与公开能力。 |
214
- | [Protocol API](#public-protocol-entrypoint) | 来自 `src/protocol.ts` 的协议常量、消息类型与 method 契约。 |
210
+ | [Root API](api-root.md) | `@heybox/hb-sdk` 的默认导出、命名导出与公开能力。 |
211
+ | [Protocol API](#public-protocol-entrypoint) | `@heybox/hb-sdk/protocol` 的协议常量、消息类型与 method 契约。 |
212
+ | [Miniapp Publish API](https://open.xiaoheihe.cn/docs/hb_sdk/reference/miniapp-publish/) | `@heybox/hb-sdk/miniapp-publish` 的构建产物发布前的公开校验工具。 |
213
+ | [Vite API](https://open.xiaoheihe.cn/docs/hb_sdk/reference/vite/) | `@heybox/hb-sdk/vite` 的Vite 工坊小程序插件。 |
215
214
 
216
215
  ## 查询建议
217
216
 
218
217
  - 想查业务接入路径:先看 [Guide](recipes.md)。
219
- - 想查导出符号:从 Root API 或 Protocol API 进入对应分类页。
218
+ - 想查导出符号:从上方对应公开入口进入分类页。
220
219
  - 想看场景化用法:优先看 Guide / Recipes 页面中的“进一步阅读”。
221
220
 
222
221
  ## 统计
223
222
 
224
223
  | 导出面 | Classes | Functions | Interfaces | Types | Constants |
225
224
  | --- | ---: | ---: | ---: | ---: | ---: |
226
- | Root API | 2 | 3 | 66 | 57 | 4 |
227
- | Protocol API | 0 | 1 | 43 | 68 | 35 |
225
+ | Root API | 2 | 3 | 66 | 57 | 0 |
226
+ | Protocol API | 0 | 3 | 43 | 67 | 32 |
227
+ | Miniapp Publish API | 0 | 5 | 2 | 0 | 0 |
228
+ | Vite API | 0 | 1 | 0 | 0 | 0 |
@@ -19,7 +19,7 @@
19
19
  ## Package metadata
20
20
 
21
21
  - Package: `@heybox/hb-sdk`
22
- - Version at generation time: `0.6.4-alpha.0`
22
+ - Version at generation time: `0.6.4`
23
23
  - Public root export: `@heybox/hb-sdk`
24
24
  - Protocol export: `@heybox/hb-sdk/protocol`
25
25
  - Vite plugin export: `@heybox/hb-sdk/vite`
@@ -450,9 +450,9 @@ SDK 需要在黑盒小程序 iframe 容器内运行。父容器会为页面注
450
450
  npm run dev
451
451
  ```
452
452
 
453
- 调试页会通过 iframe 加载本地页面并补齐小程序 bridge 环境。`hb-sdk dev` 的基础启动只依赖本地页面地址:即使项目未绑定、CLI 未登录或远端暂时不可用,浏览器 Mock、Mac 启动协议和手机二维码也会继续生成,真机 dev shell 以匿名本地沙箱加载 `mini_url`,不会把公开 `detail` 查询作为启动门禁。项目已绑定时会限时 3 秒读取远端 dev context;成功后 Mock Host 用真实 Runtime 权限快照初始化本地模拟,失败或超时则显示脱敏警告,并默认拒绝 `network.request` 等受管能力。
453
+ 调试页会通过 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。
454
454
 
455
- Mock Host 可以在内存中调整 devtools-only 权限模拟,不会重建 iframe,因此不影响 Vite HMR;本地设置不会修改线上权限。调试页会对比已读取的线上快照,提示本地放开但上线后会返回 `PERMISSION_DENIED` 的差异。权限快照只通过 mock host 的同源只读 bootstrap 接口传递,URL query 不能提供或覆盖权限。真实容器加载开发 `mini_url` 前会提示“即将打开未经验证的开发网页。该页面可能由本机或局域网服务提供,请确认来源可信后继续。”,用户确认后才继续加载。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP;遇到这种情况时,请在系统浏览器中打开同一个调试页后重试。
455
+ Mock Host 可以在内存中切换 devtools-only `network.request` 权限,不会重建 iframe,因此不影响 Vite HMR;官方域名权限只读取线上快照,本地设置不会修改线上权限。调试页会对比已读取的线上快照,提示本地放开但上线后会返回 `PERMISSION_DENIED` 的差异。权限快照只通过 mock host 的同源只读 bootstrap 接口传递,URL query 不能提供或覆盖权限。真实容器加载开发 `mini_url` 前会提示“即将打开未经验证的开发网页。该页面可能由本机或局域网服务提供,请确认来源可信后继续。”,用户确认后才继续加载。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP;遇到这种情况时,请在系统浏览器中打开同一个调试页后重试。
456
456
 
457
457
  在未使用脚手架的 Vite 项目中,可以把命令加到 `package.json`:
458
458
 
@@ -76,13 +76,13 @@ Top-level `hb-sdk deploy` has been hard-cut and must not be documented as a vali
76
76
  ## 创建外部小程序模板
77
77
 
78
78
  ```bash
79
- hb-sdk create my-miniapp
79
+ npx @heybox/hb-sdk create my-miniapp
80
80
  cd my-miniapp
81
81
  npm install
82
82
  npm run dev
83
83
  ```
84
84
 
85
- `hb-sdk create <project-name>` 会生成 Vue 3、Vite、TypeScript 和 npm 模板。`project-name` 同时作为目录名和 `package.json` `name`,必须是合法的非 scoped npm 包名。目标目录不存在时会创建;目标目录已存在但非空时会拒绝覆盖。
85
+ `hb-sdk create <target-path>` 会生成 Vue 3、Vite、TypeScript 和 npm 模板。参数可以是目录名、相对/绝对路径或 `.`;生成的 `package.json.name` 取解析后目标目录的 basename,并校验为合法的非 scoped npm 包名。目标目录不存在时会创建;目标目录已存在但非空时会拒绝覆盖。模板使用 Vite 8,需要 Node.js `^20.19.0` 或 `>=22.12.0`。
86
86
 
87
87
  CLI 只生成文件,不会自动安装依赖、初始化 git 或打开编辑器。生成模板后优先运行 `npm run dev`,它会启动 Vite 服务和内置 mock runtime host。
88
88
 
@@ -103,7 +103,7 @@ Agent rules:
103
103
  hb-sdk dev
104
104
  ```
105
105
 
106
- `hb-sdk dev` 会从当前目录向上查找最近的 `package.json`。Vite、内置 mock runtime host、Mac 启动协议和手机二维码的基础启动只依赖本地页面地址,不要求项目先绑定或 CLI 先登录。项目已绑定时,CLI 会限时 3 秒读取远端 dev context;成功后用真实 Runtime 权限快照初始化 Mock Host,失败或超时则输出脱敏警告并继续匿名调试,`network.request` 等受管能力默认拒绝。公开 `detail` 查询不再是 dev 启动门禁。本地 `package.json` 无法解析等配置错误不会被降级,命令会直接报错。调试页默认自动打开;需要真实黑盒小程序容器加载同一页面时,点击调试页里的「在 Mac 版 APP 中启动」按钮,或在「Mobile App」区域选择局域网网卡后用手机小黑盒 APP 扫码。
106
+ `hb-sdk dev` 会从当前目录向上查找最近的 `package.json`。Vite、内置 mock runtime host、Mac 启动协议和手机二维码的基础启动只依赖本地页面地址,不要求项目先绑定或 CLI 先登录。项目已绑定时,CLI 会限时 3 秒读取远端 dev context;成功后用真实 Runtime 权限快照初始化 Mock Host,失败或超时则输出脱敏警告并继续匿名调试,`network.request` 等受管能力默认拒绝。需要定位降级原因时可使用 `hb-sdk dev --verbose`;详细错误只写入本地调试日志,其中 URL 用户名、密码和敏感 query/hash 会被遮蔽,不会进入 LAN bootstrap。公开 `detail` 查询不再是 dev 启动门禁。本地 `package.json` 无法解析等配置错误不会被降级,命令会直接报错。调试页默认自动打开;需要真实黑盒小程序容器加载同一页面时,点击调试页里的「在 Mac 版 APP 中启动」按钮,或在「Mobile App」区域选择局域网网卡后用手机小黑盒 APP 扫码。
107
107
 
108
108
  常用参数:
109
109
 
@@ -120,7 +120,7 @@ hb-sdk dev
120
120
 
121
121
  不要为了本地调试再创建独立 mock runtime 包。CLI、模板和 mock host 都归属 `@heybox/hb-sdk`。
122
122
 
123
- 浏览器 Mock 的权限状态只存在于 Mock Host 内存中,URL query 不能提供或覆盖权限。远端 dev context 可用时,Mock Host 以线上快照作为初始值;不可用时匿名状态默认拒绝受管能力。开发者可以在调试页临时调整 `network.request` 和官方域名权限,变更只会重建 devtools-only mock runtime,不会重建 iframe 或中断 Vite HMR,也不会修改线上配置。调试页会对比线上快照并提示本地放开但上线后会返回 `PERMISSION_DENIED` 的差异。
123
+ 浏览器 Mock 的权限状态只存在于 Mock Host 内存中,URL query 不能提供或覆盖权限。远端 dev context 可用时,Mock Host 以线上快照作为初始值;不可用时匿名状态默认拒绝受管能力。开发者可以在调试页临时切换 `network.request` 权限;官方域名权限只读取线上快照,不能在 devtools 中手动调整。变更只会重建 devtools-only mock runtime,不会重建 iframe 或中断 Vite HMR,也不会修改线上配置。调试页会对比线上快照并提示本地放开但上线后会返回 `PERMISSION_DENIED` 的差异。
124
124
 
125
125
  本地 mock runtime 下已授权的 `network.request()` 会通过 `hb-sdk` 本地 mock network proxy 转发真实 HTTP(S) 请求,用于避免浏览器 CORS 影响本地调试。proxy 不会把黑盒客户端私有协议字段暴露给 iframe 业务代码。CLI 登录态和远端 dev context 也不会注入 iframe。
126
126
 
@@ -134,16 +134,13 @@ Use `hb-sdk dev` for local browser SDK debugging. Use the Mock runtime host's "
134
134
  hb-sdk remote deploy --release-note "修复登录状态展示,补充异常提示"
135
135
  hb-sdk remote deploy --release-note "审核通过后自动发布" --auto-publish
136
136
  hb-sdk remote deploy --from-version 1.2.3 --release-note "复用 1.2.3 历史产物"
137
- hb-sdk remote deploy --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "测试环境验证"
138
- hb-sdk remote deploy --verbose --api-base-url https://api.test.xiaoheihe.cn --login-base-url https://login.test.xiaoheihe.cn --release-note "排查预检失败"
139
- HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://127.0.0.1:8080 --release-note "本地后台联调"
140
137
  ```
141
138
 
142
139
  `hb-sdk remote deploy` 把预检、构建、上传和提交审核串成一条命令。顶层 `hb-sdk deploy` 已硬切删除,不再作为兼容别名保留:
143
140
 
144
141
  1. 读取 `package.json.heybox.miniProgramId`,缺失即报错。
145
142
  2. 校验登录态,需先 `hb-sdk login`。
146
- 3. 如果需要以公司的名义发布小程序,需先找 @秦浩东 申请小程序开发权限。
143
+ 3. 运行 `hb-sdk remote access` 确认当前主体具备开发者资格;未开通时按开放平台的小程序工坊申请入口提交申请。
147
144
  4. 读取并校验 `--release-note`;TTY 环境缺失时会提示输入,CI / 非 TTY 环境缺失时直接失败。建议让 AI 生成 1-5 条简短发布日志。
148
145
  5. 普通 remote deploy 先读取 `package.json.version`,登录后、build 前调用版本预检接口;预检通过后才执行 `<pm> run build`。
149
146
  6. `--from-version <version>` 跳过本地构建、`dist/` 读取和上传,复用指定历史版本产物提交审核。
@@ -151,8 +148,8 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
151
148
  8. 普通 remote deploy 的 `dist/manifest.json.version` 必须与预检使用的 `package.json.version` 一致,否则失败且不上传。
152
149
  9. 遍历 `dist/` 文件,过滤掉 `manifest.json`、`.DS_Store`、`*.map`;遇到 symbolic link 或 `node_modules` 路径直接报错。
153
150
  10. 校验上传路径长度不超过 64,并在任何上传请求发生前限制实际上传产物总大小不超过 100MiB。错误提示中使用 `100MB`,方便开发者理解。
154
- 11. 上传信息、上传凭证和上传回调按批次执行,每批最多 50 个文件;批次串行,批内保持 4 并发上传到 CDN。CLI 会校验 CDN 上传信息接口返回的 key 与本地期望 key 完全一致,异常时停止后续批次且不提交审核。
155
- 12. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会展示并发数、批次数、当前批次、bucket / region 和逐文件结果,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
151
+ 11. CLI 会分批上传构建产物并校验平台返回的文件集合;任何批次异常都会停止后续上传且不会提交审核。
152
+ 12. 默认只展示上传阶段和文件总数,例如 `正在上传 137/244 个文件`;`--verbose` 会补充逐文件诊断,但不会输出 keys、签名、cookie、pkey、token 或临时密钥。
156
153
  13. 全部上传成功后调用提交审核接口;`--from-version` 路径会直接提交 `source_version`。CLI 输出提交审核成功、发布策略和可用的 preview URL。
157
154
 
158
155
  `mini_program_id` 没有 CLI flag,必须落在 `package.json` 里:
@@ -167,30 +164,22 @@ HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1 hb-sdk remote deploy --api-base-url http://12
167
164
 
168
165
  `manifest.json` 仅作为提交审核接口的 `manifest` 字段提交,不会上传到 CDN。Vite 项目通过 `miniappManifest()` 插件生成;CLI 不会自动注入插件,请在 `vite.config.ts` 中显式挂载。小程序构建产物需要使用相对资源路径;`hb-sdk create` 模板会显式配置 `base: './'`,未配置 `base` 的项目也会由 `miniappManifest()` 在 build 时默认补成 `./`。构建产物只能在兼容的小黑盒 Runtime 中启动,普通浏览器直接打开时不会执行标准业务脚本。
169
166
 
170
- `dev`、手动 Vite build、`remote deploy` 的本地构建和 `--from-version` 路径都不执行客户端 `minimumSdkVersion` 查询或比较;Manifest 结构校验、版本 precheck 和服务端 submit-audit 策略仍然生效。
167
+ CLI 的 `dev` 启动、本地 Vite build、`remote deploy` 本地构建和 `--from-version` 路径都不主动查询或比较 `minimumSdkVersion`;Mac / Mobile dev shell 仍会在加载 iframe 前执行宿主侧兼容性与平台配置检查。Manifest 结构校验、版本 precheck 和服务端 submit-audit 策略仍然生效。
171
168
 
172
- 默认发布策略是 `auto_publish=false`:运营审核通过后使用 `hb-sdk remote versions` 查看版本状态,再用 `hb-sdk remote release <version>` 发布。需要审核通过后自动发布并下架旧线上版本时,使用 `--auto-publish`。如需让指定用户预览未发布候选版本,使用 `hb-sdk remote allowlist add <heybox_id>` 管理预览白名单。
169
+ 默认发布策略是 `auto_publish=false`:运营审核通过后使用 `hb-sdk remote versions` 查看版本状态,再用 `hb-sdk remote release <version>` 发布。`--auto-publish` 只适用于普通低风险版本;重大功能、活动联动、商业化、用户数据、外部账号绑定或风控策略变更应保持手动发布。需要指定用户预览未发布候选版本时,使用 `hb-sdk remote allowlist add <heybox_id>` 管理预览白名单。
173
170
 
174
- 内部测试或预发环境可通过 `HB_SDK_API_BASE_URL` / `HB_SDK_LOGIN_BASE_URL` 设置默认后台环境,也可以用 `--api-base-url` / `--login-base-url` 覆盖单次命令。自定义地址只接受 origin,不允许包含 path、query hash;API origin 默认还必须是 Heybox 受信 HTTPS 域名,只有本地联调等场景可显式使用 `--allow-unsafe-api-base-url` `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` 放开。`apiBaseUrl` 影响 `hb-sdk remote` 里的远端平台后台 API,包括预检、CDN 上传凭证/回调、提交审核、版本、发布、撤回、下架、重新上架、详情和白名单等调用;`loginBaseUrl` 用于 `hb-sdk login` 的登录入口,以及 remote 命令前校验当前 CLI 登录态是否属于同一个登录环境。开发环境如需给后台请求带 `x-rylai-service-tag` 和 `special_tag`,优先用 `--service-tag <tag>` `HB_SDK_SERVICE_TAG`。path-prefix `special_tag` 仍可在 `packages/hb-sdk/src/cli/config.ts` 里按 `@heybox/hb-types` 的 `RylaiServiceTagConfig` 配置。日志只输出 origin,不输出带身份和签名参数的完整请求 URL。
175
-
176
- `hb-sdk doctor`、npm latest 检查、mock host 的 `network.request()` 不受这些配置影响。
177
-
178
- 切换测试环境时往往需要同时配置后台 host、登录 host 和 service tag。CLI 支持加载 `.env.<name>` 预设,把其中的 `HB_SDK_*` 变量一次性注入当前进程(不覆盖已有值):`--env <name>` 读取项目根下的 `.env.<name>`,`--env-file <path>` 显式指定路径且优先级更高,也可用 `HB_SDK_ENV=<name>` 触发。使用 `--env <name>` 或 `HB_SDK_ENV=<name>` 执行 `remote deploy` 时,CLI 还会把同一个 `name` 作为 `--mode <name>` 传给项目 build,使 CLI 后端环境与 Vite mode 保持一致。文件仅支持 `KEY=VALUE`、空行和 `#` 注释,不做变量插值;文件不存在时静默跳过。
171
+ 需要给构建选择 Vite mode 时,可以使用 `--env <name>` 或 `HB_SDK_ENV=<name>`。CLI 会从当前目录向上找到项目根,读取 `.env.<name>`,把其中所有合法 key 注入当前进程和后续 build(不覆盖已有值),并将同一个 `name` 作为 `--mode <name>` 传给项目 build。`--env-file <path>` 可以相对调用目录指定其他预设文件,且优先级高于 `--env`。文件仅支持 `KEY=VALUE`、空行和 `#` 注释,不做变量插值;文件不存在时静默跳过,其他读取错误会直接失败。
179
172
 
180
173
  ```bash
181
- # 项目根准备 .env.test
182
- # HB_SDK_API_BASE_URL=https://api.test.xiaoheihe.cn
183
- # HB_SDK_LOGIN_BASE_URL=https://login.test.xiaoheihe.cn
184
- # HB_SDK_SERVICE_TAG=my-test-tag
185
-
186
- hb-sdk remote deploy --env test --release-note "测试环境验证"
187
- hb-sdk remote info --env test
188
- HB_SDK_ENV=test hb-sdk remote versions
189
- hb-sdk remote deploy --env-file .env.local --release-note "本地联调"
190
- hb-sdk remote deploy --env test --service-tag other-tag --release-note "灰度" # 单项 flag 覆盖预设
174
+ # 项目根准备 .env.preview
175
+ # VITE_API_ORIGIN=https://api.example.com
176
+
177
+ hb-sdk remote deploy --env preview --release-note "预览模式构建"
178
+ HB_SDK_ENV=preview hb-sdk remote deploy --release-note "预览模式构建"
179
+ hb-sdk remote deploy --env-file .env.local --release-note "本地配置构建"
191
180
  ```
192
181
 
193
- `--env-file` 优先于 `--env`,`--service-tag` / `--api-base-url` / `--login-base-url` 优先于 `.env` 预设注入的同名变量,而预设又不会覆盖进程已有的环境变量,因此优先级为 flag > 进程 env > `.env` 预设 > 默认值。
182
+ 预设不会覆盖进程已有的同名环境变量,因此优先级为进程 env > `.env` 预设 > 默认值。
194
183
 
195
184
  Before precheck, build, upload, or submit audit, `hb-sdk remote deploy` must verify that the current project's bound mini-program belongs to the server-side current entity. If `detail.entity_id` differs from the current entity, the command fails with both entity ids/names and suggests `hb-sdk remote entity switch <entity-id>`. It must not auto-switch entities and must not continue into precheck/build/upload/submit on mismatch.
196
185
 
@@ -241,6 +230,9 @@ Agent rules:
241
230
 
242
231
  ```bash
243
232
  hb-sdk remote access
233
+ hb-sdk remote entity list
234
+ hb-sdk remote entity current
235
+ hb-sdk remote entity switch <entity-id>
244
236
  hb-sdk remote list
245
237
  hb-sdk remote create
246
238
  hb-sdk remote bind mp_xxxxxxxx
@@ -262,9 +254,9 @@ hb-sdk remote square show
262
254
 
263
255
  `hb-sdk remote square hide` 会隐藏当前绑定小程序在普通用户侧的小程序工坊广场展示;白名单用户仍可在小程序工坊广场看到,直接链接访问已发布版本也不受影响。`hb-sdk remote square show` 会恢复普通用户侧的小程序工坊广场展示。
264
256
 
265
- `hb-sdk remote release`、`hb-sdk remote withdraw`、`hb-sdk remote take-down`、`hb-sdk remote reopen` 和 `hb-sdk remote square hide` 会改变审核、发布或用户侧可见状态。交互式终端会展示小程序 id、名称、当前状态、目标版本和操作,再要求确认;非 TTY 环境必须传 `--yes`。
257
+ `hb-sdk remote release`、`withdraw`、`take-down`、`reopen` 和 `square hide` 会改变审核、发布或用户侧可见状态。交互式终端会展示目标和变更内容后要求确认;非 TTY 环境必须传 `--yes`。`entity switch`、`square show` 和 allowlist 写操作当前不会进行这层 CLI 确认,自动化脚本不要为它们假设存在确认保护。
266
258
 
267
- 所有 `hb-sdk remote` 子命令都支持 `--json`。开启后 stdout 只输出一个 JSON 对象;进度、警告、版本提醒和 verbose 诊断不能污染 stdout
259
+ 所有 `hb-sdk remote` 子命令都支持 `--json`。开启后 stdout 只输出一个 JSON 对象;进度、警告、版本提醒和 verbose 诊断不能污染 stdout。`remote deploy --json` 不进行交互式 release note 提示,必须显式传 `--release-note`。
268
260
 
269
261
  Agent rules:
270
262
 
@@ -285,13 +277,12 @@ Agent rules:
285
277
 
286
278
  ```bash
287
279
  hb-sdk login
288
- hb-sdk login --login-base-url https://login.test.xiaoheihe.cn
289
280
  hb-sdk login status
290
281
  hb-sdk login clear
291
282
  ```
292
283
 
293
284
  - `hb-sdk login` 会打开 `login.xiaoheihe.cn`,通过本地临时回调服务接收登录结果。
294
- - `hb-sdk login --login-base-url <url>` 会打开指定登录 origin,并把该登录环境写入 CLI 登录态。
285
+ - 登录成功后默认还会查询开发者主体;`--no-select-entity` 会跳过登录后的主体选择。
295
286
  - `hb-sdk login status` 默认展示脱敏状态、`heyboxId`、`loginBaseUrl` 和登录时间;`--verbose` 额外展示 cache 路径。不输出 `pkey`、cookie 或完整请求头。
296
287
  - `hb-sdk login clear` 只清理 `hb-sdk` 自己命名空间中的 Heybox 登录态。
297
288
 
@@ -46,9 +46,10 @@ bootstrap()
46
46
 
47
47
  ## 推荐业务写法
48
48
 
49
- 业务页通常还需要监听登录态变化:
49
+ 业务页通常还需要监听登录态变化。下面以 Vue 3 为例:初始化只读取状态,登录必须由按钮等明确的用户操作触发,监听在组件卸载时清理。
50
50
 
51
51
  ```ts
52
+ import { onUnmounted } from 'vue'
52
53
  import hbSDK from '@heybox/hb-sdk'
53
54
 
54
55
  const stopAuthChange = hbSDK.on('authChange', result => {
@@ -59,15 +60,22 @@ const stopAuthChange = hbSDK.on('authChange', result => {
59
60
 
60
61
  await hbSDK.ready()
61
62
 
62
- const result = await hbSDK.user.getInfo()
63
- if (!result.isLogin) {
64
- await hbSDK.auth.login()
63
+ const initialUser = await hbSDK.user.getInfo()
64
+
65
+ async function loginFromUserAction() {
66
+ const result = await hbSDK.auth.login()
67
+ if (!result.isLogin || !result.userInfo) {
68
+ return
69
+ }
70
+
71
+ console.log('用户已登录', result.userInfo.heybox_id)
65
72
  }
66
73
 
67
- // 页面卸载时清理监听
68
- stopAuthChange()
74
+ onUnmounted(stopAuthChange)
69
75
  ```
70
76
 
77
+ 把 `loginFromUserAction` 绑定到登录按钮;不要在页面 bootstrap 阶段自动调用 `auth.login()`。
78
+
71
79
  ## ready 的含义
72
80
 
73
81
  `ready()` 表示 SDK 已完成与父容器的握手,可以安全调用开放能力。SDK 在收到 `ready` 前会自动重试握手;如果超过总超时时间仍未成功,会抛出 `READY_TIMEOUT`。它不等价于“用户已登录”,用户状态需要通过 `user.getInfo()` 或 `authChange` 判断。
@@ -87,6 +95,10 @@ stopAuthChange()
87
95
 
88
96
  - `user.getInfo()`:静默读取当前登录态与公开基础资料。
89
97
  - `auth.login()`:唤起黑盒登录流程,并返回登录后的最新公开用户资料。
98
+ - `user.getCurrentUserDetail()`:读取当前用户展示详情。
99
+ - `user.getCurrentUserProfile()`:读取当前用户敏感资料,需要对应 Runtime 权限。
100
+ - `user.getPlatformAccountOverview()` / `getPlatformAccountInfo()`:读取平台账号概览或指定平台详情。
101
+ - `user.getSteamGameList()`:读取当前用户 Steam 游戏库。
90
102
 
91
103
  ## 静默读取用户信息
92
104
 
@@ -123,9 +135,9 @@ async function ensureLogin() {
123
135
  }
124
136
  ```
125
137
 
126
- ## 暴露字段
138
+ ## 基础资料与扩展资料
127
139
 
128
- SDK 只暴露允许给外部小程序读取的公开字段:
140
+ `user.getInfo()` 和 `auth.login()` 的 `userInfo` 只包含三项公开基础字段:
129
141
 
130
142
  | 字段 | 类型 | 说明 |
131
143
  | ----------- | -------- | ------------ |
@@ -135,18 +147,35 @@ SDK 只暴露允许给外部小程序读取的公开字段:
135
147
 
136
148
  不会暴露 token、cookie、手机号或任何可用于调用主站私有接口的凭据。
137
149
 
150
+ current-user scoped API 返回独立的 `UserScopedResult<T>`。未登录时是 `{ isLogin: false, data: null }`;已登录时才有 `data`。其中 `getCurrentUserProfile()` 可能返回生日、邮箱、教育和职业等敏感资料,必须按最小必要原则使用,并以 Runtime 权限结果为准;不要把这些字段理解为 `getInfo()` 的默认返回值。
151
+
152
+ ```ts
153
+ const profile = await user.getCurrentUserProfile()
154
+ if (profile.isLogin) {
155
+ console.log(profile.data.email)
156
+ }
157
+
158
+ const platforms = await user.getPlatformAccountOverview()
159
+ if (platforms.isLogin) {
160
+ console.log(platforms.data)
161
+ }
162
+ ```
163
+
138
164
  ## 监听登录态变化
139
165
 
140
166
  如果页面上同时存在登录按钮、权限态 UI 和业务数据,建议监听 `authChange`。
141
167
 
142
168
  ```ts
169
+ import { onUnmounted } from 'vue'
143
170
  import { on } from '@heybox/hb-sdk'
144
171
 
145
- const stop = on('authChange', result => {
172
+ const stopAuthChange = on('authChange', result => {
146
173
  if (result.isLogin) {
147
174
  console.log('登录态更新', result.userInfo?.heybox_id)
148
175
  }
149
176
  })
177
+
178
+ onUnmounted(stopAuthChange)
150
179
  ```
151
180
 
152
181
  ## Lifecycle events
@@ -157,28 +186,28 @@ const stop = on('authChange', result => {
157
186
  SDK 通过 `on` 监听父容器派发的小程序生命周期和业务事件。
158
187
 
159
188
  ```ts
160
- import { on, off } from '@heybox/hb-sdk'
189
+ import { onUnmounted } from 'vue'
190
+ import { on } from '@heybox/hb-sdk'
161
191
 
162
192
  function handleShow(payload: { timestamp: number; source?: string }) {
163
193
  console.log('show from', payload.source)
164
194
  }
165
195
 
166
- on('show', handleShow)
167
- off('show', handleShow)
168
- ```
169
-
170
- `on` 也会返回取消监听函数,推荐在组件卸载时调用:
171
-
172
- ```ts
173
- import { on } from '@heybox/hb-sdk'
174
-
175
- const stop = on('hide', () => {
196
+ const stopShow = on('show', handleShow)
197
+ const stopHide = on('hide', () => {
176
198
  console.log('小程序页面隐藏')
177
199
  })
178
200
 
179
- stop()
201
+ function stopLifecycleEvents() {
202
+ stopShow()
203
+ stopHide()
204
+ }
205
+
206
+ onUnmounted(stopLifecycleEvents)
180
207
  ```
181
208
 
209
+ 框架外也可以保存 `on()` 返回的取消函数,在页面或业务模块真正销毁时调用。需要按 handler 精确移除时再使用 `off(event, handler)`;不要在注册后的同一执行流里立即取消。
210
+
182
211
  ## 事件列表
183
212
 
184
213
  | 事件 | 触发时机 | 典型用途 |
@@ -187,7 +216,7 @@ stop()
187
216
  | `ready` | SDK 可安全调用开放能力 | 标记 bridge 可用 |
188
217
  | `show` | 小程序页面展示 | 刷新可见态数据 |
189
218
  | `hide` | 小程序页面隐藏 | 暂停轮询、暂停播放 |
190
- | `unload` | 小程序页面即将卸载 | 清理资源 |
219
+ | `unload` | 当前 Runtime 上下文终止 | 清理资源并停止请求 |
191
220
  | `error` | 父容器或开放能力运行异常 | 统一错误上报 |
192
221
  | `authChange` | 登录状态变化 | 刷新用户信息和权限 |
193
222
 
@@ -202,23 +231,37 @@ stop()
202
231
  - UI 可见性相关逻辑放在 `show`、`hide`。
203
232
  - 用户状态不要只在页面加载时读一次,登录入口附近要监听 `authChange`。
204
233
  - 组件或页面销毁时清理 `on` 注册的监听,避免重复响应。
234
+ - 事件只派发给注册当时存在的监听器,不会重放;一次性 `launch`/`ready` 状态应以 `ready()` Promise 为准。
235
+ - 收到 `unload` 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
205
236
 
206
237
  ## Error handling
207
238
 
208
239
 
209
240
  # 错误处理
210
241
 
211
- SDK 对外抛出的标准错误类型是 `HbMiniProgramSDKError`。
242
+ SDK 公开两类标准错误:`HbMiniProgramSDKError` 表示 handshake、bridge、Runtime 或 capability 故障;`HbMiniProgramNetworkError` 表示 HTTP 已完成,但状态没有通过 `validateStatus`。
212
243
 
213
244
  ```ts
214
- import { HbMiniProgramSDKError, ready } from '@heybox/hb-sdk'
245
+ import {
246
+ HbMiniProgramNetworkError,
247
+ HbMiniProgramSDKError,
248
+ network,
249
+ } from '@heybox/hb-sdk'
215
250
 
216
251
  try {
217
- await ready()
252
+ await network.request({ url: 'https://api.example.com/data' })
218
253
  } catch (error) {
254
+ if (error instanceof HbMiniProgramNetworkError) {
255
+ console.log(error.status, error.data, error.headers)
256
+ return
257
+ }
258
+
219
259
  if (error instanceof HbMiniProgramSDKError) {
220
260
  console.log(error.code, error.message, error.data)
261
+ return
221
262
  }
263
+
264
+ throw error
222
265
  }
223
266
  ```
224
267
 
@@ -229,8 +272,10 @@ try {
229
272
  | `NOT_IN_IFRAME` | 当前页面不在小程序沙盒 iframe 中 | 提示运行环境错误,检查父容器接入 |
230
273
  | `MISSING_NONCE` | URL 中缺少 `hb_mini_bridge_nonce` | 检查父容器 URL 注入逻辑 |
231
274
  | `READY_TIMEOUT` | SDK 握手超时 | 检查父容器是否幂等响应重试的 `sdk.handshake` |
275
+ | `HANDSHAKE_FAILED` | 握手消息发送失败 | 检查 iframe、nonce 与 Host 消息通道 |
276
+ | `RUNTIME_UNAVAILABLE` | Runtime 已执行 `unload` | 停止当前上下文请求并结束页面工作 |
232
277
  | `REQUEST_TIMEOUT` | 开放能力调用超时 | 提示重试,并上报 method |
233
- | `SDK_DESTROYED` | SDK 已销毁但仍有请求未完成 | 检查销毁时机和并发请求 |
278
+ | `INVALID_NETWORK_RESPONSE` | Host 返回的网络响应结构无效 | 上报 Host/Runtime 协议问题 |
234
279
 
235
280
  父容器返回失败响应时,SDK 也会包装成 `HbMiniProgramSDKError`,此时 `code` 由父容器开放能力定义。
236
281
 
@@ -239,14 +284,18 @@ try {
239
284
  ```ts
240
285
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
241
286
 
242
- async function loadUser() {
287
+ type UserViewState =
288
+ | { status: 'ready'; user: Awaited<ReturnType<typeof hbSDK.user.getInfo>> }
289
+ | { status: 'failed'; error: HbMiniProgramSDKError }
290
+
291
+ async function loadUser(): Promise<UserViewState> {
243
292
  try {
244
293
  await hbSDK.ready()
245
- return await hbSDK.user.getInfo()
294
+ return { status: 'ready', user: await hbSDK.user.getInfo() }
246
295
  } catch (error) {
247
296
  if (error instanceof HbMiniProgramSDKError) {
248
297
  reportSDKError(error.code, error.message, error.data)
249
- return { isLogin: false, userInfo: null }
298
+ return { status: 'failed', error }
250
299
  }
251
300
 
252
301
  throw error
@@ -100,6 +100,8 @@ function rewriteBundledProtocolIndexLinks(markdown) {
100
100
  return markdown
101
101
  .replaceAll('(./root/)', '(api-root.md)')
102
102
  .replaceAll('(./protocol/)', '(#public-protocol-entrypoint)')
103
+ .replaceAll('(./miniapp-publish/)', '(https://open.xiaoheihe.cn/docs/hb_sdk/reference/miniapp-publish/)')
104
+ .replaceAll('(./vite/)', '(https://open.xiaoheihe.cn/docs/hb_sdk/reference/vite/)')
103
105
  .replaceAll('(../guide/)', '(recipes.md)');
104
106
  }
105
107