@heybox/hb-sdk-protocol 0.8.3-alpha.2 → 0.8.3-alpha.4
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/README.md +20 -0
- package/dist/index.cjs.js +287 -163
- package/dist/index.esm.js +283 -164
- package/generated/permission-catalog.json +2 -1
- package/package.json +1 -1
- package/src/bridge.ts +8 -0
- package/src/capabilities.ts +13 -0
- package/src/index.ts +1 -0
- package/src/local-dev-grant.ts +141 -0
- package/src/payloads.ts +21 -0
- package/src/permission-catalog.ts +1 -0
- package/types/bridge.d.ts +7 -1
- package/types/capabilities.d.ts +13 -2
- package/types/index.d.ts +1 -0
- package/types/local-dev-grant.d.ts +63 -0
- package/types/payloads.d.ts +20 -0
- package/types/permission-catalog.d.ts +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
- method payload/result 与错误的 wire 类型;
|
|
14
14
|
- Mobile Mini-program Native Host 的无版本 envelope、operation vocabulary 与跨语言 fixture;
|
|
15
15
|
- `runtime_permissions` schema 解析器和相关类型。
|
|
16
|
+
- CLI / Host 专用的 `local_dev_grant` 严格合同与纯数据合成,不向小程序业务 API 暴露权限来源。
|
|
16
17
|
|
|
17
18
|
它不拥有:
|
|
18
19
|
|
|
@@ -50,12 +51,25 @@ import { MINI_PROGRAM_PROTOCOL_CAPABILITIES, type MiniProgramBridgeMessage } fro
|
|
|
50
51
|
|
|
51
52
|
协议包不决定业务授权。`auth.login()` 的 UI、账号会话、授权码签发和 OpenAPI 都由 Host/服务端负责;协议层只传递经过约束的 request/response 数据。
|
|
52
53
|
|
|
54
|
+
## 本地调试临时权限
|
|
55
|
+
|
|
56
|
+
`parseMiniProgramLocalDevGrant()` 严格接受 schema 1、非负安全整数 revision,以及 `network` / `companion` 清单;未知字段、未知权限、重复项、非 enabled 状态或非法配置都会拒绝整份 grant。网络配置必须是 `useOfficialDomain: false`。解析成功只表示数据合法,Host 仍须验证现有启动票、canonical identity、摘要、期限、CLI lease 并取得每次启动确认。
|
|
57
|
+
|
|
58
|
+
`createMiniProgramLocalDevGrant()` 仅生成已声明而线上未批准的缺口;Companion 由 CLI 完成本地产物检查后显式列入 eligible keys。`composeLocalDevRuntimePermissions()` 将线上基线与本地声明求交后补齐合法 grant,保留已批准配置的声明子集,输出独立的普通 Runtime 快照和 Host 专用提示清单。生产路径不得调用此合成函数,grant 也不得进入 Manifest、发布资料或 iframe 握手。
|
|
59
|
+
|
|
53
60
|
## 握手环境快照
|
|
54
61
|
|
|
55
62
|
Runtime 可以在握手 response 中附带 `MiniProgramRuntimeEnvironmentInfo`。该快照只包含运行模式、Host App 版本、canonical 小程序 ID/版本和标准化操作系统信息,不包含账号、设备唯一标识、UA 或凭据。字段缺失和旧 Host 通过固定的 `null` / `'unknown'` 语义兼容;客户端 SDK 会在对外派发 `ready` 事件前缓存快照,业务代码通过根包的 `environment` 模块读取。
|
|
56
63
|
|
|
57
64
|
该 response 是 v2 envelope 上的向后兼容扩展,不新增 capability method 或权限,也不提升 `MINI_PROGRAM_MESSAGE_VERSION`。旧 SDK 没有对应 pending request,会忽略该 response;新 SDK 遇到旧 Host 时生成未知值快照。
|
|
58
65
|
|
|
66
|
+
## 窗口协议
|
|
67
|
+
|
|
68
|
+
`viewport.setDisplay` 接受 `{ orientation?: 'portrait' | 'landscape', fullscreen?: boolean }`,返回 `{ supported: boolean }`。`true` 表示原生方向与胶囊设置已完成;`false` 表示原生能力不可用,保留原生状态,宿主仍可尽力处理 H5 顶部栏。能力缺失的兼容错误由 SDK 统一转换为 `false`,其它执行错误继续保留。
|
|
69
|
+
至少传一个字段,省略字段保持当前目标值;初始为竖屏、非全屏。全屏同时收起胶囊和宿主额外顶部栏。SDK 复用 request-scoped cancel 协议;
|
|
70
|
+
Runtime 持有截止时间与意图替换语义,Host 负责原子应用与终止恢复。
|
|
71
|
+
`viewport_change` 事件载荷复用 `MiniProgramWindowInfoResult`,描述当前窗口与四边安全区。
|
|
72
|
+
|
|
59
73
|
## 公开入口
|
|
60
74
|
|
|
61
75
|
- `@heybox/hb-sdk-protocol`:本包唯一入口,适合 Host、Runtime 和协议维护代码。
|
|
@@ -85,3 +99,9 @@ pnpm --filter @heybox/hb-sdk-protocol run check:boundary
|
|
|
85
99
|
pnpm --filter @heybox/hb-sdk-protocol run test:unit
|
|
86
100
|
pnpm --filter @heybox/hb-sdk-protocol run build:package
|
|
87
101
|
```
|
|
102
|
+
|
|
103
|
+
### 展示状态事件
|
|
104
|
+
|
|
105
|
+
`display_change` 在宿主确认方向或全屏状态发生变化后发送 `{ orientation, fullscreen, source }`,包括开发者调用 `setDisplay()` 和用户点击宿主退出全屏按钮。两个字段独立;退出全屏不改变方向。重复状态、不支持(`supported: false`)、失败、超时、取消及被后续请求替换的设置不发送事件。事件不回放初始状态,新容器默认竖屏、非全屏;它不监听手机旋转传感器,窗口尺寸与安全区仍通过 `viewport_change` 获取。请在调用设置前注册监听,并在页面销毁时取消。
|
|
106
|
+
|
|
107
|
+
`display_change.source` 区分变化来源:`api` 为开发者调用,`user` 为用户点击宿主退出全屏按钮。同目标并发合并时保留首次发起操作的来源;重复状态不额外发事件。旧宿主可能不含 source,不能将缺失来源推断为用户操作。仅用户退出时跳页,应判断 `source === 'user' && !fullscreen`,再按业务需要调用竖屏设置并跳转。
|
package/dist/index.cjs.js
CHANGED
|
@@ -41,6 +41,7 @@ const USER_GET_STEAM_GAME_LIST_METHOD = 'user.getSteamGameList';
|
|
|
41
41
|
const SHARE_COPY_LINK_METHOD = 'share.copyLink';
|
|
42
42
|
const SHARE_SHOW_SHARE_MENU_METHOD = 'share.showShareMenu';
|
|
43
43
|
const SHARE_SCREENSHOT_METHOD = 'share.screenshot';
|
|
44
|
+
const VIEWPORT_SET_DISPLAY_METHOD = 'viewport.setDisplay';
|
|
44
45
|
const VIEWPORT_GET_WINDOW_INFO_METHOD = 'viewport.getWindowInfo';
|
|
45
46
|
const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle';
|
|
46
47
|
const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage';
|
|
@@ -164,6 +165,13 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
164
165
|
requirement: { kind: 'none' },
|
|
165
166
|
risk: 'low',
|
|
166
167
|
},
|
|
168
|
+
{
|
|
169
|
+
method: VIEWPORT_SET_DISPLAY_METHOD,
|
|
170
|
+
module: 'viewport',
|
|
171
|
+
capability: VIEWPORT_SET_DISPLAY_METHOD,
|
|
172
|
+
requirement: { kind: 'none' },
|
|
173
|
+
risk: 'low',
|
|
174
|
+
},
|
|
167
175
|
{
|
|
168
176
|
method: STORAGE_GET_STORAGE_METHOD,
|
|
169
177
|
module: 'storage',
|
|
@@ -439,7 +447,7 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
|
|
|
439
447
|
* @see [parseMiniProgramRuntimePermissions](/reference/symbols/protocol/functions/parseMiniProgramRuntimePermissions) Runtime 权限快照解析器。
|
|
440
448
|
*/
|
|
441
449
|
function isMiniProgramBridgeMessage(value) {
|
|
442
|
-
if (!isRecord$
|
|
450
|
+
if (!isRecord$3(value))
|
|
443
451
|
return false;
|
|
444
452
|
if (value.namespace !== MINI_PROGRAM_MESSAGE_NAMESPACE || (value.version !== 1 && value.version !== 2) || !isNonEmptyString$1(value.nonce)) {
|
|
445
453
|
return false;
|
|
@@ -589,7 +597,7 @@ function isMiniProgramRelativePath(value) {
|
|
|
589
597
|
* @see [DirectoryHandle](/reference/symbols/root/interfaces/DirectoryHandle) 可作为 derived path root 的目录代理。
|
|
590
598
|
*/
|
|
591
599
|
function isMiniProgramPathRootRef(value) {
|
|
592
|
-
if (!isRecord$
|
|
600
|
+
if (!isRecord$3(value))
|
|
593
601
|
return false;
|
|
594
602
|
if (value.kind === 'sandbox')
|
|
595
603
|
return hasOnlyKeys(value, ['kind']);
|
|
@@ -655,7 +663,7 @@ function isMiniProgramPathRootRef(value) {
|
|
|
655
663
|
* @see [FileHandle](/reference/symbols/root/interfaces/FileHandle) 使用文件引用的公开 I/O 代理。
|
|
656
664
|
*/
|
|
657
665
|
function isMiniProgramFileRef(value) {
|
|
658
|
-
if (!isRecord$
|
|
666
|
+
if (!isRecord$3(value) || value.kind !== 'file')
|
|
659
667
|
return false;
|
|
660
668
|
if (isNonEmptyString$1(value.handleId)) {
|
|
661
669
|
return hasOnlyKeys(value, ['kind', 'handleId']);
|
|
@@ -722,7 +730,7 @@ function isMiniProgramFileRef(value) {
|
|
|
722
730
|
* @see [DirectoryHandle](/reference/symbols/root/interfaces/DirectoryHandle) 使用目录引用的公开路径操作代理。
|
|
723
731
|
*/
|
|
724
732
|
function isMiniProgramDirectoryRef(value) {
|
|
725
|
-
if (!isRecord$
|
|
733
|
+
if (!isRecord$3(value) || value.kind !== 'directory')
|
|
726
734
|
return false;
|
|
727
735
|
if (isNonEmptyString$1(value.handleId)) {
|
|
728
736
|
return hasOnlyKeys(value, ['kind', 'handleId']);
|
|
@@ -796,7 +804,7 @@ function isMiniProgramDirectoryRef(value) {
|
|
|
796
804
|
* @see [SaveFileResult](/reference/symbols/protocol/types/SaveFileResult) save picker 的 direct-ref 文件结果。
|
|
797
805
|
*/
|
|
798
806
|
function isMiniProgramFileDescriptor(value) {
|
|
799
|
-
return (isRecord$
|
|
807
|
+
return (isRecord$3(value) &&
|
|
800
808
|
value.kind === 'file' &&
|
|
801
809
|
isNonEmptyString$1(value.name) &&
|
|
802
810
|
isFileMode(value.mode) &&
|
|
@@ -866,7 +874,7 @@ function isMiniProgramFileDescriptor(value) {
|
|
|
866
874
|
* @see [PickDirectoryResult](/reference/symbols/protocol/types/PickDirectoryResult) picker 的 direct-ref 返回契约。
|
|
867
875
|
*/
|
|
868
876
|
function isMiniProgramDirectoryDescriptor(value) {
|
|
869
|
-
return (isRecord$
|
|
877
|
+
return (isRecord$3(value) &&
|
|
870
878
|
value.kind === 'directory' &&
|
|
871
879
|
isNonEmptyString$1(value.name) &&
|
|
872
880
|
isFileMode(value.mode) &&
|
|
@@ -1045,7 +1053,7 @@ function isMiniProgramByteArray(value) {
|
|
|
1045
1053
|
* @see [FileHandle](/reference/symbols/root/interfaces/FileHandle) 提供 `stat()` 的当前 session 文件代理。
|
|
1046
1054
|
*/
|
|
1047
1055
|
function isMiniProgramFileStat(value) {
|
|
1048
|
-
return (isRecord$
|
|
1056
|
+
return (isRecord$3(value) &&
|
|
1049
1057
|
value.kind === 'file' &&
|
|
1050
1058
|
isNonNegativeSafeInteger(value.size) &&
|
|
1051
1059
|
(value.modifiedAt === undefined || isNonNegativeFiniteNumber(value.modifiedAt)) &&
|
|
@@ -1105,7 +1113,7 @@ function isMiniProgramFileStat(value) {
|
|
|
1105
1113
|
* @see [isMiniProgramBridgeMessage](/reference/symbols/protocol/functions/isMiniProgramBridgeMessage) operation progress envelope 的最低校验。
|
|
1106
1114
|
*/
|
|
1107
1115
|
function isMiniProgramDownloadProgressPayload(value) {
|
|
1108
|
-
if (!isRecord$
|
|
1116
|
+
if (!isRecord$3(value) ||
|
|
1109
1117
|
!isNonNegativeSafeInteger(value.loaded) ||
|
|
1110
1118
|
typeof value.lengthComputable !== 'boolean' ||
|
|
1111
1119
|
!hasOnlyKeys(value, ['loaded', 'total', 'lengthComputable'])) {
|
|
@@ -1116,7 +1124,7 @@ function isMiniProgramDownloadProgressPayload(value) {
|
|
|
1116
1124
|
return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
|
|
1117
1125
|
}
|
|
1118
1126
|
function isMiniProgramCompanionPrepareProgress(value) {
|
|
1119
|
-
if (!isRecord$
|
|
1127
|
+
if (!isRecord$3(value))
|
|
1120
1128
|
return false;
|
|
1121
1129
|
if (value.phase === 'downloading') {
|
|
1122
1130
|
return (isNonNegativeSafeInteger(value.loaded) &&
|
|
@@ -1134,10 +1142,10 @@ function isMiniProgramOperationProgressPayload(value) {
|
|
|
1134
1142
|
return isMiniProgramDownloadProgressPayload(value) || isMiniProgramCompanionPrepareProgress(value);
|
|
1135
1143
|
}
|
|
1136
1144
|
function isSDKHandshakePayload(value) {
|
|
1137
|
-
return isRecord$
|
|
1145
|
+
return isRecord$3(value) && isNonEmptyString$1(value.href) && typeof value.userAgent === 'string' && isNonEmptyString$1(value.sdkVersion);
|
|
1138
1146
|
}
|
|
1139
1147
|
function isBridgeError(value) {
|
|
1140
|
-
return isRecord$
|
|
1148
|
+
return isRecord$3(value) && isNonEmptyString$1(value.code) && typeof value.message === 'string';
|
|
1141
1149
|
}
|
|
1142
1150
|
function isFileMode(value) {
|
|
1143
1151
|
return value === 'read' || value === 'readwrite';
|
|
@@ -1155,156 +1163,10 @@ function hasOnlyKeys(value, allowedKeys) {
|
|
|
1155
1163
|
const allowed = new Set(allowedKeys);
|
|
1156
1164
|
return Object.keys(value).every((key) => allowed.has(key));
|
|
1157
1165
|
}
|
|
1158
|
-
function isRecord$
|
|
1166
|
+
function isRecord$3(value) {
|
|
1159
1167
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1160
1168
|
}
|
|
1161
1169
|
|
|
1162
|
-
/** 由 scripts/generate-native-host-contract.mjs 生成,请勿手改。 */
|
|
1163
|
-
const MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION = 1;
|
|
1164
|
-
const MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION = 1;
|
|
1165
|
-
const MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES = 65536;
|
|
1166
|
-
const MINI_PROGRAM_NATIVE_OPERATIONS = {
|
|
1167
|
-
"system": [
|
|
1168
|
-
"describe"
|
|
1169
|
-
],
|
|
1170
|
-
"network": [
|
|
1171
|
-
"open",
|
|
1172
|
-
"read",
|
|
1173
|
-
"release",
|
|
1174
|
-
"transfer"
|
|
1175
|
-
],
|
|
1176
|
-
"files": [
|
|
1177
|
-
"create",
|
|
1178
|
-
"remove",
|
|
1179
|
-
"exists",
|
|
1180
|
-
"openRead",
|
|
1181
|
-
"openWrite",
|
|
1182
|
-
"read",
|
|
1183
|
-
"release",
|
|
1184
|
-
"write",
|
|
1185
|
-
"stat",
|
|
1186
|
-
"list",
|
|
1187
|
-
"pickFiles",
|
|
1188
|
-
"pickDirectory",
|
|
1189
|
-
"saveFile"
|
|
1190
|
-
]
|
|
1191
|
-
};
|
|
1192
|
-
const MINI_PROGRAM_NATIVE_HOST_DESCRIPTION = {
|
|
1193
|
-
"protocolVersion": 1,
|
|
1194
|
-
"contractRevision": 1,
|
|
1195
|
-
"operations": {
|
|
1196
|
-
"system": [
|
|
1197
|
-
"describe"
|
|
1198
|
-
],
|
|
1199
|
-
"network": [
|
|
1200
|
-
"open",
|
|
1201
|
-
"read",
|
|
1202
|
-
"release",
|
|
1203
|
-
"transfer"
|
|
1204
|
-
],
|
|
1205
|
-
"files": [
|
|
1206
|
-
"create",
|
|
1207
|
-
"remove",
|
|
1208
|
-
"exists",
|
|
1209
|
-
"openRead",
|
|
1210
|
-
"openWrite",
|
|
1211
|
-
"read",
|
|
1212
|
-
"release",
|
|
1213
|
-
"write",
|
|
1214
|
-
"stat",
|
|
1215
|
-
"list",
|
|
1216
|
-
"pickFiles",
|
|
1217
|
-
"pickDirectory",
|
|
1218
|
-
"saveFile"
|
|
1219
|
-
]
|
|
1220
|
-
}
|
|
1221
|
-
};
|
|
1222
|
-
|
|
1223
|
-
/** Android WebMessageListener object 与 iOS WKScriptMessageHandler 共用名称。 */
|
|
1224
|
-
const MINI_PROGRAM_NATIVE_HOST_OBJECT = 'hbMiniProgramHost';
|
|
1225
|
-
/** Native 通过主文档 CustomEvent 回送 progress/result/error。 */
|
|
1226
|
-
const MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT = 'heybox:miniprogram-native-host-message';
|
|
1227
|
-
function isMiniProgramNativeHostMessage(value) {
|
|
1228
|
-
if (!isRecord$1(value) || !isNonEmptyString(value.requestId))
|
|
1229
|
-
return false;
|
|
1230
|
-
if (value.type === 'progress')
|
|
1231
|
-
return Object.prototype.hasOwnProperty.call(value, 'payload');
|
|
1232
|
-
if (value.type === 'result')
|
|
1233
|
-
return !Object.prototype.hasOwnProperty.call(value, 'error');
|
|
1234
|
-
if (value.type !== 'error' || !isRecord$1(value.error))
|
|
1235
|
-
return false;
|
|
1236
|
-
return isNonEmptyString(value.error.code) && isNonEmptyString(value.error.message);
|
|
1237
|
-
}
|
|
1238
|
-
function isMiniProgramNativeHostDescription(value) {
|
|
1239
|
-
if (!isRecord$1(value) ||
|
|
1240
|
-
!isPositiveSafeInteger(value.protocolVersion) ||
|
|
1241
|
-
!isPositiveSafeInteger(value.contractRevision) ||
|
|
1242
|
-
!isRecord$1(value.operations))
|
|
1243
|
-
return false;
|
|
1244
|
-
const operations = value.operations;
|
|
1245
|
-
if (!isOperationList(operations.system) ||
|
|
1246
|
-
!isOperationList(operations.network) ||
|
|
1247
|
-
!isOperationList(operations.files))
|
|
1248
|
-
return false;
|
|
1249
|
-
return operations.system.includes('describe');
|
|
1250
|
-
}
|
|
1251
|
-
function isMiniProgramNativeBinaryChunk(value) {
|
|
1252
|
-
return (isRecord$1(value) &&
|
|
1253
|
-
isNonEmptyString(value.resourceId) &&
|
|
1254
|
-
typeof value.data === 'string' &&
|
|
1255
|
-
Number.isSafeInteger(value.byteLength) &&
|
|
1256
|
-
Number(value.byteLength) >= 0 &&
|
|
1257
|
-
Number(value.byteLength) <= MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES &&
|
|
1258
|
-
typeof value.eof === 'boolean' &&
|
|
1259
|
-
(Number(value.byteLength) > 0 || value.eof));
|
|
1260
|
-
}
|
|
1261
|
-
function isRecord$1(value) {
|
|
1262
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
1263
|
-
}
|
|
1264
|
-
function isNonEmptyString(value) {
|
|
1265
|
-
return typeof value === 'string' && value.length > 0;
|
|
1266
|
-
}
|
|
1267
|
-
function isPositiveSafeInteger(value) {
|
|
1268
|
-
return Number.isSafeInteger(value) && Number(value) > 0;
|
|
1269
|
-
}
|
|
1270
|
-
function isOperationList(value) {
|
|
1271
|
-
return (Array.isArray(value) &&
|
|
1272
|
-
value.every(operation => isNonEmptyString(operation) && operation === operation.trim()) &&
|
|
1273
|
-
new Set(value).size === value.length);
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
/** 当前用户信息与登录能力支持的完整 scope 目录(canonical 顺序)。 */
|
|
1277
|
-
const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile', 'steam_account'];
|
|
1278
|
-
/** Companion alias 的跨构建、Runtime 与 Host 规范。 */
|
|
1279
|
-
const COMPANION_ALIAS_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;
|
|
1280
|
-
/** Companion Host 可跨 bridge 保留的稳定领域错误码。 */
|
|
1281
|
-
const COMPANION_ERROR_CODES = [
|
|
1282
|
-
'COMPANION_UNSUPPORTED',
|
|
1283
|
-
'COMPANION_PREVIEW_UNSUPPORTED',
|
|
1284
|
-
'COMPANION_NOT_DECLARED',
|
|
1285
|
-
'COMPANION_TARGET_UNSUPPORTED',
|
|
1286
|
-
'COMPANION_NOT_PREPARED',
|
|
1287
|
-
'COMPANION_PREPARATION_CANCELLED',
|
|
1288
|
-
'COMPANION_DOWNLOAD_FAILED',
|
|
1289
|
-
'COMPANION_DESCRIPTOR_UNAVAILABLE',
|
|
1290
|
-
'COMPANION_ARCHIVE_INVALID',
|
|
1291
|
-
'COMPANION_INTEGRITY_FAILED',
|
|
1292
|
-
'COMPANION_ENTRYPOINT_INVALID',
|
|
1293
|
-
'COMPANION_USER_CANCELLED',
|
|
1294
|
-
'COMPANION_ELEVATION_DENIED',
|
|
1295
|
-
'COMPANION_OS_BLOCKED',
|
|
1296
|
-
'COMPANION_LAUNCH_FAILED',
|
|
1297
|
-
'COMPANION_SESSION_VERSION_MISMATCH',
|
|
1298
|
-
'COMPANION_SESSION_OWNERSHIP_LOST',
|
|
1299
|
-
'COMPANION_SESSION_EXITED',
|
|
1300
|
-
'COMPANION_PIPE_CLOSED',
|
|
1301
|
-
'COMPANION_OUTPUT_LIMIT',
|
|
1302
|
-
'COMPANION_PROCESS_CRASHED',
|
|
1303
|
-
'COMPANION_ATTACHMENT_NOT_FOUND',
|
|
1304
|
-
'COMPANION_NOTIFICATION_UNAVAILABLE',
|
|
1305
|
-
'COMPANION_TERMINATE_FAILED',
|
|
1306
|
-
];
|
|
1307
|
-
|
|
1308
1170
|
const MINI_PROGRAM_PERMISSION_KEYS = [
|
|
1309
1171
|
'userInfo',
|
|
1310
1172
|
'steamLibrary',
|
|
@@ -1458,6 +1320,7 @@ const MINI_PROGRAM_NO_DECLARATION_METHODS = [
|
|
|
1458
1320
|
'ui.hideLoading',
|
|
1459
1321
|
'viewport.getWindowInfo',
|
|
1460
1322
|
'viewport.setNavigationBarStyle',
|
|
1323
|
+
'viewport.setDisplay',
|
|
1461
1324
|
'device.vibrate',
|
|
1462
1325
|
'navigation.close',
|
|
1463
1326
|
'navigation.reload',
|
|
@@ -1598,7 +1461,7 @@ function isManagedMiniProgramRuntimePermissionKey(key) {
|
|
|
1598
1461
|
* @see {@link https://docs.xiaoheihe.cn/hb_sdk/guide/permissions | 权限声明}
|
|
1599
1462
|
*/
|
|
1600
1463
|
function parseMiniProgramRuntimePermissions(snapshot) {
|
|
1601
|
-
if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
|
|
1464
|
+
if (!isRecord$2(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
|
|
1602
1465
|
return { valid: false, permissions: {} };
|
|
1603
1466
|
}
|
|
1604
1467
|
if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
|
|
@@ -1607,7 +1470,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
1607
1470
|
const seenKeys = new Set();
|
|
1608
1471
|
const permissions = {};
|
|
1609
1472
|
for (const rawEntry of snapshot.entries) {
|
|
1610
|
-
if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
|
|
1473
|
+
if (!isRecord$2(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
|
|
1611
1474
|
return { valid: false, permissions: {} };
|
|
1612
1475
|
}
|
|
1613
1476
|
const inputKey = rawEntry.key.trim();
|
|
@@ -1623,7 +1486,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
1623
1486
|
}
|
|
1624
1487
|
if (key === 'network') {
|
|
1625
1488
|
const config = rawEntry.config;
|
|
1626
|
-
if (!isRecord(config) || typeof config.useOfficialDomain !== 'boolean') {
|
|
1489
|
+
if (!isRecord$2(config) || typeof config.useOfficialDomain !== 'boolean') {
|
|
1627
1490
|
return { valid: false, permissions: {} };
|
|
1628
1491
|
}
|
|
1629
1492
|
permissions[key] = {
|
|
@@ -1633,7 +1496,7 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
1633
1496
|
};
|
|
1634
1497
|
continue;
|
|
1635
1498
|
}
|
|
1636
|
-
if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
|
|
1499
|
+
if (rawEntry.config !== null && rawEntry.config !== undefined && (!isRecord$2(rawEntry.config) || Object.keys(rawEntry.config).length > 0)) {
|
|
1637
1500
|
return { valid: false, permissions: {} };
|
|
1638
1501
|
}
|
|
1639
1502
|
permissions[key] = {
|
|
@@ -1644,10 +1507,266 @@ function parseMiniProgramRuntimePermissions(snapshot) {
|
|
|
1644
1507
|
}
|
|
1645
1508
|
return { valid: true, permissions };
|
|
1646
1509
|
}
|
|
1647
|
-
function isRecord(value) {
|
|
1510
|
+
function isRecord$2(value) {
|
|
1648
1511
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1649
1512
|
}
|
|
1650
1513
|
|
|
1514
|
+
/** 仅供开发工具和 Host 使用;新增权限必须单独评估,不能从平台审批目录自动推导。 */
|
|
1515
|
+
const LOCAL_DEV_GRANT_PERMISSION_KEYS = ['network', 'companion'];
|
|
1516
|
+
/**
|
|
1517
|
+
* 严格解析本地 grant。任何未知字段、重复权限或非法配置都拒绝整份输入。
|
|
1518
|
+
* 只校验数据合同;票据、身份、摘要、过期时间和 CLI lease 必须由 Host 另行验证。
|
|
1519
|
+
*/
|
|
1520
|
+
function parseMiniProgramLocalDevGrant(value) {
|
|
1521
|
+
if (!hasExactFields(value, ['schema_version', 'revision', 'entries']) ||
|
|
1522
|
+
value.schema_version !== 1 ||
|
|
1523
|
+
typeof value.revision !== 'number' ||
|
|
1524
|
+
!Number.isSafeInteger(value.revision) ||
|
|
1525
|
+
value.revision < 0 ||
|
|
1526
|
+
!Array.isArray(value.entries) ||
|
|
1527
|
+
value.entries.length > LOCAL_DEV_GRANT_PERMISSION_KEYS.length)
|
|
1528
|
+
return { valid: false };
|
|
1529
|
+
const entries = [];
|
|
1530
|
+
const seen = new Set();
|
|
1531
|
+
for (const entry of value.entries) {
|
|
1532
|
+
if (!hasExactFields(entry, ['key', 'status', 'config']) || entry.status !== 'enabled')
|
|
1533
|
+
return { valid: false };
|
|
1534
|
+
if (typeof entry.key !== 'string' || seen.has(entry.key))
|
|
1535
|
+
return { valid: false };
|
|
1536
|
+
seen.add(entry.key);
|
|
1537
|
+
if (entry.key === 'network') {
|
|
1538
|
+
if (!hasExactFields(entry.config, ['useOfficialDomain']) || entry.config.useOfficialDomain !== false)
|
|
1539
|
+
return { valid: false };
|
|
1540
|
+
entries.push({ key: 'network', status: 'enabled', config: { useOfficialDomain: false } });
|
|
1541
|
+
}
|
|
1542
|
+
else if (entry.key === 'companion') {
|
|
1543
|
+
if (!hasExactFields(entry.config, []))
|
|
1544
|
+
return { valid: false };
|
|
1545
|
+
entries.push({ key: 'companion', status: 'enabled', config: {} });
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
return { valid: false };
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
entries.sort((a, b) => LOCAL_DEV_GRANT_PERMISSION_KEYS.indexOf(a.key) - LOCAL_DEV_GRANT_PERMISSION_KEYS.indexOf(b.key));
|
|
1552
|
+
return { valid: true, grant: { schema_version: 1, revision: value.revision, entries } };
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* 从已校验声明生成批准缺口。Companion 默认不符合资格,由 CLI 确认平台、产物与摘要后显式加入。
|
|
1556
|
+
* 空 entries 可保留 revision,不能作为存在临时权限的判断依据。
|
|
1557
|
+
*/
|
|
1558
|
+
function createMiniProgramLocalDevGrant(options) {
|
|
1559
|
+
if (!Number.isSafeInteger(options.revision) || options.revision < 0)
|
|
1560
|
+
throw new Error('本地调试权限 revision 必须是非负安全整数');
|
|
1561
|
+
const approvals = parseMiniProgramRuntimePermissions(options.runtimePermissions);
|
|
1562
|
+
const eligible = new Set(options.eligiblePermissionKeys ?? ['network']);
|
|
1563
|
+
const entries = [];
|
|
1564
|
+
for (const key of LOCAL_DEV_GRANT_PERMISSION_KEYS) {
|
|
1565
|
+
if (!eligible.has(key) || options.declaredPermissions[key]?.enabled !== true)
|
|
1566
|
+
continue;
|
|
1567
|
+
if (approvals.valid && approvals.permissions[key]?.status === 'enabled')
|
|
1568
|
+
continue;
|
|
1569
|
+
entries.push(key === 'network'
|
|
1570
|
+
? { key, status: 'enabled', config: { useOfficialDomain: false } }
|
|
1571
|
+
: { key, status: 'enabled', config: {} });
|
|
1572
|
+
}
|
|
1573
|
+
return { schema_version: 1, revision: options.revision, entries };
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* 线上基线先与本地声明求交,再补齐临时权限,返回与输入脱离的普通 Runtime 快照。
|
|
1577
|
+
* 调用方只可在当前 Dev Session 已验证且用户接受后传入 grant;本函数不证明其可信来源。
|
|
1578
|
+
* 非法 grant 整体降权到基线,已批准配置不会被临时配置覆盖。
|
|
1579
|
+
*/
|
|
1580
|
+
function composeLocalDevRuntimePermissions(options) {
|
|
1581
|
+
const baseline = parseMiniProgramRuntimePermissions(options.runtimePermissions);
|
|
1582
|
+
const parsed = parseMiniProgramLocalDevGrant(options.localDevGrant);
|
|
1583
|
+
const permissions = baseline.valid ? baseline.permissions : {};
|
|
1584
|
+
for (const key of MINI_PROGRAM_PERMISSION_KEYS) {
|
|
1585
|
+
if (options.declaredPermissions[key]?.enabled !== true) {
|
|
1586
|
+
delete permissions[key];
|
|
1587
|
+
}
|
|
1588
|
+
else if (key === 'network' && permissions.network) {
|
|
1589
|
+
permissions.network.config.useOfficialDomain = permissions.network.status === 'enabled'
|
|
1590
|
+
&& permissions.network.config.useOfficialDomain === true
|
|
1591
|
+
&& options.declaredPermissions.network?.useOfficialDomain === true;
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
const temporaryPermissionKeys = [];
|
|
1595
|
+
if (parsed.valid) {
|
|
1596
|
+
for (const entry of parsed.grant.entries) {
|
|
1597
|
+
if (options.declaredPermissions[entry.key]?.enabled !== true || permissions[entry.key]?.status === 'enabled')
|
|
1598
|
+
continue;
|
|
1599
|
+
permissions[entry.key] = entry;
|
|
1600
|
+
temporaryPermissionKeys.push(entry.key);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
const revision = isRecord$1(options.runtimePermissions) && typeof options.runtimePermissions.revision === 'number'
|
|
1604
|
+
&& Number.isSafeInteger(options.runtimePermissions.revision) && options.runtimePermissions.revision >= 0
|
|
1605
|
+
? options.runtimePermissions.revision : undefined;
|
|
1606
|
+
return {
|
|
1607
|
+
runtimePermissions: {
|
|
1608
|
+
schema_version: 1,
|
|
1609
|
+
...(revision === undefined ? {} : { revision }),
|
|
1610
|
+
entries: MINI_PROGRAM_PERMISSION_KEYS.flatMap((key) => permissions[key] ? [permissions[key]] : []),
|
|
1611
|
+
},
|
|
1612
|
+
temporaryPermissionKeys,
|
|
1613
|
+
grantValid: parsed.valid,
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
function isRecord$1(value) {
|
|
1617
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
1618
|
+
}
|
|
1619
|
+
function hasExactFields(value, fields) {
|
|
1620
|
+
return isRecord$1(value) && Object.keys(value).length === fields.length
|
|
1621
|
+
&& fields.every((field) => Object.prototype.hasOwnProperty.call(value, field));
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
/** 由 scripts/generate-native-host-contract.mjs 生成,请勿手改。 */
|
|
1625
|
+
const MINI_PROGRAM_NATIVE_HOST_PROTOCOL_VERSION = 1;
|
|
1626
|
+
const MINI_PROGRAM_NATIVE_HOST_CONTRACT_REVISION = 1;
|
|
1627
|
+
const MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES = 65536;
|
|
1628
|
+
const MINI_PROGRAM_NATIVE_OPERATIONS = {
|
|
1629
|
+
"system": [
|
|
1630
|
+
"describe"
|
|
1631
|
+
],
|
|
1632
|
+
"network": [
|
|
1633
|
+
"open",
|
|
1634
|
+
"read",
|
|
1635
|
+
"release",
|
|
1636
|
+
"transfer"
|
|
1637
|
+
],
|
|
1638
|
+
"files": [
|
|
1639
|
+
"create",
|
|
1640
|
+
"remove",
|
|
1641
|
+
"exists",
|
|
1642
|
+
"openRead",
|
|
1643
|
+
"openWrite",
|
|
1644
|
+
"read",
|
|
1645
|
+
"release",
|
|
1646
|
+
"write",
|
|
1647
|
+
"stat",
|
|
1648
|
+
"list",
|
|
1649
|
+
"pickFiles",
|
|
1650
|
+
"pickDirectory",
|
|
1651
|
+
"saveFile"
|
|
1652
|
+
]
|
|
1653
|
+
};
|
|
1654
|
+
const MINI_PROGRAM_NATIVE_HOST_DESCRIPTION = {
|
|
1655
|
+
"protocolVersion": 1,
|
|
1656
|
+
"contractRevision": 1,
|
|
1657
|
+
"operations": {
|
|
1658
|
+
"system": [
|
|
1659
|
+
"describe"
|
|
1660
|
+
],
|
|
1661
|
+
"network": [
|
|
1662
|
+
"open",
|
|
1663
|
+
"read",
|
|
1664
|
+
"release",
|
|
1665
|
+
"transfer"
|
|
1666
|
+
],
|
|
1667
|
+
"files": [
|
|
1668
|
+
"create",
|
|
1669
|
+
"remove",
|
|
1670
|
+
"exists",
|
|
1671
|
+
"openRead",
|
|
1672
|
+
"openWrite",
|
|
1673
|
+
"read",
|
|
1674
|
+
"release",
|
|
1675
|
+
"write",
|
|
1676
|
+
"stat",
|
|
1677
|
+
"list",
|
|
1678
|
+
"pickFiles",
|
|
1679
|
+
"pickDirectory",
|
|
1680
|
+
"saveFile"
|
|
1681
|
+
]
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
|
|
1685
|
+
/** Android WebMessageListener object 与 iOS WKScriptMessageHandler 共用名称。 */
|
|
1686
|
+
const MINI_PROGRAM_NATIVE_HOST_OBJECT = 'hbMiniProgramHost';
|
|
1687
|
+
/** Native 通过主文档 CustomEvent 回送 progress/result/error。 */
|
|
1688
|
+
const MINI_PROGRAM_NATIVE_HOST_MESSAGE_EVENT = 'heybox:miniprogram-native-host-message';
|
|
1689
|
+
function isMiniProgramNativeHostMessage(value) {
|
|
1690
|
+
if (!isRecord(value) || !isNonEmptyString(value.requestId))
|
|
1691
|
+
return false;
|
|
1692
|
+
if (value.type === 'progress')
|
|
1693
|
+
return Object.prototype.hasOwnProperty.call(value, 'payload');
|
|
1694
|
+
if (value.type === 'result')
|
|
1695
|
+
return !Object.prototype.hasOwnProperty.call(value, 'error');
|
|
1696
|
+
if (value.type !== 'error' || !isRecord(value.error))
|
|
1697
|
+
return false;
|
|
1698
|
+
return isNonEmptyString(value.error.code) && isNonEmptyString(value.error.message);
|
|
1699
|
+
}
|
|
1700
|
+
function isMiniProgramNativeHostDescription(value) {
|
|
1701
|
+
if (!isRecord(value) ||
|
|
1702
|
+
!isPositiveSafeInteger(value.protocolVersion) ||
|
|
1703
|
+
!isPositiveSafeInteger(value.contractRevision) ||
|
|
1704
|
+
!isRecord(value.operations))
|
|
1705
|
+
return false;
|
|
1706
|
+
const operations = value.operations;
|
|
1707
|
+
if (!isOperationList(operations.system) ||
|
|
1708
|
+
!isOperationList(operations.network) ||
|
|
1709
|
+
!isOperationList(operations.files))
|
|
1710
|
+
return false;
|
|
1711
|
+
return operations.system.includes('describe');
|
|
1712
|
+
}
|
|
1713
|
+
function isMiniProgramNativeBinaryChunk(value) {
|
|
1714
|
+
return (isRecord(value) &&
|
|
1715
|
+
isNonEmptyString(value.resourceId) &&
|
|
1716
|
+
typeof value.data === 'string' &&
|
|
1717
|
+
Number.isSafeInteger(value.byteLength) &&
|
|
1718
|
+
Number(value.byteLength) >= 0 &&
|
|
1719
|
+
Number(value.byteLength) <= MINI_PROGRAM_NATIVE_CHUNK_MAX_BYTES &&
|
|
1720
|
+
typeof value.eof === 'boolean' &&
|
|
1721
|
+
(Number(value.byteLength) > 0 || value.eof));
|
|
1722
|
+
}
|
|
1723
|
+
function isRecord(value) {
|
|
1724
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
1725
|
+
}
|
|
1726
|
+
function isNonEmptyString(value) {
|
|
1727
|
+
return typeof value === 'string' && value.length > 0;
|
|
1728
|
+
}
|
|
1729
|
+
function isPositiveSafeInteger(value) {
|
|
1730
|
+
return Number.isSafeInteger(value) && Number(value) > 0;
|
|
1731
|
+
}
|
|
1732
|
+
function isOperationList(value) {
|
|
1733
|
+
return (Array.isArray(value) &&
|
|
1734
|
+
value.every(operation => isNonEmptyString(operation) && operation === operation.trim()) &&
|
|
1735
|
+
new Set(value).size === value.length);
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
/** 当前用户信息与登录能力支持的完整 scope 目录(canonical 顺序)。 */
|
|
1739
|
+
const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile', 'steam_account'];
|
|
1740
|
+
/** Companion alias 的跨构建、Runtime 与 Host 规范。 */
|
|
1741
|
+
const COMPANION_ALIAS_PATTERN = /^[a-z][a-z0-9-]{0,31}$/;
|
|
1742
|
+
/** Companion Host 可跨 bridge 保留的稳定领域错误码。 */
|
|
1743
|
+
const COMPANION_ERROR_CODES = [
|
|
1744
|
+
'COMPANION_UNSUPPORTED',
|
|
1745
|
+
'COMPANION_PREVIEW_UNSUPPORTED',
|
|
1746
|
+
'COMPANION_NOT_DECLARED',
|
|
1747
|
+
'COMPANION_TARGET_UNSUPPORTED',
|
|
1748
|
+
'COMPANION_NOT_PREPARED',
|
|
1749
|
+
'COMPANION_PREPARATION_CANCELLED',
|
|
1750
|
+
'COMPANION_DOWNLOAD_FAILED',
|
|
1751
|
+
'COMPANION_DESCRIPTOR_UNAVAILABLE',
|
|
1752
|
+
'COMPANION_ARCHIVE_INVALID',
|
|
1753
|
+
'COMPANION_INTEGRITY_FAILED',
|
|
1754
|
+
'COMPANION_ENTRYPOINT_INVALID',
|
|
1755
|
+
'COMPANION_USER_CANCELLED',
|
|
1756
|
+
'COMPANION_ELEVATION_DENIED',
|
|
1757
|
+
'COMPANION_OS_BLOCKED',
|
|
1758
|
+
'COMPANION_LAUNCH_FAILED',
|
|
1759
|
+
'COMPANION_SESSION_VERSION_MISMATCH',
|
|
1760
|
+
'COMPANION_SESSION_OWNERSHIP_LOST',
|
|
1761
|
+
'COMPANION_SESSION_EXITED',
|
|
1762
|
+
'COMPANION_PIPE_CLOSED',
|
|
1763
|
+
'COMPANION_OUTPUT_LIMIT',
|
|
1764
|
+
'COMPANION_PROCESS_CRASHED',
|
|
1765
|
+
'COMPANION_ATTACHMENT_NOT_FOUND',
|
|
1766
|
+
'COMPANION_NOTIFICATION_UNAVAILABLE',
|
|
1767
|
+
'COMPANION_TERMINATE_FAILED',
|
|
1768
|
+
];
|
|
1769
|
+
|
|
1651
1770
|
exports.AUTH_LOGIN_METHOD = AUTH_LOGIN_METHOD;
|
|
1652
1771
|
exports.CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD;
|
|
1653
1772
|
exports.CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD;
|
|
@@ -1688,6 +1807,7 @@ exports.FILE_REMOVE_METHOD = FILE_REMOVE_METHOD;
|
|
|
1688
1807
|
exports.FILE_STAT_METHOD = FILE_STAT_METHOD;
|
|
1689
1808
|
exports.FILE_WRITE_BYTES_METHOD = FILE_WRITE_BYTES_METHOD;
|
|
1690
1809
|
exports.FILE_WRITE_TEXT_METHOD = FILE_WRITE_TEXT_METHOD;
|
|
1810
|
+
exports.LOCAL_DEV_GRANT_PERMISSION_KEYS = LOCAL_DEV_GRANT_PERMISSION_KEYS;
|
|
1691
1811
|
exports.MINI_PROGRAM_BRIDGE_NONCE_PARAM = MINI_PROGRAM_BRIDGE_NONCE_PARAM;
|
|
1692
1812
|
exports.MINI_PROGRAM_MESSAGE_NAMESPACE = MINI_PROGRAM_MESSAGE_NAMESPACE;
|
|
1693
1813
|
exports.MINI_PROGRAM_MESSAGE_VERSION = MINI_PROGRAM_MESSAGE_VERSION;
|
|
@@ -1725,7 +1845,10 @@ exports.USER_GET_STEAM_GAME_LIST_METHOD = USER_GET_STEAM_GAME_LIST_METHOD;
|
|
|
1725
1845
|
exports.USER_INFO_AUTHORIZATION_SCOPES = USER_INFO_AUTHORIZATION_SCOPES;
|
|
1726
1846
|
exports.USER_REVOKE_AUTHORIZATION_METHOD = USER_REVOKE_AUTHORIZATION_METHOD;
|
|
1727
1847
|
exports.VIEWPORT_GET_WINDOW_INFO_METHOD = VIEWPORT_GET_WINDOW_INFO_METHOD;
|
|
1848
|
+
exports.VIEWPORT_SET_DISPLAY_METHOD = VIEWPORT_SET_DISPLAY_METHOD;
|
|
1728
1849
|
exports.VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
|
|
1850
|
+
exports.composeLocalDevRuntimePermissions = composeLocalDevRuntimePermissions;
|
|
1851
|
+
exports.createMiniProgramLocalDevGrant = createMiniProgramLocalDevGrant;
|
|
1729
1852
|
exports.isManagedMiniProgramRuntimePermissionKey = isManagedMiniProgramRuntimePermissionKey;
|
|
1730
1853
|
exports.isMiniProgramBridgeMessage = isMiniProgramBridgeMessage;
|
|
1731
1854
|
exports.isMiniProgramByteArray = isMiniProgramByteArray;
|
|
@@ -1744,4 +1867,5 @@ exports.isMiniProgramOperationProgressPayload = isMiniProgramOperationProgressPa
|
|
|
1744
1867
|
exports.isMiniProgramPathRootRef = isMiniProgramPathRootRef;
|
|
1745
1868
|
exports.isMiniProgramPermissionKey = isMiniProgramPermissionKey;
|
|
1746
1869
|
exports.isMiniProgramRelativePath = isMiniProgramRelativePath;
|
|
1870
|
+
exports.parseMiniProgramLocalDevGrant = parseMiniProgramLocalDevGrant;
|
|
1747
1871
|
exports.parseMiniProgramRuntimePermissions = parseMiniProgramRuntimePermissions;
|