@heybox/hb-sdk 0.8.0-alpha.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +136 -422
  2. package/README.md +28 -18
  3. package/dist/cli-chunks/{build-qWzAbpS7.cjs → build-PYCNacya.cjs} +8 -5
  4. package/dist/cli-chunks/{context-CtS2Thp0.cjs → context-m2W2XbL0.cjs} +42 -59
  5. package/dist/cli-chunks/{create-PV5ua977.cjs → create-BdAg3WGA.cjs} +2 -2
  6. package/dist/cli-chunks/{dev-CwKbAm_H.cjs → dev-CyZuw7Yn.cjs} +76 -64
  7. package/dist/cli-chunks/{doctor-tJUGOYrm.cjs → doctor-DU8rCfUF.cjs} +1 -1
  8. package/dist/cli-chunks/{index-DVuD75Hr.cjs → index-DATObqzK.cjs} +2 -2
  9. package/dist/cli-chunks/{index-De687C6-.cjs → index-MMW2ibQm.cjs} +32 -21
  10. package/dist/cli-chunks/{index.esm-B-4yrLNm.cjs → index.esm-BiAaAUFC.cjs} +8 -8
  11. package/dist/cli-chunks/{login-DolpqD8K.cjs → login-B3TThMss.cjs} +2 -2
  12. package/dist/cli-chunks/{project-vite-1rvkK-M8.cjs → project-vite-BQj8YLI4.cjs} +1 -1
  13. package/dist/cli-chunks/{remote-rIAQE_G2.cjs → remote-DNvI7tHH.cjs} +57 -25
  14. package/dist/cli-chunks/{runtime-gate-DFjw66kF.cjs → runtime-gate-BEFp1w_s.cjs} +11 -3
  15. package/dist/cli-chunks/{runtime-permission-env-CjsCe5bp.cjs → runtime-permission-env-CtL8rsjB.cjs} +351 -0
  16. package/dist/cli-chunks/{session-CzaM2Cq3.cjs → session-DjBkjaF8.cjs} +1 -1
  17. package/dist/cli-chunks/{skill-CM40_9WH.cjs → skill-cR_wnaw2.cjs} +2 -2
  18. package/dist/cli-chunks/{version-Bz-AfXQU.cjs → version-yEn1E2Bg.cjs} +1 -1
  19. package/dist/cli.cjs +1 -1
  20. package/dist/devtools/browser-dev-host/assets/browser-dev-host-TzYf9L6C.js +99 -0
  21. package/dist/devtools/browser-dev-host/assets/{index-CeP6SLB3.js → index-C5MZZDa5.js} +4 -4
  22. package/dist/devtools/browser-dev-host/assets/index-P-ra4m1y.css +1 -0
  23. package/dist/devtools/browser-dev-host/assets/workbench-state-BwV7bm4n.js +5 -0
  24. package/dist/devtools/browser-dev-host/index.html +3 -3
  25. package/dist/index.cjs.js +100 -2
  26. package/dist/index.esm.js +100 -2
  27. package/dist/protocol.cjs.js +189 -47
  28. package/dist/protocol.esm.js +189 -47
  29. package/dist/templates/{vue3-vite-ts → vanilla-vite-js}/.gitignore.ejs +0 -1
  30. package/dist/templates/vanilla-vite-js/README.md.ejs +14 -0
  31. package/dist/templates/vanilla-vite-js/index.html.ejs +20 -0
  32. package/dist/templates/vanilla-vite-js/package.json.ejs +22 -0
  33. package/dist/templates/vanilla-vite-js/src/assets/heybox-logo.svg +8 -0
  34. package/dist/templates/vanilla-vite-js/src/main.js +39 -0
  35. package/dist/templates/vanilla-vite-js/src/styles.css +155 -0
  36. package/dist/templates/{vue3-vite-ts/vite.config.ts → vanilla-vite-js/vite.config.js} +1 -2
  37. package/dist/vite.cjs.js +281 -13
  38. package/dist/vite.esm.js +281 -13
  39. package/package.json +13 -9
  40. package/skill/SKILL.md +8 -9
  41. package/skill/references/api-protocol.md +1 -3
  42. package/skill/references/api-root.md +65 -21
  43. package/skill/references/cli.md +17 -5
  44. package/skill/references/examples.md +3 -3
  45. package/skill/references/recipes.md +40 -41
  46. package/skill/references/safety-boundaries.md +9 -5
  47. package/skill/skill.json +5 -5
  48. package/types/core/mini-dev-console.d.ts +36 -0
  49. package/types/miniapp-manifest/index.d.ts +1 -0
  50. package/types/miniapp-manifest/node.d.ts +3 -0
  51. package/types/miniapp-manifest/permissions.d.ts +37 -0
  52. package/types/miniapp-manifest/schema.d.ts +5 -0
  53. package/types/modules/share/index.d.ts +1 -1
  54. package/types/modules/share/show-share-menu.d.ts +1 -1
  55. package/types/modules/share/types.d.ts +2 -4
  56. package/types/vite/index.d.ts +3 -1
  57. package/dist/devtools/browser-dev-host/assets/browser-dev-host-uq-Wac6k.js +0 -97
  58. package/dist/devtools/browser-dev-host/assets/index-KD2f3Jdz.css +0 -1
  59. package/dist/devtools/browser-dev-host/assets/workbench-state-D-1U0JRq.js +0 -5
  60. package/dist/templates/vue3-vite-ts/README.md.ejs +0 -47
  61. package/dist/templates/vue3-vite-ts/index.html.ejs +0 -12
  62. package/dist/templates/vue3-vite-ts/package.json.ejs +0 -33
  63. package/dist/templates/vue3-vite-ts/src/App.vue +0 -78
  64. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +0 -148
  65. package/dist/templates/vue3-vite-ts/src/auth-handoff.ts +0 -46
  66. package/dist/templates/vue3-vite-ts/src/main.ts +0 -5
  67. package/dist/templates/vue3-vite-ts/src/styles.css +0 -60
  68. package/dist/templates/vue3-vite-ts/src/vite-env.d.ts +0 -1
  69. package/dist/templates/vue3-vite-ts/tsconfig.app.json +0 -17
  70. package/dist/templates/vue3-vite-ts/tsconfig.json +0 -11
  71. package/dist/templates/vue3-vite-ts/tsconfig.node.json +0 -11
  72. package/dist/templates/vue3-vite-ts/vitest.config.ts +0 -10
