@heybox/hb-sdk 0.6.9 → 0.7.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +51 -7
  2. package/README.md +83 -20
  3. package/dist/cli-chunks/{build-BtGxhrcV.cjs → build-DLIhlBQA.cjs} +4 -4
  4. package/dist/cli-chunks/{context-DX1KG-8A.cjs → context-Bl_Q4RKq.cjs} +15 -2
  5. package/dist/cli-chunks/{create-DAD0OF1r.cjs → create-C--pwY0l.cjs} +1 -1
  6. package/dist/cli-chunks/{dev-Dh4HY0I8.cjs → dev-B1tyT5ql.cjs} +197 -13
  7. package/dist/cli-chunks/{doctor-BfKdiD3H.cjs → doctor-D9M2scaJ.cjs} +1 -1
  8. package/dist/cli-chunks/{index-tCURDEx8.cjs → index-BnBeTd0B.cjs} +15 -14
  9. package/dist/cli-chunks/{index-DB6Q8HaC.cjs → index-HNB8i51C.cjs} +2 -2
  10. package/dist/cli-chunks/{login-D60EJLgs.cjs → login-DnX81kof.cjs} +2 -2
  11. package/dist/cli-chunks/{project-vite-DAUaP0_3.cjs → project-vite-CgnCpNDZ.cjs} +1 -1
  12. package/dist/cli-chunks/{remote-nQDniAUY.cjs → remote-CETqg77E.cjs} +6 -6
  13. package/dist/cli-chunks/{runtime-gate-BWlU-R4h.cjs → runtime-gate-CtV7rWyX.cjs} +1 -1
  14. package/dist/cli-chunks/{runtime-permission-env-DKrhgVM3.cjs → runtime-permission-env-D-8_jPG3.cjs} +2 -0
  15. package/dist/cli-chunks/{session-D6jOKXeu.cjs → session-Davw2CMd.cjs} +1 -1
  16. package/dist/cli.cjs +1 -1
  17. package/dist/devtools/mock-host/index.html +9 -2
  18. package/dist/devtools/mock-host/main.js +426 -802
  19. package/dist/index.cjs.js +46 -90
  20. package/dist/index.esm.js +46 -90
  21. package/dist/miniapp-publish.cjs.js +2 -0
  22. package/dist/miniapp-publish.esm.js +2 -1
  23. package/dist/protocol.cjs.js +98 -42
  24. package/dist/protocol.esm.js +93 -39
  25. package/dist/templates/vue3-vite-ts/README.md.ejs +1 -1
  26. package/dist/templates/vue3-vite-ts/src/App.vue +22 -17
  27. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +37 -29
  28. package/dist/templates/vue3-vite-ts/src/auth-handoff.ts +46 -0
  29. package/dist/vite.cjs.js +2 -2
  30. package/dist/vite.esm.js +2 -2
  31. package/package.json +2 -2
  32. package/skill/SKILL.md +16 -12
  33. package/skill/references/api-protocol.md +22 -28
  34. package/skill/references/api-root.md +127 -112
  35. package/skill/references/cli.md +15 -20
  36. package/skill/references/examples.md +29 -17
  37. package/skill/references/recipes.md +180 -134
  38. package/skill/references/safety-boundaries.md +9 -3
  39. package/skill/scripts/sync-references.mjs +235 -139
  40. package/skill/scripts/validate-skill.mjs +18 -14
  41. package/skill/skill.json +4 -4
  42. package/types/index.d.ts +4 -4
  43. package/types/miniapp-publish/index.d.ts +1 -0
  44. package/types/modules/auth/index.d.ts +16 -28
  45. package/types/modules/cloud/index.d.ts +2 -2
  46. package/types/modules/network/index.d.ts +1 -2
  47. package/types/modules/user/get-info.d.ts +4 -4
  48. package/types/modules/user/get-local-identity.d.ts +9 -0
  49. package/types/modules/user/index.d.ts +13 -41
  50. package/types/modules/user/revoke-authorization.d.ts +7 -0
  51. package/types/modules/user/steam-game-list.d.ts +72 -0
  52. package/types/modules/user/types.d.ts +37 -302
  53. package/types/protocol/capabilities.d.ts +24 -49
  54. package/types/protocol/constants.d.ts +1 -1
  55. package/types/protocol/network-policy.d.ts +10 -0
  56. package/types/protocol/types.d.ts +10 -6
  57. package/types/protocol.d.ts +4 -3
  58. package/types/modules/user/get-current-user-detail.d.ts +0 -9
  59. package/types/modules/user/get-current-user-profile.d.ts +0 -9
  60. package/types/modules/user/get-platform-account-info.d.ts +0 -12
  61. package/types/modules/user/get-platform-account-overview.d.ts +0 -9
  62. package/types/modules/user/get-steam-game-list.d.ts +0 -12
package/skill/SKILL.md CHANGED
@@ -39,13 +39,16 @@ Apply these instructions when writing, reviewing, or debugging code that consume
39
39
  ## Step 4: Implement workshop mini-program code
40
40
 
41
41
  1. Call `await ready()` or `await hbSDK.ready()` near page startup when the page uses SDK capabilities.
