@heybox/hb-sdk-protocol 0.8.0-alpha.9 → 0.8.1-alpha.1

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.
@@ -79,6 +79,7 @@ import type {
79
79
  VibratePayload,
80
80
  VibrateResult,
81
81
  } from './payloads';
82
+ import type { MiniProgramPermissionRequirement } from './permission-catalog';
82
83
 
83
84
  export const AUTH_LOGIN_METHOD = 'auth.login' as const;
84
85
  export const USER_GET_INFO_METHOD = 'user.getInfo' as const;
@@ -186,140 +187,254 @@ export interface MiniProgramCapabilityDefinition {
186
187
  method: MiniProgramBridgeMethod;
187
188
  module: MiniProgramCapabilityModule;
188
189
  capability: MiniProgramBridgeMethod;
189
- permission: string;
190
+ requirement: MiniProgramPermissionRequirement;
190
191
  risk: MiniProgramCapabilityRisk;
191
192
  }
192
193
 
193
194
  export const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
194
- { method: AUTH_LOGIN_METHOD, module: 'auth', capability: AUTH_LOGIN_METHOD, permission: 'auth.login', risk: 'medium' },
195
- { method: USER_GET_INFO_METHOD, module: 'user', capability: USER_GET_INFO_METHOD, permission: 'user.getInfo', risk: 'medium' },
195
+ {
196
+ method: AUTH_LOGIN_METHOD,
197
+ module: 'auth',
198
+ capability: AUTH_LOGIN_METHOD,
199
+ requirement: { kind: 'all', permissions: ['userInfo'] },
200
+ risk: 'medium',
201
+ },
202
+ {
203
+ method: USER_GET_INFO_METHOD,
204
+ module: 'user',
205
+ capability: USER_GET_INFO_METHOD,
206
+ requirement: { kind: 'all', permissions: ['userInfo'] },
207
+ risk: 'medium',
208
+ },
196
209
  {
197
210
  method: USER_REVOKE_AUTHORIZATION_METHOD,
198
211
  module: 'user',
199
212
  capability: USER_REVOKE_AUTHORIZATION_METHOD,
200
- permission: 'user.revokeAuthorization',
213
+ requirement: { kind: 'none' },
201
214
  risk: 'high',
202
215
  },
203
216
  {
204
217
  method: USER_GET_STEAM_GAME_LIST_METHOD,
205
218
  module: 'user',
206
219
  capability: USER_GET_STEAM_GAME_LIST_METHOD,
207
- permission: 'user.platformAccount.steam',
220
+ requirement: { kind: 'all', permissions: ['steamLibrary'] },
208
221
  risk: 'high',
209
222
  },
210
- { method: SHARE_COPY_LINK_METHOD, module: 'share', capability: SHARE_COPY_LINK_METHOD, permission: 'share.copyLink', risk: 'medium' },
211
- { method: SHARE_SHOW_SHARE_MENU_METHOD, module: 'share', capability: SHARE_SHOW_SHARE_MENU_METHOD, permission: 'share.basic', risk: 'low' },
212
- { method: SHARE_SCREENSHOT_METHOD, module: 'share', capability: SHARE_SCREENSHOT_METHOD, permission: 'share.screenshot', risk: 'medium' },
223
+ {
224
+ method: SHARE_COPY_LINK_METHOD,
225
+ module: 'share',
226
+ capability: SHARE_COPY_LINK_METHOD,
227
+ requirement: { kind: 'all', permissions: ['share'] },
228
+ risk: 'medium',
229
+ },
230
+ {
231
+ method: SHARE_SHOW_SHARE_MENU_METHOD,
232
+ module: 'share',
233
+ capability: SHARE_SHOW_SHARE_MENU_METHOD,
234
+ requirement: { kind: 'all', permissions: ['share'] },
235
+ risk: 'low',
236
+ },
237
+ {
238
+ method: SHARE_SCREENSHOT_METHOD,
239
+ module: 'share',
240
+ capability: SHARE_SCREENSHOT_METHOD,
241
+ requirement: { kind: 'all', permissions: ['share'] },
242
+ risk: 'medium',
243
+ },
213
244
  {
214
245
  method: VIEWPORT_GET_WINDOW_INFO_METHOD,
215
246
  module: 'viewport',
216
247
  capability: VIEWPORT_GET_WINDOW_INFO_METHOD,
217
- permission: 'viewport.windowInfo',
248
+ requirement: { kind: 'none' },
218
249
  risk: 'low',
219
250
  },
