@heybox/hb-sdk-protocol 0.7.5-alpha.0 → 0.8.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/dist/index.cjs.js CHANGED
@@ -12,6 +12,22 @@ const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle
12
12
  const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
13
13
  const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage';
14
14
  const NETWORK_REQUEST_METHOD = 'network.request';
15
+ const NETWORK_DOWNLOAD_METHOD = 'network.download';
16
+ const FILES_PICK_FILES_METHOD = 'files.pickFiles';
17
+ const FILES_PICK_DIRECTORY_METHOD = 'files.pickDirectory';
18
+ const FILES_SAVE_FILE_METHOD = 'files.saveFile';
19
+ const FILE_CREATE_METHOD = 'file.create';
20
+ const FILE_REMOVE_METHOD = 'file.remove';
21
+ const FILE_EXISTS_METHOD = 'file.exists';
22
+ const FILE_READ_TEXT_METHOD = 'file.readText';
23
+ const FILE_WRITE_TEXT_METHOD = 'file.writeText';
24
+ const FILE_READ_BYTES_METHOD = 'file.readBytes';
25
+ const FILE_WRITE_BYTES_METHOD = 'file.writeBytes';
26
+ const FILE_STAT_METHOD = 'file.stat';
27
+ const DIRECTORY_CREATE_METHOD = 'directory.create';
28
+ const DIRECTORY_REMOVE_METHOD = 'directory.remove';
29
+ const DIRECTORY_EXISTS_METHOD = 'directory.exists';
30
+ const DIRECTORY_LIST_METHOD = 'directory.list';
15
31
  const UI_SHOW_TOAST_METHOD = 'ui.showToast';
16
32
  const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
17
33
  const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