42
- 2. Use `user.getInfo()` to read current login state without triggering login.
43
- 3. Use `auth.login()` only when the user action requires login.
44
- 4. Handle `HbMiniProgramSDKError` for SDK initialization and capability failures.
45
- 5. Handle `HbMiniProgramNetworkError` separately when HTTP completed but `validateStatus` rejected the status.
46
- 6. Cancel lifecycle/event subscriptions returned by `on()` when the page or component unmounts.
47
- 7. Use the default SDK instance exposed by the root package.
48
- 8. Use `share.showShareMenu({ post })` or `share.screenshot({ post })` to preset editable community destinations and topics. Pass partition IDs through `topicIds` and topic text without surrounding `#` through `topics`; do not construct the underlying client post protocol.
42
+ 2. For a network-enabled mini-program, use `auth.login({ scopes? })` to obtain `{ code, expiresIn: 300, scopes }`. Identity is always implicit; request only optional scopes the business actually needs.
43
+ 3. Send the code only to the developer's backend. That backend follows the backend OpenAPI documentation to exchange it for a token; mini-program code must never exchange application credentials itself.
44
+ 4. For a network-disabled mini-program, call `user.getLocalIdentity()` from a trusted user action to obtain `{ appUserId }`, because first login or identity consent may require UI. It cannot obtain a code or call OpenAPI.
45
+ 5. Handle `HbMiniProgramSDKError` for SDK initialization and capability failures.
46
+ 6. Handle `HbMiniProgramNetworkError` separately when HTTP completed but `validateStatus` rejected the status.
47
+ 7. Cancel lifecycle/event subscriptions returned by `on()` when the page or component unmounts.
48
+ 8. Use the default SDK instance exposed by the root package.
49
+ 9. When authorization UI is required, call `auth.login()` or `user.getLocalIdentity()` from a trusted user action. Missing gesture returns `USER_GESTURE_REQUIRED`; cancelling, rejecting, or closing returns `AUTHORIZATION_CANCELLED` and does not confirm or change authorization. An already-authorized `auth.login()` request may return a new code silently.
50
+ 10. `user.getSteamGameList()` is available only to network-disabled mini-programs. In a network-enabled mini-program it returns `SERVER_API_REQUIRED`, and there is no Steam library authorization scope or OpenAPI resource. Treat `user.getInfo()` and `user.getLocalIdentity()` returning `SERVER_API_REQUIRED` as a server-boundary signal, not as logged-out state.
51
+ 11. Use `share.showShareMenu({ post })` or `share.screenshot({ post })` to preset editable community destinations and topics. Pass partition IDs through `topicIds` and topic text without surrounding `#` through `topics`; do not construct the underlying client post protocol.
49
52
 
50
53
  ## Step 5: Use CLI workflows
51
54
 
@@ -56,7 +59,7 @@ Apply these instructions when writing, reviewing, or debugging code that consume
56
59
  5. Keep `miniappManifest()` explicitly enabled in `vite.config.ts`; `hb-sdk build` must fail when the required Manifest or Runtime gate output is missing.
57
60
  6. Keep project typechecking in `scripts.build`, for example `vue-tsc --noEmit && hb-sdk build`; `hb-sdk build` does not run typechecking or invoke `scripts.build` itself.
58
61
  7. Existing projects may continue to use `vite build`; do not auto-migrate them. Do not invent `--mode`, `--json`, config, or output-directory flags for `hb-sdk build`.
59
- 8. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for development and publishing commands. This login does not change the mini-program user's login state.
62
+ 8. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for development and publishing commands. This login does not change `auth.login()`, `user.getLocalIdentity()`, or the mini-program user's authorization state.
60
63
  9. Use `hb-sdk remote entity current` to confirm the current developer account and `hb-sdk remote entity switch <entity-id>` to change it before remote operations.
61
64
  10. Use `hb-sdk remote create` to create and bind a mini-program; use `hb-sdk remote bind <mini-program-id>` to bind an existing manageable mini-program.
62
65
  11. Use `hb-sdk remote info`, `hb-sdk remote list`, `hb-sdk remote access`, `hb-sdk remote versions`, `hb-sdk remote preview <version>`, and `hb-sdk remote allowlist ...` for remote inspection and preview management.
@@ -79,16 +82,17 @@ For workshop mini-program business code:
79
82
  4. Use only the public `network.request` configuration.
80
83
  5. Do not use private package paths or client protocols.
81
84
  6. Build artifacts may include `dist/manifest.json`; business code should not fetch a deployed manifest directly because it is not a CDN asset.
85
+ 7. Do not use `network.request()` to reach platform-reserved runtime auth or OpenAPI internal paths.
86
+ 8. Do not expose credentials or describe internal Host authorization state machines and routes in app-facing guidance.
82
87
 
83
88
  For CLI and local development:
84
89
 
85
90
  1. Do not print, persist in templates, or pass through pkey, cookies, tokens, or private credentials.
86
- 2. Do not use `hb-sdk login` as a workaround for mini-program user authentication.
91
+ 2. Do not use `hb-sdk login` as a workaround for `auth.login()` or mini-program user authorization.
87
92
  3. Use the built-in local debugging page instead of creating another browser Mock.
88
93
  4. Keep the Vite `miniappManifest()` plugin enabled.
89
- 5. Treat Dev Context permission changes as persistent local overrides, not online configuration changes. `hb-sdk` scopes them by real project path and `miniProgramId`, restores them after page refresh or `hb-sdk dev` restart, and clears them only after an explicit reset successfully refetches remote permissions. A regenerated Mobile App QR code may carry only a `dev_context_url` backed by a 256-bit token that expires after 5 minutes; it must not embed a permission snapshot.
90
- 6. Require the Runtime Host to fetch the immutable Dev Session snapshot before startup. Dev Session `network.request` must use the token-bound local proxy, never a native credential adapter, and must force `useOfficialDomain: false`.
91
- 7. Do not treat the legacy `dev_network_request` query as authorization or as a fallback. This Web-only flow must preserve existing Android/iOS URL pass-through behavior without requiring client changes.
94
+ 5. Treat permission changes made in the `hb-sdk dev` debugging page as local debugging overrides, not online configuration changes. Use the page's reset action to return to the remote baseline.
95
+ 6. Treat browser Mock results as development feedback only. Validate permissions, identity flows, and user interactions again in a real Heybox client before publishing.
92
96
 