@@ -40,135 +40,249 @@ const CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.getCu
40
40
  const CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.deleteCurrentUserEntry';
41
41
  const CLOUD_LEADERBOARD_GET_INFO_METHOD = 'cloud.leaderboard.getInfo';
42
42
  const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
43
- { method: AUTH_LOGIN_METHOD, module: 'auth', capability: AUTH_LOGIN_METHOD, permission: 'auth.login', risk: 'medium' },
44
- { method: USER_GET_INFO_METHOD, module: 'user', capability: USER_GET_INFO_METHOD, permission: 'user.getInfo', risk: 'medium' },
43
+ {
44
+ method: AUTH_LOGIN_METHOD,
45
+ module: 'auth',
46
+ capability: AUTH_LOGIN_METHOD,
47
+ requirement: { kind: 'all', permissions: ['userInfo'] },
48
+ risk: 'medium',
49
+ },
50
+ {
51
+ method: USER_GET_INFO_METHOD,
52
+ module: 'user',
53
+ capability: USER_GET_INFO_METHOD,
54
+ requirement: { kind: 'all', permissions: ['userInfo'] },
55
+ risk: 'medium',
56
+ },
45
57
  {
46
58
  method: USER_REVOKE_AUTHORIZATION_METHOD,
47
59
  module: 'user',
48
60
  capability: USER_REVOKE_AUTHORIZATION_METHOD,
49
- permission: 'user.revokeAuthorization',
61
+ requirement: { kind: 'none' },
50
62
  risk: 'high',
51
63
  },
52
64
  {
53
65
  method: USER_GET_STEAM_GAME_LIST_METHOD,
54
66
  module: 'user',
55
67
  capability: USER_GET_STEAM_GAME_LIST_METHOD,
56
- permission: 'user.platformAccount.steam',
68
+ requirement: { kind: 'all', permissions: ['steamLibrary'] },
57
69
  risk: 'high',
58
70
  },