@@ -62,6 +78,46 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
62
78
  { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
63
79
  { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
64
80
  { method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
81
+ { method: NETWORK_DOWNLOAD_METHOD, module: 'network', capability: NETWORK_DOWNLOAD_METHOD, permission: 'network.request', risk: 'high' },
82
+ { method: FILES_PICK_FILES_METHOD, module: 'files', capability: FILES_PICK_FILES_METHOD, permission: 'files.external', risk: 'high' },
83
+ {
84
+ method: FILES_PICK_DIRECTORY_METHOD,
85
+ module: 'files',
86
+ capability: FILES_PICK_DIRECTORY_METHOD,
87
+ permission: 'files.external',
88
+ risk: 'high',
89
+ },
90
+ { method: FILES_SAVE_FILE_METHOD, module: 'files', capability: FILES_SAVE_FILE_METHOD, permission: 'files.external', risk: 'high' },
91
+ { method: FILE_CREATE_METHOD, module: 'file', capability: FILE_CREATE_METHOD, permission: 'files.access', risk: 'high' },
92
+ { method: FILE_REMOVE_METHOD, module: 'file', capability: FILE_REMOVE_METHOD, permission: 'files.access', risk: 'high' },
93
+ { method: FILE_EXISTS_METHOD, module: 'file', capability: FILE_EXISTS_METHOD, permission: 'files.access', risk: 'high' },
94
+ { method: FILE_READ_TEXT_METHOD, module: 'file', capability: FILE_READ_TEXT_METHOD, permission: 'files.access', risk: 'high' },
95
+ { method: FILE_WRITE_TEXT_METHOD, module: 'file', capability: FILE_WRITE_TEXT_METHOD, permission: 'files.access', risk: 'high' },
96
+ { method: FILE_READ_BYTES_METHOD, module: 'file', capability: FILE_READ_BYTES_METHOD, permission: 'files.access', risk: 'high' },
97
+ { method: FILE_WRITE_BYTES_METHOD, module: 'file', capability: FILE_WRITE_BYTES_METHOD, permission: 'files.access', risk: 'high' },
98
+ { method: FILE_STAT_METHOD, module: 'file', capability: FILE_STAT_METHOD, permission: 'files.access', risk: 'high' },
99
+ {
100
+ method: DIRECTORY_CREATE_METHOD,
101
+ module: 'directory',
102
+ capability: DIRECTORY_CREATE_METHOD,
103
+ permission: 'files.access',
104
+ risk: 'high',
105
+ },
106
+ {
107
+ method: DIRECTORY_REMOVE_METHOD,
108
+ module: 'directory',
109
+ capability: DIRECTORY_REMOVE_METHOD,
110
+ permission: 'files.access',
111
+ risk: 'high',
112
+ },
113
+ {
114
+ method: DIRECTORY_EXISTS_METHOD,
115
+ module: 'directory',
116
+ capability: DIRECTORY_EXISTS_METHOD,
117
+ permission: 'files.access',
118
+ risk: 'high',
119
+ },
120
+ { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
65
121
  { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
66
122
  { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
67
123
  { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
@@ -126,15 +182,134 @@ const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
126
182
  const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
127
183
  const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
128
184
  const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
185
+ const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
129
186
 
130
187
  function isMiniProgramBridgeMessage(value) {
131
- if (!value || typeof value !== 'object')
188
+ if (!isRecord$1(value))
189
+ return false;
190
+ if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString(value.nonce)) {
132
191
  return false;
133
- const message = value;
134
- return (message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
135
- (message.version === 1 || message.version === 2) &&
136
- typeof message.nonce === 'string' &&
137
- typeof message.type === 'string');
192
+ }
193
+ if (value.type === 'handshake') {
194
+ return isNonEmptyString(value.id) && value.method === SDK_HANDSHAKE_METHOD && value.error === undefined && isSDKHandshakePayload(value.payload);
195
+ }
196
+ if (value.type === 'request') {
197
+ return isNonEmptyString(value.id) && isNonEmptyString(value.method) && value.error === undefined;
198
+ }
199
+ if (value.type === 'response') {
200
+ return (isNonEmptyString(value.id) &&
201
+ (value.method === undefined || isNonEmptyString(value.method)) &&
202
+ (value.error === undefined || isBridgeError(value.error)));
203
+ }
204
+ if (value.type === 'event') {
205
+ if (!isNonEmptyString(value.method) || value.error !== undefined)
206
+ return false;
207
+ if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
208
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
209
+ }
210
+ return value.id === undefined || isNonEmptyString(value.id);
211
+ }
212
+ if (value.type === 'cancel') {
213
+ return (value.version === 2 && isNonEmptyString(value.id) && value.method === undefined && value.payload === undefined && value.error === undefined);
214
+ }
215
+ return false;
216
+ }
217
+ function isMiniProgramRelativePath(value) {
218
+ if (typeof value !== 'string' || !value || value.startsWith('/') || value.endsWith('/')) {
219
+ return false;
220
+ }
221
+ if (/[\\\u0000-\u001f\u007f]/.test(value))
222
+ return false;
223
+ return value.split('/').every((segment) => Boolean(segment) && segment !== '.' && segment !== '..');
224
+ }
225
+ function isMiniProgramPathRootRef(value) {
226
+ if (!isRecord$1(value))
227
+ return false;
228
+ if (value.kind === 'sandbox')
229
+ return hasOnlyKeys(value, ['kind']);
230
+ return value.kind === 'directory' && isNonEmptyString(value.handleId) && hasOnlyKeys(value, ['kind', 'handleId']);
231
+ }
232
+ function isMiniProgramFileRef(value) {
233
+ if (!isRecord$1(value) || value.kind !== 'file')
234
+ return false;
235
+ if (isNonEmptyString(value.handleId)) {
236
+ return hasOnlyKeys(value, ['kind', 'handleId']);
237
+ }
238
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
239
+ }
240
+ function isMiniProgramDirectoryRef(value) {
241
+ if (!isRecord$1(value) || value.kind !== 'directory')
242
+ return false;
243
+ if (isNonEmptyString(value.handleId)) {
244
+ return hasOnlyKeys(value, ['kind', 'handleId']);
245
+ }
246
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
247
+ }
248
+ function isMiniProgramFileDescriptor(value) {
249
+ return (isRecord$1(value) &&
250
+ value.kind === 'file' &&
251
+ isNonEmptyString(value.name) &&
252
+ isFileMode(value.mode) &&
253
+ isMiniProgramFileRef(value.ref) &&
254
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
255
+ }
256
+ function isMiniProgramDirectoryDescriptor(value) {
257
+ return (isRecord$1(value) &&
258
+ value.kind === 'directory' &&
259
+ isNonEmptyString(value.name) &&
260
+ isFileMode(value.mode) &&
261
+ isMiniProgramDirectoryRef(value.ref) &&
262
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
263
+ }
264
+ function isMiniProgramFileSystemEntityDescriptor(value) {
265
+ return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
266
+ }
267
+ function isMiniProgramByteArray(value) {
268
+ return value instanceof Uint8Array && value.buffer instanceof ArrayBuffer;
269
+ }
270
+ function isMiniProgramFileStat(value) {
271
+ return (isRecord$1(value) &&
272
+ value.kind === 'file' &&
273
+ isNonNegativeSafeInteger(value.size) &&
274
+ (value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
275
+ (value.createdAt === undefined || isNonNegativeFiniteNumber(value.createdAt)) &&
276
+ hasOnlyKeys(value, ['kind', 'size', 'modifiedAt', 'createdAt']));
277
+ }
278
+ function isMiniProgramDownloadProgressPayload(value) {
279
+ if (!isRecord$1(value) ||
280
+ !isNonNegativeSafeInteger(value.loaded) ||
281
+ typeof value.lengthComputable !== 'boolean' ||
282
+ !hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])) {
283
+ return false;
284
+ }
285
+ if (!value.lengthComputable)
286
+ return value.total === undefined;
287
+ return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
288
+ }
289
+ function isSDKHandshakePayload(value) {
290
+ return isRecord$1(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
291
+ }
292
+ function isBridgeError(value) {
293
+ return isRecord$1(value) && isNonEmptyString(value.code) && typeof value.message === 'string';
294
+ }
295
+ function isFileMode(value) {
296
+ return value === 'read' || value === 'readwrite';
297
+ }
298
+ function isNonNegativeSafeInteger(value) {
299
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
300
+ }
301
+ function isNonNegativeFiniteNumber(value) {
302
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
303
+ }
304
+ function isNonEmptyString(value) {
305
+ return typeof value === 'string' && value.length > 0;
306
+ }
307
+ function hasOnlyKeys(value, allowedKeys) {
308
+ const allowed = new Set(allowedKeys);
309
+ return Object.keys(value).every((key) => allowed.has(key));
310
+ }
311
+ function isRecord$1(value) {
312
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
138
313
  }
139
314
 
140
315
  /** 当前用户信息与登录能力支持的完整 scope 目录。 */
@@ -187,13 +362,30 @@ exports.CLOUD_LEADERBOARD_GET_LIST_METHOD = CLOUD_LEADERBOARD_GET_LIST_METHOD;
187
362
  exports.CLOUD_LEADERBOARD_SUBMIT_METHOD = CLOUD_LEADERBOARD_SUBMIT_METHOD;
188
363
  exports.DEVICE_SET_CLIPBOARD_METHOD = DEVICE_SET_CLIPBOARD_METHOD;
189
364
  exports.DEVICE_VIBRATE_METHOD = DEVICE_VIBRATE_METHOD;
365
+ exports.DIRECTORY_CREATE_METHOD = DIRECTORY_CREATE_METHOD;
366
+ exports.DIRECTORY_EXISTS_METHOD = DIRECTORY_EXISTS_METHOD;
367
+ exports.DIRECTORY_LIST_METHOD = DIRECTORY_LIST_METHOD;
368
+ exports.DIRECTORY_REMOVE_METHOD = DIRECTORY_REMOVE_METHOD;
369
+ exports.FILES_PICK_DIRECTORY_METHOD = FILES_PICK_DIRECTORY_METHOD;
370
+ exports.FILES_PICK_FILES_METHOD = FILES_PICK_FILES_METHOD;
371
+ exports.FILES_SAVE_FILE_METHOD = FILES_SAVE_FILE_METHOD;
372
+ exports.FILE_CREATE_METHOD = FILE_CREATE_METHOD;
373
+ exports.FILE_EXISTS_METHOD = FILE_EXISTS_METHOD;
374
+ exports.FILE_READ_BYTES_METHOD = FILE_READ_BYTES_METHOD;
375
+ exports.FILE_READ_TEXT_METHOD = FILE_READ_TEXT_METHOD;
376
+ exports.FILE_REMOVE_METHOD = FILE_REMOVE_METHOD;
377
+ exports.FILE_STAT_METHOD = FILE_STAT_METHOD;
378
+ exports.FILE_WRITE_BYTES_METHOD = FILE_WRITE_BYTES_METHOD;
379
+ exports.FILE_WRITE_TEXT_METHOD = FILE_WRITE_TEXT_METHOD;
190
380
  exports.MINI_PROGRAM_BRIDGE_NONCE_PARAM = MINI_PROGRAM_BRIDGE_NONCE_PARAM;
191
381
  exports.MINI_PROGRAM_MESSAGE_NAMESPACE = MINI_PROGRAM_MESSAGE_NAMESPACE;
192
382
  exports.MINI_PROGRAM_MESSAGE_VERSION = MINI_PROGRAM_MESSAGE_VERSION;
383
+ exports.MINI_PROGRAM_OPERATION_PROGRESS_METHOD = MINI_PROGRAM_OPERATION_PROGRESS_METHOD;
193
384
  exports.MINI_PROGRAM_PROTOCOL_CAPABILITIES = MINI_PROGRAM_PROTOCOL_CAPABILITIES;
194
385
  exports.NAVIGATION_CLOSE_METHOD = NAVIGATION_CLOSE_METHOD;
195
386
  exports.NAVIGATION_OPEN_APP_PAGE_METHOD = NAVIGATION_OPEN_APP_PAGE_METHOD;
196
387
  exports.NAVIGATION_RELOAD_METHOD = NAVIGATION_RELOAD_METHOD;
388
+ exports.NETWORK_DOWNLOAD_METHOD = NETWORK_DOWNLOAD_METHOD;
197
389
  exports.NETWORK_REQUEST_METHOD = NETWORK_REQUEST_METHOD;
198
390
  exports.RUNTIME_LOCATION_PROBE_METHOD = RUNTIME_LOCATION_PROBE_METHOD;
199
391
  exports.SDK_CSP_VIOLATION_METHOD = SDK_CSP_VIOLATION_METHOD;
@@ -215,4 +407,14 @@ exports.VIEWPORT_GET_WINDOW_INFO_METHOD = VIEWPORT_GET_WINDOW_INFO_METHOD;
215
407
  exports.VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
216
408
  exports.isManagedMiniProgramRuntimePermissionKey = isManagedMiniProgramRuntimePermissionKey;
217
409
  exports.isMiniProgramBridgeMessage = isMiniProgramBridgeMessage;
410
+ exports.isMiniProgramByteArray = isMiniProgramByteArray;
411
+ exports.isMiniProgramDirectoryDescriptor = isMiniProgramDirectoryDescriptor;
412
+ exports.isMiniProgramDirectoryRef = isMiniProgramDirectoryRef;
413
+ exports.isMiniProgramDownloadProgressPayload = isMiniProgramDownloadProgressPayload;
414
+ exports.isMiniProgramFileDescriptor = isMiniProgramFileDescriptor;
415
+ exports.isMiniProgramFileRef = isMiniProgramFileRef;
416
+ exports.isMiniProgramFileStat = isMiniProgramFileStat;
417
+ exports.isMiniProgramFileSystemEntityDescriptor = isMiniProgramFileSystemEntityDescriptor;
418
+ exports.isMiniProgramPathRootRef = isMiniProgramPathRootRef;
419
+ exports.isMiniProgramRelativePath = isMiniProgramRelativePath;
218
420
  exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
package/dist/index.esm.js CHANGED
@@ -10,6 +10,22 @@ const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle
10
10
  const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
11
11
  const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage';
12
12
  const NETWORK_REQUEST_METHOD = 'network.request';
13
+ const NETWORK_DOWNLOAD_METHOD = 'network.download';
14
+ const FILES_PICK_FILES_METHOD = 'files.pickFiles';
15
+ const FILES_PICK_DIRECTORY_METHOD = 'files.pickDirectory';
16
+ const FILES_SAVE_FILE_METHOD = 'files.saveFile';
17
+ const FILE_CREATE_METHOD = 'file.create';
18
+ const FILE_REMOVE_METHOD = 'file.remove';
19
+ const FILE_EXISTS_METHOD = 'file.exists';
20
+ const FILE_READ_TEXT_METHOD = 'file.readText';
21
+ const FILE_WRITE_TEXT_METHOD = 'file.writeText';
22
+ const FILE_READ_BYTES_METHOD = 'file.readBytes';
23
+ const FILE_WRITE_BYTES_METHOD = 'file.writeBytes';
24
+ const FILE_STAT_METHOD = 'file.stat';
25
+ const DIRECTORY_CREATE_METHOD = 'directory.create';
26
+ const DIRECTORY_REMOVE_METHOD = 'directory.remove';
27
+ const DIRECTORY_EXISTS_METHOD = 'directory.exists';
28
+ const DIRECTORY_LIST_METHOD = 'directory.list';
13
29
  const UI_SHOW_TOAST_METHOD = 'ui.showToast';
14
30
  const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
15
31
  const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
@@ -60,6 +76,46 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
60
76
  { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
61
77
  { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
62
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' },
81
+ {
82
+ method: FILES_PICK_DIRECTORY_METHOD,
83
+ module: 'files',
84
+ capability: FILES_PICK_DIRECTORY_METHOD,
85
+ permission: 'files.external',
86
+ risk: 'high',
87
+ },
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' },
97
+ {
98
+ method: DIRECTORY_CREATE_METHOD,
99
+ module: 'directory',
100
+ capability: DIRECTORY_CREATE_METHOD,
101
+ permission: 'files.access',
102
+ risk: 'high',
103
+ },
104
+ {
105
+ method: DIRECTORY_REMOVE_METHOD,
106
+ module: 'directory',
107
+ capability: DIRECTORY_REMOVE_METHOD,
108
+ permission: 'files.access',
109
+ risk: 'high',
110
+ },
111
+ {
112
+ method: DIRECTORY_EXISTS_METHOD,
113
+ module: 'directory',
114
+ capability: DIRECTORY_EXISTS_METHOD,
115
+ permission: 'files.access',
116
+ risk: 'high',
117
+ },
118
+ { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
63
119
  { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
64
120
  { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
65
121
  { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
@@ -124,15 +180,134 @@ const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
124
180
  const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
125
181
  const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
126
182
  const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
183
+ const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
127
184
 
128
185
  function isMiniProgramBridgeMessage(value) {
129
- if (!value || typeof value !== 'object')
186
+ if (!isRecord$1(value))
187
+ return false;
188
+ if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString(value.nonce)) {
130
189
  return false;
131
- const message = value;
132
- return (message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
133
- (message.version === 1 || message.version === 2) &&
134
- typeof message.nonce === 'string' &&
135
- typeof message.type === 'string');
190
+ }
191
+ if (value.type === 'handshake') {
192
+ return isNonEmptyString(value.id) && value.method === SDK_HANDSHAKE_METHOD && value.error === undefined && isSDKHandshakePayload(value.payload);
193
+ }
194
+ if (value.type === 'request') {
195
+ return isNonEmptyString(value.id) && isNonEmptyString(value.method) && value.error === undefined;
196
+ }
197
+ if (value.type === 'response') {
198
+ return (isNonEmptyString(value.id) &&
199
+ (value.method === undefined || isNonEmptyString(value.method)) &&
200
+ (value.error === undefined || isBridgeError(value.error)));
201
+ }
202
+ if (value.type === 'event') {
203
+ if (!isNonEmptyString(value.method) || value.error !== undefined)
204
+ return false;
205
+ if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
206
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
207
+ }
208
+ return value.id === undefined || isNonEmptyString(value.id);
209
+ }
210
+ if (value.type === 'cancel') {
211
+ return (value.version === 2 && isNonEmptyString(value.id) && value.method === undefined && value.payload === undefined && value.error === undefined);
212
+ }
213
+ return false;
214
+ }
215
+ function isMiniProgramRelativePath(value) {
216
+ if (typeof value !== 'string' || !value || value.startsWith('/') || value.endsWith('/')) {
217
+ return false;
218
+ }
219
+ if (/[\\\u0000-\u001f\u007f]/.test(value))
220
+ return false;
221
+ return value.split('/').every((segment) => Boolean(segment) && segment !== '.' && segment !== '..');
222
+ }
223
+ function isMiniProgramPathRootRef(value) {
224
+ if (!isRecord$1(value))
225
+ return false;
226
+ if (value.kind === 'sandbox')
227
+ return hasOnlyKeys(value, ['kind']);
228
+ return value.kind === 'directory' && isNonEmptyString(value.handleId) && hasOnlyKeys(value, ['kind', 'handleId']);
229
+ }
230
+ function isMiniProgramFileRef(value) {
231
+ if (!isRecord$1(value) || value.kind !== 'file')
232
+ return false;
233
+ if (isNonEmptyString(value.handleId)) {
234
+ return hasOnlyKeys(value, ['kind', 'handleId']);
235
+ }
236
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
237
+ }
238
+ function isMiniProgramDirectoryRef(value) {
239
+ if (!isRecord$1(value) || value.kind !== 'directory')
240
+ return false;
241
+ if (isNonEmptyString(value.handleId)) {
242
+ return hasOnlyKeys(value, ['kind', 'handleId']);
243
+ }
244
+ return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
245
+ }
246
+ function isMiniProgramFileDescriptor(value) {
247
+ return (isRecord$1(value) &&
248
+ value.kind === 'file' &&
249
+ isNonEmptyString(value.name) &&
250
+ isFileMode(value.mode) &&
251
+ isMiniProgramFileRef(value.ref) &&
252
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
253
+ }
254
+ function isMiniProgramDirectoryDescriptor(value) {
255
+ return (isRecord$1(value) &&
256
+ value.kind === 'directory' &&
257
+ isNonEmptyString(value.name) &&
258
+ isFileMode(value.mode) &&
259
+ isMiniProgramDirectoryRef(value.ref) &&
260
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref']));
261
+ }
262
+ function isMiniProgramFileSystemEntityDescriptor(value) {
263
+ return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
264
+ }
265
+ function isMiniProgramByteArray(value) {
266
+ return value instanceof Uint8Array && value.buffer instanceof ArrayBuffer;
267
+ }
268
+ function isMiniProgramFileStat(value) {
269
+ return (isRecord$1(value) &&
270
+ value.kind === 'file' &&
271
+ isNonNegativeSafeInteger(value.size) &&
272
+ (value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
273
+ (value.createdAt === undefined || isNonNegativeFiniteNumber(value.createdAt)) &&
274
+ hasOnlyKeys(value, ['kind', 'size', 'modifiedAt', 'createdAt']));
275
+ }
276
+ function isMiniProgramDownloadProgressPayload(value) {
277
+ if (!isRecord$1(value) ||
278
+ !isNonNegativeSafeInteger(value.loaded) ||
279
+ typeof value.lengthComputable !== 'boolean' ||
280
+ !hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])) {
281
+ return false;
282
+ }
283
+ if (!value.lengthComputable)
284
+ return value.total === undefined;
285
+ return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
286
+ }
287
+ function isSDKHandshakePayload(value) {
288
+ return isRecord$1(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
289
+ }
290
+ function isBridgeError(value) {
291
+ return isRecord$1(value) && isNonEmptyString(value.code) && typeof value.message === 'string';
292
+ }
293
+ function isFileMode(value) {
294
+ return value === 'read' || value === 'readwrite';
295
+ }
296
+ function isNonNegativeSafeInteger(value) {
297
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
298
+ }
299
+ function isNonNegativeFiniteNumber(value) {
300
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
301
+ }
302
+ function isNonEmptyString(value) {
303
+ return typeof value === 'string' && value.length > 0;
304
+ }
305
+ function hasOnlyKeys(value, allowedKeys) {
306
+ const allowed = new Set(allowedKeys);
307
+ return Object.keys(value).every((key) => allowed.has(key));
308
+ }
309
+ function isRecord$1(value) {
310
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
136
311
  }
137
312
 
138
313
  /** 当前用户信息与登录能力支持的完整 scope 目录。 */
@@ -177,4 +352,4 @@ function isRecord(value) {
177
352
  return typeof value === 'object' && value !== null && !Array.isArray(value);
178
353
  }
179
354
 
180
- export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, parseMiniProgramRuntimePermissions };
355
+ export { AUTH_LOGIN_METHOD, CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD, CLOUD_LEADERBOARD_GET_INFO_METHOD, CLOUD_LEADERBOARD_GET_LIST_METHOD, CLOUD_LEADERBOARD_SUBMIT_METHOD, DEVICE_SET_CLIPBOARD_METHOD, DEVICE_VIBRATE_METHOD, DIRECTORY_CREATE_METHOD, DIRECTORY_EXISTS_METHOD, DIRECTORY_LIST_METHOD, DIRECTORY_REMOVE_METHOD, FILES_PICK_DIRECTORY_METHOD, FILES_PICK_FILES_METHOD, FILES_SAVE_FILE_METHOD, FILE_CREATE_METHOD, FILE_EXISTS_METHOD, FILE_READ_BYTES_METHOD, FILE_READ_TEXT_METHOD, FILE_REMOVE_METHOD, FILE_STAT_METHOD, FILE_WRITE_BYTES_METHOD, FILE_WRITE_TEXT_METHOD, MINI_PROGRAM_BRIDGE_NONCE_PARAM, MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_MESSAGE_VERSION, MINI_PROGRAM_OPERATION_PROGRESS_METHOD, MINI_PROGRAM_PROTOCOL_CAPABILITIES, NAVIGATION_CLOSE_METHOD, NAVIGATION_OPEN_APP_PAGE_METHOD, NAVIGATION_RELOAD_METHOD, NETWORK_DOWNLOAD_METHOD, NETWORK_REQUEST_METHOD, RUNTIME_LOCATION_PROBE_METHOD, SDK_CSP_VIOLATION_METHOD, SDK_HANDSHAKE_METHOD, SDK_LOCATION_REPORT_METHOD, SHARE_COPY_LINK_METHOD, SHARE_SCREENSHOT_METHOD, SHARE_SHOW_SHARE_MENU_METHOD, STORAGE_GET_STORAGE_METHOD, STORAGE_SET_STORAGE_METHOD, UI_HIDE_LOADING_METHOD, UI_SHOW_LOADING_METHOD, UI_SHOW_TOAST_METHOD, USER_GET_INFO_METHOD, USER_GET_STEAM_GAME_LIST_METHOD, USER_INFO_AUTHORIZATION_SCOPES, USER_REVOKE_AUTHORIZATION_METHOD, VIEWPORT_GET_WINDOW_INFO_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramPathRootRef, isMiniProgramRelativePath, parseMiniProgramRuntimePermissions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk-protocol",
3
- "version": "0.7.5-alpha.0",
3
+ "version": "0.8.0-alpha.2",
4
4
  "description": "Heybox mini-program iframe bridge wire contracts.",
5
5
  "sideEffects": false,
6
6
  "exports": {
@@ -40,6 +40,7 @@
40
40
  "test:types": "tsc -p tsconfig.dts.json --noEmit --pretty false",
41
41
  "clean": "rimraf ./dist && rimraf ./types",
42
42
  "check:boundary": "node scripts/check-boundary.cjs",
43
+ "pretest:unit": "pnpm run build:types",
43
44
  "test:unit": "NODE_OPTIONS='--conditions=heybox' vitest run",
44
45
  "test:watch": "NODE_OPTIONS='--conditions=heybox' vitest"
45
46
  }
package/src/bridge.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { MINI_PROGRAM_MESSAGE_NAMESPACE } from './constants';
2
- import type { UserInfoAuthorization } from './payloads';
1
+ import { MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_OPERATION_PROGRESS_METHOD } from './constants';
2
+ import type { DownloadProgressPayload, UserInfoAuthorization } from './payloads';
3
3
 
4
- export type MiniProgramBridgeMessageType = 'handshake' | 'request' | 'response' | 'event';
4
+ export type MiniProgramBridgeMessageType = 'handshake' | 'request' | 'response' | 'event' | 'cancel';
5
5
  export type MiniProgramEventName =
6
6
  | 'launch'
7
7
  | 'ready'
@@ -56,6 +56,24 @@ export interface MiniProgramBridgeMessage<TPayload = unknown> {
56
56
  payload?: TPayload;
57
57
  error?: MiniProgramBridgeError;
58
58
  }
59
+
60
+ export interface MiniProgramBridgeCancelMessage extends MiniProgramBridgeMessage<never> {
61
+ version: 2;
62
+ type: 'cancel';
63
+ id: string;
64
+ method?: never;
65
+ payload?: never;
66
+ error?: never;
67
+ }
68
+
69
+ export interface MiniProgramBridgeProgressMessage extends MiniProgramBridgeMessage<DownloadProgressPayload> {
70
+ version: 2;
71
+ type: 'event';
72
+ id: string;
73
+ method: typeof MINI_PROGRAM_OPERATION_PROGRESS_METHOD;
74
+ payload: DownloadProgressPayload;
75
+ error?: never;
76
+ }
59
77
  export interface MiniProgramEventPayloadMap {
60
78
  launch: { timestamp: number; url?: string };
61
79
  ready: { timestamp: number };