@heybox/hb-sdk 0.2.0-alpha.0 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -452
- package/bin/hb-sdk.cjs +1 -1
- package/dist/cli.cjs +71660 -3903
- package/dist/devtools/mock-host/index.html +13 -387
- package/dist/devtools/mock-host/main.js +975 -0
- package/dist/index.cjs.js +50 -63
- package/dist/index.esm.js +51 -50
- package/dist/miniapp-publish.cjs.js +77 -0
- package/dist/miniapp-publish.esm.js +66 -0
- package/dist/protocol.cjs.js +72 -13
- package/dist/protocol.esm.js +72 -14
- package/dist/templates/vue3-vite-ts/README.md.ejs +1 -5
- package/dist/templates/vue3-vite-ts/package.json.ejs +0 -1
- package/dist/templates/vue3-vite-ts/vite.config.ts +2 -1
- package/dist/vite.cjs.js +62 -0
- package/dist/vite.esm.js +60 -0
- package/package.json +30 -1
- package/skill/SKILL.md +106 -0
- package/skill/references/api-protocol.md +135 -0
- package/skill/references/api-root.md +474 -0
- package/skill/references/cli.md +376 -0
- package/skill/references/examples.md +119 -0
- package/skill/references/llms-index.md +44 -0
- package/skill/references/recipes.md +374 -0
- package/skill/references/safety-boundaries.md +30 -0
- package/skill/references/smoke-evaluation.md +24 -0
- package/skill/scripts/check-references.mjs +14 -0
- package/skill/scripts/package-skill.mjs +60 -0
- package/skill/scripts/package-skill.sh +6 -0
- package/skill/scripts/skill-metadata.mjs +74 -0
- package/skill/scripts/sync-references.mjs +565 -0
- package/skill/scripts/validate-skill.mjs +235 -0
- package/skill/skill.json +11 -0
- package/types/index.d.ts +8 -6
- package/types/miniapp-publish/index.d.ts +23 -0
- package/types/modules/auth/index.d.ts +2 -9
- package/types/modules/network/index.d.ts +6 -11
- package/types/modules/share/index.d.ts +3 -9
- package/types/modules/share/screenshot.d.ts +1 -7
- package/types/modules/share/show-share-menu.d.ts +1 -7
- package/types/modules/storage/index.d.ts +2 -16
- package/types/modules/user/get-info.d.ts +1 -7
- package/types/modules/user/index.d.ts +2 -8
- package/types/modules/viewport/index.d.ts +2 -9
- package/types/protocol/capabilities.d.ts +180 -0
- package/types/protocol.d.ts +8 -13
- package/types/vite/index.d.ts +17 -0
package/README.md
CHANGED
|
@@ -1,596 +1,337 @@
|
|
|
1
1
|
# @heybox/hb-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
黑盒外部小程序前端 SDK。业务页面运行在黑盒父容器创建的 iframe 沙盒中,通过这个 SDK 等待容器 ready、获取登录态、唤起登录、分享、读取窗口信息、使用隔离 storage,以及发起受控网络请求。
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
外部小程序运行在父容器创建的 iframe 沙盒中,业务页面不能直接读取主站登录态,也不应该关心底层 `postMessage` 协议、nonce 校验、请求响应关联、超时清理、客户端协议参数过滤等细节。
|
|
8
|
-
|
|
9
|
-
`@heybox/hb-sdk` 将这些通信细节封装为稳定接口,让小程序只通过被允许的能力访问父容器。父容器仍负责调用黑盒客户端协议,并在运行时过滤不适合开放给外部小程序的内部参数。网络请求能力同样遵循这个边界:SDK 提供 axios-like 的窄接口,运行时负责协议映射。
|
|
5
|
+
## 快速开始
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
创建一个新的外部小程序项目:
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npx @heybox/hb-sdk create my-miniapp
|
|
11
|
+
cd my-miniapp
|
|
12
|
+
npm install
|
|
13
|
+
npm run dev
|
|
14
|
+
```
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
- 命名导出 `ready` / `on` / `off` / `auth` / `user` / `share` / `viewport` / `storage` / `network`:默认 SDK 单例能力。
|
|
17
|
-
- `createMiniProgramSDK` / `MiniProgramSDK`:创建独立 SDK 实例,适合测试、多实例或显式生命周期管理场景。
|
|
18
|
-
- `HbMiniProgramSDKError`:bridge / 运行时 / 协议失败时的标准错误类型。
|
|
19
|
-
- `HbMiniProgramNetworkError`:HTTP 已完成但未通过 SDK `validateStatus` 校验时的网络错误类型。
|
|
20
|
-
- `MiniProgramRequester` / `MiniProgramSDKOptions`:底层请求与 SDK 初始化配置类型。
|
|
21
|
-
- bridge 协议常量、类型与守卫:根入口保留导出;运行时等宿主侧包应优先从 `@heybox/hb-sdk/protocol` 子入口导入,避免误依赖 SDK core / singleton。
|
|
22
|
-
- 模块类型与方法常量:`MiniProgramAuthModule`、`MiniProgramUserModule`、`MiniProgramShareModule`、`MiniProgramViewportModule`、`MiniProgramStorageModule`、`MiniProgramNetworkModule` 以及各模块 method 常量。
|
|
16
|
+
模板默认使用 Vue 3、Vite、TypeScript 和 npm。`npm run dev` 会启动小程序页面服务,并打开 `hb-sdk` 内置的浏览器 mock 宿主环境,适合在普通浏览器里调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面。
|
|
23
17
|
|
|
24
|
-
|
|
18
|
+
在已有项目中安装:
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
```bash
|
|
21
|
+
npm install @heybox/hb-sdk
|
|
22
|
+
```
|
|
27
23
|
|
|
28
|
-
|
|
24
|
+
然后在页面入口等待父容器 ready:
|
|
29
25
|
|
|
30
26
|
```ts
|
|
31
27
|
import hbSDK from '@heybox/hb-sdk';
|
|
32
28
|
|
|
33
29
|
await hbSDK.ready();
|
|
34
30
|
|
|
35
|
-
const
|
|
31
|
+
const user = await hbSDK.user.getInfo();
|
|
36
32
|
|
|
37
|
-
if (
|
|
38
|
-
console.log(
|
|
33
|
+
if (user.isLogin) {
|
|
34
|
+
console.log(user.userInfo.nickname);
|
|
39
35
|
}
|
|
40
36
|
```
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
也可以按需导入:
|
|
43
39
|
|
|
44
40
|
```ts
|
|
45
|
-
import {
|
|
46
|
-
|
|
47
|
-
const unsubscribe = on('show', (payload) => {
|
|
48
|
-
console.log('小程序展示', payload.timestamp, payload.source);
|
|
49
|
-
});
|
|
41
|
+
import { auth, ready, user } from '@heybox/hb-sdk';
|
|
50
42
|
|
|
51
43
|
await ready();
|
|
52
44
|
|
|
53
45
|
const currentUser = await user.getInfo();
|
|
54
46
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
分享、storage 与 network:
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
import { network, share, storage } from '@heybox/hb-sdk';
|
|
62
|
-
|
|
63
|
-
const response = await network.request<{ ok: boolean }>({
|
|
64
|
-
url: 'https://api.example.com/demo',
|
|
65
|
-
method: 'GET',
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
console.log(response.status, response.data.ok);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
await share.showShareMenu({
|
|
72
|
-
title: '分享标题',
|
|
73
|
-
desc: '分享描述',
|
|
74
|
-
url: 'https://web.xiaoheihe.cn/tools/demo',
|
|
75
|
-
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
await storage.setStorage({
|
|
79
|
-
key: 'settings',
|
|
80
|
-
data: {
|
|
81
|
-
theme: 'dark',
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
const { data } = await storage.getStorage<{ theme: string }>({
|
|
86
|
-
key: 'settings',
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
网络请求默认只把 `2xx` 视为成功;`4xx/5xx` 这类已完成 HTTP 响应会在 SDK 模块层抛出 `HbMiniProgramNetworkError`,而 bridge / 运行时 / 协议失败仍然抛出 `HbMiniProgramSDKError`。`validateStatus` 仅在 SDK 本地执行,不会把函数值透传给父容器。
|
|
91
|
-
|
|
92
|
-
## 核心概念
|
|
93
|
-
|
|
94
|
-
### 默认单例
|
|
95
|
-
|
|
96
|
-
普通小程序页面优先使用默认导出的 `hbSDK`,或直接按需导入 `ready`、`on`、`off`、`auth`、`user`、`share`、`viewport`、`storage`。默认单例会在首次调用时懒创建,业务不需要手动初始化。
|
|
97
|
-
|
|
98
|
-
```ts
|
|
99
|
-
import { ready, viewport } from '@heybox/hb-sdk';
|
|
100
|
-
|
|
101
|
-
await ready();
|
|
102
|
-
const windowInfo = await viewport.getWindowInfo();
|
|
47
|
+
if (!currentUser.isLogin) {
|
|
48
|
+
await auth.login();
|
|
49
|
+
}
|
|
103
50
|
```
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
需要显式控制生命周期、注入测试环境 window、调整超时时间,或同页存在多套沙盒通信上下文时,可以使用 `createMiniProgramSDK`。
|
|
52
|
+
## 运行环境
|
|
108
53
|
|
|
109
|
-
|
|
110
|
-
import { createMiniProgramSDK } from '@heybox/hb-sdk';
|
|
111
|
-
|
|
112
|
-
const sdk = createMiniProgramSDK({
|
|
113
|
-
timeout: 5000,
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
await sdk.ready();
|
|
54
|
+
SDK 需要在黑盒小程序 iframe 容器内运行。父容器会为页面注入 bridge nonce,并通过 `postMessage` 与 SDK 通信。普通浏览器直接打开小程序页面时通常无法完成握手;本地开发请优先使用:
|
|
117
55
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
sdk.destroy();
|
|
56
|
+
```bash
|
|
57
|
+
npm run dev
|
|
121
58
|
```
|
|
122
59
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
SDK 与父容器之间通过 `postMessage` 通信,消息会带上固定命名空间、协议版本与 iframe 实例 nonce。SDK 内部负责:
|
|
60
|
+
调试页会通过 iframe 加载本地页面并补齐小程序 bridge 环境;如果需要真实黑盒小程序容器加载同一页面,点击调试页里的「在 Mac 版 APP 中启动」按钮。
|
|
126
61
|
|
|
127
|
-
|
|
128
|
-
- 支持通过 `MiniProgramSDKOptions.targetOrigin` 显式指定发往父容器的 `postMessage targetOrigin`;未传时会尝试推断父容器 origin,失败则兼容回退为 `*`。
|
|
129
|
-
- 向父容器发送 `sdk.handshake` 握手消息;如果还没有收到 `ready` 事件,会在总超时窗口内短间隔重试。
|
|
130
|
-
- 为每次能力调用生成请求 ID,匹配父容器返回的 response。
|
|
131
|
-
- 过滤非小程序消息、非当前 nonce 消息以及非目标父窗口消息。
|
|
132
|
-
- 处理请求超时、握手总超时和销毁后的未完成请求。
|
|
62
|
+
在未使用脚手架的 Vite 项目中,可以把命令加到 `package.json`:
|
|
133
63
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
请求失败和 SDK 内部错误会统一包装为 `HbMiniProgramSDKError`,包含稳定的 `code`、面向开发者的 `message` 和可选 `data`。
|
|
139
|
-
|
|
140
|
-
```ts
|
|
141
|
-
import { HbMiniProgramSDKError, auth } from '@heybox/hb-sdk';
|
|
142
|
-
|
|
143
|
-
try {
|
|
144
|
-
await auth.login();
|
|
145
|
-
} catch (error) {
|
|
146
|
-
if (error instanceof HbMiniProgramSDKError) {
|
|
147
|
-
console.log(error.code, error.message, error.data);
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"scripts": {
|
|
67
|
+
"dev": "hb-sdk dev"
|
|
148
68
|
}
|
|
149
69
|
}
|
|
150
70
|
```
|
|
151
71
|
|
|
152
|
-
##
|
|
153
|
-
|
|
154
|
-
### Core
|
|
155
|
-
|
|
156
|
-
核心模块位于 `src/core`,负责 SDK 实例、默认单例、bridge client、事件总线、错误和工具函数。
|
|
72
|
+
## 常用能力
|
|
157
73
|
|
|
158
|
-
|
|
159
|
-
| --- | --- | --- |
|
|
160
|
-
| `core/sdk` | SDK 实例封装 | `MiniProgramSDK`、`createMiniProgramSDK` |
|
|
161
|
-
| `core/singleton` | 默认单例入口 | `ready`、`on`、`off`、`auth`、`user`、`share`、`viewport`、`storage` |
|
|
162
|
-
| `core/client` | bridge 握手、请求响应、事件分发 | `MiniProgramSDKOptions`、`MiniProgramRequester` |
|
|
163
|
-
| `core/errors` | 标准错误类型 | `HbMiniProgramSDKError` |
|
|
74
|
+
### 用户与登录
|
|
164
75
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
授权模块位于 `src/modules/auth`,承载登录授权类能力。
|
|
168
|
-
|
|
169
|
-
| API | 对应父容器能力 | 说明 |
|
|
170
|
-
| --- | --- | --- |
|
|
171
|
-
| `auth.login()` | `auth.login` | 唤起黑盒登录流程,并返回登录后的最新用户公开资料。 |
|
|
172
|
-
|
|
173
|
-
### User
|
|
174
|
-
|
|
175
|
-
用户模块位于 `src/modules/user`,只暴露允许小程序访问的公开用户资料能力。
|
|
176
|
-
|
|
177
|
-
| API | 说明 |
|
|
178
|
-
| --- | --- |
|
|
179
|
-
| `user.getInfo()` | 获取当前用户登录态与公开基础资料。未登录时不会触发登录流程。 |
|
|
180
|
-
|
|
181
|
-
用户信息只包含允许暴露给外部小程序的公开字段:
|
|
76
|
+
`user.getInfo()` 只读取当前登录态,不会主动唤起登录。需要用户操作时再调用 `auth.login()`。
|
|
182
77
|
|
|
183
78
|
```ts
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
avatar: string;
|
|
188
|
-
}
|
|
79
|
+
import { auth, user } from '@heybox/hb-sdk';
|
|
80
|
+
|
|
81
|
+
const result = await user.getInfo();
|
|
189
82
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
userInfo
|
|
83
|
+
if (!result.isLogin) {
|
|
84
|
+
const loginResult = await auth.login();
|
|
85
|
+
console.log(loginResult.userInfo);
|
|
193
86
|
}
|
|
194
87
|
```
|
|
195
88
|
|
|
196
|
-
SDK
|
|
197
|
-
|
|
198
|
-
### Network
|
|
89
|
+
SDK 只返回允许暴露给外部小程序的公开资料,不会返回 token、cookie、手机号或其他私有凭据。
|
|
199
90
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
| API | 对应父容器能力 | 说明 |
|
|
203
|
-
| --- | --- | --- |
|
|
204
|
-
| `network.request(config)` | `network.request` | 发起网络请求;默认仅 `2xx` 视为成功。 |
|
|
91
|
+
### 分享
|
|
205
92
|
|
|
206
93
|
```ts
|
|
207
|
-
|
|
208
|
-
url: string;
|
|
209
|
-
method?: string;
|
|
210
|
-
params?: Record<string, unknown>;
|
|
211
|
-
data?: unknown;
|
|
212
|
-
headers?: Record<string, string>;
|
|
213
|
-
timeout?: number;
|
|
214
|
-
withCredentials?: boolean;
|
|
215
|
-
validateStatus?: (status: number) => boolean;
|
|
216
|
-
}
|
|
94
|
+
import { share } from '@heybox/hb-sdk';
|
|
217
95
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
96
|
+
await share.showShareMenu({
|
|
97
|
+
title: '我的小程序页面',
|
|
98
|
+
desc: '来自黑盒小程序的分享',
|
|
99
|
+
url: window.location.href,
|
|
100
|
+
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
101
|
+
});
|
|
225
102
|
```
|
|
226
103
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
- `validateStatus` 只在 SDK 本地执行,不会跨 bridge 传输函数。
|
|
230
|
-
- `config` 是 SDK 公共请求配置快照,不包含任何原始 `sendRequestV2` 字段。
|
|
231
|
-
- 公开响应头为 `Record<string, string>`;无法可靠解析时应视为 `{}`。
|
|
232
|
-
- v1 不提供原始协议字段、回调函数、拦截器或上传下载进度等高级能力。
|
|
233
|
-
|
|
234
|
-
### Share
|
|
235
|
-
|
|
236
|
-
分享模块位于 `src/modules/share`,对外提供简洁配置,父容器侧再映射到黑盒客户端协议。
|
|
237
|
-
|
|
238
|
-
| API | 对应父容器能力 | 说明 |
|
|
239
|
-
| --- | --- | --- |
|
|
240
|
-
| `share.showShareMenu(options)` | `share.showShareMenu` -> `share` 协议 | 展示基础分享面板。 |
|
|
241
|
-
| `share.screenshot(options?)` | `share.screenshot` -> `screenShotShareV2` 协议 | 截图并唤起分享。 |
|
|
242
|
-
|
|
243
|
-
基础分享参数:
|
|
104
|
+
截图分享:
|
|
244
105
|
|
|
245
106
|
```ts
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
imageUrl?: string;
|
|
251
|
-
channel?: 'wechatSession' | 'wechatTimeline' | 'qqFriend' | 'qzone' | 'weibo';
|
|
252
|
-
}
|
|
107
|
+
await share.screenshot({
|
|
108
|
+
delay: 100,
|
|
109
|
+
saveToAlbum: true,
|
|
110
|
+
});
|
|
253
111
|
```
|
|
254
112
|
|
|
255
|
-
|
|
113
|
+
### 窗口信息
|
|
256
114
|
|
|
257
115
|
```ts
|
|
258
|
-
|
|
259
|
-
rect?: {
|
|
260
|
-
left: number;
|
|
261
|
-
top: number;
|
|
262
|
-
width: number;
|
|
263
|
-
height: number;
|
|
264
|
-
};
|
|
265
|
-
delay?: number;
|
|
266
|
-
saveToAlbum?: boolean;
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
为了保持外部 API 稳定,`share` 模块不开放 raw protocol、JS callback、活动上报、发帖、自定义按钮、upload-only 等内部能力。
|
|
271
|
-
|
|
272
|
-
### Viewport
|
|
273
|
-
|
|
274
|
-
Viewport 模块位于 `src/modules/viewport`,承载窗口、视口和安全区域相关能力。
|
|
275
|
-
|
|
276
|
-
| API | 对应父容器能力 | 说明 |
|
|
277
|
-
| --- | --- | --- |
|
|
278
|
-
| `viewport.getWindowInfo()` | `viewport.getWindowInfo` | 获取窗口、屏幕、安全区域等信息。 |
|
|
116
|
+
import { viewport } from '@heybox/hb-sdk';
|
|
279
117
|
|
|
280
|
-
|
|
118
|
+
const windowInfo = await viewport.getWindowInfo();
|
|
281
119
|
|
|
282
|
-
|
|
283
|
-
interface MiniProgramWindowInfoResult {
|
|
284
|
-
pixelRatio: number;
|
|
285
|
-
screenWidth: number;
|
|
286
|
-
screenHeight: number;
|
|
287
|
-
windowWidth: number;
|
|
288
|
-
windowHeight: number;
|
|
289
|
-
statusBarHeight: number;
|
|
290
|
-
safeArea: {
|
|
291
|
-
left: number;
|
|
292
|
-
right: number;
|
|
293
|
-
top: number;
|
|
294
|
-
bottom: number;
|
|
295
|
-
width: number;
|
|
296
|
-
height: number;
|
|
297
|
-
};
|
|
298
|
-
screenTop: number;
|
|
299
|
-
}
|
|
120
|
+
console.log(windowInfo.windowWidth, windowInfo.windowHeight, windowInfo.safeArea.top);
|
|
300
121
|
```
|
|
301
122
|
|
|
302
|
-
### Storage
|
|
303
|
-
|
|
304
|
-
Storage 模块位于 `src/modules/storage`,承载小程序隔离存储能力。
|
|
305
|
-
|
|
306
|
-
| API | 对应父容器能力 | 说明 |
|
|
307
|
-
| --- | --- | --- |
|
|
308
|
-
| `storage.getStorage(options)` | `storage.getStorage` -> `getStorage` 协议 | 读取小程序隔离 storage。 |
|
|
309
|
-
| `storage.setStorage(options)` | `storage.setStorage` -> `setStorage` 协议 | 写入小程序隔离 storage。 |
|
|
310
|
-
|
|
311
|
-
storage API:
|
|
123
|
+
### 隔离 Storage
|
|
312
124
|
|
|
313
125
|
```ts
|
|
126
|
+
import { storage } from '@heybox/hb-sdk';
|
|
127
|
+
|
|
314
128
|
await storage.setStorage({
|
|
315
129
|
key: 'settings',
|
|
316
130
|
data: {
|
|
317
|
-
|
|
131
|
+
theme: 'dark',
|
|
318
132
|
},
|
|
319
133
|
});
|
|
320
134
|
|
|
321
|
-
const
|
|
135
|
+
const { data } = await storage.getStorage<{ theme: string }>({
|
|
322
136
|
key: 'settings',
|
|
323
137
|
});
|
|
324
138
|
```
|
|
325
139
|
|
|
326
|
-
storage
|
|
327
|
-
|
|
328
|
-
### Protocol
|
|
329
|
-
|
|
330
|
-
协议模块位于 `src/protocol`,定义父容器与 iframe SDK 之间的消息格式、事件名、事件 payload 映射、协议常量和消息守卫。
|
|
331
|
-
|
|
332
|
-
当前支持的小程序事件:
|
|
333
|
-
|
|
334
|
-
- `launch`:小程序首次完成握手并启动。
|
|
335
|
-
- `ready`:SDK 已可安全调用开放能力。
|
|
336
|
-
- `show`:小程序页面展示。
|
|
337
|
-
- `hide`:小程序页面隐藏。
|
|
338
|
-
- `unload`:小程序页面即将卸载。
|
|
339
|
-
- `error`:父容器或开放能力运行异常。
|
|
340
|
-
- `authChange`:登录状态发生变化后的最新用户信息。
|
|
140
|
+
storage key 只允许 1-128 位字母、数字、下划线和连字符。父容器会按小程序维度隔离 key,外部小程序不能读写黑盒客户端全局 storage。
|
|
341
141
|
|
|
342
|
-
|
|
142
|
+
### 网络请求
|
|
343
143
|
|
|
344
|
-
|
|
144
|
+
`network.request()` 提供窄化的 axios-like 接口。SDK 只接受公开请求字段,真实请求由父容器运行时映射到宿主网络能力。
|
|
345
145
|
|
|
346
146
|
```ts
|
|
347
|
-
import {
|
|
147
|
+
import { HbMiniProgramNetworkError, network } from '@heybox/hb-sdk';
|
|
348
148
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
renderUser(result.userInfo);
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### 场景 2:点击按钮唤起登录
|
|
362
|
-
|
|
363
|
-
```ts
|
|
364
|
-
import { auth } from '@heybox/hb-sdk';
|
|
365
|
-
|
|
366
|
-
async function handleLoginClick() {
|
|
367
|
-
const result = await auth.login();
|
|
368
|
-
|
|
369
|
-
if (result.isLogin) {
|
|
370
|
-
renderUser(result.userInfo);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
### 场景 3:展示分享面板
|
|
376
|
-
|
|
377
|
-
```ts
|
|
378
|
-
import { share } from '@heybox/hb-sdk';
|
|
379
|
-
|
|
380
|
-
async function handleShareClick() {
|
|
381
|
-
await share.showShareMenu({
|
|
382
|
-
title: '我的小程序页面',
|
|
383
|
-
desc: '来自黑盒小程序的分享',
|
|
384
|
-
url: location.href,
|
|
385
|
-
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
386
|
-
channel: 'wechatSession',
|
|
149
|
+
try {
|
|
150
|
+
const response = await network.request<{ ok: boolean }>({
|
|
151
|
+
url: 'https://api.example.com/demo',
|
|
152
|
+
method: 'GET',
|
|
153
|
+
headers: {
|
|
154
|
+
accept: 'application/json',
|
|
155
|
+
},
|
|
387
156
|
});
|
|
388
|
-
}
|
|
389
|
-
```
|
|
390
157
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
async function handleScreenshotShare() {
|
|
397
|
-
await share.screenshot({
|
|
398
|
-
delay: 100,
|
|
399
|
-
saveToAlbum: true,
|
|
400
|
-
});
|
|
158
|
+
console.log(response.status, response.data.ok);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (error instanceof HbMiniProgramNetworkError) {
|
|
161
|
+
console.log(error.response.status, error.response.data);
|
|
162
|
+
}
|
|
401
163
|
}
|
|
402
164
|
```
|
|
403
165
|
|
|
404
|
-
|
|
166
|
+
默认只有 `2xx` 会 resolve;`4xx/5xx` 这类已完成 HTTP 响应会抛出 `HbMiniProgramNetworkError`。可以用 `validateStatus` 调整 SDK 本地判定逻辑,函数不会跨 bridge 传给父容器。
|
|
405
167
|
|
|
406
168
|
```ts
|
|
407
|
-
await
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
top: 0,
|
|
411
|
-
width: 375,
|
|
412
|
-
height: 667,
|
|
413
|
-
},
|
|
169
|
+
await network.request({
|
|
170
|
+
url: 'https://api.example.com/demo',
|
|
171
|
+
validateStatus: status => status < 500,
|
|
414
172
|
});
|
|
415
173
|
```
|
|
416
174
|
|
|
417
|
-
|
|
175
|
+
支持的 HTTP method 为 `GET`、`POST`、`PUT`、`PATCH`、`DELETE`、`HEAD`、`OPTIONS`。
|
|
418
176
|
|
|
419
|
-
|
|
420
|
-
import { viewport } from '@heybox/hb-sdk';
|
|
177
|
+
## 生命周期事件
|
|
421
178
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
console.log(windowInfo.windowWidth, windowInfo.windowHeight, windowInfo.safeArea.top);
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
### 场景 6:使用隔离 storage
|
|
179
|
+
使用 `on()` 监听父容器派发的小程序事件。`on()` 会返回取消监听函数,组件卸载或页面销毁时应及时调用。
|
|
428
180
|
|
|
429
181
|
```ts
|
|
430
|
-
import {
|
|
182
|
+
import { on } from '@heybox/hb-sdk';
|
|
431
183
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
data: {
|
|
435
|
-
enabled: true,
|
|
436
|
-
},
|
|
184
|
+
const unsubscribeShow = on('show', payload => {
|
|
185
|
+
console.log('页面展示', payload.timestamp, payload.source);
|
|
437
186
|
});
|
|
438
187
|
|
|
439
|
-
const
|
|
440
|
-
|
|
188
|
+
const unsubscribeAuth = on('authChange', payload => {
|
|
189
|
+
console.log('登录态变化', payload.isLogin, payload.userInfo);
|
|
441
190
|
});
|
|
442
191
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
192
|
+
unsubscribeShow();
|
|
193
|
+
unsubscribeAuth();
|
|
446
194
|
```
|
|
447
195
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
```ts
|
|
451
|
-
import { off, on } from '@heybox/hb-sdk';
|
|
196
|
+
当前可监听事件包括 `launch`、`ready`、`show`、`hide`、`unload`、`error`、`authChange`。
|
|
452
197
|
|
|
453
|
-
|
|
454
|
-
console.log('页面展示', payload.timestamp);
|
|
455
|
-
};
|
|
198
|
+
## 错误处理
|
|
456
199
|
|
|
457
|
-
|
|
458
|
-
console.log('登录态变化', payload.isLogin, payload.userInfo);
|
|
459
|
-
};
|
|
200
|
+
bridge、父容器运行时、协议校验或能力调用失败时会抛出 `HbMiniProgramSDKError`,其中包含稳定的 `code`、开发者可读的 `message` 和可选 `data`。
|
|
460
201
|
|
|
461
|
-
|
|
462
|
-
|
|
202
|
+
```ts
|
|
203
|
+
import { HbMiniProgramSDKError, ready } from '@heybox/hb-sdk';
|
|
463
204
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
205
|
+
try {
|
|
206
|
+
await ready();
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (error instanceof HbMiniProgramSDKError) {
|
|
209
|
+
console.log(error.code, error.message, error.data);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
467
212
|
```
|
|
468
213
|
|
|
469
|
-
|
|
214
|
+
网络请求已完成但 HTTP 状态不满足 `validateStatus` 时会抛出 `HbMiniProgramNetworkError`,其 `response` 字段包含标准化后的 `status`、`headers`、`data` 和原始公共请求配置快照。
|
|
470
215
|
|
|
471
|
-
|
|
472
|
-
const unsubscribe = on('hide', (payload) => {
|
|
473
|
-
console.log('页面隐藏', payload.timestamp);
|
|
474
|
-
});
|
|
216
|
+
## CLI
|
|
475
217
|
|
|
476
|
-
|
|
477
|
-
```
|
|
218
|
+
`@heybox/hb-sdk` 随包提供 `hb-sdk` CLI。脚手架项目已在 npm scripts 中接好常用命令;已有项目也可以自行添加 scripts。
|
|
478
219
|
|
|
479
|
-
|
|
220
|
+
| 命令 | 作用 |
|
|
221
|
+
| --- | --- |
|
|
222
|
+
| `hb-sdk create <project-name>` | 创建外部小程序模板。 |
|
|
223
|
+
| `hb-sdk dev` | 启动当前项目的 Vite dev server 和浏览器 mock 宿主环境,并默认打开调试页。 |
|
|
224
|
+
| `hb-sdk deploy [--skip-build]` | 构建并发布当前小程序到 Heybox 后台。`--skip-build` 跳过 build 直接上传 `dist/` 并 publish。 |
|
|
225
|
+
| `hb-sdk login` | 登录 Heybox,并把 CLI 自己需要的登录态保存在本地缓存中。 |
|
|
226
|
+
| `hb-sdk login status` | 查看脱敏后的 CLI 登录态。 |
|
|
227
|
+
| `hb-sdk login clear` | 清理 CLI 登录态。 |
|
|
228
|
+
| `hb-sdk doctor` | 检查本机 `hb-sdk` Agent Skill 是否匹配当前 SDK,并输出手动安装/刷新命令。 |
|
|
480
229
|
|
|
481
|
-
|
|
482
|
-
import { createMiniProgramSDK } from '@heybox/hb-sdk';
|
|
230
|
+
## hb-sdk deploy
|
|
483
231
|
|
|
484
|
-
|
|
485
|
-
nonce: 'test_nonce',
|
|
486
|
-
selfWindow: window,
|
|
487
|
-
targetWindow: parentWindow,
|
|
488
|
-
timeout: 100,
|
|
489
|
-
});
|
|
232
|
+
`hb-sdk deploy` 把 build、CDN 上传、发布 API 串成单条命令。命令前置要求:
|
|
490
233
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
234
|
+
1. `package.json` 必须含 `heybox.miniProgramId` 字段,CLI 只从这里读 mini program id:
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"heybox": {
|
|
238
|
+
"miniProgramId": "mp_xxxxxxxx"
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
2. 已运行过 `hb-sdk login` 登录 Heybox。
|
|
243
|
+
3. 项目根有 `scripts.build`,会被 CLI 通过 lockfile 自动选用的 `pnpm`、`yarn` 或 `npm` 触发;无 lockfile 时回退 `npm`。
|
|
244
|
+
4. 构建产物落在 `dist/`,包含 `index.html` 和 `manifest.json`。
|
|
494
245
|
|
|
495
|
-
|
|
246
|
+
执行流程:
|
|
496
247
|
|
|
497
|
-
|
|
248
|
+
1. 校验 `heybox.miniProgramId` 和登录态。
|
|
249
|
+
2. 触发 `<pm> run build`,除非使用 `--skip-build`。
|
|
250
|
+
3. 解析 `dist/manifest.json`,校验 `version` 为 `x.y.z`,自动剥离 BOM。
|
|
251
|
+
4. 遍历 `dist/` 文件,跳过 `manifest.json`、`.DS_Store`、`.map`;遇到 symlink 或 `node_modules` 直接报错。
|
|
252
|
+
5. 校验所有上传路径长度不超过 64。
|
|
253
|
+
6. 4 并发上传到 COS。任一文件失败立刻 abort,不调 publish。
|
|
254
|
+
7. 全部上传成功后调发布 API,原样透传后端 msg。
|
|
498
255
|
|
|
499
|
-
|
|
256
|
+
`--skip-build` 用于 CI 双阶段:上一步已经 build 完缓存好了 `dist/`,本步只做上传和 publish。`dist/manifest.json` 或 `dist/index.html` 缺失会立即报错。
|
|
500
257
|
|
|
501
|
-
|
|
502
|
-
- `@heybox/hb-sdk-runtime` **不应依赖** `@heybox/hb-sdk` 的 `core/*`、默认单例、客户端请求实现等客户端运行时逻辑。
|
|
503
|
-
- 协议变更时,`@heybox/hb-sdk` 与 `@heybox/hb-sdk-runtime` 应按一组联动能力来评审和发布,而不是分别独立演进。
|
|
258
|
+
`manifest.json` 不会上传到 CDN,只作为 publish 请求的 `manifest` 字段提交。这与 Vite 插件文档中的契约一致。
|
|
504
259
|
|
|
505
|
-
|
|
260
|
+
CLI 登录态只供 CLI 命令访问黑盒接口时复用,不会注入 iframe SDK,也不会改变 `auth.login()`、`user.getInfo()`、`network.request()` 或 mock 宿主中的用户状态。
|
|
506
261
|
|
|
507
|
-
|
|
508
|
-
| --- | --- | --- |
|
|
509
|
-
| 同一仓库主线版本 | 同一仓库主线版本 | 默认开发模式,按同一批次代码联动验证 |
|
|
510
|
-
| 仅补丁级变更 | 仅补丁级变更 | 允许,但必须保持协议常量、消息结构、事件名和 payload 兼容 |
|
|
511
|
-
| 协议字段 / 方法名 / 事件名变更 | 需要同步升级 | 不允许单边发布后假定另一侧自动兼容 |
|
|
262
|
+
`create`、`dev`、`login`、`login status`、`login clear` 这些 CLI 命令会在成功执行后检查 npm registry 上的 `@heybox/hb-sdk@latest`。如果发现新版本,会在 stderr 打印升级提醒;检查失败会静默跳过,不影响当前命令。`doctor` 不会附带版本提醒,避免把 skill 诊断输出和升级提示混在一起。可通过 `HB_SDK_NO_UPDATE_CHECK=1` 禁用版本提醒;`CI=true` 时也会自动跳过检查。
|
|
512
263
|
|
|
513
|
-
|
|
264
|
+
## SDK 与 Runtime
|
|
514
265
|
|
|
515
|
-
|
|
266
|
+
`@heybox/hb-sdk` 跑在 iframe 内部,由外部小程序业务页面使用。`@heybox/hb-sdk-runtime` 跑在 iframe 外部,由黑盒宿主壳层使用,负责启动 iframe、注入 nonce、维护 bridge server、注册能力 handler、转发宿主生命周期与登录态变化。
|
|
516
267
|
|
|
517
|
-
|
|
518
|
-
- 禁止 `@heybox/hb-sdk-runtime` 引用 `@heybox/hb-sdk/core/*`、默认单例或客户端实现层。
|
|
519
|
-
- 只允许引用协议 / 契约层入口(例如 `@heybox/hb-sdk/protocol`)。
|
|
520
|
-
2. **协议兼容性检查**
|
|
521
|
-
- 当 `MINI_PROGRAM_MESSAGE_*` 常量、事件名、方法名、payload 类型变更时,要求 `hb-sdk` 与 `hb-sdk-runtime` 相关测试同时通过。
|
|
522
|
-
3. **联动验证检查**
|
|
523
|
-
- 至少跑一组 `hb-sdk` 单测 + `hb-sdk-runtime` 单测,确保客户端与宿主运行时没有单边漂移。
|
|
524
|
-
4. **导出面检查**
|
|
525
|
-
- 若协议层导出发生调整,CI 需提醒评审同步检查 runtime 使用面,而不是默认为向后兼容。
|
|
268
|
+
两者共享同一套 bridge 协议。协议字段、事件名或能力 payload 发生变化时,应按同一批次联动升级 SDK 与 runtime;不要只升级其中一侧后假定另一侧自动兼容。
|
|
526
269
|
|
|
527
|
-
##
|
|
270
|
+
## 能力边界
|
|
528
271
|
|
|
529
|
-
- SDK 只能在父容器创建的小程序 iframe 沙盒中正常完成握手;非 iframe 环境会抛出 `NOT_IN_IFRAME`。
|
|
530
|
-
- 父容器必须在小程序 URL 上注入 `hb_mini_bridge_nonce`,否则会抛出 `MISSING_NONCE`。
|
|
531
|
-
- 父容器需要幂等响应 `sdk.handshake`;SDK 会在收到 `ready` 前自动重试握手,不引用 SDK 的普通页面不会触发握手。
|
|
532
272
|
- 调用模块能力前会自动等待 `ready()`,但业务仍建议在页面启动阶段显式 `await ready()`,便于集中处理握手失败。
|
|
533
|
-
- `user.getInfo()`
|
|
534
|
-
-
|
|
535
|
-
- `
|
|
536
|
-
- `
|
|
537
|
-
- `
|
|
538
|
-
- `
|
|
539
|
-
- `on()` 会返回取消监听函数;页面卸载或组件销毁时应及时取消监听。
|
|
540
|
-
- 独立实例不再使用时应调用 `destroy()`,以移除 message 监听并拒绝未完成请求。
|
|
273
|
+
- `user.getInfo()` 不会触发登录;登录必须由业务在用户操作后调用 `auth.login()`。
|
|
274
|
+
- 分享、截图、storage 和网络请求只开放稳定窄接口,不透传黑盒客户端内部协议参数。
|
|
275
|
+
- `network.request()` 的 `validateStatus` 只在 SDK 本地执行,不会被序列化给父容器。
|
|
276
|
+
- `on()` 返回取消监听函数;组件卸载或页面销毁时应主动取消监听。
|
|
277
|
+
- 使用 `createMiniProgramSDK()` 创建独立实例后,不再需要时应调用 `destroy()`。
|
|
278
|
+
- 构建产物可以包含 `dist/manifest.json`,业务代码不应自行 fetch 已部署的 manifest;这个文件由发布流水线读取并上送后台。
|
|
541
279
|
|
|
542
|
-
##
|
|
280
|
+
## Manifest
|
|
543
281
|
|
|
544
|
-
|
|
282
|
+
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()`。Vite 项目完成 `vite build` 后,会在输出目录写入 `manifest.json`:
|
|
545
283
|
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
npm run dev:mock
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"version": "1.2.3"
|
|
287
|
+
}
|
|
551
288
|
```
|
|
552
289
|
|
|
553
|
-
|
|
290
|
+
`version` 来自小程序项目自身的 `package.json.version`。`hb-sdk create` 生成的模板默认已注册插件;现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
|
|
554
291
|
|
|
555
|
-
|
|
556
|
-
-
|
|
557
|
-
|
|
558
|
-
- 模板内置轻量 SDK 能力演示页和 Vitest 单测配置;`npm run dev:mock` 会启动本地 Vite 服务和 hb-sdk mock runtime host。
|
|
292
|
+
```ts
|
|
293
|
+
import { miniappManifest } from '@heybox/hb-sdk/vite';
|
|
294
|
+
import { defineConfig } from 'vite';
|
|
559
295
|
|
|
560
|
-
|
|
296
|
+
export default defineConfig({
|
|
297
|
+
plugins: [miniappManifest()],
|
|
298
|
+
});
|
|
299
|
+
```
|
|
561
300
|
|
|
562
|
-
|
|
301
|
+
失败与警告语义:
|
|
563
302
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
```
|
|
303
|
+
- 读取 `package.json` 失败或 JSON 解析失败:`vite build` 直接失败,并输出具体原因。
|
|
304
|
+
- `package.json.version` 不是非空字符串:`vite build` 直接失败。
|
|
305
|
+
- `package.json.version` 仍是模板默认值 `0.0.0`:`vite build` 直接失败,并提示把模板默认版本改成实际版本号再发布。
|
|
306
|
+
- 版本号不满足极简 semver 形态 `x.y.z`:只输出 Rollup/Vite warning,仍会写入 manifest。
|
|
569
307
|
|
|
570
|
-
|
|
571
|
-
- `hb-sdk login status` 只展示脱敏状态、`heyboxId`、登录时间和 cache 路径,不输出 `pkey`、cookie 或完整请求头。
|
|
572
|
-
- `hb-sdk login clear` 只清理 `hb-sdk` 自己命名空间中的 Heybox 登录态。
|
|
308
|
+
`manifest.json` 不部署到 CDN,只交给发布流水线读取后上送后台;Host 通过后台 API 间接读取版本信息。第一阶段只支持 Vite 项目,非 Vite 打包器未来通过其他子入口扩展。
|
|
573
309
|
|
|
574
|
-
|
|
310
|
+
## 导出
|
|
575
311
|
|
|
576
|
-
|
|
312
|
+
默认导出 `hbSDK`,包含 `ready`、`on`、`off`、`auth`、`user`、`share`、`viewport`、`storage`、`network`。
|
|
577
313
|
|
|
578
|
-
|
|
314
|
+
常用命名导出:
|
|
579
315
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
316
|
+
- `ready`、`on`、`off`
|
|
317
|
+
- `auth`、`user`、`share`、`viewport`、`storage`、`network`
|
|
318
|
+
- `createMiniProgramSDK`、`MiniProgramSDK`
|
|
319
|
+
- `HbMiniProgramSDKError`、`HbMiniProgramNetworkError`
|
|
320
|
+
- 各模块公开类型,例如 `MiniProgramNetworkRequestConfig`、`MiniProgramNetworkResponse`、`MiniProgramUserInfoResult`
|
|
583
321
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
322
|
+
协议常量、消息类型和守卫仍通过根入口与 `@heybox/hb-sdk/protocol` 子入口导出。宿主运行时等非业务页面代码应优先使用 `@heybox/hb-sdk/protocol`。
|
|
323
|
+
|
|
324
|
+
构建时插件 `miniappManifest` 通过 `@heybox/hb-sdk/vite` 子入口导出,仅供 `vite.config.ts` 使用,不应在小程序业务代码里 import。
|
|
587
325
|
|
|
588
|
-
|
|
326
|
+
## 本仓库开发
|
|
589
327
|
|
|
590
328
|
```bash
|
|
591
|
-
# 运行单元测试
|
|
592
329
|
pnpm --filter @heybox/hb-sdk run test:unit
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
pnpm --filter @heybox/hb-sdk run
|
|
330
|
+
pnpm --filter @heybox/hb-sdk run build:package
|
|
331
|
+
pnpm --filter @heybox/hb-sdk run check:boundary
|
|
332
|
+
pnpm --filter @heybox/hb-sdk run check:docs-sync
|
|
596
333
|
```
|
|
334
|
+
|
|
335
|
+
`check:boundary` 用于保护 SDK、CLI、mock host 与 runtime 之间的依赖边界。调整 CLI、mock 或协议导出时应一起运行。
|
|
336
|
+
|
|
337
|
+
`check:docs-sync` 用于校验 `README`、文档站 llms 镜像、skill references 与公开 `agent-skills` payload 没有漏同步。维护清单见 `packages/hb-sdk/DOC_SYNC_CHECKLIST.md`。
|