59
- { method: SHARE_COPY_LINK_METHOD, module: 'share', capability: SHARE_COPY_LINK_METHOD, permission: 'share.copyLink', risk: 'medium' },
60
- { method: SHARE_SHOW_SHARE_MENU_METHOD, module: 'share', capability: SHARE_SHOW_SHARE_MENU_METHOD, permission: 'share.basic', risk: 'low' },
61
- { method: SHARE_SCREENSHOT_METHOD, module: 'share', capability: SHARE_SCREENSHOT_METHOD, permission: 'share.screenshot', risk: 'medium' },
71
+ {
72
+ method: SHARE_COPY_LINK_METHOD,
73
+ module: 'share',
74
+ capability: SHARE_COPY_LINK_METHOD,
75
+ requirement: { kind: 'all', permissions: ['share'] },
76
+ risk: 'medium',
77
+ },
78
+ {
79
+ method: SHARE_SHOW_SHARE_MENU_METHOD,
80
+ module: 'share',
81
+ capability: SHARE_SHOW_SHARE_MENU_METHOD,
82
+ requirement: { kind: 'all', permissions: ['share'] },
83
+ risk: 'low',
84
+ },
85
+ {
86
+ method: SHARE_SCREENSHOT_METHOD,
87
+ module: 'share',
88
+ capability: SHARE_SCREENSHOT_METHOD,
89
+ requirement: { kind: 'all', permissions: ['share'] },
90
+ risk: 'medium',
91
+ },
62
92
  {
63
93
  method: VIEWPORT_GET_WINDOW_INFO_METHOD,
64
94
  module: 'viewport',
65
95
  capability: VIEWPORT_GET_WINDOW_INFO_METHOD,
66
- permission: 'viewport.windowInfo',
96
+ requirement: { kind: 'none' },
67
97
  risk: 'low',
68
98
  },
69
99
  {
70
100
  method: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
71
101
  module: 'viewport',
72
102
  capability: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
73
- permission: 'viewport.navigationBarStyle',
103
+ requirement: { kind: 'none' },
74
104
  risk: 'low',
75
105
  },
