@heybox/hb-sdk 0.9.3-alpha.6 → 0.9.3
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/CHANGELOG.md +33 -0
- package/README.md +1 -0
- package/dist/cli-chunks/{build-B1YssPNl.cjs → build-DrFbb0V-.cjs} +5 -5
- package/dist/cli-chunks/{context-Deob2IZ5.cjs → context-CTlwLbwn.cjs} +2 -2
- package/dist/cli-chunks/{create-BWzY1CVT.cjs → create-Ccse2SW7.cjs} +1 -1
- package/dist/cli-chunks/{deploy-lock-ClcPcaSW.cjs → deploy-lock-DaGpgsU7.cjs} +1 -1
- package/dist/cli-chunks/{dev-wVCyeUOb.cjs → dev-BHsCFm4O.cjs} +8 -8
- package/dist/cli-chunks/{doctor-DHd5eYBr.cjs → doctor-BhTTMupn.cjs} +1 -1
- package/dist/cli-chunks/{games-DNhP1Om4.cjs → games-BOP_ZDp6.cjs} +2 -2
- package/dist/cli-chunks/{index-DfYr8g3I.cjs → index-CF6qh9ll.cjs} +17 -17
- package/dist/cli-chunks/{index-BOd8ouDY.cjs → index-DMall69X.cjs} +1 -1
- package/dist/cli-chunks/{index.esm-PlHUr780.cjs → index.esm-Cau47g22.cjs} +6 -6
- package/dist/cli-chunks/{login-D-iG6Um2.cjs → login-BGDovscU.cjs} +1 -1
- package/dist/cli-chunks/{project-vite-DyKHpc6h.cjs → project-vite-Dnev8Z34.cjs} +1 -1
- package/dist/cli-chunks/{remote-CyynHOcj.cjs → remote--MDcbz4m.cjs} +7 -7
- package/dist/cli-chunks/{runtime-gate-DPXnKdQ4.cjs → runtime-gate-BgWB2U5f.cjs} +2 -2
- package/dist/cli-chunks/{runtime-permission-env-BjO2KzGl.cjs → runtime-permission-env-DmJ1zEpa.cjs} +13 -2
- package/dist/cli-chunks/{skill-BOLOEDrj.cjs → skill-Bm1MmMN5.cjs} +2 -2
- package/dist/cli-chunks/{version-DX2glIk7.cjs → version-C6b3tkax.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-BHtf4WWG.js +102 -0
- package/dist/devtools/browser-dev-host/assets/desktop-app-launch-Dl4RfM9z.js +6 -0
- package/dist/devtools/browser-dev-host/assets/{index-Br7UpHGt.js → index-DFLYLAXj.js} +4 -4
- package/dist/devtools/browser-dev-host/assets/{index-7Cq8iNcD.css → index-h-fYisyX.css} +1 -1
- package/dist/devtools/browser-dev-host/index.html +3 -3
- package/dist/index.cjs.js +314 -28
- package/dist/index.esm.js +314 -29
- package/dist/miniapp-publish.cjs.js +11 -0
- package/dist/miniapp-publish.esm.js +11 -0
- package/dist/protocol.cjs.js +172 -0
- package/dist/protocol.esm.js +169 -1
- package/dist/vite.cjs.js +17 -3
- package/dist/vite.esm.js +17 -3
- package/package.json +7 -7
- package/skill/skill.json +4 -4
- package/types/index.d.ts +80 -2
- package/types/miniapp-publish/index.d.ts +1 -1
- package/types/protocol.d.ts +77 -2
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-CD6Ado2B.js +0 -102
- package/dist/devtools/browser-dev-host/assets/desktop-app-launch-CFl6m8k-.js +0 -6
package/dist/protocol.cjs.js
CHANGED
|
@@ -63,6 +63,7 @@ const DIRECTORY_CREATE_METHOD = 'directory.create';
|
|
|
63
63
|
const DIRECTORY_REMOVE_METHOD = 'directory.remove';
|
|
64
64
|
const DIRECTORY_EXISTS_METHOD = 'directory.exists';
|
|
65
65
|
const DIRECTORY_LIST_METHOD = 'directory.list';
|
|
66
|
+
const MEDIA_PICK_METHOD = 'media.pick';
|
|
66
67
|
const UI_SHOW_TOAST_METHOD = 'ui.showToast';
|
|
67
68
|
const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
|
|
68
69
|
const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
|
|
@@ -323,6 +324,13 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
323
324
|
requirement: { kind: 'all', permissions: ['filesystem'] },
|
|
324
325
|
risk: 'high',
|
|
325
326
|
},
|
|
327
|
+
{
|
|
328
|
+
method: MEDIA_PICK_METHOD,
|
|
329
|
+
module: 'media',
|
|
330
|
+
capability: MEDIA_PICK_METHOD,
|
|
331
|
+
requirement: { kind: 'all', permissions: ['media'] },
|
|
332
|
+
risk: 'high',
|
|
333
|
+
},
|
|
326
334
|
{ method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
327
335
|
{ method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
328
336
|
{ method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
@@ -1008,6 +1016,159 @@ function isMiniProgramDirectoryDescriptor(value) {
|
|
|
1008
1016
|
function isMiniProgramFileSystemEntityDescriptor(value) {
|
|
1009
1017
|
return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
|
|
1010
1018
|
}
|
|
1019
|
+
/** `media.pick` 结果数组允许的最大项数,与协议 `maxCount` 上限一致。 */
|
|
1020
|
+
const MAX_MEDIA_PICK_COUNT = 20;
|
|
1021
|
+
/** `media.pick` 单项结果的公共 canonical key 集合。 */
|
|
1022
|
+
const MEDIA_PICK_ITEM_KEYS = ['type', 'mimeType', 'size', 'width', 'height', 'previewUrl', 'file'];
|
|
1023
|
+
/**
|
|
1024
|
+
* 判断未知值是否具有 `media.pick` payload 的最低 wire 结构。
|
|
1025
|
+
*
|
|
1026
|
+
* @param value - 来自 App-facing 参数、bridge request 或其他不可信边界的候选 payload。`undefined`
|
|
1027
|
+
* 表示调用方省略整个 payload,会通过本 guard 并使用全部缺省值。
|
|
1028
|
+
* @returns 值满足 {@link MediaPickPayload} 的枚举、取值范围和键集合约束时返回 `true`,并将
|
|
1029
|
+
* TypeScript 类型收窄为 payload 类型;否则返回 `false`。
|
|
1030
|
+
*
|
|
1031
|
+
* @remarks
|
|
1032
|
+
* 对通常的对象字面量,仅允许 `source`、`mediaType`、`maxCount` 三个 canonical key:
|
|
1033
|
+
*
|
|
1034
|
+
* - `source` 可省略或为 `album` / `camera`;`mediaType` 可省略或为 `image` / `video` / `all`。
|
|
1035
|
+
* - `maxCount` 可省略,或为 1–20 的安全整数。`0`、负数、小数、`NaN`、`Infinity`、unsafe integer、
|
|
1036
|
+
* bigint 和数字字符串都会被拒绝。
|
|
1037
|
+
* - `source === 'camera'` 且提供 `maxCount` 时,只接受 `1`;大于 1 的值在此处即可拒绝,
|
|
1038
|
+
* Runtime 不应静默收窄。
|
|
1039
|
+
*
|
|
1040
|
+
* 该 guard 只建立结构类型收窄,不应用缺省值、不证明 `media` 权限已声明或启用、不检查可信用户手势、
|
|
1041
|
+
* 不确认 Host 支持 `media.pick`,也不保证系统选择器一定交付 `maxCount` 项。`all` 仅表示图片与视频,
|
|
1042
|
+
* 不包含音频或任意文件。
|
|
1043
|
+
*
|
|
1044
|
+
* @example
|
|
1045
|
+
* ```ts
|
|
1046
|
+
* import { isMiniProgramMediaPickPayload } from '@heybox/hb-sdk/protocol';
|
|
1047
|
+
*
|
|
1048
|
+
* isMiniProgramMediaPickPayload(undefined); // true:使用全部缺省值
|
|
1049
|
+
* isMiniProgramMediaPickPayload({ source: 'album', maxCount: 20 }); // true
|
|
1050
|
+
* isMiniProgramMediaPickPayload({ source: 'camera', maxCount: 2 }); // false:相机只能单选
|
|
1051
|
+
* ```
|
|
1052
|
+
*
|
|
1053
|
+
* @see [MediaPickPayload](/reference/symbols/protocol/interfaces/MediaPickPayload) wire 字段定义。
|
|
1054
|
+
* @since 0.9.3
|
|
1055
|
+
*/
|
|
1056
|
+
function isMiniProgramMediaPickPayload(value) {
|
|
1057
|
+
if (value === undefined)
|
|
1058
|
+
return true;
|
|
1059
|
+
if (!isRecord$3(value) || !hasOnlyKeys(value, ['source', 'mediaType', 'maxCount']))
|
|
1060
|
+
return false;
|
|
1061
|
+
if (value.source !== undefined && value.source !== 'album' && value.source !== 'camera')
|
|
1062
|
+
return false;
|
|
1063
|
+
if (value.mediaType !== undefined && value.mediaType !== 'image' && value.mediaType !== 'video' && value.mediaType !== 'all')
|
|
1064
|
+
return false;
|
|
1065
|
+
if (value.maxCount !== undefined) {
|
|
1066
|
+
if (!isIntegerInRange(value.maxCount, 1, MAX_MEDIA_PICK_COUNT))
|
|
1067
|
+
return false;
|
|
1068
|
+
if (value.source === 'camera' && value.maxCount !== 1)
|
|
1069
|
+
return false;
|
|
1070
|
+
}
|
|
1071
|
+
return true;
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* 判断未知值是否为单个 `media.pick` 媒体项。
|
|
1075
|
+
*
|
|
1076
|
+
* @param value - 来自 Host response、bridge result 或其他不可信边界的候选媒体项。
|
|
1077
|
+
* @returns 字段组合满足 {@link MediaPickItem} 判别联合的最低结构时返回 `true`,并将 TypeScript 类型
|
|
1078
|
+
* 收窄为图片或视频项;否则返回 `false`。
|
|
1079
|
+
*
|
|
1080
|
+
* @remarks
|
|
1081
|
+
* 以 `type` 为判别字段,两个分支都要求 `mimeType` 非空字符串、`size` 为非负安全整数、`width` /
|
|
1082
|
+
* `height` 为正安全整数、`previewUrl` 非空字符串,且 `file` 是通过
|
|
1083
|
+
* {@link isMiniProgramFileDescriptor} 的 direct file ref(`ref.kind === 'file'` 且带非空 `handleId`),
|
|
1084
|
+
* `mode` 必须固定为 `'read'`。图片分支只允许公共 key;视频分支额外要求非负安全整数的 `durationMs`,
|
|
1085
|
+
* 并拒绝图片携带该字段。
|
|
1086
|
+
*
|
|
1087
|
+
* `size` 单位为字节,`width` / `height` 是考虑方向后的显示像素尺寸,`durationMs` 单位为毫秒。
|
|
1088
|
+
* 该 guard 只校验结构与数值范围,不证明元数据与 `file` 实际内容一致、`previewUrl` 属于当前会话、
|
|
1089
|
+
* `file` 句柄由当前 Runtime 签发或仍在有效期内,也不检查 `media` 权限与 Host 能力。
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```ts
|
|
1093
|
+
* import { isMiniProgramMediaPickItem } from '@heybox/hb-sdk/protocol';
|
|
1094
|
+
*
|
|
1095
|
+
* const video = {
|
|
1096
|
+
* type: 'video',
|
|
1097
|
+
* mimeType: 'video/mp4',
|
|
1098
|
+
* size: 5_242_880,
|
|
1099
|
+
* width: 1280,
|
|
1100
|
+
* height: 720,
|
|
1101
|
+
* durationMs: 12_000,
|
|
1102
|
+
* previewUrl: 'hb-media-preview://session/resource_2',
|
|
1103
|
+
* file: { kind: 'file', name: 'clip.mp4', mode: 'read', ref: { kind: 'file', handleId: 'media_handle_2' } },
|
|
1104
|
+
* };
|
|
1105
|
+
*
|
|
1106
|
+
* isMiniProgramMediaPickItem(video); // true
|
|
1107
|
+
* isMiniProgramMediaPickItem({ ...video, type: 'image' }); // false:图片不允许 durationMs
|
|
1108
|
+
* ```
|
|
1109
|
+
*
|
|
1110
|
+
* @see [MediaPickItem](/reference/symbols/protocol/types/MediaPickItem) 判别联合定义。
|
|
1111
|
+
* @see [isMiniProgramFileDescriptor](/reference/symbols/protocol/functions/isMiniProgramFileDescriptor) 嵌套文件句柄校验。
|
|
1112
|
+
* @since 0.9.3
|
|
1113
|
+
*/
|
|
1114
|
+
function isMiniProgramMediaPickItem(value) {
|
|
1115
|
+
if (!isRecord$3(value) || (value.type !== 'image' && value.type !== 'video'))
|
|
1116
|
+
return false;
|
|
1117
|
+
const isVideo = value.type === 'video';
|
|
1118
|
+
if (!hasOnlyKeys(value, isVideo ? [...MEDIA_PICK_ITEM_KEYS, 'durationMs'] : MEDIA_PICK_ITEM_KEYS))
|
|
1119
|
+
return false;
|
|
1120
|
+
if (!isNonEmptyString$1(value.mimeType) ||
|
|
1121
|
+
!isNonNegativeSafeInteger(value.size) ||
|
|
1122
|
+
!isPositiveSafeInteger$1(value.width) ||
|
|
1123
|
+
!isPositiveSafeInteger$1(value.height) ||
|
|
1124
|
+
!isNonEmptyString$1(value.previewUrl) ||
|
|
1125
|
+
!isDirectFileDescriptor(value.file)) {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
return isVideo ? isNonNegativeSafeInteger(value.durationMs) : true;
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* 判断未知值是否为整批 `media.pick` 结果。
|
|
1132
|
+
*
|
|
1133
|
+
* @param value - 来自 Host response、bridge result 或其他不可信边界的候选结果。
|
|
1134
|
+
* @returns 值为 1–20 项且每项都通过 {@link isMiniProgramMediaPickItem} 的稠密数组时返回 `true`,
|
|
1135
|
+
* 并将 TypeScript 类型收窄为 {@link MediaPickResult};否则返回 `false`。
|
|
1136
|
+
*
|
|
1137
|
+
* @remarks
|
|
1138
|
+
* 成功结果必须是非空数组:用户取消或任一项准备失败时走整批错误,不得返回空数组或部分结果。
|
|
1139
|
+
* 本 guard 只校验全局上限 20,不校验调用方本次请求的 `maxCount`、相机必须恰好 1 项、项之间是否
|
|
1140
|
+
* 重复或顺序,也不确认结果来自当前 request 或会话仍然有效。这些约束由 Runtime 的状态机、可信手势、
|
|
1141
|
+
* 权限与句柄注册表继续执行。
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* import { isMiniProgramMediaPickResult } from '@heybox/hb-sdk/protocol';
|
|
1146
|
+
*
|
|
1147
|
+
* isMiniProgramMediaPickResult([]); // false:取消不是空数组成功
|
|
1148
|
+
* isMiniProgramMediaPickResult([imageItem]); // true
|
|
1149
|
+
* ```
|
|
1150
|
+
*
|
|
1151
|
+
* @see [MediaPickResult](/reference/symbols/protocol/types/MediaPickResult) wire 返回类型。
|
|
1152
|
+
* @see [isMiniProgramMediaPickItem](/reference/symbols/protocol/functions/isMiniProgramMediaPickItem) 单项结构与数值校验。
|
|
1153
|
+
* @since 0.9.3
|
|
1154
|
+
*/
|
|
1155
|
+
function isMiniProgramMediaPickResult(value) {
|
|
1156
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > MAX_MEDIA_PICK_COUNT)
|
|
1157
|
+
return false;
|
|
1158
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1159
|
+
if (!Object.prototype.hasOwnProperty.call(value, index) || !isMiniProgramMediaPickItem(value[index]))
|
|
1160
|
+
return false;
|
|
1161
|
+
}
|
|
1162
|
+
return true;
|
|
1163
|
+
}
|
|
1164
|
+
function isDirectFileDescriptor(value) {
|
|
1165
|
+
if (!isMiniProgramFileDescriptor(value))
|
|
1166
|
+
return false;
|
|
1167
|
+
// 媒体结果只允许只读 direct 句柄;derived ref、readwrite 与目录引用都不符合媒体契约。
|
|
1168
|
+
if (value.mode !== 'read')
|
|
1169
|
+
return false;
|
|
1170
|
+
return value.ref.kind === 'file' && 'handleId' in value.ref && isNonEmptyString$1(value.ref.handleId);
|
|
1171
|
+
}
|
|
1011
1172
|
/**
|
|
1012
1173
|
* 判断未知值是否为使用普通 `ArrayBuffer` 存储的 `Uint8Array` 字节视图。
|
|
1013
1174
|
*
|
|
@@ -1223,6 +1384,12 @@ function isFileMode(value) {
|
|
|
1223
1384
|
function isNonNegativeSafeInteger(value) {
|
|
1224
1385
|
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
|
|
1225
1386
|
}
|
|
1387
|
+
function isPositiveSafeInteger$1(value) {
|
|
1388
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
|
|
1389
|
+
}
|
|
1390
|
+
function isIntegerInRange(value, min, max) {
|
|
1391
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value >= min && value <= max;
|
|
1392
|
+
}
|
|
1226
1393
|
function isNonNegativeFiniteNumber(value) {
|
|
1227
1394
|
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
1228
1395
|
}
|
|
@@ -1244,6 +1411,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
|
1244
1411
|
'storage',
|
|
1245
1412
|
'cloud_storage',
|
|
1246
1413
|
'filesystem',
|
|
1414
|
+
'media',
|
|
1247
1415
|
'clipboard',
|
|
1248
1416
|
'leaderboard',
|
|
1249
1417
|
'network',
|
|
@@ -7271,6 +7439,7 @@ exports.FILE_REMOVE_METHOD = FILE_REMOVE_METHOD;
|
|
|
7271
7439
|
exports.FILE_STAT_METHOD = FILE_STAT_METHOD;
|
|
7272
7440
|
exports.FILE_WRITE_BYTES_METHOD = FILE_WRITE_BYTES_METHOD;
|
|
7273
7441
|
exports.FILE_WRITE_TEXT_METHOD = FILE_WRITE_TEXT_METHOD;
|
|
7442
|
+
exports.MEDIA_PICK_METHOD = MEDIA_PICK_METHOD;
|
|
7274
7443
|
exports.MINI_PROGRAM_BRIDGE_NONCE_PARAM = MINI_PROGRAM_BRIDGE_NONCE_PARAM;
|
|
7275
7444
|
exports.MINI_PROGRAM_MESSAGE_NAMESPACE = MINI_PROGRAM_MESSAGE_NAMESPACE;
|
|
7276
7445
|
exports.MINI_PROGRAM_MESSAGE_VERSION = MINI_PROGRAM_MESSAGE_VERSION;
|
|
@@ -7311,6 +7480,9 @@ exports.isMiniProgramFileDescriptor = isMiniProgramFileDescriptor;
|
|
|
7311
7480
|
exports.isMiniProgramFileRef = isMiniProgramFileRef;
|
|
7312
7481
|
exports.isMiniProgramFileStat = isMiniProgramFileStat;
|
|
7313
7482
|
exports.isMiniProgramFileSystemEntityDescriptor = isMiniProgramFileSystemEntityDescriptor;
|
|
7483
|
+
exports.isMiniProgramMediaPickItem = isMiniProgramMediaPickItem;
|
|
7484
|
+
exports.isMiniProgramMediaPickPayload = isMiniProgramMediaPickPayload;
|
|
7485
|
+
exports.isMiniProgramMediaPickResult = isMiniProgramMediaPickResult;
|
|
7314
7486
|
exports.isMiniProgramPathRootRef = isMiniProgramPathRootRef;
|
|
7315
7487
|
exports.isMiniProgramRelativePath = isMiniProgramRelativePath;
|
|
7316
7488
|
exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
|
package/dist/protocol.esm.js
CHANGED
|
@@ -61,6 +61,7 @@ const DIRECTORY_CREATE_METHOD = 'directory.create';
|
|
|
61
61
|
const DIRECTORY_REMOVE_METHOD = 'directory.remove';
|
|
62
62
|
const DIRECTORY_EXISTS_METHOD = 'directory.exists';
|
|
63
63
|
const DIRECTORY_LIST_METHOD = 'directory.list';
|
|
64
|
+
const MEDIA_PICK_METHOD = 'media.pick';
|
|
64
65
|
const UI_SHOW_TOAST_METHOD = 'ui.showToast';
|
|
65
66
|
const UI_SHOW_LOADING_METHOD = 'ui.showLoading';
|
|
66
67
|
const UI_HIDE_LOADING_METHOD = 'ui.hideLoading';
|
|
@@ -321,6 +322,13 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
321
322
|
requirement: { kind: 'all', permissions: ['filesystem'] },
|
|
322
323
|
risk: 'high',
|
|
323
324
|
},
|
|
325
|
+
{
|
|
326
|
+
method: MEDIA_PICK_METHOD,
|
|
327
|
+
module: 'media',
|
|
328
|
+
capability: MEDIA_PICK_METHOD,
|
|
329
|
+
requirement: { kind: 'all', permissions: ['media'] },
|
|
330
|
+
risk: 'high',
|
|
331
|
+
},
|
|
324
332
|
{ method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
325
333
|
{ method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
326
334
|
{ method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, requirement: { kind: 'none' }, risk: 'low' },
|
|
@@ -1006,6 +1014,159 @@ function isMiniProgramDirectoryDescriptor(value) {
|
|
|
1006
1014
|
function isMiniProgramFileSystemEntityDescriptor(value) {
|
|
1007
1015
|
return isMiniProgramFileDescriptor(value) || isMiniProgramDirectoryDescriptor(value);
|
|
1008
1016
|
}
|
|
1017
|
+
/** `media.pick` 结果数组允许的最大项数,与协议 `maxCount` 上限一致。 */
|
|
1018
|
+
const MAX_MEDIA_PICK_COUNT = 20;
|
|
1019
|
+
/** `media.pick` 单项结果的公共 canonical key 集合。 */
|
|
1020
|
+
const MEDIA_PICK_ITEM_KEYS = ['type', 'mimeType', 'size', 'width', 'height', 'previewUrl', 'file'];
|
|
1021
|
+
/**
|
|
1022
|
+
* 判断未知值是否具有 `media.pick` payload 的最低 wire 结构。
|
|
1023
|
+
*
|
|
1024
|
+
* @param value - 来自 App-facing 参数、bridge request 或其他不可信边界的候选 payload。`undefined`
|
|
1025
|
+
* 表示调用方省略整个 payload,会通过本 guard 并使用全部缺省值。
|
|
1026
|
+
* @returns 值满足 {@link MediaPickPayload} 的枚举、取值范围和键集合约束时返回 `true`,并将
|
|
1027
|
+
* TypeScript 类型收窄为 payload 类型;否则返回 `false`。
|
|
1028
|
+
*
|
|
1029
|
+
* @remarks
|
|
1030
|
+
* 对通常的对象字面量,仅允许 `source`、`mediaType`、`maxCount` 三个 canonical key:
|
|
1031
|
+
*
|
|
1032
|
+
* - `source` 可省略或为 `album` / `camera`;`mediaType` 可省略或为 `image` / `video` / `all`。
|
|
1033
|
+
* - `maxCount` 可省略,或为 1–20 的安全整数。`0`、负数、小数、`NaN`、`Infinity`、unsafe integer、
|
|
1034
|
+
* bigint 和数字字符串都会被拒绝。
|
|
1035
|
+
* - `source === 'camera'` 且提供 `maxCount` 时,只接受 `1`;大于 1 的值在此处即可拒绝,
|
|
1036
|
+
* Runtime 不应静默收窄。
|
|
1037
|
+
*
|
|
1038
|
+
* 该 guard 只建立结构类型收窄,不应用缺省值、不证明 `media` 权限已声明或启用、不检查可信用户手势、
|
|
1039
|
+
* 不确认 Host 支持 `media.pick`,也不保证系统选择器一定交付 `maxCount` 项。`all` 仅表示图片与视频,
|
|
1040
|
+
* 不包含音频或任意文件。
|
|
1041
|
+
*
|
|
1042
|
+
* @example
|
|
1043
|
+
* ```ts
|
|
1044
|
+
* import { isMiniProgramMediaPickPayload } from '@heybox/hb-sdk/protocol';
|
|
1045
|
+
*
|
|
1046
|
+
* isMiniProgramMediaPickPayload(undefined); // true:使用全部缺省值
|
|
1047
|
+
* isMiniProgramMediaPickPayload({ source: 'album', maxCount: 20 }); // true
|
|
1048
|
+
* isMiniProgramMediaPickPayload({ source: 'camera', maxCount: 2 }); // false:相机只能单选
|
|
1049
|
+
* ```
|
|
1050
|
+
*
|
|
1051
|
+
* @see [MediaPickPayload](/reference/symbols/protocol/interfaces/MediaPickPayload) wire 字段定义。
|
|
1052
|
+
* @since 0.9.3
|
|
1053
|
+
*/
|
|
1054
|
+
function isMiniProgramMediaPickPayload(value) {
|
|
1055
|
+
if (value === undefined)
|
|
1056
|
+
return true;
|
|
1057
|
+
if (!isRecord$3(value) || !hasOnlyKeys(value, ['source', 'mediaType', 'maxCount']))
|
|
1058
|
+
return false;
|
|
1059
|
+
if (value.source !== undefined && value.source !== 'album' && value.source !== 'camera')
|
|
1060
|
+
return false;
|
|
1061
|
+
if (value.mediaType !== undefined && value.mediaType !== 'image' && value.mediaType !== 'video' && value.mediaType !== 'all')
|
|
1062
|
+
return false;
|
|
1063
|
+
if (value.maxCount !== undefined) {
|
|
1064
|
+
if (!isIntegerInRange(value.maxCount, 1, MAX_MEDIA_PICK_COUNT))
|
|
1065
|
+
return false;
|
|
1066
|
+
if (value.source === 'camera' && value.maxCount !== 1)
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
return true;
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* 判断未知值是否为单个 `media.pick` 媒体项。
|
|
1073
|
+
*
|
|
1074
|
+
* @param value - 来自 Host response、bridge result 或其他不可信边界的候选媒体项。
|
|
1075
|
+
* @returns 字段组合满足 {@link MediaPickItem} 判别联合的最低结构时返回 `true`,并将 TypeScript 类型
|
|
1076
|
+
* 收窄为图片或视频项;否则返回 `false`。
|
|
1077
|
+
*
|
|
1078
|
+
* @remarks
|
|
1079
|
+
* 以 `type` 为判别字段,两个分支都要求 `mimeType` 非空字符串、`size` 为非负安全整数、`width` /
|
|
1080
|
+
* `height` 为正安全整数、`previewUrl` 非空字符串,且 `file` 是通过
|
|
1081
|
+
* {@link isMiniProgramFileDescriptor} 的 direct file ref(`ref.kind === 'file'` 且带非空 `handleId`),
|
|
1082
|
+
* `mode` 必须固定为 `'read'`。图片分支只允许公共 key;视频分支额外要求非负安全整数的 `durationMs`,
|
|
1083
|
+
* 并拒绝图片携带该字段。
|
|
1084
|
+
*
|
|
1085
|
+
* `size` 单位为字节,`width` / `height` 是考虑方向后的显示像素尺寸,`durationMs` 单位为毫秒。
|
|
1086
|
+
* 该 guard 只校验结构与数值范围,不证明元数据与 `file` 实际内容一致、`previewUrl` 属于当前会话、
|
|
1087
|
+
* `file` 句柄由当前 Runtime 签发或仍在有效期内,也不检查 `media` 权限与 Host 能力。
|
|
1088
|
+
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* ```ts
|
|
1091
|
+
* import { isMiniProgramMediaPickItem } from '@heybox/hb-sdk/protocol';
|
|
1092
|
+
*
|
|
1093
|
+
* const video = {
|
|
1094
|
+
* type: 'video',
|
|
1095
|
+
* mimeType: 'video/mp4',
|
|
1096
|
+
* size: 5_242_880,
|
|
1097
|
+
* width: 1280,
|
|
1098
|
+
* height: 720,
|
|
1099
|
+
* durationMs: 12_000,
|
|
1100
|
+
* previewUrl: 'hb-media-preview://session/resource_2',
|
|
1101
|
+
* file: { kind: 'file', name: 'clip.mp4', mode: 'read', ref: { kind: 'file', handleId: 'media_handle_2' } },
|
|
1102
|
+
* };
|
|
1103
|
+
*
|
|
1104
|
+
* isMiniProgramMediaPickItem(video); // true
|
|
1105
|
+
* isMiniProgramMediaPickItem({ ...video, type: 'image' }); // false:图片不允许 durationMs
|
|
1106
|
+
* ```
|
|
1107
|
+
*
|
|
1108
|
+
* @see [MediaPickItem](/reference/symbols/protocol/types/MediaPickItem) 判别联合定义。
|
|
1109
|
+
* @see [isMiniProgramFileDescriptor](/reference/symbols/protocol/functions/isMiniProgramFileDescriptor) 嵌套文件句柄校验。
|
|
1110
|
+
* @since 0.9.3
|
|
1111
|
+
*/
|
|
1112
|
+
function isMiniProgramMediaPickItem(value) {
|
|
1113
|
+
if (!isRecord$3(value) || (value.type !== 'image' && value.type !== 'video'))
|
|
1114
|
+
return false;
|
|
1115
|
+
const isVideo = value.type === 'video';
|
|
1116
|
+
if (!hasOnlyKeys(value, isVideo ? [...MEDIA_PICK_ITEM_KEYS, 'durationMs'] : MEDIA_PICK_ITEM_KEYS))
|
|
1117
|
+
return false;
|
|
1118
|
+
if (!isNonEmptyString$1(value.mimeType) ||
|
|
1119
|
+
!isNonNegativeSafeInteger(value.size) ||
|
|
1120
|
+
!isPositiveSafeInteger$1(value.width) ||
|
|
1121
|
+
!isPositiveSafeInteger$1(value.height) ||
|
|
1122
|
+
!isNonEmptyString$1(value.previewUrl) ||
|
|
1123
|
+
!isDirectFileDescriptor(value.file)) {
|
|
1124
|
+
return false;
|
|
1125
|
+
}
|
|
1126
|
+
return isVideo ? isNonNegativeSafeInteger(value.durationMs) : true;
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* 判断未知值是否为整批 `media.pick` 结果。
|
|
1130
|
+
*
|
|
1131
|
+
* @param value - 来自 Host response、bridge result 或其他不可信边界的候选结果。
|
|
1132
|
+
* @returns 值为 1–20 项且每项都通过 {@link isMiniProgramMediaPickItem} 的稠密数组时返回 `true`,
|
|
1133
|
+
* 并将 TypeScript 类型收窄为 {@link MediaPickResult};否则返回 `false`。
|
|
1134
|
+
*
|
|
1135
|
+
* @remarks
|
|
1136
|
+
* 成功结果必须是非空数组:用户取消或任一项准备失败时走整批错误,不得返回空数组或部分结果。
|
|
1137
|
+
* 本 guard 只校验全局上限 20,不校验调用方本次请求的 `maxCount`、相机必须恰好 1 项、项之间是否
|
|
1138
|
+
* 重复或顺序,也不确认结果来自当前 request 或会话仍然有效。这些约束由 Runtime 的状态机、可信手势、
|
|
1139
|
+
* 权限与句柄注册表继续执行。
|
|
1140
|
+
*
|
|
1141
|
+
* @example
|
|
1142
|
+
* ```ts
|
|
1143
|
+
* import { isMiniProgramMediaPickResult } from '@heybox/hb-sdk/protocol';
|
|
1144
|
+
*
|
|
1145
|
+
* isMiniProgramMediaPickResult([]); // false:取消不是空数组成功
|
|
1146
|
+
* isMiniProgramMediaPickResult([imageItem]); // true
|
|
1147
|
+
* ```
|
|
1148
|
+
*
|
|
1149
|
+
* @see [MediaPickResult](/reference/symbols/protocol/types/MediaPickResult) wire 返回类型。
|
|
1150
|
+
* @see [isMiniProgramMediaPickItem](/reference/symbols/protocol/functions/isMiniProgramMediaPickItem) 单项结构与数值校验。
|
|
1151
|
+
* @since 0.9.3
|
|
1152
|
+
*/
|
|
1153
|
+
function isMiniProgramMediaPickResult(value) {
|
|
1154
|
+
if (!Array.isArray(value) || value.length < 1 || value.length > MAX_MEDIA_PICK_COUNT)
|
|
1155
|
+
return false;
|
|
1156
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1157
|
+
if (!Object.prototype.hasOwnProperty.call(value, index) || !isMiniProgramMediaPickItem(value[index]))
|
|
1158
|
+
return false;
|
|
1159
|
+
}
|
|
1160
|
+
return true;
|
|
1161
|
+
}
|
|
1162
|
+
function isDirectFileDescriptor(value) {
|
|
1163
|
+
if (!isMiniProgramFileDescriptor(value))
|
|
1164
|
+
return false;
|
|
1165
|
+
// 媒体结果只允许只读 direct 句柄;derived ref、readwrite 与目录引用都不符合媒体契约。
|
|
1166
|
+
if (value.mode !== 'read')
|
|
1167
|
+
return false;
|
|
1168
|
+
return value.ref.kind === 'file' && 'handleId' in value.ref && isNonEmptyString$1(value.ref.handleId);
|
|
1169
|
+
}
|
|
1009
1170
|
/**
|
|
1010
1171
|
* 判断未知值是否为使用普通 `ArrayBuffer` 存储的 `Uint8Array` 字节视图。
|
|
1011
1172
|
*
|
|
@@ -1221,6 +1382,12 @@ function isFileMode(value) {
|
|
|
1221
1382
|
function isNonNegativeSafeInteger(value) {
|
|
1222
1383
|
return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
|
|
1223
1384
|
}
|
|
1385
|
+
function isPositiveSafeInteger$1(value) {
|
|
1386
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0;
|
|
1387
|
+
}
|
|
1388
|
+
function isIntegerInRange(value, min, max) {
|
|
1389
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value >= min && value <= max;
|
|
1390
|
+
}
|
|
1224
1391
|
function isNonNegativeFiniteNumber(value) {
|
|
1225
1392
|
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
1226
1393
|
}
|
|
@@ -1242,6 +1409,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
|
1242
1409
|
'storage',
|
|
1243
1410
|
'cloud_storage',
|
|
1244
1411
|
'filesystem',
|
|
1412
|
+
'media',
|
|
1245
1413
|
'clipboard',
|
|
1246
1414
|
'leaderboard',
|
|
1247
1415
|
'network',
|
|
@@ -7240,4 +7408,4 @@ object({
|
|
|
7240
7408
|
regions: array(viewRegionSchema).max(VIEW_BUDGET.maxRegions)
|
|
7241
7409
|
});
|
|
7242
7410
|
|
|
7243
|
-
export { AUTH_GET_ACCOUNT_STATE_METHOD, 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, CLOUD_STORAGE_GET_KEYS_METHOD, CLOUD_STORAGE_GET_STORAGE_METHOD, CLOUD_STORAGE_REMOVE_ITEM_METHOD, CLOUD_STORAGE_SET_STORAGE_METHOD, DEVICE_EXECUTE_PROTOCOL_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, NETWORK_UPLOAD_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_DISPLAY_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramPathRootRef, isMiniProgramRelativePath, parseMiniProgramRuntimePermissions };
|
|
7411
|
+
export { AUTH_GET_ACCOUNT_STATE_METHOD, 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, CLOUD_STORAGE_GET_KEYS_METHOD, CLOUD_STORAGE_GET_STORAGE_METHOD, CLOUD_STORAGE_REMOVE_ITEM_METHOD, CLOUD_STORAGE_SET_STORAGE_METHOD, DEVICE_EXECUTE_PROTOCOL_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, MEDIA_PICK_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, NETWORK_UPLOAD_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_DISPLAY_METHOD, VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD, isManagedMiniProgramRuntimePermissionKey, isMiniProgramBridgeMessage, isMiniProgramByteArray, isMiniProgramDirectoryDescriptor, isMiniProgramDirectoryRef, isMiniProgramDownloadProgressPayload, isMiniProgramFileDescriptor, isMiniProgramFileRef, isMiniProgramFileStat, isMiniProgramFileSystemEntityDescriptor, isMiniProgramMediaPickItem, isMiniProgramMediaPickPayload, isMiniProgramMediaPickResult, isMiniProgramPathRootRef, isMiniProgramRelativePath, parseMiniProgramRuntimePermissions };
|
package/dist/vite.cjs.js
CHANGED
|
@@ -64,6 +64,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
|
64
64
|
'storage',
|
|
65
65
|
'cloud_storage',
|
|
66
66
|
'filesystem',
|
|
67
|
+
'media',
|
|
67
68
|
'clipboard',
|
|
68
69
|
'leaderboard',
|
|
69
70
|
'network',
|
|
@@ -150,6 +151,16 @@ const MINI_PROGRAM_PERMISSION_CATALOG = [
|
|
|
150
151
|
],
|
|
151
152
|
conditions: ['外部文件继续要求有效的用户选择、会话句柄和匹配的读写模式。'],
|
|
152
153
|
},
|
|
154
|
+
{
|
|
155
|
+
key: 'media',
|
|
156
|
+
name: '媒体',
|
|
157
|
+
description: '通过系统图库或相机选择图片、视频。',
|
|
158
|
+
access: 'declaration',
|
|
159
|
+
risk: 'high',
|
|
160
|
+
config: {},
|
|
161
|
+
methods: ['media.pick'],
|
|
162
|
+
conditions: ['图库授权范围仅限本次用户选择的媒体,不包含任意文件或沙盒访问权;继续执行可信手势、Host 能力与会话资源规则。'],
|
|
163
|
+
},
|
|
153
164
|
{
|
|
154
165
|
key: 'clipboard',
|
|
155
166
|
name: '剪贴板',
|
|
@@ -10304,7 +10315,7 @@ async function ensureBasicInfoDirectory(rootPath, relative) {
|
|
|
10304
10315
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
10305
10316
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
10306
10317
|
? undefined
|
|
10307
|
-
: '0.9.3
|
|
10318
|
+
: '0.9.3';
|
|
10308
10319
|
|
|
10309
10320
|
/**
|
|
10310
10321
|
* iframe 与调试台页面的开发期 console 捕获转发。
|
|
@@ -20289,6 +20300,9 @@ const FORBIDDEN_RESOURCE_HINTS = new Set(['dns-prefetch', 'preconnect', 'prerend
|
|
|
20289
20300
|
const RELATIVE_URL_BASE = new URL('https://heybox-relative.invalid/');
|
|
20290
20301
|
const OFFICIAL_RESOURCE_ROOT_DOMAINS = ['xiaoheihe.cn', 'max-c.com', 'debugmode.cn', 'maxjia.com'];
|
|
20291
20302
|
const OFFICIAL_RESOURCE_SOURCES = OFFICIAL_RESOURCE_ROOT_DOMAINS.flatMap((rootDomain) => [`https://${rootDomain}`, `https://*.${rootDomain}`]);
|
|
20303
|
+
// 受控媒体预览通道:iOS `hbmini-media://preview/...`、鸿蒙 OHOS `hbmedia://<sessionId>/<previewId>`。
|
|
20304
|
+
// 两者是宿主注册的自定义 scheme,只允许出现在图片/媒体资源加载指令中,不放宽其它指令。
|
|
20305
|
+
const MEDIA_PREVIEW_SCHEME_SOURCES = ['hbmini-media:', 'hbmedia:'];
|
|
20292
20306
|
const URL_ATTRIBUTES = {
|
|
20293
20307
|
audio: ['src'],
|
|
20294
20308
|
embed: ['src'],
|
|
@@ -20306,9 +20320,9 @@ const PRODUCTION_CSP = [
|
|
|
20306
20320
|
"connect-src 'none'",
|
|
20307
20321
|
`script-src 'self' 'unsafe-inline' ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20308
20322
|
`style-src 'self' 'unsafe-inline' ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20309
|
-
`img-src 'self' data: blob: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20323
|
+
`img-src 'self' data: blob: ${MEDIA_PREVIEW_SCHEME_SOURCES.join(' ')} ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20310
20324
|
`font-src 'self' data: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20311
|
-
`media-src 'self' blob: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20325
|
+
`media-src 'self' blob: ${MEDIA_PREVIEW_SCHEME_SOURCES.join(' ')} ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20312
20326
|
"manifest-src 'self'",
|
|
20313
20327
|
"frame-src 'none'",
|
|
20314
20328
|
"child-src 'none'",
|
package/dist/vite.esm.js
CHANGED
|
@@ -61,6 +61,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
|
61
61
|
'storage',
|
|
62
62
|
'cloud_storage',
|
|
63
63
|
'filesystem',
|
|
64
|
+
'media',
|
|
64
65
|
'clipboard',
|
|
65
66
|
'leaderboard',
|
|
66
67
|
'network',
|
|
@@ -147,6 +148,16 @@ const MINI_PROGRAM_PERMISSION_CATALOG = [
|
|
|
147
148
|
],
|
|
148
149
|
conditions: ['外部文件继续要求有效的用户选择、会话句柄和匹配的读写模式。'],
|
|
149
150
|
},
|
|
151
|
+
{
|
|
152
|
+
key: 'media',
|
|
153
|
+
name: '媒体',
|
|
154
|
+
description: '通过系统图库或相机选择图片、视频。',
|
|
155
|
+
access: 'declaration',
|
|
156
|
+
risk: 'high',
|
|
157
|
+
config: {},
|
|
158
|
+
methods: ['media.pick'],
|
|
159
|
+
conditions: ['图库授权范围仅限本次用户选择的媒体,不包含任意文件或沙盒访问权;继续执行可信手势、Host 能力与会话资源规则。'],
|
|
160
|
+
},
|
|
150
161
|
{
|
|
151
162
|
key: 'clipboard',
|
|
152
163
|
name: '剪贴板',
|
|
@@ -10301,7 +10312,7 @@ async function ensureBasicInfoDirectory(rootPath, relative) {
|
|
|
10301
10312
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
10302
10313
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
10303
10314
|
? undefined
|
|
10304
|
-
: '0.9.3
|
|
10315
|
+
: '0.9.3';
|
|
10305
10316
|
|
|
10306
10317
|
/**
|
|
10307
10318
|
* iframe 与调试台页面的开发期 console 捕获转发。
|
|
@@ -20286,6 +20297,9 @@ const FORBIDDEN_RESOURCE_HINTS = new Set(['dns-prefetch', 'preconnect', 'prerend
|
|
|
20286
20297
|
const RELATIVE_URL_BASE = new URL('https://heybox-relative.invalid/');
|
|
20287
20298
|
const OFFICIAL_RESOURCE_ROOT_DOMAINS = ['xiaoheihe.cn', 'max-c.com', 'debugmode.cn', 'maxjia.com'];
|
|
20288
20299
|
const OFFICIAL_RESOURCE_SOURCES = OFFICIAL_RESOURCE_ROOT_DOMAINS.flatMap((rootDomain) => [`https://${rootDomain}`, `https://*.${rootDomain}`]);
|
|
20300
|
+
// 受控媒体预览通道:iOS `hbmini-media://preview/...`、鸿蒙 OHOS `hbmedia://<sessionId>/<previewId>`。
|
|
20301
|
+
// 两者是宿主注册的自定义 scheme,只允许出现在图片/媒体资源加载指令中,不放宽其它指令。
|
|
20302
|
+
const MEDIA_PREVIEW_SCHEME_SOURCES = ['hbmini-media:', 'hbmedia:'];
|
|
20289
20303
|
const URL_ATTRIBUTES = {
|
|
20290
20304
|
audio: ['src'],
|
|
20291
20305
|
embed: ['src'],
|
|
@@ -20303,9 +20317,9 @@ const PRODUCTION_CSP = [
|
|
|
20303
20317
|
"connect-src 'none'",
|
|
20304
20318
|
`script-src 'self' 'unsafe-inline' ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20305
20319
|
`style-src 'self' 'unsafe-inline' ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20306
|
-
`img-src 'self' data: blob: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20320
|
+
`img-src 'self' data: blob: ${MEDIA_PREVIEW_SCHEME_SOURCES.join(' ')} ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20307
20321
|
`font-src 'self' data: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20308
|
-
`media-src 'self' blob: ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20322
|
+
`media-src 'self' blob: ${MEDIA_PREVIEW_SCHEME_SOURCES.join(' ')} ${OFFICIAL_RESOURCE_SOURCES.join(' ')}`,
|
|
20309
20323
|
"manifest-src 'self'",
|
|
20310
20324
|
"frame-src 'none'",
|
|
20311
20325
|
"child-src 'none'",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heybox/hb-sdk",
|
|
3
|
-
"version": "0.9.3
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"./src/index.ts",
|
|
6
6
|
"./src/core/singleton.ts",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"undici": "^7.28.0",
|
|
77
77
|
"ws": "^8.18.0",
|
|
78
78
|
"sharp": "^0.34.5",
|
|
79
|
-
"@heybox/hb-sdk-protocol": "0.9.3
|
|
79
|
+
"@heybox/hb-sdk-protocol": "0.9.3"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
82
|
"vite": ">=5"
|
|
@@ -128,13 +128,13 @@
|
|
|
128
128
|
"vitest": "^3.2.4",
|
|
129
129
|
"@ai-desktop/view-contract": "file:../hb-sdk-protocol/vendor/view-contract-2.2.2-6ac49bbf6410.tgz",
|
|
130
130
|
"rollup-plugin-dts": "6.4.0",
|
|
131
|
-
"@heybox/hb-sdk-runtime": "~0.9.3-alpha.6",
|
|
132
|
-
"@heybox-domain/heybox-vue3-ui": "~0.1.0",
|
|
133
131
|
"@heybox-domain/heybox-theme": "~0.1.0",
|
|
134
|
-
"@heybox/
|
|
135
|
-
"@heybox/runtime
|
|
132
|
+
"@heybox-domain/heybox-vue3-ui": "~0.1.0",
|
|
133
|
+
"@heybox/hb-sdk-runtime": "~0.9.3",
|
|
136
134
|
"@heybox/hb-api": "~1.28.17",
|
|
137
|
-
"@heybox/runtime
|
|
135
|
+
"@heybox/runtime": "~0.2.1",
|
|
136
|
+
"@heybox/runtime-transport-fetch": "~0.2.1",
|
|
137
|
+
"@heybox/runtime-policy": "~0.2.1"
|
|
138
138
|
},
|
|
139
139
|
"publishConfig": {
|
|
140
140
|
"registry": "https://registry.npmjs.org/",
|
package/skill/skill.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hb-sdk",
|
|
3
|
-
"skillVersion": "0.9.3
|
|
3
|
+
"skillVersion": "0.9.3+skill.d0d502673711",
|
|
4
4
|
"sdk": {
|
|
5
5
|
"package": "@heybox/hb-sdk",
|
|
6
|
-
"version": "0.9.3
|
|
7
|
-
"compatibility": "0.9.3
|
|
6
|
+
"version": "0.9.3",
|
|
7
|
+
"compatibility": "0.9.3"
|
|
8
8
|
},
|
|
9
9
|
"distribution": {
|
|
10
10
|
"type": "npm",
|
|
11
11
|
"package": "@heybox/hb-sdk",
|
|
12
|
-
"version": "0.9.3
|
|
12
|
+
"version": "0.9.3",
|
|
13
13
|
"path": "skill"
|
|
14
14
|
},
|
|
15
15
|
"integrity": "sha256-d0d502673711f5d077ee62e657749125788e396d5203894b7077dfe866fd2990"
|