@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.
@@ -3,6 +3,14 @@ import type {
3
3
  CloseResult,
4
4
  CopyLinkPayload,
5
5
  CopyLinkResult,
6
+ DirectoryCreatePayload,
7
+ DirectoryCreateResult,
8
+ DirectoryExistsPayload,
9
+ DirectoryExistsResult,
10
+ DirectoryListPayload,
11
+ DirectoryListResult,
12
+ DirectoryRemovePayload,
13
+ DirectoryRemoveResult,
6
14
  DeleteCurrentUserLeaderboardEntryPayload,
7
15
  DeleteCurrentUserLeaderboardEntryResult,
8
16
  GetCurrentUserLeaderboardEntryPayload,
@@ -21,16 +29,40 @@ import type {
21
29
  GetWindowInfoResult,
22
30
  HideLoadingPayload,
23
31
  HideLoadingResult,
32
+ FileCreatePayload,
33
+ FileCreateResult,
34
+ FileExistsPayload,
35
+ FileExistsResult,
36
+ FileReadBytesPayload,
37
+ FileReadBytesResult,
38
+ FileReadTextPayload,
39
+ FileReadTextResult,
40
+ FileRemovePayload,
41
+ FileRemoveResult,
42
+ FileStatPayload,
43
+ FileStatResult,
44
+ FileWriteBytesPayload,
45
+ FileWriteBytesResult,
46
+ FileWriteTextPayload,
47
+ FileWriteTextResult,
24
48
  LoginPayload,
25
49
  LoginResult,
50
+ NetworkDownloadPayload,
51
+ NetworkDownloadResult,
26
52
  NetworkRequestPayload,
27
53
  NetworkResponsePayload,
28
54
  OpenAppPagePayload,
29
55
  OpenAppPageResult,
56
+ PickDirectoryPayload,
57
+ PickDirectoryResult,
58
+ PickFilesPayload,
59
+ PickFilesResult,
30
60
  ReloadPayload,
31
61
  ReloadResult,
32
62
  ScreenshotPayload,
33
63
  ScreenshotResult,
64
+ SaveFilePayload,
65
+ SaveFileResult,
34
66
  SetClipboardPayload,
35
67
  SetClipboardResult,
36
68
  SetNavigationBarStylePayload,
@@ -60,6 +92,22 @@ export const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationB
60
92
  export const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage' as const;
61
93
  export const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage' as const;
62
94
  export const NETWORK_REQUEST_METHOD = 'network.request' as const;
95
+ export const NETWORK_DOWNLOAD_METHOD = 'network.download' as const;
96
+ export const FILES_PICK_FILES_METHOD = 'files.pickFiles' as const;
97
+ export const FILES_PICK_DIRECTORY_METHOD = 'files.pickDirectory' as const;
98
+ export const FILES_SAVE_FILE_METHOD = 'files.saveFile' as const;
99
+ export const FILE_CREATE_METHOD = 'file.create' as const;
100
+ export const FILE_REMOVE_METHOD = 'file.remove' as const;
101
+ export const FILE_EXISTS_METHOD = 'file.exists' as const;
102
+ export const FILE_READ_TEXT_METHOD = 'file.readText' as const;
103
+ export const FILE_WRITE_TEXT_METHOD = 'file.writeText' as const;
104
+ export const FILE_READ_BYTES_METHOD = 'file.readBytes' as const;
105
+ export const FILE_WRITE_BYTES_METHOD = 'file.writeBytes' as const;
106
+ export const FILE_STAT_METHOD = 'file.stat' as const;
107
+ export const DIRECTORY_CREATE_METHOD = 'directory.create' as const;
108
+ export const DIRECTORY_REMOVE_METHOD = 'directory.remove' as const;
109
+ export const DIRECTORY_EXISTS_METHOD = 'directory.exists' as const;
110
+ export const DIRECTORY_LIST_METHOD = 'directory.list' as const;
63
111
  export const UI_SHOW_TOAST_METHOD = 'ui.showToast' as const;
64
112
  export const UI_SHOW_LOADING_METHOD = 'ui.showLoading' as const;
65
113
  export const UI_HIDE_LOADING_METHOD = 'ui.hideLoading' as const;
@@ -79,7 +127,22 @@ export type MiniProgramUserMethod = typeof USER_GET_INFO_METHOD | typeof USER_RE
79
127
  export type MiniProgramShareMethod = typeof SHARE_COPY_LINK_METHOD | typeof SHARE_SHOW_SHARE_MENU_METHOD | typeof SHARE_SCREENSHOT_METHOD;
80
128
  export type MiniProgramViewportMethod = typeof VIEWPORT_GET_WINDOW_INFO_METHOD | typeof VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
81
129
  export type MiniProgramStorageMethod = typeof STORAGE_GET_STORAGE_METHOD | typeof STORAGE_SET_STORAGE_METHOD;
82
- export type MiniProgramNetworkMethod = typeof NETWORK_REQUEST_METHOD;
130
+ export type MiniProgramNetworkMethod = typeof NETWORK_REQUEST_METHOD | typeof NETWORK_DOWNLOAD_METHOD;
131
+ export type MiniProgramFilesMethod = typeof FILES_PICK_FILES_METHOD | typeof FILES_PICK_DIRECTORY_METHOD | typeof FILES_SAVE_FILE_METHOD;
132
+ export type MiniProgramFileMethod =
133
+ | typeof FILE_CREATE_METHOD
134
+ | typeof FILE_REMOVE_METHOD
135
+ | typeof FILE_EXISTS_METHOD
136
+ | typeof FILE_READ_TEXT_METHOD
137
+ | typeof FILE_WRITE_TEXT_METHOD
138
+ | typeof FILE_READ_BYTES_METHOD
139
+ | typeof FILE_WRITE_BYTES_METHOD
140
+ | typeof FILE_STAT_METHOD;
141
+ export type MiniProgramDirectoryMethod =
142
+ | typeof DIRECTORY_CREATE_METHOD
143
+ | typeof DIRECTORY_REMOVE_METHOD
144
+ | typeof DIRECTORY_EXISTS_METHOD
145
+ | typeof DIRECTORY_LIST_METHOD;
83
146
  export type MiniProgramUiMethod = typeof UI_SHOW_TOAST_METHOD | typeof UI_SHOW_LOADING_METHOD | typeof UI_HIDE_LOADING_METHOD;
84
147
  export type MiniProgramDeviceMethod = typeof DEVICE_VIBRATE_METHOD | typeof DEVICE_SET_CLIPBOARD_METHOD;
85
148
  export type MiniProgramNavigationMethod = typeof NAVIGATION_CLOSE_METHOD | typeof NAVIGATION_RELOAD_METHOD | typeof NAVIGATION_OPEN_APP_PAGE_METHOD;
@@ -96,11 +159,27 @@ export type MiniProgramBridgeMethod =
96
159
  | MiniProgramViewportMethod
97
160
  | MiniProgramStorageMethod
98
161
  | MiniProgramNetworkMethod
162
+ | MiniProgramFilesMethod
163
+ | MiniProgramFileMethod
164
+ | MiniProgramDirectoryMethod
99
165
  | MiniProgramUiMethod
100
166
  | MiniProgramDeviceMethod
101
167
  | MiniProgramNavigationMethod
102
168
  | MiniProgramCloudMethod;
103
- export type MiniProgramCapabilityModule = 'auth' | 'user' | 'share' | 'viewport' | 'storage' | 'network' | 'ui' | 'device' | 'navigation' | 'cloud';
169
+ export type MiniProgramCapabilityModule =
170
+ | 'auth'
171
+ | 'user'
172
+ | 'share'
173
+ | 'viewport'
174
+ | 'storage'
175
+ | 'network'
176
+ | 'files'
177
+ | 'file'
178
+ | 'directory'
179
+ | 'ui'
180
+ | 'device'
181
+ | 'navigation'
182
+ | 'cloud';
104
183
  export type MiniProgramCapabilityRisk = 'low' | 'medium' | 'high';
105
184
 
106
185
  export interface MiniProgramCapabilityDefinition {
@@ -148,6 +227,46 @@ export const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
148
227
  { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
149
228
  { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
150
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' },
232
+ {
233
+ method: FILES_PICK_DIRECTORY_METHOD,
234
+ module: 'files',
235
+ capability: FILES_PICK_DIRECTORY_METHOD,
236
+ permission: 'files.external',
237
+ risk: 'high',
238
+ },
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' },
248
+ {
249
+ method: DIRECTORY_CREATE_METHOD,
250
+ module: 'directory',
251
+ capability: DIRECTORY_CREATE_METHOD,
252
+ permission: 'files.access',
253
+ risk: 'high',
254
+ },
255
+ {
256
+ method: DIRECTORY_REMOVE_METHOD,
257
+ module: 'directory',
258
+ capability: DIRECTORY_REMOVE_METHOD,
259
+ permission: 'files.access',
260
+ risk: 'high',
261
+ },
262
+ {
263
+ method: DIRECTORY_EXISTS_METHOD,
264
+ module: 'directory',
265
+ capability: DIRECTORY_EXISTS_METHOD,
266
+ permission: 'files.access',
267
+ risk: 'high',
268
+ },
269
+ { method: DIRECTORY_LIST_METHOD, module: 'directory', capability: DIRECTORY_LIST_METHOD, permission: 'files.access', risk: 'high' },
151
270
  { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
152
271
  { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
153
272
  { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
@@ -218,6 +337,22 @@ export interface MiniProgramCapabilityPayloadMap {
218
337
  [STORAGE_GET_STORAGE_METHOD]: GetStoragePayload;
219
338
  [STORAGE_SET_STORAGE_METHOD]: SetStoragePayload;
220
339
  [NETWORK_REQUEST_METHOD]: NetworkRequestPayload;
340
+ [NETWORK_DOWNLOAD_METHOD]: NetworkDownloadPayload;
341
+ [FILES_PICK_FILES_METHOD]: PickFilesPayload;
342
+ [FILES_PICK_DIRECTORY_METHOD]: PickDirectoryPayload;
343
+ [FILES_SAVE_FILE_METHOD]: SaveFilePayload;
344
+ [FILE_CREATE_METHOD]: FileCreatePayload;
345
+ [FILE_REMOVE_METHOD]: FileRemovePayload;
346
+ [FILE_EXISTS_METHOD]: FileExistsPayload;
347
+ [FILE_READ_TEXT_METHOD]: FileReadTextPayload;
348
+ [FILE_WRITE_TEXT_METHOD]: FileWriteTextPayload;
349
+ [FILE_READ_BYTES_METHOD]: FileReadBytesPayload;
350
+ [FILE_WRITE_BYTES_METHOD]: FileWriteBytesPayload;
351
+ [FILE_STAT_METHOD]: FileStatPayload;
352
+ [DIRECTORY_CREATE_METHOD]: DirectoryCreatePayload;
353
+ [DIRECTORY_REMOVE_METHOD]: DirectoryRemovePayload;
354
+ [DIRECTORY_EXISTS_METHOD]: DirectoryExistsPayload;
355
+ [DIRECTORY_LIST_METHOD]: DirectoryListPayload;
221
356
  [UI_SHOW_TOAST_METHOD]: ShowToastPayload;
222
357
  [UI_SHOW_LOADING_METHOD]: ShowLoadingPayload;
223
358
  [UI_HIDE_LOADING_METHOD]: HideLoadingPayload;
@@ -246,6 +381,22 @@ export interface MiniProgramCapabilityResultMap {
246
381
  [STORAGE_GET_STORAGE_METHOD]: GetStorageResult;
247
382
  [STORAGE_SET_STORAGE_METHOD]: void;
248
383
  [NETWORK_REQUEST_METHOD]: NetworkResponsePayload;
384
+ [NETWORK_DOWNLOAD_METHOD]: NetworkDownloadResult;
385
+ [FILES_PICK_FILES_METHOD]: PickFilesResult;
386
+ [FILES_PICK_DIRECTORY_METHOD]: PickDirectoryResult;
387
+ [FILES_SAVE_FILE_METHOD]: SaveFileResult;
388
+ [FILE_CREATE_METHOD]: FileCreateResult;
389
+ [FILE_REMOVE_METHOD]: FileRemoveResult;
390
+ [FILE_EXISTS_METHOD]: FileExistsResult;
391
+ [FILE_READ_TEXT_METHOD]: FileReadTextResult;
392
+ [FILE_WRITE_TEXT_METHOD]: FileWriteTextResult;
393
+ [FILE_READ_BYTES_METHOD]: FileReadBytesResult;
394
+ [FILE_WRITE_BYTES_METHOD]: FileWriteBytesResult;
395
+ [FILE_STAT_METHOD]: FileStatResult;
396
+ [DIRECTORY_CREATE_METHOD]: DirectoryCreateResult;
397
+ [DIRECTORY_REMOVE_METHOD]: DirectoryRemoveResult;
398
+ [DIRECTORY_EXISTS_METHOD]: DirectoryExistsResult;
399
+ [DIRECTORY_LIST_METHOD]: DirectoryListResult;
249
400
  [UI_SHOW_TOAST_METHOD]: ShowToastResult;
250
401
  [UI_SHOW_LOADING_METHOD]: ShowLoadingResult;
251
402
  [UI_HIDE_LOADING_METHOD]: HideLoadingResult;
package/src/constants.ts CHANGED
@@ -5,3 +5,4 @@ export const SDK_HANDSHAKE_METHOD = 'sdk.handshake' as const;
5
5
  export const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe' as const;
6
6
  export const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report' as const;
7
7
  export const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation' as const;
8
+ export const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress' as const;
package/src/guards.ts CHANGED
@@ -1,13 +1,167 @@
1
- import { MINI_PROGRAM_MESSAGE_NAMESPACE } from './constants';
1
+ import { MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_OPERATION_PROGRESS_METHOD, SDK_HANDSHAKE_METHOD } from './constants';
2
2
  import type { MiniProgramBridgeMessage } from './bridge';
3
+ import type {
4
+ DownloadProgressPayload,
5
+ MiniProgramDirectoryDescriptor,
6
+ MiniProgramDirectoryRef,
7
+ MiniProgramFileDescriptor,
8
+ MiniProgramFileRef,
9
+ MiniProgramFileStat,
10
+ MiniProgramFileSystemEntityDescriptor,
11
+ MiniProgramPathRootRef,
12
+ } from './payloads';
3
13
 
4
14
  export function isMiniProgramBridgeMessage(value: unknown): value is MiniProgramBridgeMessage {
5
- if (!value || typeof value !== 'object') return false;
6
- const message = value as Partial<MiniProgramBridgeMessage>;
15
+ if (!isRecord(value)) return false;
16
+ if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString(value.nonce)) {
17
+ return false;
18
+ }
19
+
20
+ if (value.type === 'handshake') {
21
+ return isNonEmptyString(value.id) && value.method === SDK_HANDSHAKE_METHOD && value.error === undefined && isSDKHandshakePayload(value.payload);
22
+ }
23
+ if (value.type === 'request') {
24
+ return isNonEmptyString(value.id) && isNonEmptyString(value.method) && value.error === undefined;
25
+ }
26
+ if (value.type === 'response') {
27
+ return (
28
+ isNonEmptyString(value.id) &&
29
+ (value.method === undefined || isNonEmptyString(value.method)) &&
30
+ (value.error === undefined || isBridgeError(value.error))
31
+ );
32
+ }
33
+ if (value.type === 'event') {
34
+ if (!isNonEmptyString(value.method) || value.error !== undefined) return false;
35
+ if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
36
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
37
+ }
38
+ return value.id === undefined || isNonEmptyString(value.id);
39
+ }
40
+ if (value.type === 'cancel') {
41
+ return (
42
+ value.version === 2 && isNonEmptyString(value.id) && value.method === undefined && value.payload === undefined && value.error === undefined
43
+ );
44
+ }
45
+ return false;
46
+ }
47
+
48
+ export function isMiniProgramRelativePath(value: unknown): value is string {
49
+ if (typeof value !== 'string' || !value || value.startsWith('/') || value.endsWith('/')) {
50
+ return false;
51
+ }
52
+ if (/[\\\u0000-\u001f\u007f]/.test(value)) return false;
53
+ return value.split('/').every((segment) => Boolean(segment) && segment !== '.' && segment !== '..');
54
+ }
55
+
56
+ export function isMiniProgramPathRootRef(value: unknown): value is MiniProgramPathRootRef {
57
+ if (!isRecord(value)) return false;
58
+ if (value.kind === 'sandbox') return hasOnlyKeys(value, ['kind']);
59
+ return value.kind === 'directory' && isNonEmptyString(value.handleId) && hasOnlyKeys(value, ['kind', 'handleId']);
60
+ }
61
+
62
+ export function isMiniProgramFileRef(value: unknown): value is MiniProgramFileRef {
63
+ if (!isRecord(value) || value.kind !== 'file') return false;
64
+ if (isNonEmptyString(value.handleId)) {
65
+ return hasOnlyKeys(value, ['kind', 'handleId']);
66
+ }
67
+ return (
68
+ isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath'])
69
+ );
70
+ }
71
+
72
+ export function isMiniProgramDirectoryRef(value: unknown): value is MiniProgramDirectoryRef {
73
+ if (!isRecord(value) || value.kind !== 'directory') return false;
74
+ if (isNonEmptyString(value.handleId)) {
75
+ return hasOnlyKeys(value, ['kind', 'handleId']);
76
+ }
7
77
  return (
8
- message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
9
- (message.version === 1 || message.version === 2) &&
10
- typeof message.nonce === 'string' &&
11
- typeof message.type === 'string'
78
+ isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath'])
12
79
  );
13
80
  }
81
+
82
+ export function isMiniProgramFileDescriptor(value: unknown): value is MiniProgramFileDescriptor {
83
+ return (
84
+ isRecord(value) &&
85
+ value.kind === 'file' &&
86
+ isNonEmptyString(value.name) &&
87
+ isFileMode(value.mode) &&
88
+ isMiniProgramFileRef(value.ref) &&
89
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref'])
90
+ );
91
+ }
92
+
93
+ export function isMiniProgramDirectoryDescriptor(value: unknown): value is MiniProgramDirectoryDescriptor {
94
+ return (
95
+ isRecord(value) &&
96
+ value.kind === 'directory' &&
97
+ isNonEmptyString(value.name) &&
98
+ isFileMode(value.mode) &&
99
+ isMiniProgramDirectoryRef(value.ref) &&
100
+ hasOnlyKeys(value, ['kind', 'name', 'mode', 'ref'])
101
+ );
102
+ }
103
+
104
+ export function isMiniProgramFileSystemEntityDescriptor(value: unknown): value is MiniProgramFileSystemEntityDescriptor {
105
+ return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
106
+ }
107
+
108
+ export function isMiniProgramByteArray(value: unknown): value is Uint8Array {
109
+ return value instanceof Uint8Array && value.buffer instanceof ArrayBuffer;
110
+ }
111
+
112
+ export function isMiniProgramFileStat(value: unknown): value is MiniProgramFileStat {
113
+ return (
114
+ isRecord(value) &&
115
+ value.kind === 'file' &&
116
+ isNonNegativeSafeInteger(value.size) &&
117
+ (value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
118
+ (value.createdAt === undefined || isNonNegativeFiniteNumber(value.createdAt)) &&
119
+ hasOnlyKeys(value, ['kind', 'size', 'modifiedAt', 'createdAt'])
120
+ );
121
+ }
122
+
123
+ export function isMiniProgramDownloadProgressPayload(value: unknown): value is DownloadProgressPayload {
124
+ if (
125
+ !isRecord(value) ||
126
+ !isNonNegativeSafeInteger(value.loaded) ||
127
+ typeof value.lengthComputable !== 'boolean' ||
128
+ !hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])
129
+ ) {
130
+ return false;
131
+ }
132
+ if (!value.lengthComputable) return value.total === undefined;
133
+ return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
134
+ }
135
+
136
+ function isSDKHandshakePayload(value: unknown) {
137
+ return isRecord(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
138
+ }
139
+
140
+ function isBridgeError(value: unknown) {
141
+ return isRecord(value) && isNonEmptyString(value.code) && typeof value.message === 'string';
142
+ }
143
+
144
+ function isFileMode(value: unknown) {
145
+ return value === 'read' || value === 'readwrite';
146
+ }
147
+
148
+ function isNonNegativeSafeInteger(value: unknown): value is number {
149
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
150
+ }
151
+
152
+ function isNonNegativeFiniteNumber(value: unknown): value is number {
153
+ return typeof value === 'number' && Number.isFinite(value) && value >= 0;
154
+ }
155
+
156
+ function isNonEmptyString(value: unknown): value is string {
157
+ return typeof value === 'string' && value.length > 0;
158
+ }
159
+
160
+ function hasOnlyKeys(value: Record<string, unknown>, allowedKeys: readonly string[]) {
161
+ const allowed = new Set(allowedKeys);
162
+ return Object.keys(value).every((key) => allowed.has(key));
163
+ }
164
+
165
+ function isRecord(value: unknown): value is Record<string, unknown> {
166
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
167
+ }
package/src/payloads.ts CHANGED
@@ -189,6 +189,180 @@ export interface NetworkResponsePayload<T = unknown> {
189
189
  headers: MiniProgramNetworkHeaders;
190
190
  }
191
191
 
192
+ export type MiniProgramFileMode = 'read' | 'readwrite';
193
+
194
+ export interface MiniProgramSandboxRootRef {
195
+ kind: 'sandbox';
196
+ }
197
+
198
+ export interface MiniProgramDirectFileRef {
199
+ kind: 'file';
200
+ handleId: string;
201
+ }
202
+
203
+ export interface MiniProgramDirectDirectoryRef {
204
+ kind: 'directory';
205
+ handleId: string;
206
+ }
207
+
208
+ export type MiniProgramPathRootRef = MiniProgramSandboxRootRef | MiniProgramDirectDirectoryRef;
209
+
210
+ export interface MiniProgramDerivedFileRef {
211
+ kind: 'file';
212
+ root: MiniProgramPathRootRef;
213
+ relativePath: string;
214
+ }
215
+
216
+ export interface MiniProgramDerivedDirectoryRef {
217
+ kind: 'directory';
218
+ root: MiniProgramPathRootRef;
219
+ relativePath: string;
220
+ }
221
+
222
+ export type MiniProgramFileRef = MiniProgramDirectFileRef | MiniProgramDerivedFileRef;
223
+ export type MiniProgramDirectoryRef = MiniProgramDirectDirectoryRef | MiniProgramDerivedDirectoryRef;
224
+ export type MiniProgramFileSystemEntityRef = MiniProgramFileRef | MiniProgramDirectoryRef;
225
+
226
+ export interface MiniProgramFileDescriptor {
227
+ kind: 'file';
228
+ name: string;
229
+ mode: MiniProgramFileMode;
230
+ ref: MiniProgramFileRef;
231
+ }
232
+
233
+ export interface MiniProgramDirectoryDescriptor {
234
+ kind: 'directory';
235
+ name: string;
236
+ mode: MiniProgramFileMode;
237
+ ref: MiniProgramDirectoryRef;
238
+ }
239
+
240
+ export type MiniProgramFileSystemEntityDescriptor = MiniProgramFileDescriptor | MiniProgramDirectoryDescriptor;
241
+
242
+ export interface MiniProgramCreateOptions {
243
+ recursive?: boolean;
244
+ exclusive?: boolean;
245
+ }
246
+
247
+ export interface MiniProgramFileStat {
248
+ kind: 'file';
249
+ size: number;
250
+ modifiedAt?: number;
251
+ createdAt?: number;
252
+ }
253
+
254
+ export type PickFilesPayload =
255
+ | {
256
+ mode?: MiniProgramFileMode;
257
+ accept?: string[];
258
+ multiple?: boolean;
259
+ }
260
+ | undefined;
261
+ export type PickFilesResult = Array<MiniProgramFileDescriptor & { ref: MiniProgramDirectFileRef }>;
262
+
263
+ export type PickDirectoryPayload = { mode?: MiniProgramFileMode } | undefined;
264
+ export type PickDirectoryResult = MiniProgramDirectoryDescriptor & { ref: MiniProgramDirectDirectoryRef };
265
+
266
+ export interface SaveFilePayload {
267
+ suggestedName: string;
268
+ }
269
+ export type SaveFileResult = MiniProgramFileDescriptor & { ref: MiniProgramDirectFileRef };
270
+
271
+ export interface FileCreatePayload extends MiniProgramCreateOptions {
272
+ target: MiniProgramFileRef;
273
+ }
274
+ export type FileCreateResult = void;
275
+
276
+ export interface FileRemovePayload {
277
+ target: MiniProgramFileRef;
278
+ }
279
+ export type FileRemoveResult = void;
280
+
281
+ export interface FileExistsPayload {
282
+ target: MiniProgramFileRef;
283
+ }
284
+ export type FileExistsResult = boolean;
285
+
286
+ export interface FileReadTextPayload {
287
+ target: MiniProgramFileRef;
288
+ }
289
+ export type FileReadTextResult = string;
290
+
291
+ export interface FileWriteTextPayload {
292
+ target: MiniProgramFileRef;
293
+ content: string;
294
+ }
295
+ export type FileWriteTextResult = void;
296
+
297
+ export interface FileReadBytesPayload {
298
+ target: MiniProgramFileRef;
299
+ }
300
+ export type FileReadBytesResult = Uint8Array;
301
+
302
+ export interface FileWriteBytesPayload {
303
+ target: MiniProgramFileRef;
304
+ content: Uint8Array;
305
+ }
306
+ export type FileWriteBytesResult = void;
307
+
308
+ export interface FileStatPayload {
309
+ target: MiniProgramFileRef;
310
+ }
311
+ export type FileStatResult = MiniProgramFileStat;
312
+
313
+ export interface DirectoryCreatePayload extends MiniProgramCreateOptions {
314
+ target: MiniProgramDirectoryRef;
315
+ }
316
+ export type DirectoryCreateResult = void;
317
+
318
+ export interface DirectoryRemovePayload {
319
+ target: MiniProgramDirectoryRef;
320
+ recursive?: boolean;
321
+ }
322
+ export type DirectoryRemoveResult = void;
323
+
324
+ export interface DirectoryExistsPayload {
325
+ target: MiniProgramDirectoryRef;
326
+ }
327
+ export type DirectoryExistsResult = boolean;
328
+
329
+ export interface DirectoryListPayload {
330
+ target: MiniProgramDirectoryRef;
331
+ limit?: number;
332
+ }
333
+ export type DirectoryListResult = MiniProgramFileSystemEntityDescriptor[];
334
+
335
+ export interface DownloadProgressPayload {
336
+ loaded: number;
337
+ total?: number;
338
+ lengthComputable: boolean;
339
+ }
340
+
341
+ interface NetworkDownloadBasePayload {
342
+ url: string;
343
+ params?: MiniProgramNetworkParams;
344
+ headers?: MiniProgramNetworkHeaders;
345
+ timeout?: number;
346
+ withCredentials?: boolean;
347
+ maxBytes?: number;
348
+ }
349
+
350
+ export type NetworkDownloadPayload = NetworkDownloadBasePayload &
351
+ (
352
+ | {
353
+ to: MiniProgramFileRef;
354
+ suggestedName?: never;
355
+ overwrite?: never;
356
+ }
357
+ | {
358
+ to: MiniProgramDirectoryRef;
359
+ suggestedName?: string;
360
+ overwrite?: boolean;
361
+ }
362
+ );
363
+
364
+ export type NetworkDownloadResult = MiniProgramFileDescriptor;
365
+
192
366
  export type MiniProgramToastStatus = 'success' | 'error';
193
367
  export interface ShowToastPayload {
194
368
  message: string;
package/types/bridge.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { MINI_PROGRAM_MESSAGE_NAMESPACE } from './constants';
2
- import type { UserInfoAuthorization } from './payloads';
3
- export type MiniProgramBridgeMessageType = 'handshake' | 'request' | 'response' | 'event';
1
+ import { MINI_PROGRAM_MESSAGE_NAMESPACE, MINI_PROGRAM_OPERATION_PROGRESS_METHOD } from './constants';
2
+ import type { DownloadProgressPayload, UserInfoAuthorization } from './payloads';
3
+ export type MiniProgramBridgeMessageType = 'handshake' | 'request' | 'response' | 'event' | 'cancel';
4
4
  export type MiniProgramEventName = 'launch' | 'ready' | 'show' | 'hide' | 'unload' | 'error' | 'heybox_app_login_change' | 'user_info_authorization_change';
5
5
  export interface MiniProgramBridgeError {
6
6
  code: string;
@@ -46,6 +46,22 @@ export interface MiniProgramBridgeMessage<TPayload = unknown> {
46
46
  payload?: TPayload;
47
47
  error?: MiniProgramBridgeError;
48
48
  }
49
+ export interface MiniProgramBridgeCancelMessage extends MiniProgramBridgeMessage<never> {
50
+ version: 2;
51
+ type: 'cancel';
52
+ id: string;
53
+ method?: never;
54
+ payload?: never;
55
+ error?: never;
56
+ }
57
+ export interface MiniProgramBridgeProgressMessage extends MiniProgramBridgeMessage<DownloadProgressPayload> {
58
+ version: 2;
59
+ type: 'event';
60
+ id: string;
61
+ method: typeof MINI_PROGRAM_OPERATION_PROGRESS_METHOD;
62
+ payload: DownloadProgressPayload;
63
+ error?: never;
64
+ }
49
65
  export interface MiniProgramEventPayloadMap {
50
66
  launch: {
51
67
  timestamp: number;