76
- { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
77
- { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
78
- { method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
79
- { method: NETWORK_DOWNLOAD_METHOD, module: 'network', capability: NETWORK_DOWNLOAD_METHOD, permission: 'network.request', risk: 'high' },
80
- { method: FILES_PICK_FILES_METHOD, module: 'files', capability: FILES_PICK_FILES_METHOD, permission: 'files.external', risk: 'high' },
106
+ {
107
+ method: STORAGE_GET_STORAGE_METHOD,
108
+ module: 'storage',
109
+ capability: STORAGE_GET_STORAGE_METHOD,
110
+ requirement: { kind: 'all', permissions: ['storage'] },
111
+ risk: 'low',
112
+ },
113
+ {
114
+ method: STORAGE_SET_STORAGE_METHOD,
115
+ module: 'storage',
116
+ capability: STORAGE_SET_STORAGE_METHOD,
117
+ requirement: { kind: 'all', permissions: ['storage'] },
118
+ risk: 'medium',
119
+ },
120
+ {
121
+ method: NETWORK_REQUEST_METHOD,
122
+ module: 'network',
123
+ capability: NETWORK_REQUEST_METHOD,
124
+ requirement: { kind: 'all', permissions: ['network'] },
125
+ risk: 'high',
126
+ },
127
+ {
128
+ method: NETWORK_DOWNLOAD_METHOD,
129
+ module: 'network',
130
+ capability: NETWORK_DOWNLOAD_METHOD,
131
+ requirement: { kind: 'all', permissions: ['network', 'filesystem'] },
132
+ risk: 'high',
133
+ },
134
+ {
135
+ method: FILES_PICK_FILES_METHOD,
136
+ module: 'files',
137
+ capability: FILES_PICK_FILES_METHOD,
138
+ requirement: { kind: 'all', permissions: ['filesystem'] },
139
+ risk: 'high',
140
+ },
81
141
  {
82
142
  method: FILES_PICK_DIRECTORY_METHOD,
83
143
  module: 'files',
84
144
  capability: FILES_PICK_DIRECTORY_METHOD,
85
- permission: 'files.external',
145
+ requirement: { kind: 'all', permissions: ['filesystem'] },
146
+ risk: 'high',
147
+ },
148
+ {
149
+ method: FILES_SAVE_FILE_METHOD,
150
+ module: 'files',
151
+ capability: FILES_SAVE_FILE_METHOD,
152
+ requirement: { kind: 'all', permissions: ['filesystem'] },
153
+ risk: 'high',
154
+ },
155
+ {
156
+ method: FILE_CREATE_METHOD,
157
+ module: 'file',
158
+ capability: FILE_CREATE_METHOD,
159
+ requirement: { kind: 'all', permissions: ['filesystem'] },
160
+ risk: 'high',
161
+ },
162
+ {
163
+ method: FILE_REMOVE_METHOD,
164
+ module: 'file',
165
+ capability: FILE_REMOVE_METHOD,
166
+ requirement: { kind: 'all', permissions: ['filesystem'] },
86
167
  risk: 'high',
87
168
  },
88
- { method: FILES_SAVE_FILE_METHOD, module: 'files', capability: FILES_SAVE_FILE_METHOD, permission: 'files.external', risk: 'high' },
89
- { method: FILE_CREATE_METHOD, module: 'file', capability: FILE_CREATE_METHOD, permission: 'files.access', risk: 'high' },
90
- { method: FILE_REMOVE_METHOD, module: 'file', capability: FILE_REMOVE_METHOD, permission: 'files.access', risk: 'high' },
91
- { method: FILE_EXISTS_METHOD, module: 'file', capability: FILE_EXISTS_METHOD, permission: 'files.access', risk: 'high' },
92
- { method: FILE_READ_TEXT_METHOD, module: 'file', capability: FILE_READ_TEXT_METHOD, permission: 'files.access', risk: 'high' },
93
- { method: FILE_WRITE_TEXT_METHOD, module: 'file', capability: FILE_WRITE_TEXT_METHOD, permission: 'files.access', risk: 'high' },
94
- { method: FILE_READ_BYTES_METHOD, module: 'file', capability: FILE_READ_BYTES_METHOD, permission: 'files.access', risk: 'high' },
95
- { method: FILE_WRITE_BYTES_METHOD, module: 'file', capability: FILE_WRITE_BYTES_METHOD, permission: 'files.access', risk: 'high' },
96
- { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, permission: 'files.access', risk: 'high' },
169
+ {
170
+ method: FILE_EXISTS_METHOD,
171
+ module: 'file',
172
+ capability: FILE_EXISTS_METHOD,
173
+ requirement: { kind: 'all', permissions: ['filesystem'] },
174
+ risk: 'high',
175
+ },
176
+ {
177
+ method: FILE_READ_TEXT_METHOD,
178
+ module: 'file',
179
+ capability: FILE_READ_TEXT_METHOD,
180
+ requirement: { kind: 'all', permissions: ['filesystem'] },
181
+ risk: 'high',
182
+ },
183
+ {
184
+ method: FILE_WRITE_TEXT_METHOD,
185
+ module: 'file',
186
+ capability: FILE_WRITE_TEXT_METHOD,
187
+ requirement: { kind: 'all', permissions: ['filesystem'] },
188
+ risk: 'high',
189
+ },
190
+ {
191
+ method: FILE_READ_BYTES_METHOD,
192
+ module: 'file',
193
+ capability: FILE_READ_BYTES_METHOD,
194
+ requirement: { kind: 'all', permissions: ['filesystem'] },
195
+ risk: 'high',
196
+ },
197
+ {
198
+ method: FILE_WRITE_BYTES_METHOD,
199
+ module: 'file',
200
+ capability: FILE_WRITE_BYTES_METHOD,
201
+ requirement: { kind: 'all', permissions: ['filesystem'] },
202
+ risk: 'high',
203
+ },
204
+ { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, requirement: { kind: 'all', permissions: ['filesystem'] }, risk: 'high' },
97
205
  {
98
206
  method: DIRECTORY_CREATE_METHOD,
99
207
  module: 'directory',
100
208
  capability: DIRECTORY_CREATE_METHOD,
101
- permission: 'files.access',
209
+ requirement: { kind: 'all', permissions: ['filesystem'] },
102
210
  risk: 'high',
103
211
  },
104
212
  {
105
213
  method: DIRECTORY_REMOVE_METHOD,
106
214
  module: 'directory',
107
215
  capability: DIRECTORY_REMOVE_METHOD,
108
- permission: 'files.access',
216
+ requirement: { kind: 'all', permissions: ['filesystem'] },
109
217
  risk: 'high',
110
218
  },
111
219
  {
112
220
  method: DIRECTORY_EXISTS_METHOD,
113
221
  module: 'directory',
114
222
  capability: DIRECTORY_EXISTS_METHOD,
115
- permission: 'files.access',
223
+ requirement: { kind: 'all', permissions: ['filesystem'] },
224
+ risk: 'high',
225
+ },
226
+ {
227
+ method: DIRECTORY_LIST_METHOD,
228
+ module: 'directory',
229
+ capability: DIRECTORY_LIST_METHOD,
230
+ requirement: { kind: 'all', permissions: ['filesystem'] },
116
231
  risk: 'high',
117
232
  },
118
- { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
119
- { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
120
- { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
121
- { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
122
- { method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, permission: 'device.vibrate', risk: 'low' },
233
+ { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, requirement: { kind: 'none' }, risk: 'low' },
234
+ { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
235
+ { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
236
+ { method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, requirement: { kind: 'none' }, risk: 'low' },
123
237
  {
124
238
  method: DEVICE_SET_CLIPBOARD_METHOD,
125
239
  module: 'device',
126
240
  capability: DEVICE_SET_CLIPBOARD_METHOD,
127
- permission: 'device.clipboard.write',
241
+ requirement: { kind: 'all', permissions: ['clipboard'] },
128
242
  risk: 'medium',
129
243
  },
130
- { method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, permission: 'navigation.close', risk: 'medium' },
131
- { method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, permission: 'navigation.reload', risk: 'medium' },
244
+ { method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, requirement: { kind: 'none' }, risk: 'medium' },
245
+ { method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, requirement: { kind: 'none' }, risk: 'medium' },
132
246
  {
133
247
  method: NAVIGATION_OPEN_APP_PAGE_METHOD,
134
248
  module: 'navigation',
135
249
  capability: NAVIGATION_OPEN_APP_PAGE_METHOD,
136
- permission: 'navigation.openAppPage',
250
+ requirement: { kind: 'none' },
137
251
  risk: 'medium',
138
252
  },
139
253
  {
140
254
  method: CLOUD_LEADERBOARD_SUBMIT_METHOD,
141
255
  module: 'cloud',
142
256
  capability: CLOUD_LEADERBOARD_SUBMIT_METHOD,
143
- permission: 'cloud.leaderboard.write',
257
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
144
258
  risk: 'medium',
145
259
  },
146
260
  {
147
261
  method: CLOUD_LEADERBOARD_GET_LIST_METHOD,
148
262
  module: 'cloud',
149
263
  capability: CLOUD_LEADERBOARD_GET_LIST_METHOD,
150
- permission: 'cloud.leaderboard.read',
264
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
151
265
  risk: 'low',
152
266
  },
153
267
  {
154
268
  method: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
155
269
  module: 'cloud',
156
270
  capability: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
157
- permission: 'cloud.leaderboard.currentUserEntry.read',
271
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
158
272
  risk: 'medium',
159
273
  },
160
274
  {
161
275
  method: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
162
276
  module: 'cloud',
163
277
  capability: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
164
- permission: 'cloud.leaderboard.currentUserEntry.delete',
278
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
165
279
  risk: 'medium',
166
280
  },
167
281
  {
168
282
  method: CLOUD_LEADERBOARD_GET_INFO_METHOD,
169
283
  module: 'cloud',
170
284
  capability: CLOUD_LEADERBOARD_GET_INFO_METHOD,
171
- permission: 'cloud.leaderboard.info.read',
285
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
172
286
  risk: 'low',
173
287
  },
174
288
  ];
@@ -313,7 +427,19 @@ function isRecord$1(value) {
313
427
  /** 当前用户信息与登录能力支持的完整 scope 目录。 */
314
428
  const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile'];
315
429
 
316
- const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
430
+ const MINI_PROGRAM_PERMISSION_KEYS = [
431
+ 'userInfo',
432
+ 'steamLibrary',
433
+ 'share',
434
+ 'storage',
435
+ 'filesystem',
436
+ 'clipboard',
437
+ 'leaderboard',
438
+ 'network',
439
+ ];
440
+ new Set(MINI_PROGRAM_PERMISSION_KEYS);
441
+
442
+ const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(MINI_PROGRAM_PERMISSION_KEYS);
317
443
  function isManagedMiniProgramRuntimePermissionKey(key) {
318
444
  return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
319
445
  }
@@ -330,20 +456,36 @@ function parseMiniProgramRuntimePermissions(snapshot) {
330
456
  if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
331
457
  return { valid: false, permissions: {} };
332
458
  }
333
- const key = rawEntry.key.trim();
334
- if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
459
+ const inputKey = rawEntry.key.trim();
460
+ const key = inputKey === 'network.request' ? 'network' : inputKey;
461
+ if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled')) {
335
462
  return { valid: false, permissions: {} };
336
463
  }
337
464
  seenKeys.add(key);
338
- if (!isManagedMiniProgramRuntimePermissionKey(key))
465
+ if (!isManagedMiniProgramRuntimePermissionKey(key)) {
466
+ if (!isRecord(rawEntry.config))
467
+ return { valid: false, permissions: {} };
468
+ continue;
469
+ }
470
+ if (key === 'network') {
471
+ const config = rawEntry.config;
472
+ if (!isRecord(config) || typeof config.useOfficialDomain !== 'boolean') {
473
+ return { valid: false, permissions: {} };
474
+ }
475
+ permissions[key] = {
476
+ key,
477
+ status: rawEntry.status,
478
+ config: { useOfficialDomain: config.useOfficialDomain },
479
+ };
339
480
  continue;
340
- if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
481
+ }
482
+ if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
341
483
  return { valid: false, permissions: {} };
342
484
  }
343
485
  permissions[key] = {
344
486
  key,
345
487
  status: rawEntry.status,
346
- config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
488
+ config: {},
347
489
  };
348
490
  }
349
491
  return { valid: true, permissions };
@@ -1,5 +1,4 @@
1
1
  node_modules
2
2
  dist
3
- coverage
4
3
  *.local
5
4
  .DS_Store
@@ -0,0 +1,14 @@
1
+ # <%= projectName %>
2
+
3
+ ## 命令
4
+
5
+ ```bash
6
+ npm install
7
+ npm run dev
8
+ npm run build
9
+ npm run deploy -- --release-note "更新说明"
10
+ ```
11
+
12
+ `vite.config.js` 默认声明 `android`、`ios`、`ohos`。发布前请在每个声明的平台完成真机验收;需要支持桌面平台时,由项目自行加入并验收。
13
+
14
+ 更多内容见 [CLI 指南](https://docs.xiaoheihe.cn/hb_sdk/guide/cli) 和 [SDK 文档](https://docs.xiaoheihe.cn/hb_sdk/)。
@@ -0,0 +1,20 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <title><%= projectName %></title>
7
+ </head>
8
+ <body>
9
+ <main class="page">
10
+ <div class="content">
11
+ <img class="logo" src="/src/assets/heybox-logo.svg" alt="小黑盒" />
12
+ <h1>Hello, World!</h1>
13
+ <p class="welcome">欢迎来到小黑盒小程序工坊</p>
14
+ <button type="button" data-testid="greeting-button">打个招呼</button>
15
+ <p class="error" data-testid="greeting-error" role="status" aria-live="polite"></p>
16
+ </div>
17
+ </main>
18
+ <script type="module" src="/src/main.js"></script>
19
+ </body>
20
+ </html>
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "<%= packageName %>",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "heybox": {
7
+ "miniProgramId": "",
8
+ "permissions": {}
9
+ },
10
+ "scripts": {
11
+ "hb-sdk": "hb-sdk",
12
+ "dev": "hb-sdk dev",
13
+ "build": "hb-sdk build",
14
+ "deploy": "hb-sdk remote deploy"
15
+ },
16
+ "dependencies": {
17
+ "@heybox/hb-sdk": "^<%= sdkVersion %>"
18
+ },
19
+ "devDependencies": {
20
+ "vite": "^8.0.12"
21
+ }
22
+ }
@@ -0,0 +1,8 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path
3
+ fill-rule="evenodd"
4
+ clip-rule="evenodd"
5
+ d="M16.5 6.59477C16.5 6.43342 16.3831 6.23597 16.2396 6.15586L10.2098 2.76306C10.0663 2.68296 9.94826 2.61751 9.94595 2.61864C9.94363 2.61977 9.82561 2.55433 9.68212 2.47422L8.89989 2.03418C8.75641 1.95407 8.63953 2.01952 8.63953 2.18086V8.42036C8.63953 8.5817 8.77376 8.71259 8.93923 8.71259H10.9584C11.1251 8.71259 11.2593 8.5817 11.2593 8.42036V6.74032C11.2593 6.57897 11.3762 6.51353 11.5197 6.59364L13.6187 7.7761C13.7622 7.85621 13.8791 8.05366 13.8791 8.21501V14.8562C13.8791 15.0175 13.9959 15.083 14.1394 15.0029L16.2396 13.8215C16.3831 13.7414 16.5 13.544 16.5 13.3826V6.59477ZM9.03937 11.2825C8.87383 11.2825 8.73954 11.4133 8.73954 11.5745L8.74301 13.2518C8.74301 13.413 8.62609 13.4784 8.48254 13.3983L6.3814 12.2181C6.23901 12.1381 6.12208 11.9408 6.12208 11.7796V5.14365C6.12208 4.98246 6.00516 4.91708 5.86161 4.99711L3.76047 6.17732C3.61692 6.25735 3.5 6.45462 3.5 6.61581V13.3972C3.5 13.5584 3.61692 13.7557 3.76047 13.8357L8.02642 16.2344C8.16997 16.3145 8.2869 16.381 8.2869 16.3821C8.2869 16.3832 8.40266 16.4497 8.54621 16.5298L11.1 17.9658C11.2435 18.0459 11.3605 17.9805 11.3605 17.8193V11.5745C11.3593 11.4133 11.225 11.2825 11.0595 11.2825H9.03937Z"
6
+ fill="#14191E"
7
+ />
8
+ </svg>
@@ -0,0 +1,39 @@
1
+ import hbSDK from '@heybox/hb-sdk';
2
+ import './styles.css';
3
+
4
+ const greetingButton = document.querySelector('[data-testid="greeting-button"]');
5
+ const greetingError = document.querySelector('[data-testid="greeting-error"]');
6
+ const colorScheme = window.matchMedia('(prefers-color-scheme: dark)');
7
+
8
+ async function greet() {
9
+ greetingButton.disabled = true;
10
+ greetingButton.setAttribute('aria-busy', 'true');
11
+ greetingError.textContent = '';
12
+
13
+ try {
14
+ await hbSDK.ui.showToast({
15
+ message: '欢迎来到小黑盒小程序工坊',
16
+ status: 'success',
17
+ });
18
+ } catch (error) {
19
+ console.error('无法显示欢迎提示', error);
20
+ greetingError.textContent = '欢迎提示无法显示,请重试';
21
+ } finally {
22
+ greetingButton.disabled = false;
23
+ greetingButton.setAttribute('aria-busy', 'false');
24
+ }
25
+ }
26
+
27
+ function syncNavigationBar() {
28
+ hbSDK.viewport
29
+ .setNavigationBarStyle({ foregroundStyle: colorScheme.matches ? 'light' : 'dark' })
30
+ .catch((error) => console.error('无法同步导航栏样式', error));
31
+ }
32
+
33
+ greetingButton.addEventListener('click', greet);
34
+ if (typeof colorScheme.addEventListener === 'function') {
35
+ colorScheme.addEventListener('change', syncNavigationBar);
36
+ } else if (typeof colorScheme.addListener === 'function') {
37
+ colorScheme.addListener(syncNavigationBar);
38
+ }
39
+ syncNavigationBar();
@@ -0,0 +1,155 @@
1
+ :root {
2
+ --page-background: #f7f8f9;
3
+ --text-primary: #14191e;
4
+ --text-secondary: #64696e;
5
+ --button-background: #14191e;
6
+ --button-foreground: #ffffff;
7
+ --button-hover: #393d40;
8
+ --button-pressed: #000000;
9
+ --button-disabled: #c8cdd2;
10
+ --focus-ring: #009015;
11
+ --error: #c92228;
12
+ color-scheme: light dark;
13
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
14
+ color: var(--text-primary);
15
+ background: var(--page-background);
16
+ }
17
+
18
+ * {
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ html,
23
+ body {
24
+ margin: 0;
25
+ min-width: 0;
26
+ min-height: 100%;
27
+ background: var(--page-background);
28
+ }
29
+
30
+ body {
31
+ min-height: 100vh;
32
+ min-height: 100dvh;
33
+ }
34
+
35
+ .page {
36
+ display: grid;
37
+ min-height: 100vh;
38
+ min-height: 100dvh;
39
+ place-items: center;
40
+ padding: max(32px, env(safe-area-inset-top)) max(24px, env(safe-area-inset-right)) max(32px, env(safe-area-inset-bottom))
41
+ max(24px, env(safe-area-inset-left));
42
+ }
43
+
44
+ .content {
45
+ width: min(100%, 360px);
46
+ text-align: center;
47
+ }
48
+
49
+ .logo {
50
+ display: block;
51
+ width: 36px;
52
+ height: 36px;
53
+ margin: 0 auto 32px;
54
+ object-fit: contain;
55
+ }
56
+
57
+ h1 {
58
+ margin: 0;
59
+ color: var(--text-primary);
60
+ font-size: 32px;
61
+ line-height: 1.25;
62
+ letter-spacing: 0;
63
+ }
64
+
65
+ .welcome {
66
+ margin: 12px 0 32px;
67
+ color: var(--text-secondary);
68
+ font-size: 16px;
69
+ line-height: 1.5;
70
+ }
71
+
72
+ button {
73
+ width: 160px;
74
+ min-height: 48px;
75
+ border: 0;
76
+ border-radius: 6px;
77
+ color: var(--button-foreground);
78
+ background: var(--button-background);
79
+ font: inherit;
80
+ font-weight: 600;
81
+ cursor: pointer;
82
+ transition:
83
+ background-color 160ms ease,
84
+ transform 160ms ease;
85
+ }
86
+
87
+ button:active:not(:disabled) {
88
+ background: var(--button-pressed);
89
+ transform: scale(0.98);
90
+ }
91
+
92
+ button:focus-visible {
93
+ outline: 3px solid var(--focus-ring);
94
+ outline-offset: 3px;
95
+ }
96
+
97
+ button:disabled {
98
+ background: var(--button-disabled);
99
+ cursor: wait;
100
+ }
101
+
102
+ .error {
103
+ min-height: 24px;
104
+ margin: 12px 0 0;
105
+ color: var(--error);
106
+ font-size: 14px;
107
+ line-height: 24px;
108
+ }
109
+
110
+ @media (hover: hover) {
111
+ button:hover:not(:disabled) {
112
+ background: var(--button-hover);
113
+ }
114
+ }
115
+
116
+ @media (prefers-color-scheme: dark) {
117
+ :root {
118
+ --page-background: #14191e;
119
+ --text-primary: #f7f8f9;
120
+ --text-secondary: #91959a;
121
+ --button-background: #f7f8f9;
122
+ --button-foreground: #14191e;
123
+ --button-hover: #ffffff;
124
+ --button-pressed: #c4c8cc;
125
+ --button-disabled: #696e72;
126
+ --focus-ring: #32b846;
127
+ --error: #fa3c4b;
128
+ }
129
+
130
+ .logo {
131
+ filter: invert(1);
132
+ }
133
+ }
134
+
135
+ @media (max-height: 420px) and (orientation: landscape) {
136
+ .page {
137
+ place-items: start center;
138
+ padding-top: max(20px, env(safe-area-inset-top));
139
+ padding-bottom: max(20px, env(safe-area-inset-bottom));
140
+ }
141
+
142
+ .logo {
143
+ margin-bottom: 16px;
144
+ }
145
+
146
+ .welcome {
147
+ margin-bottom: 20px;
148
+ }
149
+ }
150
+
151
+ @media (prefers-reduced-motion: reduce) {
152
+ button {
153
+ transition: none;
154
+ }
155
+ }
@@ -1,8 +1,7 @@
1
- import vue from '@vitejs/plugin-vue';
2
1
  import { miniappManifest } from '@heybox/hb-sdk/vite';
3
2
  import { defineConfig } from 'vite';
4
3
 
5
4
  export default defineConfig({
6
5
  base: './',
7
- plugins: [vue(), miniappManifest({ platforms: ['android', 'ios', 'ohos'] })],
6
+ plugins: [miniappManifest({ platforms: ['android', 'ios', 'ohos'] })],
8
7
  });