93
97
  For host/runtime/protocol-maintenance code:
94
98
 
@@ -23,13 +23,16 @@ export {
23
23
  MINI_PROGRAM_BRIDGE_NONCE_PARAM,
24
24
  MINI_PROGRAM_MESSAGE_NAMESPACE,
25
25
  MINI_PROGRAM_MESSAGE_VERSION,
26
- RUNTIME_LOCATION_PROBE_METHOD,
27
- SDK_CSP_VIOLATION_METHOD,
28
26
  SDK_HANDSHAKE_METHOD,
29
- SDK_LOCATION_REPORT_METHOD,
30
27
  } from './protocol/constants';
31
28
  export { isMiniProgramBridgeMessage } from './protocol/guards';
32
29
  export { isManagedMiniProgramRuntimePermissionKey, parseMiniProgramRuntimePermissions } from './protocol/runtime-permissions';
30
+ export {
31
+ isOfficialMiniProgramNetworkUrl,
32
+ isProtectedMiniProgramNetworkPath,
33
+ MINI_PROGRAM_NETWORK_PROTECTED_PATHS,
34
+ normalizeMiniProgramNetworkPathname,
35
+ } from './protocol/network-policy';
33
36
  export type {
34
37
  MiniProgramRuntimePermissionEntry,
35
38
  MiniProgramRuntimePermissionStatus,
@@ -43,12 +46,7 @@ export type {
43
46
  MiniProgramEventHandler,
44
47
  MiniProgramEventName,
45
48
  MiniProgramEventPayloadMap,
46
- RuntimeLocationProbePayload,
47
- SDKCSPBlockedResourceType,
48
- SDKCSPViolationPayload,
49
49
  SDKHandshakePayload,
50
- SDKLocationReportPayload,
51
- SDKLocationReportTrigger,
52
50
  } from './protocol/types';
53
51
  export {
54
52
  AUTH_LOGIN_METHOD,
@@ -71,12 +69,10 @@ export {
71
69
  UI_HIDE_LOADING_METHOD,
72
70
  UI_SHOW_LOADING_METHOD,
73
71
  UI_SHOW_TOAST_METHOD,
74
- USER_GET_CURRENT_USER_DETAIL_METHOD,
75
- USER_GET_CURRENT_USER_PROFILE_METHOD,
76
- USER_GET_INFO_METHOD,
77
- USER_GET_PLATFORM_ACCOUNT_INFO_METHOD,
78
- USER_GET_PLATFORM_ACCOUNT_OVERVIEW_METHOD,
72
+ USER_GET_LOCAL_IDENTITY_METHOD,
73
+ USER_REVOKE_AUTHORIZATION_METHOD,
79
74
  USER_GET_STEAM_GAME_LIST_METHOD,
75
+ USER_GET_INFO_METHOD,
80
76
  VIEWPORT_GET_WINDOW_INFO_METHOD,
81
77
  VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
82
78
  } from './protocol/capabilities';
@@ -100,7 +96,7 @@ export type {
100
96
  MiniProgramUserMethod,
101
97
  MiniProgramViewportMethod,
102
98
  } from './protocol/capabilities';
103
- export type { LoginPayload, LoginResult } from './modules/auth';
99
+ export type { LoginOptions, LoginPayload, LoginResult, LoginScope } from './modules/auth';
104
100
  export type {
105
101
  DeleteCurrentUserLeaderboardEntryPayload,
106
102
  DeleteCurrentUserLeaderboardEntryResult,
@@ -116,25 +112,23 @@ export type {
116
112
  SubmitLeaderboardEntryResult,
117
113
  } from './modules/cloud';
118
114
  export type {
119
- GetCurrentUserDetailPayload,
120
- GetCurrentUserDetailResult,
121
- GetCurrentUserProfilePayload,
122
- GetCurrentUserProfileResult,
123
- GetPlatformAccountInfoPayload,
124
- GetPlatformAccountInfoResult,
125
- GetPlatformAccountOverviewPayload,
126
- GetPlatformAccountOverviewResult,
115
+ AuthorizedUserInfo,
116
+ GetLocalIdentityPayload,
117
+ GetLocalIdentityResult,
118
+ GetUserInfoPayload,
119
+ GetUserInfoResult,
120
+ RevokeAuthorizationPayload,
121
+ RevokeAuthorizationResult,
127
122
  GetSteamGameListOptions,
128
123
  GetSteamGameListPayload,
129
124
  GetSteamGameListResult,
130
- GetUserInfoPayload,
131
- GetUserInfoResult,
132
- MiniProgramUserInfo,
133
125
  MiniProgramUserInfoResult,
126
+ UserInfoAuthorization,
127
+ UserInfoAuthorizationStatus,
134
128
  SteamGameListData,
135
129
  SteamGameListItem,
136
- SteamGameListSort,
137
130
  SteamGamePrice,
131
+ SteamGameListSort,
138
132
  } from './modules/user';
139
133
  export type { ScreenshotPayload, ScreenshotResult } from './modules/share/screenshot';
140
134
  export type { ShowShareMenuPayload, ShowShareMenuResult } from './modules/share/show-share-menu';
@@ -213,7 +207,7 @@ Reference 由 `@heybox/hb-sdk` 的公开导出与源码注释自动生成,不
213
207
 
214
208
  | 导出面 | Classes | Functions | Interfaces | Types | Constants |
215
209
  | --- | ---: | ---: | ---: | ---: | ---: |
216
- | Root API | 2 | 3 | 67 | 57 | 0 |
217
- | Protocol API | 0 | 3 | 44 | 67 | 32 |
210
+ | Root API | 2 | 3 | 51 | 52 | 0 |
211
+ | Protocol API | 0 | 6 | 46 | 65 | 31 |
218
212
  | Miniapp Publish API | 0 | 5 | 2 | 0 | 0 |
219
213
  | Vite API | 0 | 1 | 0 | 0 | 0 |
@@ -20,10 +20,11 @@
20
20
  - [Vite plugin export](#vite-plugin-export)
21
21
  - [App-facing concepts](#app-facing-concepts)
22
22
  - [Public modules](#public-modules)
23
+ - [Cloud leaderboard](#cloud-leaderboard)
23
24
  ## Package metadata
24
25
 
25
26
  - Package: `@heybox/hb-sdk`
26
- - Version at generation time: `0.6.9`
27
+ - Version at generation time: `0.7.0-alpha.2`
27
28
  - Public root export: `@heybox/hb-sdk`
28
29
  - Protocol export: `@heybox/hb-sdk/protocol`
29
30
  - Vite plugin export: `@heybox/hb-sdk/vite`
@@ -33,12 +34,8 @@
33
34
  ```ts
34
35
  export { HbMiniProgramSDKError, HbMiniProgramNetworkError } from './core/errors';
35
36
  export { ready, on, off, auth, user, share, viewport, storage, network, ui, device, navigation, cloud } from './core/singleton';
36
- export type {
37
- MiniProgramEventHandler,
38
- MiniProgramEventName,
39
- MiniProgramEventPayloadMap,
40
- } from './protocol/types';
41
- export type { LoginPayload, LoginResult, MiniProgramAuthModule } from './modules/auth';
37
+ export type { MiniProgramEventHandler, MiniProgramEventName, MiniProgramEventPayloadMap } from './protocol/types';
38
+ export type { LoginOptions, LoginPayload, LoginResult, LoginScope, MiniProgramAuthModule } from './modules/auth';
42
39
  export type {
43
40
  DeleteCurrentUserLeaderboardEntryPayload,
44
41
  DeleteCurrentUserLeaderboardEntryResult,
@@ -56,47 +53,24 @@ export type {
56
53
  SubmitLeaderboardEntryResult,
57
54
  } from './modules/cloud';
58
55
  export type {
59
- BasePlatformAccountInfo,
60
- CurrentUserAvatarConfig,
61
- CurrentUserAvatarDecoration,
62
- CurrentUserBbsInfo,
63
- CurrentUserDetail,
64
- CurrentUserLevelInfo,
65
- CurrentUserMedal,
66
- CurrentUserProfile,
67
- EpicPlatformAccountInfo,
68
- GetCurrentUserDetailPayload,
69
- GetCurrentUserDetailResult,
70
- GetCurrentUserProfilePayload,
71
- GetCurrentUserProfileResult,
72
- GetPlatformAccountInfoPayload,
73
- GetPlatformAccountInfoResult,
74
- GetPlatformAccountOverviewPayload,
75
- GetPlatformAccountOverviewResult,
56
+ AuthorizedUserInfo,
57
+ GetLocalIdentityPayload,
58
+ GetLocalIdentityResult,
59
+ GetUserInfoPayload,
60
+ GetUserInfoResult,
61
+ RevokeAuthorizationPayload,
62
+ RevokeAuthorizationResult,
76
63
  GetSteamGameListOptions,
77
64
  GetSteamGameListPayload,
78
65
  GetSteamGameListResult,
79
- GetUserInfoPayload,
80
- GetUserInfoResult,
81
- MiniProgramUserInfo,
82
66
  MiniProgramUserInfoResult,
83
67
  MiniProgramUserModule,
84
- MobilePlatformAccountInfo,
85
- PcHardwareAccountInfo,
86
- PlatformAccountInfoMap,
87
- PlatformAccountOverview,
88
- PlatformAccountResult,
89
- PlatformAccountType,
90
- PlatformStatItem,
91
- PsnPlatformAccountInfo,
68
+ UserInfoAuthorization,
69
+ UserInfoAuthorizationStatus,
92
70
  SteamGameListData,
93
71
  SteamGameListItem,
94
- SteamGameListSort,
95
72
  SteamGamePrice,
96
- SteamPlatformAccountInfo,
97
- SwitchPlatformAccountInfo,
98
- UserScopedResult,
99
- XboxPlatformAccountInfo,
73
+ SteamGameListSort,
100
74
  } from './modules/user';
101
75
  export type {
102
76
  MiniProgramScreenshotOptions,
@@ -121,12 +95,7 @@ export type {
121
95
  SetNavigationBarStylePayload,
122
96
  SetNavigationBarStyleResult,
123
97
  } from './modules/viewport';
124
- export type {
125
- GetStoragePayload,
126
- GetStorageResult,
127
- MiniProgramStorageModule,
128
- SetStoragePayload,
129
- } from './modules/storage';
98
+ export type { GetStoragePayload, GetStorageResult, MiniProgramStorageModule, SetStoragePayload } from './modules/storage';
130
99
  export type {
131
100
  MiniProgramNetworkHeaders,
132
101
  MiniProgramNetworkModule,
@@ -391,63 +360,66 @@ hb-sdk build [--env <name>] [--verbose]
391
360
 
392
361
  # 快速开始
393
362
 
394
- 如果页面不需要小黑盒开放能力,可以不接入 SDK。这是最短接入路径:等待 SDK 就绪,然后读取当前用户登录态。
363
+ 如果页面不需要小黑盒开放能力,可以不接入 SDK。需要开放能力时,先等待 `ready()`,再根据小程序是否开通网络权限选择身份流程。
364
+
365
+ ## 未开通网络权限
366
+
367
+ 无网络小程序可以在本地能力中使用按小程序隔离的 `appUserId`:
395
368
 
396
369
  ```ts
397
- import hbSDK from '@heybox/hb-sdk'
370
+ import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
398
371
 
399
- async function bootstrap() {
372
+ async function getLocalIdentityFromUserAction() {
400
373
  await hbSDK.ready()
401
374
 
402
- const result = await hbSDK.user.getInfo()
403
- if (result.isLogin && result.userInfo) {
404
- console.log(result.userInfo.nickname)
405
- return
375
+ try {
376
+ const { appUserId } = await hbSDK.user.getLocalIdentity()
377
+ return appUserId
378
+ } catch (error) {
379
+ if (error instanceof HbMiniProgramSDKError && error.code === 'AUTHORIZATION_CANCELLED') {
380
+ return undefined
381
+ }
382
+ throw error
406
383
  }
407
-
408
- console.log('当前用户未登录')
409
384
  }
410
-
411
- bootstrap()
412
385
  ```
413
386
 
414
- ## 推荐业务写法
387
+ `getLocalIdentityFromUserAction` 绑定到按钮点击等可信用户操作。首次登录或 identity consent 需要 UI 而缺少可信手势时返回 `USER_GESTURE_REQUIRED`;取消或关闭时返回 `AUTHORIZATION_CANCELLED`,不会确认或改变授权状态。这条路径不能获取授权码或调用 OpenAPI,也不要把 `appUserId` 发送到外部服务。
415
388
 
416
- 业务页通常还需要监听登录态变化。下面以 Vue 3 为例:初始化只读取状态,登录必须由按钮等明确的用户操作触发,监听在组件卸载时清理。
389
+ ## 已开通网络权限
417
390
 
418
- ```ts
419
- import { onUnmounted } from 'vue'
420
- import hbSDK from '@heybox/hb-sdk'
391
+ 有网络小程序通过 `auth.login()` 获取短期授权码。登录可能展示 UI,因此应绑定到按钮点击等明确的用户操作:
421
392
 
422
- const stopAuthChange = hbSDK.on('authChange', result => {
423
- if (result.isLogin) {
424
- console.log('用户已登录', result.userInfo?.heybox_id)
425
- }
426
- })
393
+ ```ts
394
+ import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
427
395
 
428
396
  await hbSDK.ready()
429
397
 
430
- const initialUser = await hbSDK.user.getInfo()
431
-
432
398
  async function loginFromUserAction() {
433
- const result = await hbSDK.auth.login()
434
- if (!result.isLogin || !result.userInfo) {
435
- return
436
- }
399
+ try {
400
+ const result = await hbSDK.auth.login({ scopes: ['profile'] })
437
401
 
438
- console.log('用户已登录', result.userInfo.heybox_id)
402
+ await hbSDK.network.request({
403
+ url: 'https://api.example.com/session/heybox',
404
+ method: 'POST',
405
+ data: { code: result.code },
406
+ })
407
+ } catch (error) {
408
+ if (error instanceof HbMiniProgramSDKError && error.code === 'AUTHORIZATION_CANCELLED') {
409
+ return
410
+ }
411
+ throw error
412
+ }
439
413
  }
440
-
441
- onUnmounted(stopAuthChange)
442
414
  ```
443
415
 
444
- `loginFromUserAction` 绑定到登录按钮;不要在页面 bootstrap 阶段自动调用 `auth.login()`。
416
+ 返回值与边界以[用户身份与登录](/guide/auth)为准。页面只把 `code` 提交给自己的服务端。不要在页面初始化阶段自动调用 `auth.login()`。
445
417
 
446
418
  ## ready 的含义
447
419
 
448
- `ready()` 表示 SDK 已就绪,可以安全调用开放能力。如果当前不在可用的小程序运行环境中,它会抛出公开错误。`ready()` 不等价于“用户已登录”,用户状态需要通过 `user.getInfo()` 或 `authChange` 判断。
420
+ `ready()` 只表示 SDK 已就绪,可以安全调用开放能力。它不表示已经取得用户授权,也不返回用户身份。
449
421
 
450
- ## 默认单例适合什么场景
422
+ ## 默认单例
451
423
 
452
424
  大多数小程序页面都应该使用默认实例。0.6 起不再对业务代码提供独立实例工厂。
453
425
 
@@ -460,11 +432,7 @@ SDK 公开两类标准错误:
460
432
  - `HbMiniProgramNetworkError`:网络请求已返回,但 HTTP 状态未通过 `validateStatus`。
461
433
 
462
434
  ```ts
463
- import {
464
- HbMiniProgramNetworkError,
465
- HbMiniProgramSDKError,
466
- network,
467
- } from '@heybox/hb-sdk'
435
+ import { HbMiniProgramNetworkError, HbMiniProgramSDKError, network } from '@heybox/hb-sdk'
468
436
 
469
437
  try {
470
438
  await network.request({ url: 'https://api.example.com/data' })
@@ -487,6 +455,9 @@ try {
487
455
 
488
456
  - 根据 `error.code` 区分运行环境、权限、超时和业务失败,不要只比对错误文案。
489
457
  - 权限失败时给出可理解的提示,不要将它当成未登录。
458
+ - `USER_GESTURE_REQUIRED` 表示潜在授权 UI 缺少可信用户手势,应让用户点击按钮后重试。
459
+ - `AUTHORIZATION_CANCELLED` 表示用户取消、拒绝或关闭授权页面,应正常结束当前操作。
460
+ - `SERVER_API_REQUIRED` 表示当前用户数据必须经开发者服务端 OpenAPI 获取,不应在页面重试对应 Host API。
490
461
  - 超时或运行环境不可用时,允许用户重试或退出当前流程。
491
462
  - 上报 `code`、`message` 和必要的业务上下文,不要上报用户凭据或敏感数据。
492
463
 
@@ -497,16 +468,22 @@ try {
497
468
  ```ts
498
469
  import hbSDK, { HbMiniProgramSDKError } from '@heybox/hb-sdk'
499
470
 
500
- type UserViewState =
501
- | { status: 'ready'; user: Awaited<ReturnType<typeof hbSDK.user.getInfo>> }
471
+ type LoginViewState =
472
+ | { status: 'ready' }
473
+ | { status: 'cancelled' }
502
474
  | { status: 'failed'; error: HbMiniProgramSDKError }
503
475
 
504
- async function loadUser(): Promise<UserViewState> {
476
+ async function loginFromUserAction(): Promise<LoginViewState> {
505
477
  try {
506
478
  await hbSDK.ready()
507
- return { status: 'ready', user: await hbSDK.user.getInfo() }
479
+ const result = await hbSDK.auth.login()
480
+ await exchangeCodeWithDeveloperServer(result.code)
481
+ return { status: 'ready' }
508
482
  } catch (error) {
509
483
  if (error instanceof HbMiniProgramSDKError) {
484
+ if (error.code === 'AUTHORIZATION_CANCELLED') {
485
+ return { status: 'cancelled' }
486
+ }
510
487
  reportSDKError(error.code, error.message, error.data)
511
488
  return { status: 'failed', error }
512
489
  }
@@ -515,29 +492,39 @@ async function loadUser(): Promise<UserViewState> {
515
492
  }
516
493
  }
517
494
 
518
- function reportSDKError(code: string, message: string, data?: unknown) {
519
- console.log('[hb-sdk]', code, message, data)
495
+ async function exchangeCodeWithDeveloperServer(code: string) {
496
+ await hbSDK.network.request({
497
+ url: 'https://api.example.com/session/heybox',
498
+ method: 'POST',
499
+ data: { code },
500
+ })
501
+ }
502
+
503
+ function reportSDKError(errorCode: string, message: string, data?: unknown) {
504
+ console.log('[hb-sdk]', errorCode, message, data)
520
505
  }
521
506
  ```
522
507
 
508
+ 授权码在取得后立即交给开发者服务端交换,不要写入页面状态、DOM、日志或持久化存储。UI 只处理服务端会话是否建立成功。
509
+
523
510
  ## Public modules
524
511
 
525
512
  ## 能力概览
526
513
 
527
514
  除 `ready()` 外,SDK 还提供 `on()` 和 `off()` 处理前后台、登录态等生命周期事件。
528
515
 
529
- | 模块 | 用途 |
530
- | ------------ | -------------------------------- |
531
- | `auth` | 由用户操作触发登录 |
532
- | `user` | 读取当前用户、账号资料和游戏数据 |
533
- | `share` | 打开分享或截图分享流程 |
534
- | `ui` | 展示 Toast 和 Loading |
535
- | `device` | 调用振动和剪贴板能力 |
536
- | `navigation` | 关闭、刷新页面或打开小黑盒页面 |
537
- | `viewport` | 读取窗口信息和设置导航栏样式 |
538
- | `storage` | 读写当前小程序的隔离存储 |
539
- | `cloud` | 使用小程序云端排行榜 |
540
- | `network` | 发起经过平台授权的网络请求 |
516
+ | 模块 | 用途 |
517
+ | ------------ | ------------------------------------------------------------ |
518
+ | `auth` | 获取交给开发者服务端交换的短期授权码 |
519
+ | `user` | 使用 Host current-user APIs 或读取无网络小程序的本地隔离身份 |
520
+ | `share` | 打开分享或截图分享流程 |
521
+ | `ui` | 展示 Toast 和 Loading |
522
+ | `device` | 调用振动和剪贴板能力 |
523
+ | `navigation` | 关闭、刷新页面或打开小黑盒页面 |
524
+ | `viewport` | 读取窗口信息和设置导航栏样式 |
525
+ | `storage` | 读写当前小程序的隔离存储 |
526
+ | `cloud` | 使用小程序云端排行榜 |
527
+ | `network` | 发起经过平台授权的网络请求 |
541
528
 
542
529
  具体方法、参数和返回值以 [API Reference](https://docs.xiaoheihe.cn/hb_sdk/reference/) 为准,常见组合写法见 [Recipes](https://docs.xiaoheihe.cn/hb_sdk/recipes/)。
543
530
 
@@ -571,15 +558,15 @@ onUnmounted(stopLifecycleEvents)
571
558
 
572
559
  ## 事件列表
573
560
 
574
- | 事件 | 触发时机 | 典型用途 |
575
- | ------------ | ------------------------ | ------------------ |
576
- | `launch` | 小程序首次启动 | 初始化一次性数据 |
577
- | `ready` | SDK 可安全调用开放能力 | 标记 SDK 可用 |
578
- | `show` | 小程序页面展示 | 刷新可见态数据 |
579
- | `hide` | 小程序页面隐藏 | 暂停轮询、暂停播放 |
580
- | `unload` | 当前小程序运行环境终止 | 清理资源并停止请求 |
581
- | `error` | 小程序或开放能力运行异常 | 统一错误上报 |
582
- | `authChange` | 登录状态变化 | 刷新用户信息和权限 |
561
+ | 事件 | 触发时机 | 典型用途 |
562
+ | ------------------------- | ------------------------ | -------------------------------- |
563
+ | `launch` | 小程序首次启动 | 初始化一次性数据 |
564
+ | `ready` | SDK 可安全调用开放能力 | 标记 SDK 可用 |
565
+ | `show` | 小程序页面展示 | 刷新可见态数据 |
566
+ | `hide` | 小程序页面隐藏 | 暂停轮询、暂停播放 |
567
+ | `unload` | 当前小程序运行环境终止 | 清理资源并停止请求 |
568
+ | `error` | 小程序或开放能力运行异常 | 统一错误上报 |
569
+ | `heybox_app_login_change` | 黑盒 APP 登录状态变化 | 刷新依赖 Host 当前用户的本地能力 |
583
570
 
584
571
  完整载荷与事件名见:
585
572
 
@@ -590,7 +577,35 @@ onUnmounted(stopLifecycleEvents)
590
577
 
591
578
  - 初始化开放能力前先 `await ready()`。
592
579
  - UI 可见性相关逻辑放在 `show`、`hide`。
593
- - 用户状态不要只在页面加载时读一次,登录入口附近要监听 `authChange`。
580
+ - 使用 Host current-user APIs 的无网络小程序,可以在 `heybox_app_login_change` 后刷新本地状态。已开通网络权限的小程序使用 `auth.login()` 获取 code,并由开发者服务端维护业务会话。
594
581
  - 组件或页面销毁时清理 `on` 注册的监听,避免重复响应。
595
582
  - 事件只派发给注册当时存在的监听器,不会重放;一次性 `launch`/`ready` 状态应以 `ready()` Promise 为准。
596
583
  - 收到 `unload` 后,当前 SDK 上下文不可恢复,未完成请求会失败;不要在同一页面上下文继续重试能力调用。
584
+
585
+ ## 云端排行榜
586
+
587
+ 删除当前用户的排行榜成绩属于破坏性操作,只能在明确的用户操作和二次确认后执行:
588
+
589
+ ```ts
590
+ async function deleteMyLeaderboardEntryFromUserAction() {
591
+ const confirmed = window.confirm('确定删除自己的榜单成绩吗?');
592
+ if (!confirmed) return;
593
+
594
+ try {
595
+ await hbSDK.cloud.leaderboard.deleteCurrentUserEntry({ key: 'cube_run_total' });
596
+ } catch (error) {
597
+ if (error instanceof HbMiniProgramSDKError) {
598
+ console.error(error.code, error.message);
599
+ }
600
+ throw error;
601
+ }
602
+ }
603
+ ```
604
+
605
+ 排行榜记录的 `extra` 会展示给榜单中的其他读取者,只能包含公开展示必需的数据;不得写入个人身份信息(PII)、token、设备标识或非必要行为数据。
606
+
607
+ 管理员删除完整榜单及其排名记录时,必须显式传入匹配的榜单 key 进行确认:
608
+
609
+ ```bash
610
+ hb-sdk remote cloud leaderboard delete <key> --confirm <key>
611
+ ```
@@ -29,7 +29,7 @@
29
29
 
30
30
  Use the bundled `hb-sdk` CLI to create a workshop mini-program, open the local debugging page, test in the Heybox Mac or mobile App, or manage and publish a remote mini-program.
31
31
 
32
- `hb-sdk login` is for development and publishing commands only. It does not change `auth.login()`, `user.getInfo()`, or `network.request()` inside a mini-program.
32
+ `hb-sdk login` is for development and publishing commands only. It does not authorize mini-program users and does not change `auth.login()`, `user.getLocalIdentity()`, or `network.request()` inside a mini-program.
33
33
 
34
34
  ## Command surface
35
35
 
@@ -113,12 +113,12 @@ CLI 会启动页面服务并自动打开本地调试页。调试页会展示小
113
113
  浏览器 Mock 支持热更新,适合快速检查:
114
114
 
115
115
  - 页面布局和主要交互
116
- - SDK 初始化、用户状态与登录流程
116
+ - SDK 初始化与用户身份授权流程
117
117
  - 生命周期、Storage 和排行榜等能力
118
118
 
119
- Dev Context 中调整的 `network.request` 权限不会修改线上配置,但会持久化到 `hb-sdk` 用户级本地缓存,并按项目真实路径与启动时绑定的 `miniProgramId` 隔离;远端权限暂时读取失败时仍会使用已知绑定 scope。刷新调试页或重启 `hb-sdk dev` 后覆盖仍然生效,直到点击“恢复初始权限”;未绑定项目使用独立匿名 scope,之后绑定小程序时不会继承匿名覆盖。调试页会分别展示远端基线与本地覆盖,多页面或多进程写入同一 scope 时以最后成功写入的完整配置为准,不提供冲突合并。缓存写入失败时当前页面仍立即生效,并提示刷新或重启后会丢失。已绑定项目重置时会先重新读取远端权限,读取失败则保留当前覆盖;匿名项目直接清除本地覆盖。
119
+ Dev Context 中调整的权限只影响当前本地调试,不会修改线上配置。调试页会区分线上基线与本地覆盖;恢复初始权限后重新按远端配置验收。
120
120
 
121
- 切换权限后 Mobile App 二维码会自动重生成;二维码只携带使用 256-bit 随机 token 的 `dev_context_url`,并在 5 分钟后失效,调试页会在会话到期时自动生成新二维码。重新扫码后,Runtime Host 会拉取对应的不可变权限快照,再启动手机局域网预览。工坊小程序默认不能进行网络请求,网络权限暂未开放申请;不要把本地调试结果当成线上能力。
121
+ 切换权限后 Mobile App 二维码会自动重生成;旧二维码失效时按调试页提示重新扫码。工坊小程序默认不能进行网络请求,网络权限暂未开放申请;不要把本地调试结果当成线上能力。
122
122
 
123
123
  ### 3. 再用 Mac 或手机真机验收
124
124
 
@@ -127,20 +127,21 @@ Dev Context 中调整的 `network.request` 权限不会修改线上配置,但
127
127
  - 点击「在 Mac 版 APP 中启动」。
128
128
  - 在「Mobile App」区域选择局域网网卡,再用手机小黑盒 APP 扫码。
129
129
 
130
- 手机与电脑需要处于同一局域网。二维码无法访问时,先确认选择了正确的 **Network** 网卡。发布前至少完成一次真实客户端验收。
130
+ 手机与电脑需要处于同一局域网。二维码默认使用 HTTPS `open_inapp` 包装链接;需要二维码直接编码裸 `heybox://` 协议时,以 `hb-sdk dev --raw-protocol` 启动。二维码无法访问时,先确认选择了正确的 **Network** 网卡。发布前至少完成一次真实客户端验收。
131
131
 
132
132
  ### 浏览器 Mock 的边界
133
133
 
134
- 浏览器 Mock 用于提高开发效率,不代表正式线上环境。Dev Session 的网络请求只对绑定 token 的本机或局域网开发页面生效,通过本地代理转发,不使用黑盒原生凭据 adapter;`useOfficialDomain` 始终为 `false`。代理允许访问本机、局域网和保留地址,并对初始 URL 与每次重定向分别解析和固定连接地址。旧 `dev_network_request` query 不再授权,权限只能来自有效的不可变 Dev Session 快照。该方案不要求修改 Android/iOS 客户端;用户状态仍只保存在浏览器 Mock,线上权限、客户端兼容性和最终交互仍需按真实发布配置验收。
134
+ 浏览器 Mock 用于提高开发效率,不代表正式线上环境。本地网络调试通过开发工具转发,不提供黑盒原生凭据,也不能访问平台保留的 runtime auth OpenAPI 内部路径。线上权限、客户端兼容性和最终交互仍需按真实发布配置验收。
135
135
 
136
136
  ### 常用参数
137
137
 
138
- | 参数 | 用途 |
139
- | --------------------- | -------------------------------- |
140
- | `--port <port>` | 指定页面开发服务端口。 |
141
- | `--mock-port <port>` | 指定本地调试端口。 |
142
- | `--no-open` | 启动后不自动打开浏览器。 |
143
- | `--verbose` | 出现问题时输出更详细的诊断信息。 |
138
+ | 参数 | 用途 |
139
+ | -------------------- | ----------------------------------------- |
140
+ | `--port <port>` | 指定页面开发服务端口。 |
141
+ | `--mock-port <port>` | 指定本地调试端口。 |
142
+ | `--raw-protocol` | 让手机二维码直接编码裸 `heybox://` 协议。 |
143
+ | `--no-open` | 启动后不自动打开浏览器。 |
144
+ | `--verbose` | 出现问题时输出更详细的诊断信息。 |
144
145
 
145
146
  Use `hb-sdk dev` to open the local debugging page. The "在 Mac 版 APP 中启动" button opens the page in the Mac App; the "Mobile App" QR code opens it in the phone App after a LAN interface is selected. These entries remain available without CLI login or project binding, but managed capabilities are denied by default. The phone and computer must be on the same LAN. If an embedded browser cannot open the App, use the system browser.
146
147
 
@@ -196,13 +197,7 @@ hb-sdk remote deploy --release-note "修复登录状态展示"
196
197
 
197
198
  这条命令会完成检查、执行项目的 `scripts.build`、上传和提交审核,因此项目定义的类型检查仍会执行。默认在审核通过后等待手动发布;普通低风险版本可以追加 `--auto-publish`。完整命令见 `hb-sdk remote --help`,提交要求见[小程序工坊上架规则](https://docs.xiaoheihe.cn/hb_sdk/guide/mini-program-publishing-rules)。
198
199
 
199
- 构建产物上传从 `0.6.8` 起强制使用服务端上传 session,`0.6.7` 及更早版本不能继续部署,请先升级 `@heybox/hb-sdk`。deploy 从整包签名开始到上传结束都把 `dist/` 视为稳定输出,不要在此期间由其他进程修改构建目录;上传中断后可重新执行 deploy,服务端会按已确认回执恢复缺失文件。
200
-
201
- 普通 deploy 会按 API 环境、`miniProgramId` 和版本在本机缓存目录获取短文件锁,避免两个 CLI 进程同时构建并上传同一版本。进程异常退出后锁可按 PID 回收;缓存目录不可用时会降级为无锁执行,不影响上传主流程。`--from-version` 不执行本地构建和上传,因此不会获取该锁。
202
-
203
- 上传信息、上传凭证和上传回调按每批最多 50 个文件串行处理,批内保持 4 并发。CLI 每批获取一次仅授权当前 session 目录前缀的凭证,并校验服务端返回的 key 和 size 与本地文件完全一致;任何异常都会停止后续上传且不会提交审核。
204
-
205
- 普通构建上传时,CLI 会计算整包签名,并把相对路径和文件大小一起提交给服务端创建或恢复上传会话;同一账号下签名和文件清单一致时,服务端返回已有 session 与 `uploaded_keys`,CLI 只上传缺失文件。CLI 不保存本地上传会话缓存。构建产物变化时服务端会创建新的隔离目录,并尽力清理旧目录。上传回调在当前命令内失败会重试;仍失败时可重新执行 deploy,服务端根据 `uploaded_keys` 继续恢复,同 key 的 COS 重传是幂等的。
200
+ `0.6.7` 及更早版本不能继续部署,请先升级 `@heybox/hb-sdk`。部署期间不要由其他进程修改 `dist/`;上传中断后可重新执行同一命令恢复。
206
201
 
207
202
  Before publishing, `hb-sdk remote deploy` verifies that the bound mini-program belongs to the current developer account. If it does not, the command stops and asks the user to switch accounts.
208
203
 
@@ -255,7 +250,7 @@ Agent rules:
255
250
 
256
251
  ## CLI 登录态
257
252
 
258
- CLI 登录态只用于开发工具和远端管理,不等同于小程序内的用户登录态,也不会改变 `auth.login()` 或 `user.getInfo()` 的结果。
253
+ CLI 登录态只用于开发工具和远端管理,不等同于小程序内的用户登录态,也不会改变 `auth.login()`、`user.getLocalIdentity()` 或开发者服务端会话。
259
254
 
260
255
  ```bash
261
256
  hb-sdk login status