220
251
  {
221
252
  method: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
222
253
  module: 'viewport',
223
254
  capability: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
224
- permission: 'viewport.navigationBarStyle',
255
+ requirement: { kind: 'none' },
225
256
  risk: 'low',
226
257
  },
227
- { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
228
- { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
229
- { method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
230
- { method: NETWORK_DOWNLOAD_METHOD, module: 'network', capability: NETWORK_DOWNLOAD_METHOD, permission: 'network.request', risk: 'high' },
231
- { method: FILES_PICK_FILES_METHOD, module: 'files', capability: FILES_PICK_FILES_METHOD, permission: 'files.external', risk: 'high' },
258
+ {
259
+ method: STORAGE_GET_STORAGE_METHOD,
260
+ module: 'storage',
261
+ capability: STORAGE_GET_STORAGE_METHOD,
262
+ requirement: { kind: 'all', permissions: ['storage'] },
263
+ risk: 'low',
264
+ },
265
+ {
266
+ method: STORAGE_SET_STORAGE_METHOD,
267
+ module: 'storage',
268
+ capability: STORAGE_SET_STORAGE_METHOD,
269
+ requirement: { kind: 'all', permissions: ['storage'] },
270
+ risk: 'medium',
271
+ },
272
+ {
273
+ method: NETWORK_REQUEST_METHOD,
274
+ module: 'network',
275
+ capability: NETWORK_REQUEST_METHOD,
276
+ requirement: { kind: 'all', permissions: ['network'] },
277
+ risk: 'high',
278
+ },
279
+ {
280
+ method: NETWORK_DOWNLOAD_METHOD,
281
+ module: 'network',
282
+ capability: NETWORK_DOWNLOAD_METHOD,
283
+ requirement: { kind: 'all', permissions: ['network', 'filesystem'] },
284
+ risk: 'high',
285
+ },
286
+ {
287
+ method: FILES_PICK_FILES_METHOD,
288
+ module: 'files',
289
+ capability: FILES_PICK_FILES_METHOD,
290
+ requirement: { kind: 'all', permissions: ['filesystem'] },
291
+ risk: 'high',
292
+ },
232
293
  {
233
294
  method: FILES_PICK_DIRECTORY_METHOD,
234
295
  module: 'files',
235
296
  capability: FILES_PICK_DIRECTORY_METHOD,
236
- permission: 'files.external',
297
+ requirement: { kind: 'all', permissions: ['filesystem'] },
298
+ risk: 'high',
299
+ },
300
+ {
301
+ method: FILES_SAVE_FILE_METHOD,
302
+ module: 'files',
303
+ capability: FILES_SAVE_FILE_METHOD,
304
+ requirement: { kind: 'all', permissions: ['filesystem'] },
305
+ risk: 'high',
306
+ },
307
+ {
308
+ method: FILE_CREATE_METHOD,
309
+ module: 'file',
310
+ capability: FILE_CREATE_METHOD,
311
+ requirement: { kind: 'all', permissions: ['filesystem'] },
312
+ risk: 'high',
313
+ },
314
+ {
315
+ method: FILE_REMOVE_METHOD,
316
+ module: 'file',
317
+ capability: FILE_REMOVE_METHOD,
318
+ requirement: { kind: 'all', permissions: ['filesystem'] },
319
+ risk: 'high',
320
+ },
321
+ {
322
+ method: FILE_EXISTS_METHOD,
323
+ module: 'file',
324
+ capability: FILE_EXISTS_METHOD,
325
+ requirement: { kind: 'all', permissions: ['filesystem'] },
326
+ risk: 'high',
327
+ },
328
+ {
329
+ method: FILE_READ_TEXT_METHOD,
330
+ module: 'file',
331
+ capability: FILE_READ_TEXT_METHOD,
332
+ requirement: { kind: 'all', permissions: ['filesystem'] },
333
+ risk: 'high',
334
+ },
335
+ {
336
+ method: FILE_WRITE_TEXT_METHOD,
337
+ module: 'file',
338
+ capability: FILE_WRITE_TEXT_METHOD,
339
+ requirement: { kind: 'all', permissions: ['filesystem'] },
340
+ risk: 'high',
341
+ },
342
+ {
343
+ method: FILE_READ_BYTES_METHOD,
344
+ module: 'file',
345
+ capability: FILE_READ_BYTES_METHOD,
346
+ requirement: { kind: 'all', permissions: ['filesystem'] },
237
347
  risk: 'high',
238
348
  },
239
- { method: FILES_SAVE_FILE_METHOD, module: 'files', capability: FILES_SAVE_FILE_METHOD, permission: 'files.external', risk: 'high' },
240
- { method: FILE_CREATE_METHOD, module: 'file', capability: FILE_CREATE_METHOD, permission: 'files.access', risk: 'high' },
241
- { method: FILE_REMOVE_METHOD, module: 'file', capability: FILE_REMOVE_METHOD, permission: 'files.access', risk: 'high' },
242
- { method: FILE_EXISTS_METHOD, module: 'file', capability: FILE_EXISTS_METHOD, permission: 'files.access', risk: 'high' },
243
- { method: FILE_READ_TEXT_METHOD, module: 'file', capability: FILE_READ_TEXT_METHOD, permission: 'files.access', risk: 'high' },
244
- { method: FILE_WRITE_TEXT_METHOD, module: 'file', capability: FILE_WRITE_TEXT_METHOD, permission: 'files.access', risk: 'high' },
245
- { method: FILE_READ_BYTES_METHOD, module: 'file', capability: FILE_READ_BYTES_METHOD, permission: 'files.access', risk: 'high' },
246
- { method: FILE_WRITE_BYTES_METHOD, module: 'file', capability: FILE_WRITE_BYTES_METHOD, permission: 'files.access', risk: 'high' },
247
- { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, permission: 'files.access', risk: 'high' },
349
+ {
350
+ method: FILE_WRITE_BYTES_METHOD,
351
+ module: 'file',
352
+ capability: FILE_WRITE_BYTES_METHOD,
353
+ requirement: { kind: 'all', permissions: ['filesystem'] },
354
+ risk: 'high',
355
+ },
356
+ { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, requirement: { kind: 'all', permissions: ['filesystem'] }, risk: 'high' },
248
357
  {
249
358
  method: DIRECTORY_CREATE_METHOD,
250
359
  module: 'directory',
251
360
  capability: DIRECTORY_CREATE_METHOD,
252
- permission: 'files.access',
361
+ requirement: { kind: 'all', permissions: ['filesystem'] },
253
362
  risk: 'high',
254
363
  },
255
364
  {
256
365
  method: DIRECTORY_REMOVE_METHOD,
257
366
  module: 'directory',
258
367
  capability: DIRECTORY_REMOVE_METHOD,
259
- permission: 'files.access',
368
+ requirement: { kind: 'all', permissions: ['filesystem'] },
260
369
  risk: 'high',
261
370
  },
262
371
  {
263
372
  method: DIRECTORY_EXISTS_METHOD,
264
373
  module: 'directory',
265
374
  capability: DIRECTORY_EXISTS_METHOD,
266
- permission: 'files.access',
375
+ requirement: { kind: 'all', permissions: ['filesystem'] },
376
+ risk: 'high',
377
+ },
378
+ {
379
+ method: DIRECTORY_LIST_METHOD,
380
+ module: 'directory',
381
+ capability: DIRECTORY_LIST_METHOD,
382
+ requirement: { kind: 'all', permissions: ['filesystem'] },
267
383
  risk: 'high',
268
384
  },
269
- { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
270
- { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
271
- { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
272
- { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
273
- { method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, permission: 'device.vibrate', risk: 'low' },
385
+ { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, requirement: { kind: 'none' }, risk: 'low' },
386
+ { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
387
+ { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
388
+ { method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, requirement: { kind: 'none' }, risk: 'low' },
274
389
  {
275
390
  method: DEVICE_SET_CLIPBOARD_METHOD,
276
391
  module: 'device',
277
392
  capability: DEVICE_SET_CLIPBOARD_METHOD,
278
- permission: 'device.clipboard.write',
393
+ requirement: { kind: 'all', permissions: ['clipboard'] },
279
394
  risk: 'medium',
280
395
  },
281
- { method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, permission: 'navigation.close', risk: 'medium' },
282
- { method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, permission: 'navigation.reload', risk: 'medium' },
396
+ { method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, requirement: { kind: 'none' }, risk: 'medium' },
397
+ { method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, requirement: { kind: 'none' }, risk: 'medium' },
283
398
  {
284
399
  method: NAVIGATION_OPEN_APP_PAGE_METHOD,
285
400
  module: 'navigation',
286
401
  capability: NAVIGATION_OPEN_APP_PAGE_METHOD,
287
- permission: 'navigation.openAppPage',
402
+ requirement: { kind: 'none' },
288
403
  risk: 'medium',
289
404
  },
290
405
  {
291
406
  method: CLOUD_LEADERBOARD_SUBMIT_METHOD,
292
407
  module: 'cloud',
293
408
  capability: CLOUD_LEADERBOARD_SUBMIT_METHOD,
294
- permission: 'cloud.leaderboard.write',
409
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
295
410
  risk: 'medium',
296
411
  },
297
412
  {
298
413
  method: CLOUD_LEADERBOARD_GET_LIST_METHOD,
299
414
  module: 'cloud',
300
415
  capability: CLOUD_LEADERBOARD_GET_LIST_METHOD,
301
- permission: 'cloud.leaderboard.read',
416
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
302
417
  risk: 'low',
303
418
  },
304
419
  {
305
420
  method: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
306
421
  module: 'cloud',
307
422
  capability: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
308
- permission: 'cloud.leaderboard.currentUserEntry.read',
423
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
309
424
  risk: 'medium',
310
425
  },
311
426
  {
312
427
  method: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
313
428
  module: 'cloud',
314
429
  capability: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
315
- permission: 'cloud.leaderboard.currentUserEntry.delete',
430
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
316
431
  risk: 'medium',
317
432
  },
318
433
  {
319
434
  method: CLOUD_LEADERBOARD_GET_INFO_METHOD,
320
435
  module: 'cloud',
321
436
  capability: CLOUD_LEADERBOARD_GET_INFO_METHOD,
322
- permission: 'cloud.leaderboard.info.read',
437
+ requirement: { kind: 'all', permissions: ['leaderboard'] },
323
438
  risk: 'low',
324
439
  },
325
440
  ] as const satisfies readonly MiniProgramCapabilityDefinition[];
package/src/index.ts CHANGED
@@ -3,4 +3,5 @@ export * from './capabilities';
3
3
  export * from './constants';
4
4
  export * from './guards';
5
5
  export * from './payloads';
6
+ export * from './permission-catalog';
6
7
  export * from './permissions';
@@ -0,0 +1,168 @@
1
+ import type { MiniProgramBridgeMethod, MiniProgramCapabilityRisk } from './capabilities';
2
+
3
+ export const MINI_PROGRAM_PERMISSION_KEYS = [
4
+ 'userInfo',
5
+ 'steamLibrary',
6
+ 'share',
7
+ 'storage',
8
+ 'filesystem',
9
+ 'clipboard',
10
+ 'leaderboard',
11
+ 'network',
12
+ ] as const;
13
+
14
+ export type MiniProgramPermissionKey = (typeof MINI_PROGRAM_PERMISSION_KEYS)[number];
15
+ export type MiniProgramPermissionRequirement =
16
+ | { readonly kind: 'none' }
17
+ | { readonly kind: 'all'; readonly permissions: readonly MiniProgramPermissionKey[] };
18
+ export type MiniProgramPermissionAccess = 'declaration' | 'platform-approval';
19
+
20
+ export interface MiniProgramPermissionConfigFieldDefinition {
21
+ readonly type: 'boolean';
22
+ readonly required: boolean;
23
+ readonly default: boolean;
24
+ readonly description: string;
25
+ }
26
+
27
+ export interface MiniProgramPermissionDefinition {
28
+ readonly key: MiniProgramPermissionKey;
29
+ readonly name: string;
30
+ readonly description: string;
31
+ readonly access: MiniProgramPermissionAccess;
32
+ readonly risk: MiniProgramCapabilityRisk;
33
+ readonly config: Readonly<Record<string, MiniProgramPermissionConfigFieldDefinition>>;
34
+ readonly methods: readonly MiniProgramBridgeMethod[];
35
+ readonly conditions: readonly string[];
36
+ }
37
+
38
+ export const MINI_PROGRAM_PERMISSION_CATALOG = [
39
+ {
40
+ key: 'userInfo',
41
+ name: '用户信息',
42
+ description: '登录小程序并读取当前用户的授权信息。',
43
+ access: 'declaration',
44
+ risk: 'medium',
45
+ config: {},
46
+ methods: ['auth.login', 'user.getInfo'],
47
+ conditions: ['继续执行黑盒登录、用户授权和可信手势规则。'],
48
+ },
49
+ {
50
+ key: 'steamLibrary',
51
+ name: 'Steam 游戏库',
52
+ description: '读取当前用户授权的 Steam 游戏库。',
53
+ access: 'declaration',
54
+ risk: 'high',
55
+ config: {},
56
+ methods: ['user.getSteamGameList'],
57
+ conditions: ['继续执行账号绑定和数据可用性规则。'],
58
+ },
59
+ {
60
+ key: 'share',
61
+ name: '分享',
62
+ description: '使用小程序分享、分享菜单和截图能力。',
63
+ access: 'declaration',
64
+ risk: 'medium',
65
+ config: {},
66
+ methods: ['share.copyLink', 'share.showShareMenu', 'share.screenshot'],
67
+ conditions: ['继续执行分享参数校验和 Host 支持检查。'],
68
+ },
69
+ {
70
+ key: 'storage',
71
+ name: '键值存储',
72
+ description: '读写按小程序隔离的简单键值数据。',
73
+ access: 'declaration',
74
+ risk: 'medium',
75
+ config: {},
76
+ methods: ['storage.getStorage', 'storage.setStorage'],
77
+ conditions: ['仅用于简单键值存储,不包含文件系统。'],
78
+ },
79
+ {
80
+ key: 'filesystem',
81
+ name: '文件系统',
82
+ description: '访问小程序沙盒文件和用户选择的外部文件。',
83
+ access: 'declaration',
84
+ risk: 'high',
85
+ config: {},
86
+ methods: [
87
+ 'network.download',
88
+ 'files.pickFiles',
89
+ 'files.pickDirectory',
90
+ 'files.saveFile',
91
+ 'file.create',
92
+ 'file.remove',
93
+ 'file.exists',
94
+ 'file.readText',
95
+ 'file.writeText',
96
+ 'file.readBytes',
97
+ 'file.writeBytes',
98
+ 'file.stat',
99
+ 'directory.create',
100
+ 'directory.remove',
101
+ 'directory.exists',
102
+ 'directory.list',
103
+ ],
104
+ conditions: ['外部文件继续要求有效的用户选择、会话句柄和匹配的读写模式。'],
105
+ },
106
+ {
107
+ key: 'clipboard',
108
+ name: '剪贴板',
109
+ description: '向系统剪贴板写入文本。',
110
+ access: 'declaration',
111
+ risk: 'medium',
112
+ config: {},
113
+ methods: ['device.setClipboard'],
114
+ conditions: ['继续执行文本长度和 Host 支持限制。'],
115
+ },
116
+ {
117
+ key: 'leaderboard',
118
+ name: '排行榜',
119
+ description: '读写小程序云排行榜。',
120
+ access: 'declaration',
121
+ risk: 'medium',
122
+ config: {},
123
+ methods: [
124
+ 'cloud.leaderboard.submit',
125
+ 'cloud.leaderboard.getList',
126
+ 'cloud.leaderboard.getCurrentUserEntry',
127
+ 'cloud.leaderboard.deleteCurrentUserEntry',
128
+ 'cloud.leaderboard.getInfo',
129
+ ],
130
+ conditions: ['排行榜必须已创建,用户和资源规则保持不变。'],
131
+ },
132
+ {
133
+ key: 'network',
134
+ name: '网络',
135
+ description: '通过 network 模块请求或下载外部资源。',
136
+ access: 'platform-approval',
137
+ risk: 'high',
138
+ config: {
139
+ useOfficialDomain: {
140
+ type: 'boolean',
141
+ required: false,
142
+ default: false,
143
+ description: '是否申请访问小黑盒官方域名。',
144
+ },
145
+ },
146
+ methods: ['network.request', 'network.download'],
147
+ conditions: ['声明后仍需平台批准,并继续执行网络安全策略。'],
148
+ },
149
+ ] as const satisfies readonly MiniProgramPermissionDefinition[];
150
+
151
+ export const MINI_PROGRAM_NO_DECLARATION_METHODS = [
152
+ 'user.revokeAuthorization',
153
+ 'ui.showToast',
154
+ 'ui.showLoading',
155
+ 'ui.hideLoading',
156
+ 'viewport.getWindowInfo',
157
+ 'viewport.setNavigationBarStyle',
158
+ 'device.vibrate',
159
+ 'navigation.close',
160
+ 'navigation.reload',
161
+ 'navigation.openAppPage',
162
+ ] as const satisfies readonly MiniProgramBridgeMethod[];
163
+
164
+ const PERMISSION_KEY_SET = new Set<string>(MINI_PROGRAM_PERMISSION_KEYS);
165
+
166
+ export function isMiniProgramPermissionKey(key: string): key is MiniProgramPermissionKey {
167
+ return PERMISSION_KEY_SET.has(key);
168
+ }
@@ -1,11 +1,13 @@
1
- const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
1
+ import { MINI_PROGRAM_PERMISSION_KEYS, type MiniProgramPermissionKey } from './permission-catalog';
2
2
 
3
- export function isManagedMiniProgramRuntimePermissionKey(key: string) {
3
+ const MANAGED_RUNTIME_PERMISSION_KEYS = new Set<string>(MINI_PROGRAM_PERMISSION_KEYS);
4
+
5
+ export function isManagedMiniProgramRuntimePermissionKey(key: string): key is MiniProgramPermissionKey {
4
6
  return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
5
7
  }
6
8
  export type MiniProgramRuntimePermissionStatus = 'enabled' | 'disabled';
7
9
  export interface MiniProgramRuntimePermissionEntry {
8
- key: string;
10
+ key: MiniProgramPermissionKey;
9
11
  status: MiniProgramRuntimePermissionStatus;
10
12
  config: Record<string, unknown>;
11
13
  }
@@ -16,7 +18,7 @@ export interface MiniProgramRuntimePermissionsSnapshot {
16
18
  }
17
19
  export interface ParsedMiniProgramRuntimePermissions {
18
20
  valid: boolean;
19
- permissions: Record<string, MiniProgramRuntimePermissionEntry>;
21
+ permissions: Partial<Record<MiniProgramPermissionKey, MiniProgramRuntimePermissionEntry>>;
20
22
  }
21
23
 
22
24
  export function parseMiniProgramRuntimePermissions(snapshot: unknown): ParsedMiniProgramRuntimePermissions {
@@ -28,24 +30,40 @@ export function parseMiniProgramRuntimePermissions(snapshot: unknown): ParsedMin
28
30
  }
29
31
 
30
32
  const seenKeys = new Set<string>();
31
- const permissions: Record<string, MiniProgramRuntimePermissionEntry> = {};
33
+ const permissions: Partial<Record<MiniProgramPermissionKey, MiniProgramRuntimePermissionEntry>> = {};
32
34
  for (const rawEntry of snapshot.entries) {
33
35
  if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
34
36
  return { valid: false, permissions: {} };
35
37
  }
36
- const key = rawEntry.key.trim();
37
- if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
38
+ const inputKey = rawEntry.key.trim();
39
+ const key = inputKey === 'network.request' ? 'network' : inputKey;
40
+ if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled')) {
38
41
  return { valid: false, permissions: {} };
39
42
  }
40
43
  seenKeys.add(key);
41
- if (!isManagedMiniProgramRuntimePermissionKey(key)) continue;
42
- if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
44
+ if (!isManagedMiniProgramRuntimePermissionKey(key)) {
45
+ if (!isRecord(rawEntry.config)) return { valid: false, permissions: {} };
46
+ continue;
47
+ }
48
+ if (key === 'network') {
49
+ const config = rawEntry.config;
50
+ if (!isRecord(config) || typeof config.useOfficialDomain !== 'boolean') {
51
+ return { valid: false, permissions: {} };
52
+ }
53
+ permissions[key] = {
54
+ key,
55
+ status: rawEntry.status,
56
+ config: { useOfficialDomain: config.useOfficialDomain },
57
+ };
58
+ continue;
59
+ }
60
+ if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
43
61
  return { valid: false, permissions: {} };
44
62
  }
45
63
  permissions[key] = {
46
64
  key,
47
65
  status: rawEntry.status,
48
- config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
66
+ config: {},
49
67
  };
50
68
  }
51
69
  return { valid: true, permissions };